Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Oct 2002 16:00:17 +0800 (NKZS)
From:      Eugene Grosbein <eugen@grosbein.pp.ru>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/43577: [PATCH] New kernel option SHUTDOWN_BEEP
Message-ID:  <200210020800.g9280Hvp019089@main.svzserv.kemerovo.su>

next in thread | raw e-mail | index | archive | help

>Number:         43577
>Category:       kern
>Synopsis:       [PATCH] New kernel option SHUTDOWN_BEEP
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 02 01:10:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.6-STABLE
>Organization:
Svyaz Service JSC
>Environment:
System: FreeBSD i386, FreeBSD alpha, FreeBSD pc98

>Description:
	There is common practice to run headless servers,
	that are servers without any kind of console.
	Sometimes such server mush be shut down for maintenance.
	There is a race when determining rigth time to power off machine
	if it does not turn power off itself and you have not console.

>How-To-Repeat:

	Try to shutdown headless system and not make fsck run on startup.

>Fix:

	One can reboot machine instead of shutting it down as workaround,
	most BIOS'es will beep on startup. One can turn power off
	immediately after beep and hope that's right time but there is
	a race still.

	This patch introduces new kernel option SHUTDOWN_BEEP.
	kernel compiled with this option will beep after unmounting
	disks right before 'The operating system has halted' message
	written to console, if any. So it's safe to turn power off
	after beeps.

	The patch was tested with several i386 machines and one
	Alpha Station 400. I have no PC98 to test but it should work.

	There are several sysctl's for fine tuning of beeps, see
	LINT after 'cd /usr/src/sys; patch < /path/to/patch'

	The patch is for 4.6-STABLE.

	NB: I put call to shutdown_beep() into shutdown_halt() first.
	But tests show tha shutdown_halt() is not invoked for alpha
	at this time (that's seem to be a bug), so I put the call
	to into boot().

Index: alpha/alpha/clock.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/clock.c,v
retrieving revision 1.13.2.2
diff -u -r1.13.2.2 clock.c
--- alpha/alpha/clock.c	17 Dec 2001 14:03:15 -0000	1.13.2.2
+++ alpha/alpha/clock.c	2 Oct 2002 03:26:00 -0000
@@ -492,7 +492,7 @@
 	return (0);
 }
 
-static void
+void
 sysbeepstop(void *chan)
 {
 	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
@@ -507,7 +507,10 @@
 #ifndef TIMER_FREQ
 #define	TIMER_FREQ	1193182
 #endif
-#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
+
+u_int	timer_freq = TIMER_FREQ;
+
+#define TIMER_DIV(x) ((timer_freq+(x)/2)/(x))
 
 int
 sysbeep(int pitch, int period)
Index: alpha/include/clock.h
===================================================================
RCS file: /home/ncvs/src/sys/alpha/include/clock.h,v
retrieving revision 1.5
diff -u -r1.5 clock.h
--- alpha/include/clock.h	29 Dec 1999 04:27:55 -0000	1.5
+++ alpha/include/clock.h	2 Oct 2002 03:34:00 -0000
@@ -14,9 +14,11 @@
 extern	int	disable_rtc_set;
 extern	int	wall_cmos_clock;
 extern	int	adjkerntz;
+extern	u_int	timer_freq;
 
 void	DELAY __P((int usec));
 int	sysbeep __P((int pitch, int period));
+void	sysbeepstop __P((void *chan));
 int	acquire_timer2 __P((int mode));
 int	release_timer2 __P((void));
 
Index: conf/options
===================================================================
RCS file: /home/ncvs/src/sys/conf/options,v
retrieving revision 1.191.2.44
diff -u -r1.191.2.44 options
--- conf/options	1 Sep 2002 07:18:21 -0000	1.191.2.44
+++ conf/options	2 Oct 2002 02:56:44 -0000
@@ -487,3 +487,6 @@
 
 # Polling device handling
 DEVICE_POLLING		opt_global.h
+
+# Issue sysctl-driven beeps at the end of shutdown
+SHUTDOWN_BEEP		opt_shutdown.h
Index: i386/conf/LINT
===================================================================
RCS file: /home/ncvs/src/sys/i386/conf/Attic/LINT,v
retrieving revision 1.749.2.123
diff -u -r1.749.2.123 LINT
--- i386/conf/LINT	17 Sep 2002 22:39:52 -0000	1.749.2.123
+++ i386/conf/LINT	2 Oct 2002 02:56:44 -0000
@@ -979,6 +979,21 @@
 # Size of the kernel message buffer.  Should be N * pagesize.
 options 	MSGBUF_SIZE=40960
 
+# The option SHUTDOWN_BEEP make kernel issue beep three times
+# after it has completed shutdown(8) or halt(8) procedures
+# right before CPU halt. It may be useful for headless system shutdown.
+# Fine tuning can be done using sysctl:
+#
+# kern.shutdown.beep_duration	- duration of beep in miliseconds,
+#				  zero value disables beeps
+# kern.shutdown.beep_hz		- tone of beep in hertz,
+#				  zero value disables beeps
+# kern.shutdown.beep_number	- number of beeps,
+#				  zero disables beeps
+# kern.shutdown.beep_pause	- pause between beeps, in miliseconds,
+#				  use zero value for infinite beep.
+options		SHUTDOWN_BEEP
+
 
 #####################################################################
 # HARDWARE DEVICE CONFIGURATION
Index: i386/include/clock.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/clock.h,v
retrieving revision 1.38
diff -u -r1.38 clock.h
--- i386/include/clock.h	29 Dec 1999 04:32:58 -0000	1.38
+++ i386/include/clock.h	2 Oct 2002 02:56:44 -0000
@@ -44,6 +44,7 @@
 int	release_timer1 __P((void));
 #endif
 int	sysbeep __P((int pitch, int period));
+void	sysbeepstop __P((void *chan));
 void	i8254_restore __P((void));
 
 #endif /* _KERNEL */
Index: i386/isa/clock.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/isa/clock.c,v
retrieving revision 1.149.2.5
diff -u -r1.149.2.5 clock.c
--- i386/isa/clock.c	30 Jun 2002 07:56:49 -0000	1.149.2.5
+++ i386/isa/clock.c	2 Oct 2002 02:56:44 -0000
@@ -509,7 +509,7 @@
 #endif
 }
 
