mirror of
https://github.com/troglobit/finit.git
synced 2026-10-25 12:04:36 +00:00
Add support for if:[!]ident and ifdef:[!]ident for run/task/services
Conditional loading of stanza depending on ident is already loaded. The if: checks as in-band while ifdef: checks out-of-band, i.e., post eval. The optional leading '!' negates the comparison, if NOT foo then ... Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
ed383eaaa6
commit
fa71f97dcf
5 files changed
+72
No files matched your search
@@ -1011,6 +1011,9 @@ int conf_reload(void)
|
|||||||
/* Mark any reverse deps as chenaged. */
|
/* Mark any reverse deps as chenaged. */
|
||||||
service_update_rdeps();
|
service_update_rdeps();
|
||||||
|
|
||||||
|
/* Prune according to ifdef:[!]ident */
|
||||||
|
service_mark_unavail();
|
||||||
|
|
||||||
/* Set up top-level cgroups */
|
/* Set up top-level cgroups */
|
||||||
cgroup_config();
|
cgroup_config();
|
||||||
done:
|
done:
|
||||||
|
|||||||
@@ -1395,6 +1395,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
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, *conflict = NULL;
|
char *ready_script = NULL, *conflict = NULL;
|
||||||
|
char *ifdef = NULL, *ifident = NULL;
|
||||||
char *notify = NULL;
|
char *notify = NULL;
|
||||||
struct tty tty = { 0 };
|
struct tty tty = { 0 };
|
||||||
char *dev = NULL;
|
char *dev = NULL;
|
||||||
@@ -1507,6 +1508,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
cgroup = arg; /* with group */
|
cgroup = arg; /* with group */
|
||||||
else if (MATCH_CMD(cmd, "conflict:", arg))
|
else if (MATCH_CMD(cmd, "conflict:", arg))
|
||||||
conflict = arg;
|
conflict = arg;
|
||||||
|
else if (MATCH_CMD(cmd, "if:", arg))
|
||||||
|
ifident = arg;
|
||||||
|
else if (MATCH_CMD(cmd, "ifdef:", arg))
|
||||||
|
ifdef = arg;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1520,6 +1525,18 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
if (!id)
|
if (!id)
|
||||||
id = "";
|
id = "";
|
||||||
|
|
||||||
|
if (ifident) {
|
||||||
|
char ident[MAX_IDENT_LEN];
|
||||||
|
|
||||||
|
if (id[0]) {
|
||||||
|
snprintf(ident, sizeof(ident), "%s:%s", name, id);
|
||||||
|
} else
|
||||||
|
strlcpy(ident, name, sizeof(ident));
|
||||||
|
|
||||||
|
if (!svc_ifthen(ident, ifident))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
levels = conf_parse_runlevels(runlevels);
|
levels = conf_parse_runlevels(runlevels);
|
||||||
if (runlevel > 0 && !ISOTHER(levels, 0)) {
|
if (runlevel > 0 && !ISOTHER(levels, 0)) {
|
||||||
dbg("Skipping %s%s%s, bootstrap is completed.",
|
dbg("Skipping %s%s%s, bootstrap is completed.",
|
||||||
@@ -1710,6 +1727,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
strlcpy(svc->conflict, conflict, sizeof(svc->conflict));
|
strlcpy(svc->conflict, conflict, sizeof(svc->conflict));
|
||||||
else
|
else
|
||||||
memset(svc->conflict, 0, sizeof(svc->conflict));
|
memset(svc->conflict, 0, sizeof(svc->conflict));
|
||||||
|
if (ifdef)
|
||||||
|
strlcpy(svc->ifdef, ifdef, sizeof(svc->ifdef));
|
||||||
|
else
|
||||||
|
memset(svc->ifdef, 0, sizeof(svc->ifdef));
|
||||||
svc->manual = manual;
|
svc->manual = manual;
|
||||||
svc->respawn = respawn;
|
svc->respawn = respawn;
|
||||||
svc->forking = forking;
|
svc->forking = forking;
|
||||||
@@ -1897,6 +1918,25 @@ void service_update_rdeps(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop services with 'if:otherserv' if otherserv does not exist.
|
||||||
|
* Drop services with 'if:!otherserv' if otherserv does exist.
|
||||||
|
*/
|
||||||
|
void service_mark_unavail(void)
|
||||||
|
{
|
||||||
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
|
char buf[MAX_IDENT_LEN];
|
||||||
|
|
||||||
|
if (!svc->ifdef[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!svc_ifthen(svc_ident(svc, buf, sizeof(buf)), svc->ifdef))
|
||||||
|
svc_mark(svc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void service_kill_script(svc_t *svc)
|
static void service_kill_script(svc_t *svc)
|
||||||
{
|
{
|
||||||
if (svc->pid <= 1)
|
if (svc->pid <= 1)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ void service_unregister (svc_t *svc);
|
|||||||
void service_runtask_clean (void);
|
void service_runtask_clean (void);
|
||||||
void service_reload_dynamic (void);
|
void service_reload_dynamic (void);
|
||||||
void service_update_rdeps (void);
|
void service_update_rdeps (void);
|
||||||
|
void service_mark_unavail (void);
|
||||||
|
|
||||||
void service_ready_script (svc_t *svc); /* XXX: only for pidfile plugin before notify framework */
|
void service_ready_script (svc_t *svc); /* XXX: only for pidfile plugin before notify framework */
|
||||||
|
|
||||||
|
|||||||
@@ -686,6 +686,32 @@ int svc_conflicts(svc_t *svc)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int svc_ifthen(const char *ident, const char *stmt)
|
||||||
|
{
|
||||||
|
int not = 0;
|
||||||
|
svc_t *svc;
|
||||||
|
|
||||||
|
if (!stmt || !stmt[0])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (stmt[0] == '!') {
|
||||||
|
stmt++;
|
||||||
|
not++;
|
||||||
|
}
|
||||||
|
|
||||||
|
svc = svc_find_by_str(stmt);
|
||||||
|
if (not && svc) {
|
||||||
|
dbg("skipping %s, %s already loaded.", ident, svc_ident(svc, NULL, 0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!not && !svc) {
|
||||||
|
dbg("skipping %s, %s not available.", ident, stmt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ typedef struct svc {
|
|||||||
int job; /* For intenal use only, canonical ref is NAME:ID */
|
int job; /* For intenal use only, canonical ref is NAME:ID */
|
||||||
char name[MAX_ARG_LEN];
|
char name[MAX_ARG_LEN];
|
||||||
char id[MAX_ID_LEN]; /* :ID */
|
char id[MAX_ID_LEN]; /* :ID */
|
||||||
|
char ifdef[MAX_IDENT_LEN];
|
||||||
|
|
||||||
/* Counters */
|
/* Counters */
|
||||||
char once; /* run/task, (at least) once per runlevel */
|
char once; /* run/task, (at least) once per runlevel */
|
||||||
@@ -237,6 +238,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_conflicts (svc_t *svc);
|
||||||
|
int svc_ifthen (const char *ident, const char *ifstm);
|
||||||
|
|
||||||
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 *));
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user