Bug 5910
| Summary: | stat()'ается /etc/cron.d а не /etc/cron.d/* | ||
|---|---|---|---|
| Product: | Sisyphus | Reporter: | drF_ckoff <dfo> |
| Component: | vixie-cron | Assignee: | placeholder <placeholder> |
| Status: | NEW --- | QA Contact: | qa-sisyphus |
| Severity: | normal | ||
| Priority: | P2 | CC: | anton, george, glebfm, lav, ldv, mike, placeholder |
| Version: | unstable | ||
| Hardware: | all | ||
| OS: | Linux | ||
Серёж, не смотрел на текущий часом? (In reply to comment #1) > Серёж, не смотрел на текущий часом? Этот баг добавляется патчем vixie-cron-4.1.20040916-owl-crond.patch, который, судя по history, обновлялся с 2004 года ровно один раз и по абсолютно другой причине. Так что баг актуален должен быть всё ещё актуален. 2 ldv: баг/фича/багофича/отдам? (В ответ на комментарий №3) Судя по тому, что баг висит 4 года он явно никому не critical. Угу. Благодаря этой баге, задание выполнилось нескорректированным. (Изначально задание было записано в файл /etc/cron.d/rsync, затем подправлено.) По системным логам, изменения задания не были замечены. Только - после рестарта службы crond. Прошу исправить слежку. (В ответ на комментарий №6) > Прошу исправить слежку. Vixie-cron применяется также в Debian 7 (пакет cron, информация по man). Там такой баг не воспроизводится: задания автоматически корректируются после изменения файла /etc/cron.d/* без дополнительных действий. В man у Debian написано такое: Like /etc/crontab, the files in the /etc/cron.d directory are monitored for changes. In general, the system administrator should not use /etc/cron.d/, but use the standard system crontab /etc/crontab. То есть хотя поддержка и есть, они предлагают их не использовать почему-то. Ну в Debian есть несколько патчей для правильной поддержки run-parts: https://launchpadlibrarian.net/188407008/cron_3.0pl1-127ubuntu1.diff.gz Подтверждается на vixie-cron 4.1.20060426-alt10.3. Причина — в патче vixie-cron-4.1.20040916-owl-crond.patch: load_database() считает maxtime только по mtime каталогов (/var/spool/cron, /etc/cron.d) и /etc/crontab, поэтому правка файла в /etc/cron.d на месте (без пересоздания) не замечается до перезапуска crond.
Проверено в контейнере Sisyphus: задание в /etc/cron.d/t5910 «* * * * * root echo A >> /tmp/out», через две минуты файл перезаписан на «echo B» (inode и mtime каталога не менялись) — стоковый crond продолжает выполнять A (вывод «A A A»). С патчем ниже (собран как alt10.4 в podman) после перезаписи выполняется B («A A A B»).
Пакет по rdb orphaned (ldv@ — 2016, последняя сборка antohami@ — 2022), нужен желающий собрать.
Track mtime of files in system crontab directories, not only of the directories
crond only re-reads /etc/cron.d when the mtime of the directory itself
changes, i.e. when a file is created, removed or renamed. Editing a
file in place (which is what most editors and "cat > file" do) leaves
the directory mtime untouched, so the change is silently ignored until
crond is restarted. Take the newest mtime among the files of every
tracked directory into account as well.
--- a/usr.sbin/cron/database.c
+++ b/usr.sbin/cron/database.c
@@ -48,6 +48,38 @@ static void process_crontab(const char *, const char *,
const char *, struct stat *,
cron_db *, cron_db *);
+/* Return the newest of MAXTIME and the mtimes of the regular files in
+ * directory PATH. Editing a crontab in place does not touch the mtime
+ * of the directory, so the directory mtime alone is not enough to
+ * notice the change.
+ */
+static time_t
+dir_files_mtime(const char *path, time_t maxtime)
+{
+ struct stat st;
+ DIR_T *dp;
+ DIR *dir;
+ char tabname[MAXPATHLEN];
+
+ if (!(dir = opendir(path)))
+ return maxtime;
+
+ while (NULL != (dp = readdir(dir))) {
+ if (dp->d_name[0] == '.')
+ continue;
+ if (snprintf(tabname, sizeof tabname, "%s/%s", path,
+ dp->d_name) >= sizeof(tabname))
+ continue;
+ if (stat(tabname, &st) < OK || !S_ISREG(st.st_mode))
+ continue;
+ if (st.st_mtime > maxtime)
+ maxtime = st.st_mtime;
+ }
+ closedir(dir);
+
+ return maxtime;
+}
+
void
load_database(cron_db *old_db) {
struct stat statbuf, syscron_stat;
@@ -74,6 +106,7 @@ load_database(cron_db *old_db) {
}
if (statbuf.st_mtime > maxtime)
maxtime = statbuf.st_mtime;
+ maxtime = dir_files_mtime(p->path, maxtime);
p++;
}
|

Description
drF_ckoff 2005-01-21 12:25:07 MSK