Date: Wed, 21 Jan 1998 17:20:16 +0200 (EET) From: Calin Andrian <calin@ibd.dbio.ro> To: freebsd-hackers@FreeBSD.ORG Subject: Kernel patches for POWEROFF Message-ID: <Pine.BSF.3.96.980121170836.325A-100000@ibd.dbio.ro>
next in thread | raw e-mail | index | archive | help
While playing with my APC back-ups I was advised by Bruce M. Walter that the POST_SYNC queue is not the safe place for a poweroff routine. The way to do it is to patch the kernel. The patches follow. The new, improved and packed with these diffs APC Back-UPS monitor is now: ftp://ftp.dbio.ro/pub/FreeBSD/local/apcb-0.2.tgz Sorry for respawning so rapidly. WHAT THE DIFFS CHANGE: at_shutdown() has a new queue named SHUTDOWN_POWEROFF which calls functions that are supposed to turn off the power (after POST_SYNC queue is done). This happens when /sbin/reboot and its links are run with -p switch. Maybe it should have been a single function not a whole queue, but the list ops were already there, so... /sbin/reboot no longer defines RB_HALT when called with -p switch. This means that if the poweroff fails, the system reboots for /sbin/reboot and halts for /sbin/halt. For example, if the APC back-ups has AC input, you cannot shut down the UPS (it ignores you). So, if the power was restored after you committed the system shutdown, the system restarts immediately. The original /sbin/reboot didn't allow this. If you don't want to reboot, use /sbin/halt ! DIFFS: (3 pcs) *** /usr/src/sys/kern/kern_shutdown.c.orig Wed Jan 21 12:53:39 1998 --- /usr/src/sys/kern/kern_shutdown.c Wed Jan 21 13:13:45 1998 *************** *** 118,123 **** --- 118,124 ---- */ static sle_p shutdown_list1; static sle_p shutdown_list2; + static sle_p shutdown_list3; static void dumpsys(void); *************** *** 247,252 **** --- 248,265 ---- (*ep->function)(howto, ep->arg); ep = ep->next; } + if (howto & RB_POWEROFF) { + printf("\nTurning off power...\n"); + DELAY(1000 * 1000); + ep = shutdown_list3; + while (ep) { + shutdown_list3 = ep->next; + (*ep->function)(howto, ep->arg); + ep = ep->next; + } + DELAY(5000 * 1000); /* Wait 5 secs for power off */ + /* Continue if power off failed */ + } splhigh(); if (howto & RB_HALT) { printf("\n"); *************** *** 411,416 **** --- 424,432 ---- case SHUTDOWN_POST_SYNC: epp = &shutdown_list2; break; + case SHUTDOWN_POWEROFF: + epp = &shutdown_list3; + break; default: printf("bad exit callout list specified\n"); return (EINVAL); *************** *** 451,456 **** --- 467,484 ---- ep = *epp; } 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; + } + epp = &shutdown_list3; ep = *epp; while (ep) { if ((ep->function == function) && (ep->arg == arg)) { *** /usr/src/sbin/reboot/reboot.c.orig Wed Jan 21 13:09:08 1998 --- /usr/src/sbin/reboot/reboot.c Wed Jan 21 13:09:36 1998 *************** *** 85,91 **** break; case 'p': pflag = 1; ! howto |= (RB_POWEROFF | RB_HALT); break; case 'q': qflag = 1; --- 85,91 ---- break; case 'p': pflag = 1; ! howto |= RB_POWEROFF; break; case 'q': qflag = 1; *** /usr/src/sys/sys/systm.h.orig Wed Jan 21 13:11:56 1998 --- /usr/src/sys/sys/systm.h Wed Jan 21 13:11:27 1998 *************** *** 171,176 **** --- 171,177 ---- int rm_at_shutdown(bootlist_fn function, void *arg); #define SHUTDOWN_PRE_SYNC 0 #define SHUTDOWN_POST_SYNC 1 + #define SHUTDOWN_POWEROFF 2 /* forking */ /* XXX not yet */ typedef void (*forklist_fn)(struct proc *parent,struct proc *child,int flags);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.980121170836.325A-100000>