Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Apr 2011 05:11:44 -0500
From:      Brooks Davis <brooks@freebsd.org>
To:        Ryan Stone <rysto32@gmail.com>
Cc:        freebsd-rc@freebsd.org
Subject:   Re: rc.d scripts can be missed if they aren't ordered with respect to the early-late divider
Message-ID:  <20110429101144.GF75044@lor.one-eyed-alien.net>
In-Reply-To: <BANLkTi=FH4DeB-bH9Dcre_U-5J%2BP%2B3o_BA@mail.gmail.com>
References:  <BANLkTi=FH4DeB-bH9Dcre_U-5J%2BP%2B3o_BA@mail.gmail.com>

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

--Bqc0IY4JZZt50bUr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Apr 29, 2011 at 11:29:41AM -0400, Ryan Stone wrote:
> 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.
>=20
> 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.
>=20
> 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.

I've wanted to do this for a while.  I believe this is the right
approach.

> 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?

It's hard to do it in general, but if you want to support common things
like scripts containing '.', you can use the ltr function.  I used this
to collapse '.' '-' '/' and '+' to '_' in network.subr (search for
_punct_c).  I might just support '.' or maybe '.' and '-'.

The general answer to this problem would probably be to add a
non-standard associative array type based on ksh or bash.

The patch below looks fine to me.  If you have access to some slow
hardware (soekris or something) it might be worth bench marking this to
make sure it doesn't slow things down too much but all in all I think
the correctness is likely worth it.

-- Brooks

> --- rc  (revision 221208)
> +++ rc  (working copy)
> @@ -86,6 +86,9 @@
>=20
>  for _rc_elem in ${files}; do
>         run_rc_script ${_rc_elem} ${_boot}
> +       _rc_basename=3D${_rc_elem##*/}
> +       eval _${_rc_basename%%.*}_has_run=3D1
> +       unset _rc_basename
>=20
>         case "$_rc_elem" in
>         */${early_late_divider})        break ;;
> @@ -103,13 +106,16 @@
>  esac
>=20
>  files=3D`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
> -_skip_early=3D1
>  for _rc_elem in ${files}; do
> -       case "$_skip_early" in
> -       1)      case "$_rc_elem" in
> -               */${early_late_divider})        _skip_early=3D0 ;;
> -               esac
> -               continue
> +       case "$_rc_elem" in
> +       /etc/rc.d/*)
> +               _rc_basename=3D${_rc_elem##*/}
> +               eval _has_run=3D\$_${_rc_basename%%.*}_has_run
> +               if [ -n "$_has_run" ]; then
> +                       unset _has_run _rc_basename
> +                       continue
> +               fi
> +               unset _has_run _rc_basename
>                 ;;
>         esac
> _______________________________________________
> freebsd-rc@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-rc
> To unsubscribe, send any mail to "freebsd-rc-unsubscribe@freebsd.org"
>=20

--Bqc0IY4JZZt50bUr
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iD8DBQFNuo7gXY6L6fI4GtQRAsiVAKCRdcCv3SYYOHyUDeI6E14Z40WfngCg1lZP
eZCIbLXUp1fpTyVkFD+nITU=
=cxWy
-----END PGP SIGNATURE-----

--Bqc0IY4JZZt50bUr--



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