From 3865ce765ee4437ab21601a51a66d589e8cc391c Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 22 Apr 2020 10:27:37 +0200 Subject: [PATCH] src: svc: Handle case where multiple services have same PID file Services may exist in multiple runlevels, i.e. one behavior at bootstrap and another at runtime. If the user does not set a specific PID file to be used as condition finit can match the wrong svc. This patch extends svc_find_by_pidfile() to also compare the contents of the PID file with the PID of the registered svc_t. Signed-off-by: Joachim Nilsson --- src/svc.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/svc.c b/src/svc.c index 68c71517..230011d3 100644 --- a/src/svc.c +++ b/src/svc.c @@ -376,6 +376,14 @@ svc_t *svc_find_by_nameid(char *name, char *id) * svc_find_by_plidfile - Find an service object by its PID file * @fn: PID file, can be absolute path or relative to /run * + * This function is primarily used by the pidfile plugin to track the + * conditions and dependencies of services. + * + * Note, the PID file is assumed to exist so the contents can be + * compared to the the PID of a located service. There may be several + * services, in many runlevels, that use the same name for the PID file. + * So we won't know for sure until the PID is compared. + * * Returns: * A pointer to an &svc_t object, or %NULL if not found. */ @@ -385,9 +393,17 @@ svc_t *svc_find_by_pidfile(char *fn) for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) { char path[MAX_ARG_LEN]; + pid_t pid; - if (string_compare(pid_runpath(fn, path, sizeof(path)), pid_file(svc))) - return svc; + pid_runpath(fn, path, sizeof(path)); + if (!string_compare(path, pid_file(svc))) + continue; + + pid = pid_file_read(path); + if (svc->pid != pid) + continue; + + return svc; } return NULL;