Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 454120

Summary: sys-apps/openrc-0.11.8: Service XY stop makes other services stop, but consequent start of XY leaves the others stopped
Product: Gentoo Hosted Projects Reporter: Roman Žilka <roman.zilka>
Component: OpenRCAssignee: OpenRC Team <openrc>
Status: RESOLVED WONTFIX    
Severity: enhancement    
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---

Description Roman Žilka 2013-01-26 09:43:51 UTC
Let's have services AB and CD that depend on the service XY. All these services are started. Then I manually stop service XY which forces AB and CD to stop as well. That's OK. But when I later start XY again, AB and CD remain stopped. It's certainly a matter of discussion, but IMO it would be more intuitive and convenient if AB and CD were started along with XY. OpenRC would have to distinguish two kinds of stopped services: 1. those that were stopped, because their dependency was stopped; 2. those that were stopped for another reason.

This functionality should take into consideration the fact that the net.* services may be able to take each other's place as deps. And perhaps other groups of services that are interchangeable in this manner, if any such exist. E.g.:

# /etc/init.d/net.eth0 stop
sshd          | * Stopping sshd ...
mpdscribble   | * Stopping Music Player Daemon Audioscrobbler client ...                                      [ ok ]
netmount      | * Unmounting network filesystems ...                                                          [ ok ]
net.eth0      | * Bringing down interface eth0
net.eth0      | *   Removing addresses
net.eth0      | *     10.0.0.20/24
# /etc/init.d/net.wlan0 start
net.wlan0     | * Bringing up interface wlan0
net.wlan0     | *   Starting wpa_supplicant on wlan0 ...                                                      [ ok ]
net.wlan0     | *   Starting wpa_cli on wlan0 ...                                                             [ ok ]
net.wlan0     | *   Backgrounding ... ...
net.wlan0     | * WARNING: net.wlan0 has started, but is inactive

(Please ignore the warning.) In this scenario, sshd, mpdscribble and netmount were stopped because I requested net.eth0 top stop. Upon net.wlan0 start I would expect that sshd, mpdscribble and netmount start again. Firstly because they were only stopped because their dep (net.eth0) stopped and secondly because, although this same dep is not the one being started now, another service which is dependency-equivalent to net.eth0 is being started (i.e., net.wlan0).

