.conf: don't rely on mtime to determine if service needs reloading

Until now Finit has used mtime to determine if a file has been changed,
or simply touched to request reload, when `initctl reload` is called.
Using mtime for this purpose is a monumentally bad idea since time can
be changed at any point: a user may adjust the time, NTP continously
tunes the clock, and time stamps are stored as the walltime.  So if we
compare timestamps against the last time we (booted or) did reload, we
would miss .conf file changes.

This patch replaces the mtime mistake with an inotify watcher for the
following files: /etc/finit.d/*.conf, /etc/finit.d/available/*.conf,
and /etc/finit.conf.  All file changes between (bootstraps and) calls
to `initctl reload` are tracked, like the mtime backend it replaces.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2017-12-22 13:08:38 +01:00
1 parent bb3d9c8670
commit b439ac670d
10 files changed
+261 -90

No files matched your search

+8 -4
View File
@@ -474,7 +474,7 @@ void service_runlevel(int newlevel)
* @type: %SVC_TYPE_SERVICE(0), %SVC_TYPE_TASK(1), %SVC_TYPE_RUN(2)
* @cfg: Configuration, complete command, with -- for description text
* @rlimit: Limits for this service/task/run/inetd, may be global limits
* @mtime: The modification time if service is loaded from /etc/finit.d
* @file: The file name service was loaded from
*
* This function is used to register commands to be run on different
* system runlevels with optional username. The @type argument details
@@ -521,7 +521,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 *cfg, struct rlimit rlimit[], struct timeval *mtime)
int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
{
int i = 0;
int id = -1;
@@ -727,9 +727,13 @@ recreate:
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
/* New, recently modified or unchanged ... used on reload. */
svc_check_dirty(svc, mtime);
free(line);
if (file && conf_changed(file))
svc_mark_dirty(svc);
else
svc_mark_clean(svc);
/* Free duped line, from above */
free(line);
return 0;
}