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:
Jacques de Laval committed 2021-04-01 16:18:54 +02:00
1 parent 665d212bd6
commit 10f4c7fa18
4 files changed
+34 -11

No files matched your search

+26 -8
View File
@@ -937,23 +937,29 @@ static void parse_name(svc_t *svc, char *arg)
*/
static void parse_cmdline_args(svc_t *svc, char *cmd)
{
int diff = 0;
char sep = 0;
char *arg;
int i = 0;
if (strcmp(svc->args[i], cmd))
diff++;
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
* array to be zero-terminated.
*/
for (i = 1; (arg = strtok(NULL, " ")) && i < (MAX_NUM_SVC_ARGS - 1);) {
char prev[sizeof(svc->args[0])];
char ch = arg[0];
size_t len;
if (!sep) {
strlcpy(prev, svc->args[i], sizeof(prev));
svc->args[i][0] = 0;
}
/* XXX: ugly string arg re-concatenation, fixme */
if (ch == '"' || ch == '\'')
sep = ch;
@@ -970,6 +976,9 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
continue;
}
if (strcmp(svc->args[i], prev))
diff++;
sep = 0;
i++;
}
@@ -978,8 +987,12 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
* Clear remaining args in case they were set earlier.
* This also zero-terminates the args array.
*/
while (i < MAX_NUM_SVC_ARGS)
svc->args[i++][0] = 0;
while (i < MAX_NUM_SVC_ARGS) {
if (svc->args[i++][0]) {
svc->args[i-1][0] = 0;
diff++;
}
}
#if 0
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
if (!svc->args[i][0])
@@ -987,6 +1000,10 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
_d("%s ", svc->args[i]);
}
#endif
if (diff)
_d("Modified args for %s detected", cmd);
svc->args_dirty = (diff > 0);
}
@@ -1500,7 +1517,9 @@ restart:
case COND_ON:
if (svc_is_changed(svc)) {
if (svc->sighup) {
if (svc_nohup(svc))
service_stop(svc);
else {
/*
* wait until all processes have been
* stopped before continuing...
@@ -1508,8 +1527,7 @@ restart:
if (sm_is_in_teardown(&sm))
break;
service_restart(svc);
} else
service_stop(svc);
}
svc_mark_clean(svc);
}
+1
View File
@@ -498,6 +498,7 @@ void svc_mark_dirty(svc_t *svc)
void svc_mark_clean(svc_t *svc)
{
*((int *)&svc->dirty) = 0;
*((int *)&svc->args_dirty) = 0;
}
void svc_enable(svc_t *svc)
+2 -1
View File
@@ -142,6 +142,7 @@ typedef struct svc {
/* Command, arguments and service description */
char cmd[MAX_ARG_LEN];
char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN];
int args_dirty;
char desc[MAX_STR_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_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 void svc_starting (svc_t *svc) { if (svc) svc->starting = 1; }