Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 652716 - sys-apps/openrc: start-stop-daemon: can't stop a daemon when pidfile is gone
Summary: sys-apps/openrc: start-stop-daemon: can't stop a daemon when pidfile is gone
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: OpenRC (show other bugs)
Hardware: All Linux
: Normal minor
Assignee: OpenRC Team
URL: https://bugs.gentoo.org/646274
Whiteboard:
Keywords:
Depends on:
Blocks: 646274
  Show dependency tree
 
Reported: 2018-04-07 00:09 UTC by Andriy Utkin (RETIRED)
Modified: 2018-05-07 17:45 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
A proposed patch (0001-s-s-d-don-t-fail-stopping-if-pidfile-is-gone.patch,2.32 KB, patch)
2018-04-07 00:10 UTC, Andriy Utkin (RETIRED)
Details | Diff
A proposed patch (0001-s-s-d-don-t-fail-stopping-if-pidfile-is-gone.patch,2.09 KB, patch)
2018-04-07 00:26 UTC, Andriy Utkin (RETIRED)
Details | Diff
A fix implemented per William Hubbs suggestion (0001-s-s-d-don-t-fail-stopping-if-pidfile-is-gone.patch,1.19 KB, patch)
2018-04-21 22:16 UTC, Andriy Utkin (RETIRED)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andriy Utkin (RETIRED) gentoo-dev 2018-04-07 00:09:50 UTC
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.
Comment 1 Andriy Utkin (RETIRED) gentoo-dev 2018-04-07 00:10:41 UTC
Created attachment 526742 [details, diff]
A proposed patch
Comment 2 Andriy Utkin (RETIRED) gentoo-dev 2018-04-07 00:26:40 UTC
Created attachment 526744 [details, diff]
A proposed patch

Avoided einfo string wrapping per dwfreed suggestion.
Comment 3 William Hubbs gentoo-dev 2018-04-14 18:00:03 UTC
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);
Comment 4 Andriy Utkin (RETIRED) gentoo-dev 2018-04-21 22:12:46 UTC
(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.
Comment 5 Andriy Utkin (RETIRED) gentoo-dev 2018-04-21 22:16:05 UTC
Created attachment 528180 [details, diff]
A fix implemented per William Hubbs suggestion
Comment 6 William Hubbs gentoo-dev 2018-05-02 18:59:12 UTC
https://github.com/openrc/openrc/commit/0200002b

This will be in OpenRC 0.36.
Comment 7 William Hubbs gentoo-dev 2018-05-02 22:34:28 UTC
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.
Comment 8 William Hubbs gentoo-dev 2018-05-02 23:09:51 UTC
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.
Comment 9 William Hubbs gentoo-dev 2018-05-07 17:45:25 UTC
I am closing this for now, but if there are regressions we will need to
re-visit.