rc.conf sanity check in reboot or better parsing?

I thought I would post this to get some comments.

The rc scripts do a . (aka source) import of /etc/rc.conf which means any syntax error makes the machine unusable.

A simple `sh /etc/rc.conf` will show these errors but kills the shell that runs it.
Is there a way that /sbin/reboot could do that test and ask if it should reboot a broken system?
Another option would be fix rc to do checking and fallback to something like /etc/rc.conf.safe or a line by line parsing to keep some of the system running like bringing up interfaces and sshd. Most rc.conf files could be split -l 1 and then sourced independently.

Simply sourcing the rc.conf in a subshell does work:
Code:
#!/bin/sh
`. ./rc.test || echo bad1` || echo Bad2
Will claim "Bad2" if given bad input such as:
Code:
#syntax error double double quote at end:
foo_enable="YES""

Perhaps the best option is if `. rc.conf` then . rc.conf else . rc.conf.safe? Or split and do that per line?
The problem is reboot is sometimes scripted with no human interaction so "rc.conf is borked, no reboot for you" isn't an option and splitting the rc.conf needs safe place to do it that is writable very early in the boot process way before things are set up nice and sane.
 
Use sysrc(8). You can check the config with sysrc -c. And your machine is not unusable. You can boot single user mode where you can mount the root filesystem read-write and edit the file manually.
If it is remote and I have to go visit it, it is unusable in my opinion.
sysrc's check feature isn't intuitive and sysrc -f rc.test -a works the same as sh rc.test. Perhaps a new sysrc -t should default to useful defaults for testing mirroring apachectl -t. Either way having reboot do a check (maybe only when run from a tty) seems to be a sane thing to me.
 
[…] Is there a way that /sbin/reboot could do that test and ask if it should reboot a broken system?
[…]
shutdown(8) (or reboot(8)) isn’t configurable, like, you can’t place a configuration file somewhere mandating such a check. (There’s /etc/rc.shutdown but it cannot block the request.) What you can do, though, is write your own wrapper script bearing the same name of the respective command, and place it in a (newly created) directory appearing before /sbin in $PATH of an interactive sh(1)ell.​
Bash:
printf 'This is %s, a wrapper script.\n' "${0}"
sh -n /etc/rc.conf || {
	printf 'Reboot anyway? [y|N] '
	read -r confirmation
	[ "${confirmation%es}" = 'y' ] || exit 1
}
exec /sbin/shutdown -r "${@}"
For a more elaborate solution – for inspiration – take a look at Molly Guard, in particular run.d/30-query-hostname: users logged in via ssh(1) are asked to type out the machine name. Unfortunately it isn’t available for FreeBSD.​
[…] Perhaps the best option is if `. rc.conf` then . rc.conf else . rc.conf.safe?
That really just shifts the problem from A to B.​
Or split and do that per line? […]
It may be suitable to you, but I want my system to either work as I configured it, or not work at all, e. g. because the partial configuration is a security threat.​
 
If it's remote you need IPMI or some other remote KVM solution. What about typos in /etc/fstab? Or a botched upgrade? There are many reasons why a system could fail to boot.
The one that prompted this had a broken IPMI as well. I expect it happens enough that simple fixes should be considered.

I know the many ways to break systems. My first was a bad edit for a sysv initab so long ago.
On current systems 'sh -b /etc/rc.conf' provides status if that key file is broken. I had the concern that running odd code in rc.conf on reboot or testing could have nasty implications but this fixes that. So can reboot do a 'if `sh -b /etc/rc.conf` ... else print "fix rc.conf, do you want to reboot to a broken system?" sort of thing. Also I'm open to alternate names for /etc/rc.conf.TheRealOneIsBrokenSoUseThis because I think doing fixes in rc isn't too complex and isn't much different than other existing tests.
 
Back
Top