Subject: Re: ^C in fsck (segue from tech-kern)
To: None <tech-userlevel@NetBSD.org>
From: Alan Barrett <apb@cequrux.com>
List: tech-userlevel
Date: 04/05/2007 09:32:57
On Thu, 05 Apr 2007, der Mouse wrote:
> > I may not understand correctly the framework, but not stopping on
> > error for a script in rc.d/ not ending in ".sh" is a feature.
> 
> ...huh?  If a script is one for which ignoring errors is appropriate,
> it's perfectly capable of doing so itself.  How is it a feature to
> silently ignore errors if the name doesn't happen to end in .sh (which
> certainly doesn't say "pay attention to errors" to *me*, at least).

I agree.  However, ...

> > To "fault", a script must end in ".sh".
> 
> Where is this documented, and what is the connection betwee ".sh" and
> "is capable of faulting autoboot and going to single-user"?

It's documented in the the rc(8) man page.  Unfortunately, the
behaviour doesn't match the documentation.  I cooked up the appended
patch but haven't tested it.

--apb (Alan Barrett)

Index: etc/rc.subr
===================================================================
--- etc/rc.subr	27 Jan 2007 14:30:26 -0000	1.68
+++ etc/rc.subr	5 Apr 2007 07:29:07 -0000
@@ -39,6 +39,7 @@
 #
 
 : ${rcvar_manpage:='rc.conf(5)'}
+: ${RC_PID:=$$} ; export RC_PID
 
 #
 #	functions
@@ -84,6 +85,20 @@
 }
 
 #
+# If booting directly to multiuser, send SIGTERM to
+# the parent (/etc/rc) to abort the boot.
+# Otherwise just exit.
+#
+stop_boot()
+{
+	if [ "$autoboot" = yes ]; then
+		echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
+		kill -TERM ${RC_PID}
+	fi
+	exit 1
+}
+
+#
 # mount_critical_filesystems type
 #	Go through the list of critical filesystems as provided in
 #	the rc.conf(5) variable $critical_filesystems_${type}, checking
Index: etc/rc.d/fixsb
===================================================================
--- etc/rc.d/fixsb	30 Dec 2004 09:32:13 -0000	1.12
+++ etc/rc.d/fixsb	5 Apr 2007 07:29:07 -0000
@@ -127,16 +127,6 @@
 	done
 }
 
-stop_boot()
-{
-	# Terminate the process (which may include the parent /etc/rc)
-	# if booting directly to multiuser mode.
-	if [ "$autoboot" = "yes" ]; then
-		kill -TERM $$
-	fi
-	exit 1
-}
-
 do_fsck()
 {
 	# During fsck ignore SIGQUIT
Index: etc/rc.d/fsck
===================================================================
--- etc/rc.d/fsck	7 Oct 2006 04:11:23 -0000	1.6
+++ etc/rc.d/fsck	5 Apr 2007 07:29:07 -0000
@@ -12,17 +12,6 @@
 start_cmd="fsck_start"
 stop_cmd=":"
 
-stop_boot()
-{
-	#	Terminate the process (which may include the parent /etc/rc)
-	#	if booting directly to multiuser mode.
-	#
-	if [ "$autoboot" = yes ]; then
-		kill -TERM $$
-	fi
-	exit 1
-}
-
 fsck_start()
 {
 	if [ -e /fastboot ]; then
Index: etc/rc.d/ipfilter
===================================================================
--- etc/rc.d/ipfilter	23 Dec 2004 03:31:54 -0000	1.14
+++ etc/rc.d/ipfilter	5 Apr 2007 07:29:07 -0000
@@ -27,14 +27,7 @@
 	if [ ! -f /etc/ipf.conf ] && [ ! -f /etc/ipf6.conf ]; then
 		warn "/etc/ipf*.conf not readable; ipfilter start aborted."
 
-			# If booting directly to multiuser, send SIGTERM to
-			# the parent (/etc/rc) to abort the boot
-			#
-		if [ "$autoboot" = yes ]; then
-			echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
-			kill -TERM $$
-			exit 1
-		fi
+		stop_boot
 		return 1
 	fi
 	return 0
Index: etc/rc.d/ipsec
===================================================================
--- etc/rc.d/ipsec	13 Aug 2004 18:08:03 -0000	1.8
+++ etc/rc.d/ipsec	5 Apr 2007 07:29:07 -0000
@@ -24,15 +24,8 @@
 {
 	if [ ! -f /etc/ipsec.conf ]; then
 		warn "/etc/ipsec.conf not readable; ipsec start aborted."
-			#
-			# If booting directly to multiuser, send SIGTERM to
-			# the parent (/etc/rc) to abort the boot
-			#
-		if [ "$autoboot" = yes ]; then
-			echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
-			kill -TERM $$
-			exit 1
-		fi
+
+		stop_boot
 		return 1
 	fi
 	return 0
Index: etc/rc.d/pf
===================================================================
--- etc/rc.d/pf	23 Aug 2005 12:12:56 -0000	1.6
+++ etc/rc.d/pf	5 Apr 2007 07:29:07 -0000
@@ -23,13 +23,7 @@
 	if [ ! -f ${pf_rules} ]; then
 		warn "${pf_rules} not readable; pf start aborted."
 
-		# If booting directly to multiuser, send SIGTERM to
-		# the parent (/etc/rc) to abort the boot
-		if [ "$autoboot" = yes ]; then
-			echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
-			kill -TERM $$
-			exit 1
-		fi
+		stop_boot
 		return 1
 	fi
 	return 0
Index: etc/rc.d/pf_boot
===================================================================
--- etc/rc.d/pf_boot	23 Aug 2005 12:12:56 -0000	1.1
+++ etc/rc.d/pf_boot	5 Apr 2007 07:29:07 -0000
@@ -26,8 +26,7 @@
 		/sbin/pfctl -q -f /etc/defaults/pf.boot.conf
 	else
 		warn "can't load initial pf rules; pf start aborted."
-		echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
-		kill -TERM $$
+		stop_boot
 		exit 1
 	fi
 
Index: share/man/man8/rc.8
===================================================================
--- share/man/man8/rc.8	6 Jan 2004 14:46:11 -0000	1.28
+++ share/man/man8/rc.8	5 Apr 2007 07:29:07 -0000
@@ -219,16 +219,10 @@
 early in the boot.
 .It Pa bar
 Scripts that are sourced in a subshell.
-These can stop the boot if necessary with the following shell
-commands:
-.Bd -literal -offset
-	if [ "$autoboot" = yes ]; then
-		kill -TERM $$
-	fi
-	exit 1
-.Ed
 .Pp
-Note that this should be used extremely sparingly!
+The boot does not stop if such a script terminates with a non-zero status,
+but a script can stop the boot if necessary by invoking the
+stop_boot() function.
 .El
 .Pp
 Each script should contain