-static void
+void
 sysbeepstop(void *chan)
 {
 	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
Index: kern/kern_shutdown.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_shutdown.c,v
retrieving revision 1.72.2.12
diff -u -r1.72.2.12 kern_shutdown.c
--- kern/kern_shutdown.c	21 Feb 2002 19:15:10 -0000	1.72.2.12
+++ kern/kern_shutdown.c	2 Oct 2002 06:58:40 -0000
@@ -200,6 +200,57 @@
 }
 
 /*
+ * Issue beeps if requested. It may be useful for headless system shutdown.
+ */
+
+#include "opt_shutdown.h"
+
+#ifdef	SHUTDOWN_BEEP
+static unsigned beep_duration = 300;	/* duration of beep in miliseconds */
+					/* zero disables beeps		   */
+static unsigned beep_hz = 500;	    /* tone of beep in hertz, 0 - no beeps */
+static unsigned beep_number = 3;      /* number of beeps, 0 disables beeps */
+static unsigned beep_pause = 300; /* pause between beeps, 0-infinite beep  */
+
+SYSCTL_UINT(_kern_shutdown, OID_AUTO, beep_duration, CTLFLAG_RW,
+    &beep_duration, 0, "");
+SYSCTL_UINT(_kern_shutdown, OID_AUTO, beep_hz, CTLFLAG_RW,
+    &beep_hz, 0, "");
+SYSCTL_UINT(_kern_shutdown, OID_AUTO, beep_number, CTLFLAG_RW,
+    &beep_number, 0, "");
+SYSCTL_UINT(_kern_shutdown, OID_AUTO, beep_pause, CTLFLAG_RW,
+    &beep_pause, 0, "");
+
+static void
+shutdown_beep(void)
+{
+	int i;
+
+	if (beep_hz==0 || beep_duration==0 || beep_number==0)
+		return;
+
+
+	beep_duration*=1000;			/* Adjust dimensions */
+	beep_pause*=1000;
+	beep_hz=timer_freq/beep_hz;
+			
+	for (i=1; i<beep_number; i++) {
+		sysbeep(beep_hz,0);		/* Issue one */
+		DELAY(beep_duration);
+		if (beep_pause>0) {
+			sysbeepstop(NULL);	/* Do pause */
+			DELAY(beep_pause);
+		}
+	}
+	sysbeep(beep_hz,0);
+	if (beep_pause>0) {		/* Zero pause means infinite beep */
+	    DELAY(beep_duration);
+	    sysbeepstop(NULL);
+	}
+}
+#endif	/* SHUTDOWN_BEEP */
+
+/*
  *  Go through the rigmarole of shutting down..
  * this used to be in machdep.c but I'll be dammned if I could see
  * anything machine dependant in it.
@@ -314,6 +365,14 @@
 	splhigh();
 	if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold)
 		dumpsys();
+
+#ifdef	SHUTDOWN_BEEP
+	/* Make beeps to say operator of (possibly) headless system
+	 * that it is now safe to turn power off.
+	 */
+	if (howto & RB_HALT)
+		shutdown_beep();
+#endif
 
 	/* Now that we're going to really halt the system... */
 	EVENTHANDLER_INVOKE(shutdown_final, howto);
Index: pc98/pc98/clock.c
===================================================================
RCS file: /home/ncvs/src/sys/pc98/pc98/clock.c,v
retrieving revision 1.81.2.3
diff -u -r1.81.2.3 clock.c
--- pc98/pc98/clock.c	29 Jun 2002 17:19:29 -0000	1.81.2.3
+++ pc98/pc98/clock.c	2 Oct 2002 03:01:57 -0000
@@ -571,7 +571,7 @@
 #endif
 }
 
-static void
+void
 sysbeepstop(void *chan)
 {
 #ifdef PC98	/* PC98 */


Eugene Grosbein
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210020800.g9280Hvp019089>