Reproducible: Always
Comment 1 William Hubbs gentoo-dev 2013-03-08 22:42:44 UTC
(In reply to comment #0)
> Let's have services AB and CD that depend on the service XY. All these
> services are started. Then I manually stop service XY which forces AB and CD
> to stop as well. That's OK. But when I later start XY again, AB and CD
> remain stopped. It's certainly a matter of discussion, but IMO it would be
> more intuitive and convenient if AB and CD were started along with XY.
> OpenRC would have to distinguish two kinds of stopped services: 1. those
> that were stopped, because their dependency was stopped; 2. those that were
> stopped for another reason.

You are asking us to start services that are reverse dependencies of XY when XY starts if they were stopped indirectly.

In your example, AB and CD declare their dependency on XY, but not the other way around. When you restart XY, we resolve things that XY depends on, but we do not attempt to resolve things that depend on XY. Furthermore, I do not know of any init system anywhere that does attempt this.

I'll give a day or so for someone else to respond, but if no one else does, I will close this as wontfix.
Comment 2 Roman Žilka 2013-03-09 01:22:45 UTC
(In reply to comment #1)
> You are asking us to start services that are reverse dependencies of XY when
> XY starts if they were stopped indirectly.

That's right.

> In your example, AB and CD declare their dependency on XY, but not the other
> way around. When you restart XY, we resolve things that XY depends on, but
> we do not attempt to resolve things that depend on XY.

Yes, OpenRC doesn't do the reverse lookup now. That's why this enhancement proposal is here. Why not implement it sometime?

I think you don't need to implement general reverse deps resolution. It might be enough just to keep track of what was stopped and why and consult this record when starting a service.

And if you feel the user should have means of forcefully stopping a service which is currently only stopped because its dep stopped, a new state of a service could be introduced - something like "conditionally stopped" which would be different from the current "stopped" state. And the user could explicitly request that a service be stopped (for good, or until he starts it again) - and not just conditionally stopped - by the obligatory /etc/init.d/service stop.
Comment 3 William Hubbs gentoo-dev 2013-03-09 18:41:50 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > You are asking us to start services that are reverse dependencies of XY when
> > XY starts if they were stopped indirectly.
> 
> That's right.
> 
> > In your example, AB and CD declare their dependency on XY, but not the other
> > way around. When you restart XY, we resolve things that XY depends on, but
> > we do not attempt to resolve things that depend on XY.
> 
> Yes, OpenRC doesn't do the reverse lookup now. That's why this enhancement
> proposal is here. Why not implement it sometime?
> 
> I think you don't need to implement general reverse deps resolution. It
> might be enough just to keep track of what was stopped and why and consult
> this record when starting a service.

No, it wouldn't be enough to keep track of what is stopped and why.

We have services AB, CD, EF, WX and YZ, all started.
AB and CD depend on WX, and EF depends on YZ.

Using your logic, if I stop WX and YZ, the services that depend on them (AB, CD and EF) are stopped indirectly and we track this.

Suppose that I do this, then later want to start either WX or YZ, but not both. Without reverse dependency resolution, I have to start all services that were indirectly stopped, so I would have to start AB, CD and EF, regardless of whether I manually start WX or YZ.

The other concern I have is that this could lead to things like shutting down a network interface or even the network when someone stops a service like sshd, which would be very bad.
Comment 4 Roman Žilka 2013-03-09 19:10:20 UTC
(In reply to comment #3)
> We have services AB, CD, EF, WX and YZ, all started.
> AB and CD depend on WX, and EF depends on YZ.
> 
> Using your logic, if I stop WX and YZ, the services that depend on them (AB,
> CD and EF) are stopped indirectly and we track this.
> 
> Suppose that I do this, then later want to start either WX or YZ, but not
> both. Without reverse dependency resolution, I have to start all services
> that were indirectly stopped, so I would have to start AB, CD and EF,
> regardless of whether I manually start WX or YZ.

You could simply:
1. User requests stop(WX)
2. Find what deps on WX and stop it: stop(AB), stop(CD)
3. Make note: "AB stopped because of WX", "CD stopped because of WX"
4. stop(WX)
5. User requests stop(YZ)
6. Find what deps on YZ and stop it: stop(EF)
7. Make note: "EF stopped because of YZ"
8. stop(YZ)
9. User requests start(WX)
10. start(WX)
11. Find in notes what stopped because of WX and start it: start(AB), start(CD)
12. Delete note "AB stopped because of WX", "CD stopped because of WX"

If the user wants AB or CD not to start at step 11, he can call stop(AB) explicitly, which removes openrc's note that "AB stopped because of WX", so the lookup in step 11 doesn't attempt to start AB.

In between steps 2 and 11 the services AB and CD are in the state I previously called "conditionally stopped" (as opposed to "stopped").

This is not full revdep resolution and could be easy to implement.

> The other concern I have is that this could lead to things like shutting
> down a network interface or even the network when someone stops a service
> like sshd, which would be very bad.

This wouldn't happen - sshd deps on net.eth0, not the other way around. When the user requests stop(net.eth0), openrc stops sshd as well. That's the current behavior. With the proposed enhancement, sshd would automatically start when the user later starts net.eth0. I see no danger here.
Comment 5 William Hubbs gentoo-dev 2013-03-09 19:29:22 UTC
If you are willing to write the patch, test it and make sure everything
works as expected, I will consider applying it. This is not something I
would consider spending any time on myself however, because I don't
really see how it is intuitive to start reverse-dependent services when
I start a single service. Dependencies yes, but not reverse
dependencies.

If anyone on the OpanRC Development team disagrees with me, please feel
free to re-open this bug and claim it.

Thanks,

William