Date: Fri, 29 Apr 2011 11:29:41 -0400 From: Ryan Stone <rysto32@gmail.com> To: freebsd-rc@freebsd.org Subject: rc.d scripts can be missed if they aren't ordered with respect to the early-late divider Message-ID: <BANLkTi=FH4DeB-bH9Dcre_U-5J%2BP%2B3o_BA@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
The only day I ran into an issue where certain rc.d scripts were being skipped during boot. I investigated it and the problem was that when rc went to execute the early rc.d scripts, rcorder placed the missed scripts after the early-late divider. However when rcorder was run the second time the missed scripts were placed before the early-late divider. Because of this, rc skipped over those scripts incorrectly. Ultimately, the problem is that we don't have a total ordering over the rc.d scripts. This means that the sequence produced by rcorder isn't guaranteed to be consistent. In particular, if an rc.d script is not ordered with respect to the early-late divider rcorder is free to place it either before or after the divider. If you're unlucky, rcorder may reorder a script on the second invocation. Below I have a patch that fixes the issue for me. Rather than making the incorrect assumption that the second rcorder invocation will create a sequence that is consistent with the first invocation, and skipping all scripts that the second invocation orders before the early-late divider, I instead have rc track with rc.d scripts have already run, and when running the late rc.d scripts rc skips all scripts that have yet to run. There's one caveat to this patch. It assumes that you don't have two different scripts in /etc/rc.d named foo and foo.sh (or foo.bar, for that matter). I can't figure out a way to resolve this with the limited facilities available to rc before the early scripts have been run, but maybe somebody else has an idea? --- rc (revision 221208) +++ rc (working copy) @@ -86,6 +86,9 @@ for _rc_elem in ${files}; do run_rc_script ${_rc_elem} ${_boot} + _rc_basename=${_rc_elem##*/} + eval _${_rc_basename%%.*}_has_run=1 + unset _rc_basename case "$_rc_elem" in */${early_late_divider}) break ;; @@ -103,13 +106,16 @@ esac files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null` -_skip_early=1 for _rc_elem in ${files}; do - case "$_skip_early" in - 1) case "$_rc_elem" in - */${early_late_divider}) _skip_early=0 ;; - esac - continue + case "$_rc_elem" in + /etc/rc.d/*) + _rc_basename=${_rc_elem##*/} + eval _has_run=\$_${_rc_basename%%.*}_has_run + if [ -n "$_has_run" ]; then + unset _has_run _rc_basename + continue + fi + unset _has_run _rc_basename ;; esac
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BANLkTi=FH4DeB-bH9Dcre_U-5J%2BP%2B3o_BA>