]> granicus.if.org Git - cronie/commitdiff
Fix handling of HUP signal with inotify enabled.
authorTomas Mraz <t8m@centrum.cz>
Mon, 22 Dec 2008 15:01:39 +0000 (16:01 +0100)
committerTomas Mraz <t8m@centrum.cz>
Mon, 22 Dec 2008 15:01:39 +0000 (16:01 +0100)
src/cron.c
src/database.c
src/funcs.h
src/structs.h

index bcb877581804397ad065f9798db6aa527e095567..be1c32c07744e12edc22583e8a7cb3843e331237 100644 (file)
@@ -79,7 +79,8 @@ set_cron_watched(int fd) {
                int w;
 
                w = inotify_add_watch(fd, watchpaths[i],
-                       IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO | IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE);
+                       IN_CREATE | IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO |
+                       IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE | IN_DELETE_SELF);
                if (w < 0) {
                        if (wd[i] != -1) {
                                log_it("CRON", pid, "This directory or file can't be watched", watchpaths[i], errno);
@@ -100,6 +101,27 @@ set_cron_watched(int fd) {
 }
 #endif
 
+static void
+handle_signals(cron_db *database) {
+       if (got_sighup) {
+               got_sighup = 0;
+#if defined WITH_INOTIFY
+               /* watches must be reinstated on reload */
+               if (inotify_enabled) {
+                       set_cron_unwatched(database->ifd);
+                       inotify_enabled = 0;
+               }
+#endif
+               database->mtime = (time_t) 0;
+               log_close();
+       }
+
+       if (got_sigchld) {
+               got_sigchld = 0;
+               sigchld_reaper();
+       }
+}
+
 static void
 usage(void) {
        const char **dflags;
@@ -216,7 +238,7 @@ main(int argc, char *argv[]) {
                wd[i] = -2;
        }
 
-       fd = inotify_init();
+       database.ifd = fd = inotify_init();
        if (fd < 0)
                log_it("CRON", pid, "INFO", "Inotify init failed", errno);
        set_cron_watched(fd);
@@ -252,19 +274,19 @@ main(int argc, char *argv[]) {
                 * clock.  Classify the change into one of 4 cases.
                 */
                timeDiff = timeRunning - virtualTime;
-               if (inotify_enabled) {
 #if defined WITH_INOTIFY
-                       check_inotify_database(&database, fd);
-#endif
+               if (inotify_enabled) {
+                       check_inotify_database(&database);
                }
                else {
-                       load_database(&database);
-#if defined WITH_INOTIFY
-                       /* try reinstating the watches */
-                       set_cron_watched(fd);
-#endif                 
+                       if(load_database(&database))
+                               /* try reinstating the watches */
+                               set_cron_watched(fd);
                }
-               
+#else
+               load_database(&database);
+#endif
+
                /* shortcut for the most common case */
                if (timeDiff == 1) {
                        virtualTime = timeRunning;
@@ -354,17 +376,7 @@ main(int argc, char *argv[]) {
                /* Jobs to be run (if any) are loaded; clear the queue. */
                job_runqueue();
 
-               /* Check to see if we received a signal while running jobs. */
-               if (got_sighup) {
-                       got_sighup = 0;
-               if (!inotify_enabled)
-                       database.mtime = (time_t) 0;
-                       log_close();
-               }
-               if (got_sigchld) {
-                       got_sigchld = 0;
-                       sigchld_reaper();
-               }
+               handle_signals(&database);
        }
 
 #if defined WITH_INOTIFY
@@ -521,16 +533,8 @@ cron_sleep(int target, cron_db *db) {
                 * If so, service the signal(s) then continue sleeping
                 * where we left off.
                 */
-               if (got_sighup) {
-                       got_sighup = 0;
-                       if (!inotify_enabled)
-                               db->mtime = (time_t) 0;
-                       log_close();
-               }
-               if (got_sigchld) {
-                       got_sigchld = 0;
-                       sigchld_reaper();
-               }
+               handle_signals(db);
+
                t2 = time(NULL) + GMToff;
                seconds_to_wait -= (int)(t2 - t1);
                t1 = t2;
index 14023c69c4d0c5786d198edd7cf03aba08d0c4bb..12e8c209c7e5057370d7356091e8e9ea931ece3b 100644 (file)
@@ -153,7 +153,7 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
 
 #if defined WITH_INOTIFY
 void
-check_inotify_database(cron_db *old_db, int fd) {
+check_inotify_database(cron_db *old_db) {
        cron_db new_db;
        DIR_T *dp;
        DIR *dir;
@@ -167,17 +167,18 @@ check_inotify_database(cron_db *old_db, int fd) {
        time.tv_usec = 0;
 
        FD_ZERO(&rfds);
-       FD_SET(fd, &rfds);
+       FD_SET(old_db->ifd, &rfds);
 
-       retval = select(fd + 1, &rfds, NULL, NULL, &time);
+       retval = select(old_db->ifd + 1, &rfds, NULL, NULL, &time);
        if (retval == -1) {
                if (errno != EINTR)
                        log_it("CRON", pid, "INOTIFY", "select failed", errno);
                return;
        }
-       else if (FD_ISSET(fd, &rfds)) {
+       else if (FD_ISSET(old_db->ifd, &rfds)) {
                new_db.head = new_db.tail = NULL;
-               while ((retval=read(fd, buf, sizeof(buf))) == -1 && errno == EINTR);
+               new_db.ifd = old_db->ifd;
+               while ((retval=read(old_db->ifd, buf, sizeof(buf))) == -1 && errno == EINTR);
 
                if (retval == 0) {
                        /* this should not happen as the buffer is large enough */
@@ -195,7 +196,7 @@ check_inotify_database(cron_db *old_db, int fd) {
                /* we must reinstate the watches here - TODO reinstate only watches
                 * which get IN_IGNORED event
                 */
-               set_cron_watched(fd);
+               set_cron_watched(old_db->ifd);
 
                /* TODO: parse the events and read only affected files */
 
@@ -269,7 +270,7 @@ overwrite_database(cron_db *old_db, cron_db *new_db) {
        *old_db = *new_db;
 }
 
-void
+int
 load_database(cron_db *old_db) {
        struct stat statbuf, syscron_stat, crond_stat;
        cron_db new_db;
@@ -318,7 +319,7 @@ load_database(cron_db *old_db) {
           ){
                Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n",
                              (long)pid))
-               return;
+               return 0;
        }
 
        /* something's different.  make a new database, moving unchanged
@@ -329,6 +330,9 @@ load_database(cron_db *old_db) {
        new_db.mtime = TMAX(crond_stat.st_mtime,
                            TMAX(statbuf.st_mtime, syscron_stat.st_mtime));
        new_db.head = new_db.tail = NULL;
+#if defined WITH_INOTIFY
+       new_db.ifd = old_db->ifd;
+#endif
 
        if (syscron_stat.st_mtime)
                process_crontab("root", NULL, SYSCRONTAB, &new_db, old_db);
@@ -382,6 +386,7 @@ load_database(cron_db *old_db) {
 
        overwrite_database(old_db, &new_db);
        Debug(DLOAD, ("load_database is done\n"))
+       return 1;
 }
 
 void
index 85a6dc0f3f7158a8415880f0b5a7e649266adcc3..0635cb90bbf8541369e99408b9684cb6032f579d 100644 (file)
@@ -41,14 +41,13 @@ void                set_cron_uid(void),
                log_it(const char *, PID_T, const char *, const char *, int),
                log_close(void);
 #if defined WITH_INOTIFY
-void   load_inotify_database(cron_db *, int ),
-               set_cron_watched(int ),
+void           set_cron_watched(int ),
                set_cron_unwatched(int ),
-               check_inotify_database(cron_db *, int );
+               check_inotify_database(cron_db *);
 #endif
-void   load_database(cron_db *);
 
-int            job_runqueue(void),
+int            load_database(cron_db *),
+               job_runqueue(void),
                set_debug_flags(const char *),
                get_char(FILE *),
                get_string(char *, int, FILE *, char *),
index b1b3c3773c6e14effad39504a5701151d426538a..fec51865a3a0ca704f71aad63e5a6e13bca7d773 100644 (file)
@@ -60,6 +60,9 @@ typedef       struct _user {
 typedef        struct _cron_db {
        user            *head, *tail;   /* links */
        time_t          mtime;          /* last modtime on spooldir */
+#ifdef WITH_INOTIFY
+       int             ifd;
+#endif
 } cron_db;
                                /* in the C tradition, we only create
                                 * variables for the main program, just