From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> In some cases the caller of virPidFileRead might like extra checks to determine whether the pid just read is really the one they are expecting. This adds virPidFileReadIfValid which will check whether the pid is still alive with kill(0, -1), and (on linux only) will look at /proc/$PID/path * libvirt_private.syms, util/virpidfile.c, util/virpidfile.h: Add virPidFileReadIfValid and virPidFileReadPathIfValid * network/bridge_driver.c: Use new APIs to check PID validity --- src/libvirt_private.syms | 2 + src/network/bridge_driver.c | 35 ++++--------------------- src/util/virpidfile.c | 58 +++++++++++++++++++++++++++++++++++++++++++ src/util/virpidfile.h | 8 ++++++ 4 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7a96c1e..fee3520 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1122,7 +1122,9 @@ virFileFdopen; # virpidfile.h virPidFileBuildPath; virPidFileRead; +virPidFileReadIfAlive; virPidFileReadPath; +virPidFileReadPathIfAlive; virPidFileWrite; virPidFileWritePath; virPidFileDelete; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 8b27320..cea8771 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -217,40 +217,17 @@ networkFindActiveConfigs(struct network_driver *driver) { /* Try and read dnsmasq/radvd pids if any */ if (obj->def->ips && (obj->def->nips > 0)) { - char *pidpath, *radvdpidbase; - - if (virPidFileRead(NETWORK_PID_DIR, obj->def->name, - &obj->dnsmasqPid) == 0) { - /* Check that it's still alive */ - if (kill(obj->dnsmasqPid, 0) != 0) - obj->dnsmasqPid = -1; - if (virAsprintf(&pidpath, "/proc/%d/exe", obj->dnsmasqPid) < 0) { - virReportOOMError(); - goto cleanup; - } - if (virFileLinkPointsTo(pidpath, DNSMASQ) == 0) - obj->dnsmasqPid = -1; - VIR_FREE(pidpath); - } + char *radvdpidbase; + + ignore_value(virPidFileReadIfAlive(NETWORK_PID_DIR, obj->def->name, + &obj->dnsmasqPid, DNSMASQ)); if (!(radvdpidbase = networkRadvdPidfileBasename(obj->def->name))) { virReportOOMError(); goto cleanup; } - if (virPidFileRead(NETWORK_PID_DIR, radvdpidbase, - &obj->radvdPid) == 0) { - /* Check that it's still alive */ - if (kill(obj->radvdPid, 0) != 0) - obj->radvdPid = -1; - if (virAsprintf(&pidpath, "/proc/%d/exe", obj->radvdPid) < 0) { - virReportOOMError(); - VIR_FREE(radvdpidbase); - goto cleanup; - } - if (virFileLinkPointsTo(pidpath, RADVD) == 0) - obj->radvdPid = -1; - VIR_FREE(pidpath); - } + ignore_value(virPidFileReadIfAlive(NETWORK_PID_DIR, radvdpidbase, + &obj->radvdPid, RADVD)); VIR_FREE(radvdpidbase); } } diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 25c3272..dc92868 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -24,6 +24,7 @@ #include <config.h> #include <fcntl.h> +#include <signal.h> #include "virpidfile.h" #include "virfile.h" @@ -164,6 +165,63 @@ int virPidFileRead(const char *dir, } +int virPidFileReadPathIfAlive(const char *path, + pid_t *pid, + const char *binpath) +{ + int rc; + char *procpath = NULL; + + rc = virPidFileReadPath(path, pid); + if (rc < 0) + return rc; + + /* Check that it's still alive */ + if (kill(*pid, 0) < 0) { + *pid = -1; + return 0; + } + + if (virAsprintf(&procpath, "/proc/%d/exe", *pid) < 0) { + *pid = -1; + return 0; + } +#ifdef __linux__ + if (virFileLinkPointsTo(procpath, binpath) == 0) + *pid = -1; +#endif + VIR_FREE(procpath); + + return 0; +} + + +int virPidFileReadIfAlive(const char *dir, + const char *name, + pid_t *pid, + const char *binpath) +{ + int rc = 0; + char *pidfile = NULL; + + if (name == NULL || dir == NULL) { + rc = -EINVAL; + goto cleanup; + } + + if (!(pidfile = virPidFileBuildPath(dir, name))) { + rc = -ENOMEM; + goto cleanup; + } + + rc = virPidFileReadPathIfAlive(pidfile, pid, binpath); + +cleanup: + VIR_FREE(pidfile); + return rc; +} + + int virPidFileDeletePath(const char *pidfile) { int rc = 0; diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h index e28a3c1..6659f1c 100644 --- a/src/util/virpidfile.h +++ b/src/util/virpidfile.h @@ -42,6 +42,14 @@ int virPidFileRead(const char *dir, const char *name, pid_t *pid) ATTRIBUTE_RETURN_CHECK; +int virPidFileReadPathIfAlive(const char *path, + pid_t *pid, + const char *binpath) ATTRIBUTE_RETURN_CHECK; +int virPidFileReadIfAlive(const char *dir, + const char *name, + pid_t *pid, + const char *binpath) ATTRIBUTE_RETURN_CHECK; + int virPidFileDeletePath(const char *path); int virPidFileDelete(const char *dir, const char *name); -- 1.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list