From 9d0247153a70ab1909d0690ec9b7f4d20e8cb602 Mon Sep 17 00:00:00 2001 Message-Id: <9d0247153a70ab1909d0690ec9b7f4d20e8cb602@dist-git> From: Vasiliy Ulyanov Date: Wed, 2 Feb 2022 17:28:15 +0100 Subject: [PATCH] virpidfile: Add virPidFileReadPathIfLocked func The function will attempt to read a pid from @path, and store it in @pid. The @pid will only be set, however, if @path is locked by virFileLock() at byte 0 and the pid in @path is running. Signed-off-by: Vasiliy Ulyanov Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik (cherry picked from commit 013ab22f79d1345daf6b2778ca498acb16939011) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152188 Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 1 + src/util/virpidfile.c | 35 +++++++++++++++++++++++++++++++++++ src/util/virpidfile.h | 2 ++ 3 files changed, 38 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa734dfd33..568b0f34a1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3061,6 +3061,7 @@ virPidFileRead; virPidFileReadIfAlive; virPidFileReadPath; virPidFileReadPathIfAlive; +virPidFileReadPathIfLocked; virPidFileRelease; virPidFileReleasePath; virPidFileWrite; diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 7069f8343d..9d194f7336 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -302,6 +302,41 @@ int virPidFileReadIfAlive(const char *dir, return 0; } +/** + * virPidFileReadPathIfLocked: + * @path: path to pidfile + * @pid: variable to return pid in + * + * This will attempt to read a pid from @path, and store it in + * @pid. The @pid will only be set, however, if the pid in @path + * is running, and @path is locked by virFileLock() at byte 0 + * (which is exactly what virCommandSetPidFile() results in). + * This adds protection against returning a stale pid. + * + * Returns -1 upon error, or zero on successful + * reading of the pidfile. If @path is not locked + * or if the PID was not still alive, zero will + * be returned, but @pid will be set to -1. + */ +int virPidFileReadPathIfLocked(const char *path, pid_t *pid) +{ + VIR_AUTOCLOSE fd = -1; + + if ((fd = open(path, O_RDWR)) < 0) + return -1; + + if (virFileLock(fd, false, 0, 1, false) >= 0) { + /* The file isn't locked. PID is stale. */ + *pid = -1; + return 0; + } + + if (virPidFileReadPathIfAlive(path, pid, NULL) < 0) + return -1; + + return 0; +} + int virPidFileDeletePath(const char *pidfile) { diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h index fd8013c41e..e84542f298 100644 --- a/src/util/virpidfile.h +++ b/src/util/virpidfile.h @@ -48,6 +48,8 @@ int virPidFileReadIfAlive(const char *dir, const char *name, pid_t *pid, const char *binpath) G_GNUC_WARN_UNUSED_RESULT; +int virPidFileReadPathIfLocked(const char *path, + pid_t *pid) G_GNUC_WARN_UNUSED_RESULT; int virPidFileDeletePath(const char *path); int virPidFileDelete(const char *dir, -- 2.39.0