Listening to events from init.d scripts

Asked by ArunNair on 2009-11-03

Hi - I'm in the process of migrating all our init.d scripts to upstart and was wondering if I had to migrate them all at once, or I can migrate them one at a time, using events from the existing init.d scripts in my new upstart event.d scripts.

Let me explain with an example. Say I have two scripts in init.d: mysql and superapp. The latter requires mysql so currently it's startup script is numbered higher than mysql in init.d.

I want to first migrate superapp to event.d but keep mysql in init.d. Is there someway I can get events in the superapp upstart script that indicates that the mysql service is "started" or "stopping"?

Thanks.

Question information

Language:
English Edit question
Status:
Solved
For:
upstart Edit question
Assignee:
No assignee Edit question
Solved by:
Caleb Callaway
Solved:
2009-11-14
Last query:
2009-11-14
Last reply:
2009-11-10

I believe you can accomplish this (assuming your version of Upstart is recent) using initctl's "emit" command--see the initctl manpage and the getting started page (http://upstart.ubuntu.com/getting-started.html) for details.

ArunNair (arun-bvinetworks) said : #2

Thanks Despot. So you mean I would add an "initctl emit" command at the end of every init.d script i want to tie an upstart script into? So in my example I would add an "initctl emit mysql-started" and "initctly emit mysql-stopping" at the appropriate places in the mysql init.d script, and use those events to control starting/stopping in my upstart script?

That's my understanding, yes. I haven't tried it myself, but I'd be very interested to know what you find out.

schaze (schaze) said : #4

Hi ArunNair,

did have any progress on this so far?
I have just move the newest Mythbuntu 9.10 and face exactly this problem:

mythbackend has been mirgrated to upstart but mysql has not. This is no problem for mythbackend as it simply retries connecting until mysql is started, but as I boot from an SSD the X server and the mythfrontend are actually started before mysql.

If I could tie a connection between mythbackend and mysql like you with you superapp example that would probably solve my problems to.

Any hint would be appreciated.

Thanks a lot,
schaze

ArunNair (arun-bvinetworks) said : #5

schaze -

I initially started migrating the mysql init.d script to upstart, but that ended up being too much work :) So I added a few lines to the mysql init.d script to emit custom events everytime MySQL was starting or stopping (e.g. initctl emit mysql-started). In my superapp upstart script, I start superapp on a mysql-started event, and stop it on a mysql-stopping event.

This works great. The only downside to this approach is that I suppose mysql could potentially stop before your app does, i.e. the mysql init.d script fires the mysql-stopping event and proceeds to shutdown mysql. Ideally you want your app to shutdown *before* mysql does, but the mysql script is not upstart based and this is not synchronized, mysql could potentially shutdown before your app has had a chance to.

ArunNair (arun-bvinetworks) said : #6

Thanks Despot, that solved my question.

schaze (schaze) said : #7

Hi ArunNair,

thanks for your reply.

I can imagine the trouble with migrating mysql to upstart. (that's probably the reason canonical also didn't do it yet)

I tried the approach with the emitting. and it is working quite fine. I don't really need to worry about starting and stopping as the box is only turned on and all stuff is pretty straight forward.
However my problem is now that just the backend is started as the very last service which does not solve the problem with my frontend starting too early (I fixed that now with a while loop in the start script waiting for the DB and backend to be up) but now all the great speedy startup is for nothing as it takes about 10 sec to start mysql after the login as the old startup scipts come last.

So I will have to move on and try to find the possiblity to migrate mysql as I need the possibility to start mysql directly before the backend as a condition within the backend service to get back the speed...

Good luck with you work. If continue anyway and succeed in migrating mysql I would be veeeery interested ;)

/schaze

ArunNair (arun-bvinetworks) said : #8

schaze -

I don't quite understand your scenario. If you control both the frontend and backend scripts, and the startup order you want is 1. mysql 2. backend 3. frontend, this is how I'd do it:

