summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1996-08-22 03:50:33 +0000
committerjulian <julian@FreeBSD.org>1996-08-22 03:50:33 +0000
commite5048c6cd53c81e64bc5beaf9cc05549039c4188 (patch)
tree36f241a22c1b649e9fd947dfe20092d354b2dfe0
parent2da1db6ea869d363d2b95c24f7947a1905a0183d (diff)
downloadFreeBSD-src-e5048c6cd53c81e64bc5beaf9cc05549039c4188.zip
FreeBSD-src-e5048c6cd53c81e64bc5beaf9cc05549039c4188.tar.gz
Some cleanups to the callout lists recently added.
note that at_shutdown has a new parameter to indicate When during a shutdown the callout should be made. also add a RB_POWEROFF flag to reboot "howto" parameter.. tells the reboot code in our at_shutdown module to turn off the UPS and kill the power. bound to be useful eventually on laptops
-rw-r--r--lib/libc/sys/reboot.23
-rw-r--r--share/man/man9/at_shutdown.916
-rw-r--r--sys/dev/vn/vn.c4
-rw-r--r--sys/kern/kern_exit.c41
-rw-r--r--sys/kern/kern_fork.c67
-rw-r--r--sys/kern/kern_shutdown.c95
-rw-r--r--sys/sys/reboot.h3
-rw-r--r--sys/sys/systm.h8
8 files changed, 151 insertions, 86 deletions
diff --git a/lib/libc/sys/reboot.2 b/lib/libc/sys/reboot.2
index ad66ee5..d51468d 100644
--- a/lib/libc/sys/reboot.2
+++ b/lib/libc/sys/reboot.2
@@ -81,6 +81,9 @@ for more information.
.It Dv RB_HALT
the processor is simply halted; no reboot takes place.
This option should be used with caution.
+.It Dv RB_POWEROFF
+After halting, the shutdown code will do what it can to turn
+of the power. This requires hardware support.
.It Dv RB_INITNAME
An option allowing the specification of an init program (see
.Xr init 8 )
diff --git a/share/man/man9/at_shutdown.9 b/share/man/man9/at_shutdown.9
index 73e3a1f..47e7a44 100644
--- a/share/man/man9/at_shutdown.9
+++ b/share/man/man9/at_shutdown.9
@@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $Id: at_shutdown.9,v 1.1 1996/08/19 02:22:15 julian Exp $
+.\" $Id: at_shutdown.9,v 1.2 1996/08/21 21:43:19 mpp Exp $
.\" "
.Dd August 15, 1996
.Os
@@ -33,14 +33,14 @@
.Nm rm_at_shutdown
.Nd ask that a function be run at shutdown.
.Sh SYNOPSIS
-.Fd #include <sys/systm.h>
.Fd #include <sys/reboot.h>
+.Fd #include <sys/systm.h>
.Ft typedef void \*(lp*bootlist_fn\*(rp \*(lpint, void *\*(rp;
.Ft void
-.Fn at_shutdown "bootlist_fn func" "void *arg"
+.Fn at_shutdown "bootlist_fn func" "void *arg" "int when"
.Ft void
.Fn rm_at_shutdown "bootlist_fn func" "void *arg"
.Sh DESCRIPTION
@@ -62,6 +62,16 @@ and
.Ar arg
arguments as the corresponding call to
.Fn at_shutdown .
+There are two shutdown queues, one run before the final sync and one after.
+The last argument to
+.Nm at_shutdown
+should be one of
+.Em SHUTDOWN_PRE_SYNC
+or
+.Em SHUTDOWN_POST_SYNC
+to specify which queue should be used.
+.Nm rm_at_shutdown
+will remove an entry from either queue.
.Pp
.Sh RETURN VALUES
.Nm at_shutdown
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c
index 1a03644..70a31ef 100644
--- a/sys/dev/vn/vn.c
+++ b/sys/dev/vn/vn.c
@@ -38,7 +38,7 @@
* from: Utah Hdr: vn.c 1.13 94/04/02
*
* from: @(#)vn.c 8.6 (Berkeley) 4/1/94
- * $Id: vn.c,v 1.38 1996/08/19 20:06:41 julian Exp $
+ * $Id: vn.c,v 1.39 1996/08/19 21:06:39 julian Exp $
*/
/*
@@ -621,7 +621,7 @@ vn_drvinit(void *unused)
if( ! vn_devsw_installed ) {
bdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &vn_bdevsw);
- if(at_shutdown(&vnshutdown,NULL)) {
+ if(at_shutdown(&vnshutdown, NULL, SHUTDOWN_POST_SYNC)) {
printf("vn: could not install shutdown hook\n");
return;
}
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index fc58173..0201635 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.36 1996/08/19 02:28:23 julian Exp $
+ * $Id: kern_exit.c,v 1.37 1996/08/20 07:17:47 smpatel Exp $
*/
#include "opt_ktrace.h"
@@ -130,11 +130,11 @@ exit1(p, rv)
vmsizmon();
#endif
/*
- * Check if any LKMs need anything done at process exit
+ * Check if any LKMs need anything done at process exit.
* e.g. SYSV IPC stuff
* XXX what if one of these generates an error?
*/
- while(ep) {
+ while (ep) {
(*ep->function)(p);
ep = ep->next;
}
@@ -501,11 +501,12 @@ proc_reparent(child, parent)
child->p_pptr = parent;
}
-/*********************************************************
- * general routines to handle adding/deleting items on the
+/*
+ * The next two functions are to handle adding/deleting items on the
* exit callout list
- *****
- * Take the arguments given and put them onto the exit callout list.
+ *
+ * at_exit():
+ * Take the arguments given and put them onto the exit callout list,
* However first make sure that it's not already there.
* returns 0 on success.
*/
@@ -513,39 +514,43 @@ int
at_exit(exitlist_fn function)
{
ele_p ep;
- if(rm_at_exit(function)) {
+
+ /* Be noisy if the programmer has lost track of things */
+ if (rm_at_exit(function))
printf("exit callout entry already present\n");
- }
- ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT);
- if(!ep) return ENOMEM;
+ ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
+ if (ep == NULL)
+ return (ENOMEM);
ep->next = exit_list;
ep->function = function;
exit_list = ep;
- return 0;
+ return (0);
}
/*
* Scan the exit callout list for the given items and remove them.
* Returns the number of items removed.
+ * Logically this can only be 0 or 1.
*/
int
rm_at_exit(exitlist_fn function)
{
- ele_p *epp,ep;
- int count = 0;
+ ele_p *epp, ep;
+ int count;
+ count = 0;
epp = &exit_list;
ep = *epp;
- while(ep) {
- if(ep->function == function) {
+ while (ep) {
+ if (ep->function == function) {
*epp = ep->next;
- free(ep,M_TEMP);
+ free(ep, M_TEMP);
count++;
} else {
epp = &ep->next;
}
ep = *epp;
}
- return count;
+ return (count);
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index f6bb284..d037fbd 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
- * $Id: kern_fork.c,v 1.23 1996/07/31 09:26:34 davidg Exp $
+ * $Id: kern_fork.c,v 1.24 1996/08/19 02:28:24 julian Exp $
*/
#include "opt_ktrace.h"
@@ -65,18 +65,19 @@
static int fork1 __P((struct proc *p, int flags, int *retval));
/*
- * callout list for things to do at fork time
+ * These are the stuctures used to create a callout list for things to do
+ * when forking a process
*/
typedef struct fork_list_element {
struct fork_list_element *next;
forklist_fn function;
} *fle_p;
-static fle_p fork_list;
+static fle_p fork_list;
#ifndef _SYS_SYSPROTO_H_
struct fork_args {
- int dummy;
+ int dummy;
};
#endif
@@ -124,8 +125,9 @@ fork1(p1, flags, retval)
struct proc *newproc;
int count;
static int nextpid, pidchecked = 0;
- fle_p ep = fork_list;
+ fle_p ep ;
+ ep = fork_list;
if ((flags & RFPROC) == 0)
return (EINVAL);
if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
@@ -346,14 +348,14 @@ again:
}
/*
- * Both processes are set up,
- * check if any LKMs want to adjust anything
- * What if they have an error? XXX
+ * Both processes are set up, now check if any LKMs want
+ * to adjust anything.
+ * What if they have an error? XXX
*/
- while(ep) {
- (*ep->function)(p1,p2,flags);
- ep = ep->next;
- }
+ while (ep) {
+ (*ep->function)(p1, p2, flags);
+ ep = ep->next;
+ }
/*
* Make child runnable and add to run queue.
@@ -385,52 +387,57 @@ again:
return (0);
}
-
-/*********************************************************
- * general routines to handle adding/deleting items on the
- * fork callout list
- *****
- * Take the arguments given and put them onto the fork callout list.
+/*
+ * The next two functionms are general routines to handle adding/deleting
+ * items on the fork callout list.
+ *
+ * at_fork():
+ * Take the arguments given and put them onto the fork callout list,
* However first make sure that it's not already there.
- * returns 0 on success.
+ * Returns 0 on success or a standard error number.
*/
int
at_fork(forklist_fn function)
{
fle_p ep;
- if(rm_at_fork(function)) {
+
+ /* let the programmer know if he's been stupid */
+ if (rm_at_fork(function))
printf("fork callout entry already present\n");
- }
- ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT);
- if(!ep) return ENOMEM;
+ ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
+ if (ep == NULL)
+ return (ENOMEM);
ep->next = fork_list;
ep->function = function;
fork_list = ep;
- return 0;
+ return (0);
}
+
/*
* Scan the exit callout list for the given items and remove them.
* Returns the number of items removed.
+ * Theoretically this value can only be 0 or 1.
*/
int
rm_at_fork(forklist_fn function)
{
- fle_p *epp,ep;
- int count = 0;
+ fle_p *epp, ep;
+ int count;
+ count= 0;
epp = &fork_list;
ep = *epp;
- while(ep) {
- if(ep->function == function) {
+ while (ep) {
+ if (ep->function == function) {
*epp = ep->next;
- free(ep,M_TEMP);
+ free(ep, M_TEMP);
count++;
} else {
epp = &ep->next;
}
ep = *epp;
}
- return count;
+ return (count);
}
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 1ded33f..4d6b555 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94
- * $Id: kern_shutdown.c,v 1.1 1996/08/19 02:19:21 julian Exp $
+ * $Id: kern_shutdown.c,v 1.2 1996/08/19 20:06:59 julian Exp $
*/
#include "opt_ddb.h"
@@ -102,7 +102,12 @@ typedef struct shutdown_list_element {
void *arg;
} *sle_p;
-static sle_p shutdown_list;
+/*
+ * there are two shutdown lists. Some things need to be shut down
+ * Earlier than others.
+ */
+static sle_p shutdown_list1;
+static sle_p shutdown_list2;
@@ -170,7 +175,7 @@ __dead void
boot(howto)
int howto;
{
- sle_p ep = shutdown_list;
+ sle_p ep;
/*
* eventually the at_shutdown() method will totally replace the
@@ -180,14 +185,15 @@ boot(howto)
*/
if ((howto & RB_NOSYNC) == 0 ) {
printf("\ncleaning up... ");
- while(*cleanups) {
+ while (*cleanups) {
printf("Using obsolete shutdown callout..\n");
printf("update code to use at_shutdown()\n");
(**cleanups++)();
}
}
- while(ep) {
- shutdown_list = ep->next;
+ ep = shutdown_list1;
+ while (ep) {
+ shutdown_list1 = ep->next;
(*ep->function)(howto, ep->arg);
ep = ep->next;
}
@@ -239,6 +245,12 @@ boot(howto)
DELAY(100000); /* wait for console output to finish */
dev_shutdownall(FALSE);
}
+ ep = shutdown_list2;
+ while (ep) {
+ shutdown_list2 = ep->next;
+ (*ep->function)(howto, ep->arg);
+ ep = ep->next;
+ }
splhigh();
if (howto & RB_HALT) {
printf("\n");
@@ -378,53 +390,78 @@ panic(const char *fmt, ...)
boot(bootopt);
}
-
-/*********************************************************
- * general routines to handle adding/deleting items on the
- * shutdown callout list
- *****
+/*
+ * Two routines to handle adding/deleting items on the
+ * shutdown callout lists
+ *
+ * at_shutdown():
* Take the arguments given and put them onto the shutdown callout list.
* However first make sure that it's not already there.
* returns 0 on success.
*/
int
-at_shutdown(bootlist_fn function, void *arg)
+at_shutdown(bootlist_fn function, void *arg, int position)
{
- sle_p ep;
- if(rm_at_shutdown(function, arg)) {
- printf("exit callout entry already present\n");
+ sle_p ep, *epp;
+
+ switch(position) {
+ case SHUTDOWN_PRE_SYNC:
+ epp = &shutdown_list1;
+ break;
+ case SHUTDOWN_POST_SYNC:
+ epp = &shutdown_list2;
+ break;
+ default:
+ printf("bad exit callout list specified\n");
+ return (EINVAL);
}
- ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT);
- if(!ep) return ENOMEM;
- ep->next = shutdown_list;
+ if (rm_at_shutdown(function, arg))
+ printf("exit callout entry already present\n");
+ ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT);
+ if (ep == NULL)
+ return (ENOMEM);
+ ep->next = *epp;
ep->function = function;
ep->arg = arg;
- shutdown_list = ep;
- return 0;
+ *epp = ep;
+ return (0);
}
+
/*
- * Scan the exit callout list for the given items and remove them.
+ * Scan the exit callout lists for the given items and remove them.
* Returns the number of items removed.
*/
int
rm_at_shutdown(bootlist_fn function, void *arg)
{
- sle_p *epp,ep;
- int count = 0;
+ sle_p *epp, ep;
+ int count;
- epp = &shutdown_list;
+ count = 0;
+ epp = &shutdown_list1;
ep = *epp;
- while(ep) {
- if((ep->function == function) && (ep->arg = arg)) {
+ while (ep) {
+ if ((ep->function == function) && (ep->arg = arg)) {
*epp = ep->next;
- free(ep,M_TEMP);
+ free(ep, M_TEMP);
count++;
} else {
epp = &ep->next;
}
ep = *epp;
}
- return count;
+ epp = &shutdown_list2;
+ ep = *epp;
+ while (ep) {
+ if ((ep->function == function) && (ep->arg = arg)) {
+ *epp = ep->next;
+ free(ep, M_TEMP);
+ count++;
+ } else {
+ epp = &ep->next;
+ }
+ ep = *epp;
+ }
+ return (count);
}
-
diff --git a/sys/sys/reboot.h b/sys/sys/reboot.h
index b3b3033..ecf6cb8 100644
--- a/sys/sys/reboot.h
+++ b/sys/sys/reboot.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)reboot.h 8.3 (Berkeley) 12/13/94
- * $Id: reboot.h,v 1.11 1996/02/24 06:46:17 hsu Exp $
+ * $Id: reboot.h,v 1.11 1996/03/11 02:09:55 hsu Exp $
*/
#ifndef _SYS_REBOOT_H_
@@ -57,6 +57,7 @@
#define RB_VERBOSE 0x800 /* print all potentially useful info */
#define RB_SERIAL 0x1000 /* user serial port as console */
#define RB_CDROM 0x2000 /* use cdrom as root */
+#define RB_POWEROFF 0x4000 /* if you can, turn the power off */
#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 8a4ccc2..1896783 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)systm.h 8.7 (Berkeley) 3/29/95
- * $Id: systm.h,v 1.40 1996/07/01 18:12:13 bde Exp $
+ * $Id: systm.h,v 1.41 1996/08/19 02:19:23 julian Exp $
*/
#ifndef _SYS_SYSTM_H_
@@ -190,10 +190,12 @@ void untimeout(timeout_func_t, void *);
void logwakeup __P((void));
/* Various other callout lists that modules might want to know about */
-/* shutdown */
+/* shutdown callout list definitions */
typedef void (*bootlist_fn)(int,void *);
-int at_shutdown(bootlist_fn function, void *arg);
+int at_shutdown(bootlist_fn function, void *arg, int);
int rm_at_shutdown(bootlist_fn function, void *arg);
+#define SHUTDOWN_PRE_SYNC 0
+#define SHUTDOWN_POST_SYNC 1
/* forking */ /* XXX not yet */
typedef void (*forklist_fn)(struct proc *parent,struct proc *child,int flags);
OpenPOWER on IntegriCloud