[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Upstart support for LSB headers (Two line init.d scripts? Sure, that will work!)



Excerpts from Tollef Fog Heen's message of 2014-02-06 11:58:37 -0800:
> ]] Sergey B Kirpichev 
> 
> > Are you trying to sell me yet another init or do you suggest some
> > alternative solution *with* Debian's sysvinit, not using
> > "Should-Start/Stop: $all"?  If the first, please stop.  If
> > the second - please go ahead.
> 
> No.
> 
> I'm pointing out why $all doesn't do what you want.  «$all» means «after
> everything else has started» and if you have two of those, you have a
> loop.  Loops are bugs.
> 
> In your particular case (and sysvinit), I'd say the admin should just
> add dependencies on the monit script for the monitored services since I
> don't think sysvinit support dynamically generating those dependencies
> on boot. (If it does, I'm sure somebody will chime in with how to do it
> for sysvinit.)
> 
> With systemd, I'd say a generator that adds After+Wants:
> $monitored_services would be the right (and better) solution (this would
> also solve the shutdown problem).  I assume upstart has a reasonable way
> to solve this, but I'm not familiar with what it should be.
> 

Correct me if I'm wrong, but there are basically two problems.

1) Some services are fragile and will behave badly if started before
some explicit services (nfsd needs nis-things running if nis is in use)
2) Some services are meant to be started after the system has reached a
steady state (monit, cron, etc).

For (1), upstart uses an upstart job I wrote, called wait-for-state.
This should be built into upstart, but ENOROUNDTUITS. You basically put
this in your pre-start:

pre-start exec start wait-for-state WAITER=$JOB WAIT_FOR=thingtowaitfor

This job will wait for the job if it is starting, or start it if it is
stopped, but can work in reverse for stopping/stopped things as well. This
works fairly reliably, but it is somewhat confusing. Ideally upstart
would just have a 'while' condition instead of or in addition to 'start
on'. It is, btw, a myth that Upstart is not state based. It is, it just
makes it a huge PITA to actually use the state it tracks quite nicely.

For (2), the system startup itself needs some re-working from the way
Ubuntu has done it and upstart works in Debian. Right now, you basically
have carefully orchestrated plumbing events that lead up to the system
reaching the default runlevel. At that point, we go into hyper-parallel
mode because most daemons should be:

start on runlevel [2345]
stop on runlevel [016]

This works fine for things like apache and mysql, because they can start
in parallel and if your web app doesn't work for a few seconds while
mysql gets its stuff together oh-well. Trying really hard to get all of
the relationships right for all of the daemons in Debian is not going to
work well.  There is no reason that anything that normally communicates
over the network should ever assume its dependent services are already up.

For the things that matter a lot, the wait-for-state method exists.

But for monit, we want to start after basically everything, so we go
after sysvinit is completely done:

start on stopped rc RUNLEVEL=[2345]
stop on starting rc RUNLEVEL=[016]

This will at least start those things after mysql and apache are starting,
but rc is not blocked on them being _started_.  To do that, one just
needs to create some grouping jobs like this:

--/etc/init/network-services.conf--
start on runlevel [2345]
stop on runlevel [016]
description "All Network Services"
--end--

Then all the jobs that used runlevel just migrate to this:

start on starting network-services
stop on stopped network-services

Aside from making more sense to humans, that would allow things like
monit to say:

start on started network-services
stop on stopping network-services

This is just one of those things that requires time, and only fixes
really subtle bugs.


Reply to: