mirror of
https://github.com/troglobit/finit.git
synced 2026-11-06 15:51:03 +00:00
Fix nasty service matcher bug
In some conditions, typically when the same command is used for multiple services, e.g. the modules-load plugin, the svc_find() function returned an existing "similar" entry instead of NULL, causing loss of config. When creating, and searching for, a run/task/service we must follow the new name:id paradigm to the letter. Always create based on name:id and always search for matching name:id. The name may be derived from the command, but they cannot be used interchangably. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
7e37ac348e
commit
d3c6351ed8
5 files changed
+16
-38
No files matched your search
@@ -198,7 +198,7 @@ static svc_t *do_find(char *buf, size_t len)
|
|||||||
if (!id)
|
if (!id)
|
||||||
return svc_named_iterator(&iter, 1, input);
|
return svc_named_iterator(&iter, 1, input);
|
||||||
|
|
||||||
return svc_find_by_nameid(input, id);
|
return svc_find(input, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static svc_t *do_find_byc(char *buf, size_t len)
|
static svc_t *do_find_byc(char *buf, size_t len)
|
||||||
|
|||||||
+1
-1
@@ -794,7 +794,7 @@ int main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if (whichp(FINIT_LIBPATH_ "/watchdogd") && fexist(WDT_DEVNODE)) {
|
if (whichp(FINIT_LIBPATH_ "/watchdogd") && fexist(WDT_DEVNODE)) {
|
||||||
service_register(SVC_TYPE_SERVICE, "[123456789] cgroup.init name:watchdog :finit " FINIT_LIBPATH_ "/watchdogd -- Finit watchdog daemon", global_rlimit, NULL);
|
service_register(SVC_TYPE_SERVICE, "[123456789] cgroup.init name:watchdog :finit " FINIT_LIBPATH_ "/watchdogd -- Finit watchdog daemon", global_rlimit, NULL);
|
||||||
wdog = svc_find_by_nameid("watchdog", "finit");
|
wdog = svc_find("watchdog", "finit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-2
@@ -1352,11 +1352,11 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
next:
|
next:
|
||||||
svc = svc_find_by_tty(dev);
|
svc = svc_find_by_tty(dev);
|
||||||
} else
|
} else
|
||||||
svc = svc_find(cmd, id);
|
svc = svc_find(name, id);
|
||||||
|
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
_d("Creating new svc for %s name %s id %s type %d", cmd, name, id, type);
|
_d("Creating new svc for %s name %s id %s type %d", cmd, name, id, type);
|
||||||
svc = svc_new(cmd, id, type);
|
svc = svc_new(cmd, name, id, type);
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
_e("Out of memory, cannot register service %s", cmd);
|
_e("Out of memory, cannot register service %s", cmd);
|
||||||
return errno = ENOMEM;
|
return errno = ENOMEM;
|
||||||
|
|||||||
@@ -107,16 +107,17 @@ static void svc_gc(void *arg)
|
|||||||
/**
|
/**
|
||||||
* svc_new - Create a new service
|
* svc_new - Create a new service
|
||||||
* @cmd: External program to call
|
* @cmd: External program to call
|
||||||
|
* @name: Default or custom svc name
|
||||||
* @id: Instance id
|
* @id: Instance id
|
||||||
* @type: Service type, one of service, task, run
|
* @type: Service type, one of service, task, run
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
||||||
*/
|
*/
|
||||||
svc_t *svc_new(char *cmd, char *id, int type)
|
svc_t *svc_new(char *cmd, char *name, char *id, int type)
|
||||||
{
|
{
|
||||||
int job = -1;
|
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
int job = -1;
|
||||||
|
|
||||||
/* Find first job n:o if registering multiple instances */
|
/* Find first job n:o if registering multiple instances */
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
@@ -134,6 +135,8 @@ svc_t *svc_new(char *cmd, char *id, int type)
|
|||||||
|
|
||||||
svc->type = type;
|
svc->type = type;
|
||||||
svc->job = job;
|
svc->job = job;
|
||||||
|
if (name)
|
||||||
|
strlcpy(svc->name, name, sizeof(svc->name));
|
||||||
if (id && id[0])
|
if (id && id[0])
|
||||||
strlcpy(svc->id, id, sizeof(svc->id));
|
strlcpy(svc->id, id, sizeof(svc->id));
|
||||||
if (cmd)
|
if (cmd)
|
||||||
@@ -348,13 +351,13 @@ svc_t *svc_stop_completed(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* svc_find - Find a service object by its full path name
|
* svc_find - Find a service object by its full path name
|
||||||
* @cmd: Full path name, e.g., /sbin/syslogd
|
* @name: Full path name, e.g., /sbin/syslogd
|
||||||
* @id: Optional instance id
|
* @id: Optional instance id
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
* A pointer to an &svc_t object, or %NULL if not found.
|
||||||
*/
|
*/
|
||||||
svc_t *svc_find(char *cmd, char *id)
|
svc_t *svc_find(char *name, char *id)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
@@ -362,7 +365,7 @@ svc_t *svc_find(char *cmd, char *id)
|
|||||||
id = "";
|
id = "";
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
if (!strcmp(svc->cmd, cmd) && !strcmp(svc->id, id))
|
if (!strcmp(svc->name, name) && !strcmp(svc->id, id))
|
||||||
return svc;
|
return svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,30 +414,6 @@ svc_t *svc_find_by_jobid(int job, char *id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* svc_find_by_nameid - Find an service object by its basename:ID
|
|
||||||
* @name: Process name to match
|
|
||||||
* @id: Optional instance id
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
|
||||||
*/
|
|
||||||
svc_t *svc_find_by_nameid(char *name, char *id)
|
|
||||||
{
|
|
||||||
svc_t *svc, *iter = NULL;
|
|
||||||
|
|
||||||
if (!id)
|
|
||||||
id = "";
|
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
|
||||||
if (!strcmp(svc->id, id) && !strcmp(name, svc->name))
|
|
||||||
return svc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
svc_t *svc_find_by_tty(char *dev)
|
svc_t *svc_find_by_tty(char *dev)
|
||||||
{
|
{
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
@@ -720,7 +699,7 @@ int svc_parse_jobstr(char *str, size_t len, void *user_data, int (*found)(svc_t
|
|||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
id = ptr;
|
id = ptr;
|
||||||
|
|
||||||
svc = svc_find_by_nameid(token, id);
|
svc = svc_find(token, id);
|
||||||
if (!svc && not_found)
|
if (!svc && not_found)
|
||||||
result += not_found(token, id, user_data);
|
result += not_found(token, id, user_data);
|
||||||
else if (found)
|
else if (found)
|
||||||
|
|||||||
@@ -193,14 +193,13 @@ typedef struct svc {
|
|||||||
struct timespec gc;
|
struct timespec gc;
|
||||||
} svc_t;
|
} svc_t;
|
||||||
|
|
||||||
svc_t *svc_new (char *cmd, char *id, int type);
|
svc_t *svc_new (char *cmd, char *name, char *id, int type);
|
||||||
int svc_del (svc_t *svc);
|
int svc_del (svc_t *svc);
|
||||||
void svc_validate (svc_t *svc);
|
void svc_validate (svc_t *svc);
|
||||||
|
|
||||||
svc_t *svc_find (char *cmd, char *id);
|
svc_t *svc_find (char *name, char *id);
|
||||||
svc_t *svc_find_by_pid (pid_t pid);
|
svc_t *svc_find_by_pid (pid_t pid);
|
||||||
svc_t *svc_find_by_jobid (int job, char *id);
|
svc_t *svc_find_by_jobid (int job, char *id);
|
||||||
svc_t *svc_find_by_nameid (char *name, char *id);
|
|
||||||
svc_t *svc_find_by_tty (char *dev);
|
svc_t *svc_find_by_tty (char *dev);
|
||||||
svc_t *svc_find_by_pidfile (char *fn);
|
svc_t *svc_find_by_pidfile (char *fn);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user