Race between cron and crontab
Ian Lepore
freebsd at damnhippie.dyndns.org
Fri Feb 3 01:45:03 UTC 2012
On Thu, 2012-02-02 at 17:03 -0800, Doug Barton wrote:
> On 02/01/2012 04:42, John Baldwin wrote:
> > On Tuesday, January 31, 2012 9:23:12 pm Doug Barton wrote:
> >> On 01/31/2012 08:49, John Baldwin wrote:
> >>> A co-worker ran into a race between updating a cron tab via crontab(8) and
> >>> cron(8) yesterday. Specifically, cron(8) failed to notice that a crontab was
> >>> updated. The problem is that 1) by default our filesystems only use second
> >>> granularity for timestamps and 2) cron only caches the seconds portion of a
> >>> file's timestamp when checking for changes anyway. This means that cron can
> >>> miss updates to a spool directory if multiple updates to the directory are
> >>> performed within a single second and cron wakes up to scan the spool directory
> >>> within the same second and scans it before all of the updates are complete.
> >>>
> >>> Specifically, when replacing a crontab, crontab(8) first creates a temporary
> >>> file in /var/cron/tabs and then uses a rename to install it followed by
> >>> touching the spool directory to update its modification time. However, the
> >>> creation of the temporary file already changes the modification time of the
> >>> directory, and cron may "miss" the rename if it scans the directory in between
> >>> the creation of the temporary file and the rename.
> >>>
> >>> The "fix" I am planning to use locally is to simply force crontab(8) to sleep
> >>> for a second before it touches the spool directory, thus ensuring that it the
> >>> touch of the spool directory will use a later modification time than the
> >>> creation of the temporary file.
> >>
> >> If you really want cron to have sub-second granularity I don't see how
> >> you could do it without using flags.
> >>
> >> crontab open sets flag that it is editing a file
> >> crontab close clears "editing" flag, sets "something changed" flag
> >> (if something actually changed of course)
> >>
> >> cron checks existence of "something changed" flag, pulls the
> >> update if there is no "editing" flag, clears "changed" flag
> >
> > I don't want it to have sub-second granularity,
>
> Ok, I was interpolating, sorry if I misinterpreted your intentions.
>
> > I just want to make
> > 'crontab -e' more reliable so that cron doesn't miss edits. cron is
> > currently using the mod-time of the spool directory as the 'something
> > changed' flag (have you read the cron code?).
>
> I understand the spool behavior from history/experience, and I am
> relying on your excellent summary for the details. :)
>
> > The problem is that it
> > currently can set the 'something changed' flag non-atomically while it is
> > updating a crontab.
>
> That much I understood from your post. My response to what it is I think
> you're trying to achieve is that it's not likely that you can achieve it
> by only using 1 flag, no matter what that 1 flag is. I may be wrong
> about that, but hopefully my suggestion gives you some other ideas to
> consider.
>
> Meanwhile, I was thinking more about this and TMK cron doesn't actually
> *run* jobs with seconds granularity, only minutes, right? If so then it
> seems that the only really important seconds to care about are :59 and
> :00. That would seem to present a solution that rather than having cron
> wake up every second to see if something has changed that it only do
> that at :59 (or however many seconds in advance of :00 that it needs,
> although if it's more than 1 I'll be surprised). That limits the race to
> someone who writes out a new crontab entry at the point during second
> :59 that is after cron wakes up to look but before :00. So that's not a
> perfect solution to your problem, but it should limit the race to a very
> narrow window without having to modify the code very much.
>
>
> hth,
>
> Doug
I think part of the problem here is that I started typing without
thinking enough... I thought I was offering a different small change
that fixed more than one problem, but it was wrong. My mistake seems to
be having the unintended effect of sidetracking a perfectly reasonable
small fix for a problem that's known to happen in the real world, just
because it doesn't also fix a theoretical problem that might happen
somewhere some day; that sure wasn't my intention.
-- Ian
More information about the freebsd-current
mailing list