On Wed, Sep 30, 2026 at 10:38:31AM +0200, Janne Johansson wrote:
> 
>     >Synopsis:      rc.subr: spurious "kill: <pid>: no such process" on start 
> with rc_bg=YES
> 
>  
> 
>     When starting a package daemon whose rc.d script sets rc_bg=YES,
>     the following message is sometimes printed at boot:
>     The daemon starts correctly and "rcctl check oficina" reports ok,
>     so the problem is cosmetic.
> 
>  
> Not just cosmetic.
> 
> 
> 
>     With rc_bg=YES, rc_start returns immediately. If rc_check already
>     succeeds inside _rc_wait_for_start, the loop breaks, the subshell
>     runs "pkill -ALRM -P $$" and exits, so the later
>     "kill -ALRM ${_TIMERSUB}" targets a process that no longer exists
>     and prints an error.
>     -                       kill -ALRM ${_TIMERSUB}
>     +                       kill -ALRM ${_TIMERSUB} 2>/dev/null 
> 
> 
> I am not talking for the project, but I am quite certain that trying to kill 
> the wrong process
> is what needs to be fixed, not silencing that it happens.
> What will the system do if the PID got reused in that time span?

Hi and thanks for the report.

There's a real race here indeed. Hiding is not the solution :-)

The rc_alarm timer sends a SIGALRM to all children of rc_cmd to detach rc_start.
But the timer is also a child... and can then die while rc_cmd() is about to
kill it; that's when you get the error (as it's already gone).
So we make the timer ignore SIGALRM and let it get killed by rc_cmd.

If you're able to easily reproduce, could you try this?

Index: rc.subr
===================================================================
RCS file: /cvs/src/etc/rc.d/rc.subr,v
diff -u -p -r1.168 rc.subr
--- rc.subr     16 Sep 2026 00:52:19 -0000      1.168
+++ rc.subr     30 Sep 2026 16:26:25 -0000
@@ -143,13 +143,6 @@ _rc_exit() {
        exit ${_ret}
 }
 
-_rc_alarm()
-{
-       trap - ALRM
-       kill -ALRM ${_TIMERSUB} 2>/dev/null # timer may not be running anymore
-       kill $! 2>/dev/null # kill last job if it's running
-}
-
 _rc_printname()
 {
        local _n
@@ -162,15 +155,20 @@ _rc_sendsig() {
 }
 
 _rc_wait_for_start() {
-       trap "_rc_alarm" ALRM
+       # catch SIGALRM, it's only needed for the process spawned by rc_start;
+       trap : ALRM
+       trap 'exit' TERM
        while ((SECONDS < daemon_timeout)); do
                if _rc_do rc_check; then
                        [ X"${rc_bg}" = X"YES" ] || [ -z "$$" ] && break
                fi
-               sleep .5
-       done & wait
+               sleep .5 & wait
+       done
        pkill -ALRM -P $$
-       return
+       # wait for rc_cmd() signal
+       while kill -0 $$ 2>/dev/null; do
+               sleep .5 & wait
+       done
 }
 
 rc_exec() {
@@ -257,10 +255,10 @@ rc_cmd() {
                        fi
                        # prevent hanging the boot sequence
                        _rc_do _rc_wait_for_start & _TIMERSUB=$!
-                       trap "_rc_alarm" ALRM
+                       trap : ALRM
                        _rc_do rc_start; _ret=$?
-                       kill -ALRM ${_TIMERSUB}
-                       wait ${_TIMERSUB} 2>/dev/null # don't print Alarm clock
+                       kill -TERM ${_TIMERSUB}
+                       wait ${_TIMERSUB} 2>/dev/null # don't print Terminated
                        # XXX for unknown reason, rc_check can fail (e.g. redis)
                        # while it just succeeded in _rc_wait_for_start;
                        # check to cope with failing daemons returning 0
@@ -292,7 +290,7 @@ rc_cmd() {
                                break
                        ${_1stloop} && _1stloop=false || sleep .5
                done
-               kill -ALRM ${_timer} 2>/dev/null
+               pkill -ALRM -P $$
                wait ${_timer} # don't print Alarm clock
                [[ $? == 0 ]] || _exit=failed
                # KILL the process
@@ -314,7 +312,7 @@ rc_cmd() {
                        pkill -0 -P "$$" 2>/dev/null || break
                        ${_1stloop} && _1stloop=false || sleep .5
                done
-               kill -ALRM ${_timer} 2>/dev/null
+               pkill -ALRM -P $$
                wait ${_timer} # don't print Alarm clock
                _ret=$?
                [[ ${_ret} == 142 ]] && _exit=timeout || [[ ${_ret} == 0 ]] ||



-- 
Antoine

Reply via email to