[PATCH v3 1/3] virpidfile: Add virPidFileReadPathIfLocked func

Vasiliy Ulyanov vulyanov at suse.de
Wed Feb 2 16:28:15 UTC 2022


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 <vulyanov at suse.de>
---
 src/libvirt_private.syms |  1 +
 src/util/virpidfile.c    | 34 ++++++++++++++++++++++++++++++++++
 src/util/virpidfile.h    |  2 ++
 3 files changed, 37 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9bc3d9530b..447ba9d82b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3070,6 +3070,7 @@ virPidFileRead;
 virPidFileReadIfAlive;
 virPidFileReadPath;
 virPidFileReadPathIfAlive;
+virPidFileReadPathIfLocked;
 virPidFileRelease;
 virPidFileReleasePath;
 virPidFileWrite;
diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c
index 7069f8343d..b8bb455e5e 100644
--- a/src/util/virpidfile.c
+++ b/src/util/virpidfile.c
@@ -302,6 +302,40 @@ 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. 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.34.1





More information about the libvir-list mailing list