From owner-freebsd-rc@FreeBSD.ORG Fri Apr 29 15:57:54 2011 Return-Path: Delivered-To: freebsd-rc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B4E0A106564A for ; Fri, 29 Apr 2011 15:57:54 +0000 (UTC) (envelope-from rysto32@gmail.com) Received: from mail-ey0-f182.google.com (mail-ey0-f182.google.com [209.85.215.182]) by mx1.freebsd.org (Postfix) with ESMTP id 4C1008FC14 for ; Fri, 29 Apr 2011 15:57:53 +0000 (UTC) Received: by eyg7 with SMTP id 7so1492961eyg.13 for ; Fri, 29 Apr 2011 08:57:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:date:message-id:subject:from:to :content-type; bh=K7y+amzw7Ze94gqWXHHyi3Mm4Za5aD7KV7rP95gbhKs=; b=bBj+4kEw/+fE2QgCOk80XnfwG+VhUpDOe/h5g4E/ooi3bN86zo61TsQWll5ghkoP6H 0NjUVHsnBcFao7ldr6hH/pCW3KsHW08MfTyq8gqjW2S8HQkh8hPnDQMYcXeCpfIdn89X vejKBNOK0UoFsUGwxCDAkJCX0fM7Ve7++RRQU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=ePdNGd5E0DA2FdRKeUGt6tcUOpg33QnslfYT/nbQZubnFqF/HHhUPGIrAEJOnT9lox na1oOvFE12Oynm82HgtAA3M6yFsONEpqzm1I2K+MvPELkjdW2bGAXpVnrNPZofi/Ub3b e+jLtgOpzR1dT0IoW0I6/Be9lGWZcPEQSw4A8= MIME-Version: 1.0 Received: by 10.213.29.73 with SMTP id p9mr254073ebc.149.1304090981978; Fri, 29 Apr 2011 08:29:41 -0700 (PDT) Received: by 10.213.35.70 with HTTP; Fri, 29 Apr 2011 08:29:41 -0700 (PDT) Date: Fri, 29 Apr 2011 11:29:41 -0400 Message-ID: From: Ryan Stone To: freebsd-rc@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: rc.d scripts can be missed if they aren't ordered with respect to the early-late divider X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Apr 2011 15:57:54 -0000 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