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 <vulyanov@suse.de>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Vasiliy Ulyanov 2022-02-02 17:28:15 +01:00 committed by Michal Privoznik
parent 5c0125b4f8
commit 013ab22f79
3 changed files with 38 additions and 0 deletions

View File

@ -3077,6 +3077,7 @@ virPidFileRead;
virPidFileReadIfAlive;
virPidFileReadPath;
virPidFileReadPathIfAlive;
virPidFileReadPathIfLocked;
virPidFileRelease;
virPidFileReleasePath;
virPidFileWrite;

View 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)
{

View 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,