diff --git a/lib/libc/sys/reboot.2 b/lib/libc/sys/reboot.2 index ad66ee5646db..d51468d8c358 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 73e3a1f0bced..47e7a448c6e0 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 .Fd #include +.Fd #include .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 1a0364498b75..70a31ef959f5 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 fc58173a6c2f..02016353cdb9 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 f6bb2840748b..d037fbd8240f 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 @@ fork1(p1, flags, retval) } /* - * 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 @@ fork1(p1, flags, retval) 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 1ded33f77cb3..4d6b555c9b47 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 b3b3033b72eb..ecf6cb89bd71 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 8a4ccc2bbeb5..1896783568fe 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);