]> xenbits.xensource.com Git - libvirt.git/commitdiff
virpidfile: Add virPidFileReadPathIfLocked func
authorVasiliy Ulyanov <vulyanov@suse.de>
Wed, 2 Feb 2022 16:28:15 +0000 (17:28 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 4 Feb 2022 09:27:30 +0000 (10:27 +0100)
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@suse.de>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/libvirt_private.syms
src/util/virpidfile.c
src/util/virpidfile.h

index 41322ab12d05e485397cb82789f7e30132a34d4f..398cc79ee311864c5420daee12446cfedcadb89e 100644 (file)
@@ -3077,6 +3077,7 @@ virPidFileRead;
 virPidFileReadIfAlive;
 virPidFileReadPath;
 virPidFileReadPathIfAlive;
+virPidFileReadPathIfLocked;
 virPidFileRelease;
 virPidFileReleasePath;
 virPidFileWrite;
index 7069f8343dc785291f795bb18e0420c4b306d567..9d194f7336c15f6c732c9fd3d49ccfff8a391ded 100644 (file)
@@ -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)
 {
index fd8013c41e05b0b23768483527db5232e9f80d19..e84542f298e875b548bc80570cac9c448e1f703f 100644 (file)
@@ -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,