mirror of
https://github.com/troglobit/finit.git
synced 2026-11-06 15:51:03 +00:00
Do a full restart rather than HUP if command line of a service has changed
By keeping track of when a full restart is needed, Finit can relieve the user of having to track modifications to service configuration. This also makes initctl reload easier to explain and reason about as the effect of a reload should now be that any configuration updates to services will be fully "commited" by initctl reload. Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
This commit is contained in:
1 parent
665d212bd6
commit
10f4c7fa18
4 files changed
+34
-11
No files matched your search
@@ -232,8 +232,11 @@ For more information, see [doc/plugins.md](doc/plugins.md).
|
|||||||
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
|
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
|
||||||
registering any changes to `.conf` files. To activate a change the user
|
registering any changes to `.conf` files. To activate a change the user
|
||||||
must call `initctl reload`, which reloads all modified files, stops any
|
must call `initctl reload`, which reloads all modified files, stops any
|
||||||
removed services, starts new ones, and restarts any modified ones, with
|
removed services, starts new ones, and restarts any modified ones. If the
|
||||||
SIGHUP if the process supports it.
|
command line arguments of a service have changed, the process will be
|
||||||
|
terminated and then started again with the updated arguments. If the arguments
|
||||||
|
have not been modified and the process supports SIGHUP, the process will
|
||||||
|
receive a SIGHUP rather than being terminated and started.
|
||||||
|
|
||||||
For some use-cases the extra step of calling `initctl reload` creates an
|
For some use-cases the extra step of calling `initctl reload` creates an
|
||||||
unnecessary overhead, which can be removed at build-time using:
|
unnecessary overhead, which can be removed at build-time using:
|
||||||
|
|||||||
+26
-8
@@ -937,23 +937,29 @@ static void parse_name(svc_t *svc, char *arg)
|
|||||||
*/
|
*/
|
||||||
static void parse_cmdline_args(svc_t *svc, char *cmd)
|
static void parse_cmdline_args(svc_t *svc, char *cmd)
|
||||||
{
|
{
|
||||||
|
int diff = 0;
|
||||||
char sep = 0;
|
char sep = 0;
|
||||||
char *arg;
|
char *arg;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
if (strcmp(svc->args[i], cmd))
|
||||||
|
diff++;
|
||||||
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
|
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
|
||||||
|
|
||||||
while (i < MAX_NUM_SVC_ARGS)
|
|
||||||
svc->args[i++][0] = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy supplied args. Stop at MAX_NUM_SVC_ARGS-1 to allow the args
|
* Copy supplied args. Stop at MAX_NUM_SVC_ARGS-1 to allow the args
|
||||||
* array to be zero-terminated.
|
* array to be zero-terminated.
|
||||||
*/
|
*/
|
||||||
for (i = 1; (arg = strtok(NULL, " ")) && i < (MAX_NUM_SVC_ARGS - 1);) {
|
for (i = 1; (arg = strtok(NULL, " ")) && i < (MAX_NUM_SVC_ARGS - 1);) {
|
||||||
|
char prev[sizeof(svc->args[0])];
|
||||||
char ch = arg[0];
|
char ch = arg[0];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (!sep) {
|
||||||
|
strlcpy(prev, svc->args[i], sizeof(prev));
|
||||||
|
svc->args[i][0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: ugly string arg re-concatenation, fixme */
|
/* XXX: ugly string arg re-concatenation, fixme */
|
||||||
if (ch == '"' || ch == '\'')
|
if (ch == '"' || ch == '\'')
|
||||||
sep = ch;
|
sep = ch;
|
||||||
@@ -970,6 +976,9 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(svc->args[i], prev))
|
||||||
|
diff++;
|
||||||
|
|
||||||
sep = 0;
|
sep = 0;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -978,8 +987,12 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
* Clear remaining args in case they were set earlier.
|
* Clear remaining args in case they were set earlier.
|
||||||
* This also zero-terminates the args array.
|
* This also zero-terminates the args array.
|
||||||
*/
|
*/
|
||||||
while (i < MAX_NUM_SVC_ARGS)
|
while (i < MAX_NUM_SVC_ARGS) {
|
||||||
svc->args[i++][0] = 0;
|
if (svc->args[i++][0]) {
|
||||||
|
svc->args[i-1][0] = 0;
|
||||||
|
diff++;
|
||||||
|
}
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
|
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
|
||||||
if (!svc->args[i][0])
|
if (!svc->args[i][0])
|
||||||
@@ -987,6 +1000,10 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
_d("%s ", svc->args[i]);
|
_d("%s ", svc->args[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (diff)
|
||||||
|
_d("Modified args for %s detected", cmd);
|
||||||
|
svc->args_dirty = (diff > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1500,7 +1517,9 @@ restart:
|
|||||||
|
|
||||||
case COND_ON:
|
case COND_ON:
|
||||||
if (svc_is_changed(svc)) {
|
if (svc_is_changed(svc)) {
|
||||||
if (svc->sighup) {
|
if (svc_nohup(svc))
|
||||||
|
service_stop(svc);
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* wait until all processes have been
|
* wait until all processes have been
|
||||||
* stopped before continuing...
|
* stopped before continuing...
|
||||||
@@ -1508,8 +1527,7 @@ restart:
|
|||||||
if (sm_is_in_teardown(&sm))
|
if (sm_is_in_teardown(&sm))
|
||||||
break;
|
break;
|
||||||
service_restart(svc);
|
service_restart(svc);
|
||||||
} else
|
}
|
||||||
service_stop(svc);
|
|
||||||
|
|
||||||
svc_mark_clean(svc);
|
svc_mark_clean(svc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,6 +498,7 @@ void svc_mark_dirty(svc_t *svc)
|
|||||||
void svc_mark_clean(svc_t *svc)
|
void svc_mark_clean(svc_t *svc)
|
||||||
{
|
{
|
||||||
*((int *)&svc->dirty) = 0;
|
*((int *)&svc->dirty) = 0;
|
||||||
|
*((int *)&svc->args_dirty) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void svc_enable(svc_t *svc)
|
void svc_enable(svc_t *svc)
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ typedef struct svc {
|
|||||||
/* Command, arguments and service description */
|
/* Command, arguments and service description */
|
||||||
char cmd[MAX_ARG_LEN];
|
char cmd[MAX_ARG_LEN];
|
||||||
char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN];
|
char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN];
|
||||||
|
int args_dirty;
|
||||||
char desc[MAX_STR_LEN];
|
char desc[MAX_STR_LEN];
|
||||||
char env[MAX_ARG_LEN];
|
char env[MAX_ARG_LEN];
|
||||||
|
|
||||||
@@ -194,7 +195,7 @@ static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTAS
|
|||||||
static inline int svc_is_forking (svc_t *svc) { return (svc_is_daemon(svc) || svc_is_sysv(svc)) && svc->pidfile[0] == '!'; }
|
static inline int svc_is_forking (svc_t *svc) { return (svc_is_daemon(svc) || svc_is_sysv(svc)) && svc->pidfile[0] == '!'; }
|
||||||
|
|
||||||
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
||||||
static inline int svc_has_sighup (svc_t *svc) { return svc && 0 != svc->sighup; }
|
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
|
||||||
static inline int svc_has_pidfile (svc_t *svc) { return svc_is_daemon(svc) && svc->pidfile[0] != 0 && svc->pidfile[0] != '!'; }
|
static inline int svc_has_pidfile (svc_t *svc) { return svc_is_daemon(svc) && svc->pidfile[0] != 0 && svc->pidfile[0] != '!'; }
|
||||||
|
|
||||||
static inline void svc_starting (svc_t *svc) { if (svc) svc->starting = 1; }
|
static inline void svc_starting (svc_t *svc) { if (svc) svc->starting = 1; }
|
||||||
|
|||||||
Reference in new issue
Block a user