<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>5910</bug_id>
          
          <creation_ts>2005-01-21 12:25:07 +0300</creation_ts>
          <short_desc>stat()&apos;ается /etc/cron.d а не /etc/cron.d/*</short_desc>
          <delta_ts>2026-09-08 22:50:35 +0300</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>4</classification_id>
          <classification>Development</classification>
          <product>Sisyphus</product>
          <component>vixie-cron</component>
          <version>unstable</version>
          <rep_platform>all</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="drF_ckoff">dfo</reporter>
          <assigned_to name="placeholder@altlinux.org">placeholder</assigned_to>
          <cc>anton</cc>
    
    <cc>george</cc>
    
    <cc>glebfm</cc>
    
    <cc>lav</cc>
    
    <cc>ldv</cc>
    
    <cc>mike</cc>
    
    <cc>placeholder</cc>
          
          <qa_contact>qa-sisyphus</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>21191</commentid>
    <comment_count>0</comment_count>
    <who name="drF_ckoff">dfo</who>
    <bug_when>2005-01-21 12:25:07 +0300</bug_when>
    <thetext>По ману крон должен раз в минуту перечитывать содержимое crontab, в том числе и
/etc/cron.d/*. Он так и делает. Только вот он смотрит на время изменения
каталога cron.d а не на время изменения файлов внутри каталога. То есть если
файлы внутри cron.d пересоздавать, то они изменяют время модификации каталога и
крон их перечитывает. А если просто изменять - то время изменения каталога не
меняются и крон считает, что неча ему там смотреть. Возможно это &quot;фича&quot;, но,
imho, это баг =/</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>68508</commentid>
    <comment_count>1</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2008-04-17 11:35:54 +0400</bug_when>
    <thetext>Серёж, не смотрел на текущий часом?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>69097</commentid>
    <comment_count>2</comment_count>
    <who name="Slava Semushin">php-coder</who>
    <bug_when>2008-04-29 10:25:41 +0400</bug_when>
    <thetext>(In reply to comment #1)
&gt; Серёж, не смотрел на текущий часом?

Этот баг добавляется патчем vixie-cron-4.1.20040916-owl-crond.patch, который,
судя по history, обновлялся с 2004 года ровно один раз и по абсолютно другой
причине. Так что баг актуален должен быть всё ещё актуален.
</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>87803</commentid>
    <comment_count>3</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2009-03-24 13:18:10 +0300</bug_when>
    <thetext>2 ldv: баг/фича/багофича/отдам?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>87804</commentid>
    <comment_count>4</comment_count>
    <who name="Slava Semushin">php-coder</who>
    <bug_when>2009-03-24 13:20:28 +0300</bug_when>
    <thetext>(В ответ на комментарий №3)
Судя по тому, что баг висит 4 года он явно никому не critical.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>142143</commentid>
    <comment_count>5</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2013-08-15 17:20:16 +0400</bug_when>
    <thetext>Угу.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>149704</commentid>
    <comment_count>6</comment_count>
    <who name="">anton</who>
    <bug_when>2015-01-15 17:28:04 +0300</bug_when>
    <thetext>Благодаря этой баге, задание выполнилось нескорректированным. (Изначально задание было записано в файл /etc/cron.d/rsync, затем подправлено.) По системным логам, изменения задания не были замечены. Только - после рестарта службы crond. Прошу исправить слежку.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>149711</commentid>
    <comment_count>7</comment_count>
    <who name="">anton</who>
    <bug_when>2015-01-15 18:06:53 +0300</bug_when>
    <thetext>(В ответ на комментарий №6)
&gt; Прошу исправить слежку.

Vixie-cron применяется также в Debian 7 (пакет cron, информация по man). Там такой баг не воспроизводится: задания автоматически корректируются после изменения файла /etc/cron.d/* без дополнительных действий.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>153662</commentid>
    <comment_count>8</comment_count>
    <who name="Vitaly Lipatov">lav</who>
    <bug_when>2015-11-12 15:45:46 +0300</bug_when>
    <thetext>В 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</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>297274</commentid>
    <comment_count>9</comment_count>
    <who name="Anton Farygin">rider</who>
    <bug_when>2026-09-08 22:50:35 +0300</bug_when>
    <thetext>Подтверждается на 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 &gt;&gt; /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 &quot;cat &gt; file&quot; 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-&gt;d_name[0] == &apos;.&apos;)
+			continue;
+		if (snprintf(tabname, sizeof tabname, &quot;%s/%s&quot;, path,
+			     dp-&gt;d_name) &gt;= sizeof(tabname))
+			continue;
+		if (stat(tabname, &amp;st) &lt; OK || !S_ISREG(st.st_mode))
+			continue;
+		if (st.st_mtime &gt; 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 &gt; maxtime)
 			maxtime = statbuf.st_mtime;
+		maxtime = dir_files_mtime(p-&gt;path, maxtime);
 		p++;
 	}</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>