Add support run/task/service 'conflict:foo' handling

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2023-02-28 00:49:55 +01:00
1 parent a613ee908f
commit 56a89db889
4 files changed
+82 -1

No files matched your search

+18
View File
@@ -721,6 +721,24 @@ optional `name` argument:
name:<service-name> name:<service-name>
If multiple instances of a service, with the same `name`, exist. Set
the identifier `:ID` to prevent Finit from replacing previous instances:
service :eth1 ssdpd eth1 -- Windows discovery on eth1
service :eth2 ssdpd eth2 -- Windows discovery on eth2
If you have conflicting services and want to prevent them from starting,
use the `conflict:` argument:
service [S12345789] udevd -- Device event management daemon
run [S] conflict:udevd mdev -s -- Populating device tree
Multiple conflicting services can be separated using `,`:
service :1 abc
service :2 abc
service conflict:abc:1,abc:2 cde
As mentioned previously, services are automatically restarted, this is As mentioned previously, services are automatically restarted, this is
configurable with the following options: configurable with the following options:
+17 -1
View File
@@ -605,6 +605,13 @@ static int service_start(svc_t *svc)
} }
} }
/* Don't start if it conflicts with something else already started */
if (svc_conflicts(svc)) {
logit(LOG_INFO, "Not starting %s, conflicts with %s",
svc_ident(svc, NULL, 0), svc->conflict);
return 1;
}
compose_cmdline(svc, cmdline, sizeof(cmdline)); compose_cmdline(svc, cmdline, sizeof(cmdline));
if (svc_is_sysv(svc)) if (svc_is_sysv(svc))
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline); logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline);
@@ -1387,7 +1394,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *name = NULL, *halt = NULL, *delay = NULL; char *name = NULL, *halt = NULL, *delay = NULL;
char *id = NULL, *env = NULL, *cgroup = NULL; char *id = NULL, *env = NULL, *cgroup = NULL;
char *pre_script = NULL, *post_script = NULL; char *pre_script = NULL, *post_script = NULL;
char *ready_script = NULL; char *ready_script = NULL, *conflict = NULL;
char *notify = NULL; char *notify = NULL;
struct tty tty = { 0 }; struct tty tty = { 0 };
char *dev = NULL; char *dev = NULL;
@@ -1498,6 +1505,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
cgroup = arg; /* only settings */ cgroup = arg; /* only settings */
else if (MATCH_CMD(cmd, "cgroup.", arg)) else if (MATCH_CMD(cmd, "cgroup.", arg))
cgroup = arg; /* with group */ cgroup = arg; /* with group */
else if (MATCH_CMD(cmd, "conflict:", arg))
conflict = arg;
else else
break; break;
@@ -1696,6 +1705,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
strlcpy(svc->file, file, sizeof(svc->file)); strlcpy(svc->file, file, sizeof(svc->file));
else else
memset(svc->file, 0, sizeof(svc->file)); memset(svc->file, 0, sizeof(svc->file));
if (conflict)
strlcpy(svc->conflict, conflict, sizeof(svc->conflict));
else
memset(svc->conflict, 0, sizeof(svc->conflict));
svc->manual = manual; svc->manual = manual;
svc->respawn = respawn; svc->respawn = respawn;
svc->forking = forking; svc->forking = forking;
@@ -2488,6 +2501,9 @@ int service_completed(void)
if (!svc_enabled(svc)) if (!svc_enabled(svc))
continue; continue;
if (svc_conflicts(svc))
continue;
if (strstr(svc->cond, plugin_hook_str(HOOK_SVC_UP)) || if (strstr(svc->cond, plugin_hook_str(HOOK_SVC_UP)) ||
strstr(svc->cond, plugin_hook_str(HOOK_SYSTEM_UP))) { strstr(svc->cond, plugin_hook_str(HOOK_SYSTEM_UP))) {
dbg("Skipping %s(%s), post-strap hook", svc->desc, svc_ident(svc, NULL, 0)); dbg("Skipping %s(%s), post-strap hook", svc->desc, svc_ident(svc, NULL, 0));
+45
View File
@@ -619,6 +619,51 @@ int svc_enabled(svc_t *svc)
return 1; return 1;
} }
/**
* svc_conflicts - Check if svc conflicts with any other running svc
* @svc:
*
* Returns:
* %TRUE(1) or %FALSE(0)
*/
int svc_conflicts(svc_t *svc)
{
char *ptr, *nm;
int rc = 0;
if (!svc->conflict[0])
return 0;
ptr = strdup(svc->conflict);
if (!ptr)
return 0;
nm = strtok(ptr, ",");
while (nm) {
char *name, *id;
svc_t *s;
name = strdupa(nm);
id = strchr(name, ':');
if (id)
id++ = 0;
else
id = "";
s = svc_find(name, id);
if (s) {
if (s->state >= SVC_STOPPING_STATE)
rc = 1;
break;
}
nm = strtok(NULL, ",");
}
free(ptr);
return rc;
}
/* break up "job:id job:id job:id ..." into several "job:id" tokens */ /* break up "job:id job:id job:id ..." into several "job:id" tokens */
static char *tokstr(char *str, size_t len) static char *tokstr(char *str, size_t len)
{ {
+2
View File
@@ -181,6 +181,7 @@ typedef struct svc {
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; int args_dirty;
char conflict[MAX_ARG_LEN];
char desc[MAX_STR_LEN]; char desc[MAX_STR_LEN];
char env[MAX_ARG_LEN]; char env[MAX_ARG_LEN];
char pre_script[MAX_ARG_LEN]; char pre_script[MAX_ARG_LEN];
@@ -233,6 +234,7 @@ void svc_prune_bootstrap (void);
void svc_enable (svc_t *svc); void svc_enable (svc_t *svc);
int svc_enabled (svc_t *svc); int svc_enabled (svc_t *svc);
int svc_conflicts (svc_t *svc);
int svc_parse_jobstr (char *str, size_t len, void *user_data, int (*found)(svc_t *, void *), int (not_found)(char *, char *, void *)); int svc_parse_jobstr (char *str, size_t len, void *user_data, int (*found)(svc_t *, void *), int (not_found)(char *, char *, void *));