From a95df9d64b0bb2be2ad3282b1302b891e385b6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Wed, 11 Jan 2017 16:25:39 +0100 Subject: [PATCH] svc: The timestamp should have subsecond resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When finit completes quicker than one second it will not find if any configurations has been changed. Signed-off-by: Mattias Walström --- conf.c | 13 ++++++++----- service.c | 2 +- service.h | 2 +- svc.c | 11 +++++++---- svc.h | 6 +++--- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/conf.c b/conf.c index 4c3839fa..02e11e74 100644 --- a/conf.c +++ b/conf.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "finit.h" #include "cond.h" @@ -293,7 +294,7 @@ static void parse_static(char *line) } if (MATCH_CMD(line, "startx ", x)) { - service_register(SVC_TYPE_SERVICE, strip_line(x), 0, username); + service_register(SVC_TYPE_SERVICE, strip_line(x), NULL, username); return; } @@ -332,7 +333,7 @@ static void parse_static(char *line) } } -static void parse_dynamic(char *line, time_t mtime) +static void parse_dynamic(char *line, struct timeval *mtime) { char *x; @@ -385,7 +386,7 @@ static void tabstospaces(char *line) } } -static int parse_conf_dynamic(char *file, time_t mtime) +static int parse_conf_dynamic(char *file, struct timeval *mtime) { FILE *fp = fopen(file, "r"); @@ -453,7 +454,7 @@ static int parse_conf(char *file) _d("conf: %s", line); parse_static(line); - parse_dynamic(line, 0); + parse_dynamic(line, NULL); } fclose(fp); @@ -481,6 +482,7 @@ void conf_reload_dynamic(void) char *name = e[i]->d_name; char path[CMD_SIZE]; struct stat st; + struct timeval mtime; snprintf(path, sizeof(path), "%s/%s", dir, name); @@ -498,7 +500,8 @@ void conf_reload_dynamic(void) continue; } - parse_conf_dynamic(path, st.st_mtime); + TIMESPEC_TO_TIMEVAL(&mtime, &st.st_mtim); + parse_conf_dynamic(path, &mtime); } while (num--) diff --git a/service.c b/service.c index cd35e858..04f20064 100644 --- a/service.c +++ b/service.c @@ -538,7 +538,7 @@ void service_runlevel(int newlevel) * Returns: * POSIX OK(0) on success, or non-zero errno exit status on failure. */ -int service_register(int type, char *line, time_t mtime, char *username) +int service_register(int type, char *line, struct timeval *mtime, char *username) { int i = 0; int id = 1; /* Default to ID:1 */ diff --git a/service.h b/service.h index 606cc236..1f593b8f 100644 --- a/service.h +++ b/service.h @@ -28,7 +28,7 @@ #include "svc.h" void service_runlevel (int newlevel); -int service_register (int type, char *line, time_t mtime, char *username); +int service_register (int type, char *line, struct timeval *mtime, char *username); void service_unregister (svc_t *svc); int service_enabled (svc_t *svc); diff --git a/svc.c b/svc.c index 71acadd7..5400a87c 100644 --- a/svc.c +++ b/svc.c @@ -24,6 +24,7 @@ #include #include +#include #include "finit.h" #include "svc.h" @@ -172,7 +173,7 @@ svc_t *svc_dynamic_iterator(int first) svc_t *svc; for (svc = svc_iterator(first); svc; svc = svc_iterator(0)) { - if (svc->mtime) + if (svc->mtime.tv_sec) return svc; } @@ -415,13 +416,15 @@ void svc_mark_clean(svc_t *svc) *((int *)&svc->dirty) = 0; } -void svc_check_dirty(svc_t *svc, time_t mtime) +void svc_check_dirty(svc_t *svc, struct timeval *mtime) { - if (svc->mtime != mtime) + if (mtime && timercmp(&svc->mtime, mtime, !=)) svc_mark_dirty(svc); else svc_mark_clean(svc); - svc->mtime = mtime; + + svc->mtime.tv_sec = mtime ? mtime->tv_sec : 0; + svc->mtime.tv_usec = mtime ? mtime->tv_usec : 0; } /** diff --git a/svc.h b/svc.h index 7360e2b1..a9a30bb9 100644 --- a/svc.h +++ b/svc.h @@ -86,7 +86,7 @@ typedef struct svc { pid_t pid; const svc_state_t state; /* Paused, Reloading, Restart, Running, ... */ svc_type_t type; - time_t mtime; /* Modification time for .conf from /etc/finit.d/ */ + struct timeval mtime; /* Modification time for .conf from /etc/finit.d/ */ const int dirty; /* Set if old mtime != new mtime => reloaded, * or -1 when marked for removal */ int starting; /* ... waiting for pidfile to be re-asserted */ @@ -160,7 +160,7 @@ void svc_foreach_type (int types, void (*cb)(svc_t *)); int svc_stop_completed (void); void svc_mark_dynamic (void); -void svc_check_dirty (svc_t *svc, time_t mtime); +void svc_check_dirty (svc_t *svc, struct timeval *mtime); void svc_mark_dirty (svc_t *svc); void svc_mark_clean (svc_t *svc); void svc_clean_dynamic (void (*cb)(svc_t *)); @@ -177,7 +177,7 @@ static inline void svc_starting (svc_t *svc) { svc->starting = 1; } static inline void svc_started (svc_t *svc) { svc->starting = 0; } static inline int svc_is_starting (svc_t *svc) { return 0 != svc->starting; } -static inline int svc_is_dynamic (svc_t *svc) { return svc && 0 != svc->mtime; } +static inline int svc_is_dynamic (svc_t *svc) { return svc && 0 != svc->mtime.tv_sec; } static inline int svc_is_removed (svc_t *svc) { return svc && -1 == svc->dirty; } static inline int svc_is_changed (svc_t *svc) { return svc && 0 != svc->dirty; } static inline int svc_is_updated (svc_t *svc) { return svc && 1 == svc->dirty; }