mirror of
https://github.com/troglobit/finit.git
synced 2026-10-17 10:49:34 +00:00
Add <~cond> condition modifier for tightly coupled services
Conditions in Finit are dependencies: if A is asserted, service B is
allowed to run. When A goes through FLUX (e.g., upstream reloads),
dependents are PAUSED and then simply resumed when the condition is
reasserted -- this is the correct behavior for barrier-style deps
like <pid/syslogd>.
However, some setups have tightly coupled services where dependents
must be reloaded/restarted when an upstream service reloads, not just
resumed. E.g., the FRR routing stack on Infix OS:
netd <pid/mgmtd> ← zebra <!pid/netd> ← {staticd,ripd} <!pid/zebra>
When netd reloads (SIGHUP), zebra and its dependents must be restarted
to pick up the new configuration.
The new '~' condition prefix marks a dependency as flux-sensitive:
service <!~pid/netd> name:zebra ...
When the upstream condition goes FLUX and returns to ON, the dependent
is reloaded (SIGHUP) or restarted (noreload '!') instead of merely
resumed. Transitivity follows naturally through the condition chain.
Closes #416
Closes #476
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
6 files changed
+77
-12
No files matched your search
+13
@@ -745,8 +745,21 @@ void conf_parse_cond(svc_t *svc, char *cond)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The '~' prefix means a reload of the upstream service is
|
||||
* propagated to this service -- it will be reloaded (SIGHUP)
|
||||
* or restarted (noreload), not just paused and resumed.
|
||||
* Syntax: <!~pid/foo,~pid/bar> or <~pid/foo>
|
||||
*
|
||||
* Strip '~' from each condition and set the service-level
|
||||
* flag. This allows '~' on any condition in the list.
|
||||
*/
|
||||
svc->cond[0] = 0;
|
||||
for (i = 0, c = strtok(ptr, ","); c; c = strtok(NULL, ","), i++) {
|
||||
if (c[0] == '~') {
|
||||
c++;
|
||||
svc->flux_reload = 1;
|
||||
}
|
||||
devmon_add_cond(c);
|
||||
if (i)
|
||||
strlcat(svc->cond, ",", sizeof(svc->cond));
|
||||
|
||||
@@ -3147,6 +3147,19 @@ restart:
|
||||
case COND_ON:
|
||||
kill(svc->pid, SIGCONT);
|
||||
svc_set_state(svc, SVC_RUNNING_STATE);
|
||||
|
||||
/*
|
||||
* Propagate reload (~): upstream reloaded, so
|
||||
* we must also reload/restart, not just resume.
|
||||
*/
|
||||
if (svc->flux_reload && !svc_is_changed(svc)) {
|
||||
if (svc_is_noreload(svc))
|
||||
service_stop(svc);
|
||||
else
|
||||
service_reload(svc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reassert condition if we go from waiting and no change */
|
||||
if (!svc_is_changed(svc)) {
|
||||
if (svc->notify == SVC_NOTIFY_PID) {
|
||||
|
||||
@@ -146,6 +146,7 @@ typedef struct svc {
|
||||
int starting; /* ... waiting for pidfile to be re-asserted */
|
||||
int runlevels;
|
||||
int sighup; /* This service supports SIGHUP :) */
|
||||
int flux_reload; /* Propagate reload from dependency, '~' prefix */
|
||||
int forking; /* This is a service/sysv daemon that forks, wait for it ... */
|
||||
svc_block_t block; /* Reason that this service is currently stopped */
|
||||
char cond[MAX_COND_LEN];
|
||||
|
||||
Reference in new issue
Block a user