1. In the MySQL init.d script, add "initctl emit mysql-started" right after you exit the script (as mentioned earlier)
2. Set backend to "start on mysql-started".
3. Set frontend to "start on started backend"

Similarly for shutdown.

schaze (schaze) said : #9

Hi ArunNair

I have a (ugly) solution for my problem now.

To describe my scenario and make my solution perhaps use full for others:

I have the following programs that need to be started:

1. mysql (daemon)
2. mythtv-backend (daemon)
3. mythfrontend (application started via autostart in xfce)

Problem:

mysql --> still an old init script
mythtv-backend --> converted to upstart job

When my PC boot the following happens:

mythtv-backend is started very early and tries to connect to mysql, which is not possble as the remaining old init scripts seem to be started after all the upstart jobs. This is no problem as mythtv-backend simply retries to connect until the mysql db is up.
But as GDM was also converted to upstart the userinterface (xfce) is started already before the init scripts are started and so does then the mythfrontend via autostart. As the mythfrontend needs a connection to both, mysql and myth-backend it fails to start properly as it cannot connect to the DB. unlike the backend the frontend does not start to reconnect several times and so I am stuck, as this is thought to be a htpc to watch television and movies in the living room without keyboard and mouse, only IR remote.

I hope this explains the problem.

One solution is to change the script that starts the mythfrontend and have it wait in a loop until the DB is up. This works fine, however it kills the whole effect of a fast boot on the new Ubuntu Karmic as I have to wait about 8-10 seconds after autologin to xfce for the DB.

My second solution I now did is quite simple but also very ugly as it mixes the old init scripts with upstart.
I simply changed the mythtv-backend job in upstart and added to folowing pre-start script:

pre-start script
   /etc/init.d/mysql start
end script

with this the DB is started before the mythtv-backend is started. and it is still done in parallel to any other potential upstart jobs and also before GDM is started. so my problem is solved.
As the mythtv-backend needs to be stopped for changing the base settings but the DB needs to be up I did not simply add mysql to a pre-stop script, but left the old init script for mysql also active. Now the following happens during boot and shutdown:

1. mythtv-backend job is beginning to start
1a. pre-start starts mysql
1b. after pre-start the real job is run and mythtv-backend is started
2. GDM starts
3. mythfrontend starts and can connect
4 between 2 and 3 the mysql init script runs and detects that mysql is already up and does nothing

on shutodwn the mysql database is simply stopped by the old initscript independand from the mythtv-backend.

I know this is not a very clean thing to do something but it work and it still has the benefit of a fast boot.

So my problem is solved for now. I will post this comment in the 'no upstart for mysql' bug too so others can perhaps use it.

Thanks a lot for comments and help,
schaze

Keith (buurin) said : #10

I also have a mysql+mythbackend+xfce setup.

If it still helps, I have ported mysql to upstart. It is primitive (doesn't respawn failed instances and some settings have to entered here as environment variables) but it does allow upstart to manage it directly. Edit the start/stop trigger as appropriate.

#
# mysqld: The MySQL server
#
# processname: mysqld

description "MySQL server"

start on started filesystem and (starting mythbackend or started network)
stop on starting shutdown

env LEDIR=/usr/libexec
env DATADIR=/var/lib/mysql
env PID=/var/lib/mysql/htcore.pid
env BASEDIR=/usr
env USER=mysql
env SOCK=/var/run/mysql/mysql.sock
env LOG=/var/lib/mysql/htcore.err

# mysqld expects a specific working directory
chdir /usr

# mysqld doesn't daemonize itself
#expect none

#console output

# Script mysqld_safe was used in the standard distribution to do some safe handling
# including restarting mysqld should it die (could be done by adding respawn but this
# could interfere with shutting down via mysqladmin) but upstart handles this now
# so we can invoke the server binary directly
exec /usr/libexec/mysqld --basedir=$BASEDIR --datadir=$DATADIR --user=$USER --pid-file=$PID --skip-external-locking
# --log=$LOG

# pre-start cleanup, just in case
pre-start script
rm -f $SOCK $PID
end script