Date: 07 Jan 98 15:48:46 +0100 From: leifn@image.dk (Leif Neland) To: freebsd-questions@freebsd.org Subject: making reboot/halt execute /etc/rc.shutdown Message-ID: <815_9801071814@swimsuit.swimsuit.roskildebc.dk>
next in thread | raw e-mail | index | archive | help
I have this diff for making halt/reboot execute /etc/rc.shutdown as init does when going singleuser/rebooting. I have also submitted it using send-pr. *** reboot.8 Sat Aug 24 03:39:59 1996 --- reboot.8.NE Wed Jan 7 12:48:34 1998 *************** *** 31,37 **** .\" .\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 .\" ! .Dd June 9, 1993 .Dt REBOOT 8 .Os .Sh NAME --- 31,37 ---- .\" .\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 .\" ! .Dd Jan 6, 1998 .Dt REBOOT 8 .Os .Sh NAME *************** *** 98,103 **** --- 98,119 ---- .Xr shutdown 8 utility is used when the system needs to be halted or restarted, giving users advance warning of their impending doom. + .Pp + If + .Nm halt + and + .Nm reboot + is not invoked with the "impatient" -n or -q flags, + .Nm init + is sent signal SIGINT, SIGUSR1 or SIGUSR2 to reboot, halt or powerdown, + instead of + .Nm halt/reboot + doing it itself. This allows + .Nm init + to execute + .Nm /etc/rc.shutdown, + to shut down system services gracefully. + .Sh SEE ALSO .Xr utmp 5 , .Xr boot 8 , *** reboot.c Sun Sep 14 21:41:49 1997 --- reboot.c.NE Wed Jan 7 12:57:59 1998 *************** *** 33,38 **** --- 33,54 ---- * $Id: reboot.c,v 1.3.2.3 1997/09/14 19:41:49 jkh Exp $ */ + /* Changes by Leif Neland, leifn@image.dk: 6 jan 1998 + * + * When init shuts multiuser mode down, the script /etc/rc.shutdown is + * executed. However reboot and halt doesn't signal init to shutdown, it + * just kills processes itself. + * + * I have modified init to accept SIGUSR1 meaning shutdown and halt, + * and accept SIGUSR2 meaning shutdown and poweroff. + * + * I have modified reboot to sending SIGINT, SIGUSR1 and SIGUSR2, if + * reboot, halt or reboot -p is called. + * + * However, init sync's, so if -n, nosync is wanted, init is not signaled, + * instead we just let reboot kill processes as usual. + * + */ #ifndef lint static char copyright[] = "@(#) Copyright (c) 1980, 1986, 1993\n\ *************** *** 122,138 **** } logwtmp("~", "shutdown", ""); /* * Do a sync early on, so disks start transfers while we're off * killing processes. Don't worry about writes done before the * processes die, the reboot system call syncs the disks. */ ! if (!nflag) sync(); ! /* Just stop init -- if we fail, we'll restart it. */ ! if (kill(1, SIGTSTP) == -1) ! err(1, "SIGTSTP init"); /* Ignore the SIGHUP we get when our parent shell dies. */ (void)signal(SIGHUP, SIG_IGN); --- 138,195 ---- } logwtmp("~", "shutdown", ""); + /* Stop init spawning gettys -- if we fail, we'll restart it. */ + if (kill(1, SIGTSTP) == -1) + err(1, "SIGTSTP init"); + /* * Do a sync early on, so disks start transfers while we're off * killing processes. Don't worry about writes done before the * processes die, the reboot system call syncs the disks. + * + * if the nflag is not set, just tell init to reboot/ + * halt/powerdown, by sending it a SIGINT/SIGUSR1/SIGUSR2. + * This will allow init to execute /etc/rc.shutdown. + * */ ! if (!nflag) { sync(); ! /* Try letting init handle it. If signal accepted, ! * then exit and let init do its stuff, else ! * we do it ourselves ! */ ! if (howto == RB_AUTOBOOT) { ! if (kill(1, SIGINT) == -1) { ! err(1, "SIGINT init") ; ! } else { ! #ifdef NOISY ! printf("I have told init to reboot\n"); ! #endif ! exit(0); ! } ! } ! if (howto & RB_POWEROFF) { ! if (kill(1, SIGUSR2) == -1) { ! err(1, "SIGUSR2 init") ; ! } else { ! #ifdef NOISY ! printf("I have told init to poweroff\n"); ! #endif ! exit(0); ! } ! } ! if (howto & RB_HALT) { ! if (kill(1, SIGUSR1) == -1) { ! err(1, "SIGUSR1 init") ; ! } else { ! #ifdef NOISY ! printf("I have told init to halt\n"); ! #endif ! exit(0); ! } ! } ! } /* Ignore the SIGHUP we get when our parent shell dies. */ (void)signal(SIGHUP, SIG_IGN); *** init.8 Mon Aug 18 05:30:04 1997 --- init.8.NE Wed Jan 7 12:48:10 1998 *************** *** 35,41 **** .\" @(#)init.8 8.3 (Berkeley) 4/18/94 .\" $Id: init.8,v 1.4.2.3 1997/08/18 03:30:04 davidn Exp $ .\" ! .Dd April 18, 1994 .Dt INIT 8 .Os BSD 4 .Sh NAME --- 35,41 ---- .\" @(#)init.8 8.3 (Berkeley) 4/18/94 .\" $Id: init.8,v 1.4.2.3 1997/08/18 03:30:04 davidn Exp $ .\" ! .Dd Jan 6, 1997 .Dt INIT 8 .Os BSD 4 .Sh NAME *************** *** 249,254 **** --- 249,262 ---- as .Nm innd (the InterNetNews server). + .Pp + .Dq Li "kill \-USR1 1" + and + .Dq Li "kill \-USR2 1" + works like + .Dq Li "kill \-INT 1" + except instead of rebooting after the system is shut down, the machine is + either halted or powered down (hardware permitting). .Pp The role of .Nm init *** init.c Mon Aug 18 05:30:04 1997 --- init.c.NE Wed Jan 7 14:59:00 1998 *************** *** 98,103 **** --- 98,104 ---- #define RESOURCE_RC "daemon" #define RESOURCE_WINDOW "default" #define RESOURCE_GETTY "default" + #define FAKE_SYSTEM_V_INIT void handle __P((sig_t, ...)); void delset __P((sigset_t *, ...)); *************** *** 130,135 **** --- 131,138 ---- #define TRUE 1 int Reboot = FALSE; + int Halt = FALSE; + int Powerdown = FALSE; int devfs; *************** *** 202,209 **** /* System V users like to reexec init. */ if (getpid() != 1) errx(1, "already running"); ! /* * Note that this does NOT open a file... * Does 'init' deserve its own facility number? --- 205,242 ---- /* System V users like to reexec init. */ if (getpid() != 1) + { + #ifdef FAKE_SYSTEM_5_INIT + /* So give them what they want */ + if (argc == 1) + {c = argv[1][1]; + switch (c) { + case '0': + kill(1,SIGUSR1); + break; + case '1': + kill(1,SIGTERM); + break; + case '6': + kill(1,SIGINT); + break; + case 'p': + kill(1,SIGUSR2); + break; + case 'q': + kill(1,SIGHUP); + break; + case 'c': + kill(1,SIGTSTP); + break; + default: + warning("unrecognized option: '%c'", c); + break; + } + } + #endif errx(1, "already running"); ! } /* * Note that this does NOT open a file... * Does 'init' deserve its own facility number? *************** *** 258,268 **** handle(badsys, SIGSYS, 0); handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); ! handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, ! SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, 0); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; --- 291,303 ---- handle(badsys, SIGSYS, 0); handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); ! handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGUSR1, ! SIGUSR2, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, ! SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, ! SIGUSR1, SIGUSR2, 0); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; *************** *** 594,600 **** sync(); alarm(2); pause(); ! reboot(RB_AUTOBOOT); _exit(0); } --- 629,635 ---- sync(); alarm(2); pause(); ! reboot(Powerdown ? RB_POWEROFF : Halt ? RB_HALT : RB_AUTOBOOT); _exit(0); } *************** *** 1234,1239 **** --- 1268,1277 ---- case SIGHUP: requested_transition = clean_ttys; break; + case SIGUSR2: + Powerdown = TRUE; + case SIGUSR1: + Halt = TRUE; case SIGINT: Reboot = TRUE; case SIGTERM: *************** *** 1412,1417 **** --- 1450,1456 ---- /* Try to run the rc.shutdown script within a period of time */ (void) runshutdown(); + for (i = 0; i < 2; ++i) { if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) return (state_func_t) single_user; ------------------------------------------------------------------------------- - --- |Fidonet: Leif Neland 2:234/49 |Internet: leifn@image.dk
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?815_9801071814>