net-wireless/hostapd is an example of a daemon which removes its pidfile when it is exiting. If this daemon terminates prematurely, that is, without s-s-d involvement, then openrc fails to restart it, because s-s-d "stop" command fails when pidfile is missing. Reproducible: Always Steps to Reproduce: 1. rc-service hostapd start 2. killall hostapd 3. rc-service hostapd restart Actual Results: Failed to stop hostapd Expected Results: Successful restart Alternatives to the attached patch are: patch to s-s-d.sh: https://gist.github.com/andrey-utkin/cf3fd47aeacf6dd0657d18e1811dd72f trivial patch to hostapd init script to exit early from custom stop(). The attached patch is a proof of concept. I don't really like how many levels of indentation are there, am open to suggestions how to rearrange that. Seems some global refactoring of this 800-lines main() is due, and I was not eager to do that now.
Created attachment 526742 [details, diff] A proposed patch
Created attachment 526744 [details, diff] A proposed patch Avoided einfo string wrapping per dwfreed suggestion.
This is untested, but in theory, I think you should be able to test errno if get_pid returns -1, something like: pid = get_pid(applet, pidfile); if (pid == -1 && errno != ENOENT) exit(EXIT_FAILURE);
(In reply to William Hubbs from comment #3) > This is untested, but in theory, I think you should be able to test > errno if get_pid returns -1, something like: > > pid = get_pid(applet, pidfile); > if (pid == -1 && errno != ENOENT) > exit(EXIT_FAILURE); This appears to do the job: # killall hostapd # /etc/init.d/hostapd restart Authenticating root. * Stopping hostapd ... * start-stop-daemon: no matching processes found [ ok ] * Starting hostapd ... The debug output bit around stopping: # /etc/init.d/hostapd -d restart ... + ebegin 'Stopping hostapd' * Stopping hostapd ... + start-stop-daemon --stop --exec /usr/sbin/hostapd --pidfile /run/hostapd.pid * start-stop-daemon: no matching processes found + eend 0 'Failed to stop hostapd' [ ok ] ... So looks correct, and doesn't make a mess of the source code as my original patch does.
Created attachment 528180 [details, diff] A fix implemented per William Hubbs suggestion
https://github.com/openrc/openrc/commit/0200002b This will be in OpenRC 0.36.
I should have re-opened this bug instead of #646274. I haven't reverted this yet, but there may be a better fix, that is to define restart as stop/zap/start instead of just stop/start.
Here is my thought about this and why I think a better fix is to add a zap step to the restart command. It is possible and legit for a daemon to remove its pid file when it stopps successfully. It is also possible to rm the pid file manually while the daemon is still running which would leave things in a bad state. Your fix changes the behaviour of start-stop-daemon to say that if we are stopping something and specify a pidfile if that pidfile doesn't exist assume that it is stopped. Is this always true? I think it is better to let zap handle this and add a zap step to the restart command than to change the behaviour of stop. I am willing to be convinced that no pid file is always ok when something is being stopped though.
I am closing this for now, but if there are regressions we will need to re-visit.