sys-process/vixie-cron-4.1-r10 processes files from /etc/cron.d even days after they are deleted. I had uploaded on remote boxes /home/user/script.sh to do something and added simple one line entry for it to /etc/cron.d (/etc/cron.d.entry) The script runned like planned (each hour at defined time) and after some days I needed to stop running it at regular time, but i wanted to run it ocassionally on demand, so i deleted the entry in /etc/cron.d But the script was runned still, as if the file was not deleted. /var/log/cron have entry for this calls and so. Apparently the cron have cached the context of the entry somewhere in memory and even if the entry file is deleted, then cron is using the cached version. I also tried to: touch /etc/cron.d killall -SIGHUP cron touch /etc/crontab (it got reloaded, but the entry was still in use) lsof (no open files in /etc/cron.d was found) /etc/init.d/vixie-cron restart (this one ofcourse helped, but it is not, what i would like to do regulary) Reproducible: Always Steps to Reproduce: 1. create script /home/user/script.sh, make it executable, make it append time to some log file at each run ( $cat /home/user/script.sh #!/bin/bash date >> /home/user/logfile ) 2. cerate entry for it in /etc/cron.d ( # cat /etc/cron.d/entry PATH=/usr/local/bin:/usr/bin:/bin:/opt/bin 20 * * * * user /home/usr/script.sh &>/dev/null ) 3. after some time delete the entry rm /etc/cron.d/entry Actual Results: the script is executed even after the entry is deleted. The /home/user/logfile is increasind and contains all the times. /var/log/cron shows the /home/usr/script.sh is being executed regardles the /etc/cron.d/entry is long time (like in days) deleted Expected Results: after deleting /etc/cron.d/entry the cron on next minute would find the file does not exist and so the /home/usr/script.sh is not executed anymore (alternatively have some way like touching file/directory, or sending signal to cron which would simply force the cron to forgot everything and re-read ALL files to run only what really exists) Happens on many different boxes to me. the same routine. the same problem. Severity: there is ugly workaround, but it is ugly way. It would be good, if it get fixed, or at least explained (and added to man cron), why it would be this way.
I can confirm this. There are multiple problems with the /etc/cron.d patch, vixie-cron-4.1-gentoo-r4.patch.bz2: @@ -53,6 +53,11 @@ (void) exit(ERROR_EXIT); } + if (stat("/etc/cron.d", &crond_stat) < OK) { + log_it("CRON", getpid(), "STAT FAILED", SPOOL_DIR); Wrong log entry, SPOOL_DIR is supposed to be "/etc/cron.d". @@ -76,13 +82,43 @@ * actually changed. Whatever is left in the old database when * we're done is chaff -- crontabs that disappeared. */ - new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + new_db.mtime = TMAX(crond_stat.st_mtime, + TMAX(statbuf.st_mtime, syscron_stat.st_mtime)); This only takes mtime from /etc/cron.d dir, ignoring changed files within. new_db.head = new_db.tail = NULL; if (syscron_stat.st_mtime) process_crontab("root", NULL, SYSCRONTAB, &syscron_stat, &new_db, old_db); + if (!(dir = opendir("/etc/cron.d"))) { + log_it("CRON", getpid(), "OPENDIR FAILED", "/etc/cron.d"); + (void) exit(ERROR_EXIT); + } + + while (NULL != (dp = readdir(dir))) { + char fname[MAXNAMLEN+1], + tabname[MAXNAMLEN+1]; + + /* avoid file names beginning with ".". this is good + * because we would otherwise waste two guaranteed calls + * to getpwnam() for . and .., and there shouldn't be + * hidden files in here anyway. Also ignore files beginning + * with '#' and ending with '~'. + */ + if (dp->d_name[0] == '.' || + dp->d_name[0] == '#' || + dp->d_name[strlen(dp->d_name) - 1] == '~') + continue; + + (void) strncpy(fname, dp->d_name, MAXNAMLEN); + snprintf(tabname, MAXNAMLEN+1, "/etc/cron.d/%s", fname); + + process_crontab("root", NULL, tabname, + &crond_stat, &new_db, old_db); The NULL here will make process_crontab() use "*system*" as user, and also as key to store in the database. We need unique identifiers though, so I suggest using the full path of the file as key. Patch follows.
Created attachment 201206 [details, diff] fix reloading of changed files in /etc/cron.d This fixes reloading of files within /etc/cron.d/ based on mtime. It *still* only checks for changed files within /etc/cron.d if /etc/cron.d's mtime has changed! If you edit the file in place (open/truncate/write/close) the directory won't get changed and cron will not reread the file. This is actually the same behavior as in /var/spool/cron/crontabs, but there you would usually use "crontab -e" anyways, which will update the directory's mtime.
gilhad, I hope you're still on to this. Would you please test if this works for you?
Package removed.