Small Mosaic


Categories:

/books
/career
/codinghorrors
/events
/geekstuff
/justdont
/languages
/languages/bash
/linkshot
/magazines
/meta
/misctech
/movies
/nottech
/operatingsystems
/operatingsystems/linux
/operatingsystems/linux/debian
/operatingsystems/solaris
/perl
/presentations
/programming
/python
/ruby
/security
/security/apache
/security/tools
/serversmells
/services
/services/dns
/sites
/specifications
/sysadmin
/testing
/tools
/tools/commandline
/tools/firefox
/tools/gui
/tools/network
/tools/online
/tools/online/greasemonkey
/tools/puppet
/unixdaemon

Archives:

July 20111
June 20112
May 20113
April 20112
March 20117
January 20111
December 20103
November 20103
August 20101
July 20101
June 20104
May 20102
April 20101
March 20108
February 20101
January 20102
Full Archives

Thu, 27 Aug 2009

@reboot - explaining simple cron magic
In a conversation with Stuart the subject of cron timings came up, and after a brief discussion the ugly head of @reboot reared. While most people know that you can use the special 'event' syntax to trigger cronjobs at specific times I'd guess a very small number of them actually know how it works. For example does cron rerun @reboot jobs when the service is restarted? (hint - no it doesn't.)

After a quick discussion on how cron knew the machine hadn't really rebooted we had a short list on how it was doing it - tracking uptime, watching run level states, calling the init script only on certain levels... the only problem is that all of those had obvious issues that stopped them being a good choice. So I dug a little deeper.

First I needed a canary cronjob that would show me when @reboot was actually triggered successfully and a cronjob to run it -



$ vi /home/dwilson/log-cron
#!/bin/bash
logger "Cron ran me"

$ chmod a+rx /home/dwilson/log-cron

# and then the crontab
$ sudo vi /etc/cron.d/logme
@reboot dwilson /home/dwilson/log-cron


Once I had this in place I ran through the possible triggers, changing run levels, stopping and starting the script and changing the uptime were the big three - and none of them worked. In the logs were a number of 'Added a cronjob and got - (CRON) INFO (Skipping @reboot jobs -- not system startup) in syslog when I restarted.' lines instead.

After a quick run under strace I gave up under the sheer weight of output and decided to look at the code. As my test machine was Debian I added a source line for apt and pulled down the packages source.


echo "deb-src http://ftp.uk.debian.org/debian etch main contrib non-free " > /etc/apt/sources.list.d/source.list
apt-get update

mkdir cron-src
cd cron-src

apt-get source cron

Now it was time to do some digging and get some line numbers to look at. In the cron directory I ran some greps to get an overview of possible code locations:


cd cron-3.0pl1/

grep -n -i reboot -r .
grep -i -r WHEN_REBOOT *
grep -n -i '@reboot' -r .

// ... snip ... //
cron.c:284:#define REBOOT_FILE "/var/run/crond.reboot"
cron.c:286:     if (access(REBOOT_FILE, F_OK) == 0) {
cron.c:293:     if ((rbfd = creat(REBOOT_FILE, S_IRUSR&S_IWUSR)) < 0) {
// ... snip ... //

# ls -alh /var/run/crond.reboot
---------- 1 root root 0 2008-11-07 11:07 /var/run/crond.reboot

Looking at the three interesting lines above we see how cron, on Debian at least, knows if it's been a real reboot. It uses the access function to check REBOOT_FILE. Nosing around a little more I also found the creat line and saw that the file had no permissions. The delving was nearly over but there was one thing I didn't get - how did the file get removed?

A quick look at the /var/run Filesystem Hierarchy Standard page cleared this up - 'Files under this directory must be cleared (removed or truncated as appropriate) at the beginning of the boot process.'. Which Debian does in /etc/init.d/bootclean Why is it done on system boot? So that if the system failed it still gets cleaned out.

With a much better idea how this should work, and just to double check, I stopped crond, deleted the /var/run/crond.reboot file by hand and turned crond back on. And my cronjob logged a little line. Not much feedback for all those commands but it was oddly worth it.

Like this post? - Digg Me! | Add to del.icio.us! | reddit this!

Posted: 2009/08/27 21:52 | /operatingsystems/linux/debian | Permanent link to this entry | This entry and same date


books career codinghorrors events geekstuff justdont magazines meta misctech movies nottech operatingsystems/linux operatingsystems/linux/debian operatingsystems/solaris perl programming python ruby security security/apache security/tools serversmells services/dns sites sysadmin testing tools tools/commandline tools/firefox tools/gui tools/network tools/online tools/online/greasemonkey tools/puppet unixdaemon

Copyright © 2000-2010 Dean Wilson XML feed logo