From owner-freebsd-current@FreeBSD.ORG Wed Feb 1 21:26:49 2012 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67CA61065670; Wed, 1 Feb 2012 21:26:49 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id 407848FC1B; Wed, 1 Feb 2012 21:26:49 +0000 (UTC) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [96.47.65.170]) by cyrus.watson.org (Postfix) with ESMTPSA id D784D46B06; Wed, 1 Feb 2012 16:26:48 -0500 (EST) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 66171B946; Wed, 1 Feb 2012 16:26:48 -0500 (EST) From: John Baldwin To: Doug Barton Date: Wed, 1 Feb 2012 07:42:11 -0500 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p10; KDE/4.5.5; amd64; ; ) References: <201201311149.32760.jhb@freebsd.org> <4F28A210.90303@FreeBSD.org> In-Reply-To: <4F28A210.90303@FreeBSD.org> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201202010742.11936.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Wed, 01 Feb 2012 16:26:48 -0500 (EST) Cc: current@freebsd.org Subject: Re: Race between cron and crontab X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Feb 2012 21:26:49 -0000 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, 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?). The problem is that it currently can set the 'something changed' flag non-atomically while it is updating a crontab. -- John Baldwin