util: virPidFileForceCleanupPath: add group argument

Add a version of virPidFileForceCleanupPath that takes
a 'group' bool argument and propagate it all the way
down to virProcessKillPainfullyDelay.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Ján Tomko 2021-06-23 11:34:57 +02:00
parent 4b39c2aa2e
commit ff7b8043b6
6 changed files with 32 additions and 9 deletions

View File

@ -3038,6 +3038,7 @@ virPidFileConstructPath;
virPidFileDelete; virPidFileDelete;
virPidFileDeletePath; virPidFileDeletePath;
virPidFileForceCleanupPath; virPidFileForceCleanupPath;
virPidFileForceCleanupPathFull;
virPidFileRead; virPidFileRead;
virPidFileReadIfAlive; virPidFileReadIfAlive;
virPidFileReadPath; virPidFileReadPath;

View File

@ -7700,7 +7700,8 @@ qemuProcessKill(virDomainObj *vm, unsigned int flags)
* to be safe against stalls by the kernel freeing up the resources */ * to be safe against stalls by the kernel freeing up the resources */
return virProcessKillPainfullyDelay(vm->pid, return virProcessKillPainfullyDelay(vm->pid,
!!(flags & VIR_QEMU_PROCESS_KILL_FORCE), !!(flags & VIR_QEMU_PROCESS_KILL_FORCE),
vm->def->nhostdevs * 2); vm->def->nhostdevs * 2,
false);
} }

View File

@ -514,7 +514,7 @@ virPidFileConstructPath(bool privileged,
* Returns 0 if the pidfile was successfully cleaned up, -1 otherwise. * Returns 0 if the pidfile was successfully cleaned up, -1 otherwise.
*/ */
int int
virPidFileForceCleanupPath(const char *path) virPidFileForceCleanupPathFull(const char *path, bool group)
{ {
pid_t pid = 0; pid_t pid = 0;
int fd = -1; int fd = -1;
@ -529,10 +529,15 @@ virPidFileForceCleanupPath(const char *path)
if (fd < 0) { if (fd < 0) {
virResetLastError(); virResetLastError();
if (pid > 1 && group)
pid = virProcessGroupGet(pid);
/* Only kill the process if the pid is valid one. 0 means /* Only kill the process if the pid is valid one. 0 means
* there is somebody else doing the same pidfile cleanup * there is somebody else doing the same pidfile cleanup
* machinery. */ * machinery. */
if (pid) if (group)
virProcessKillPainfullyDelay(pid, true, 0, true);
else if (pid)
virProcessKillPainfully(pid, true); virProcessKillPainfully(pid, true);
if (virPidFileDeletePath(path) < 0) if (virPidFileDeletePath(path) < 0)
@ -544,3 +549,9 @@ virPidFileForceCleanupPath(const char *path)
return 0; return 0;
} }
int
virPidFileForceCleanupPath(const char *path)
{
return virPidFileForceCleanupPathFull(path, false);
}

View File

@ -73,4 +73,6 @@ int virPidFileConstructPath(bool privileged,
const char *progname, const char *progname,
char **pidfile); char **pidfile);
int virPidFileForceCleanupPathFull(const char *path,
bool group) ATTRIBUTE_NONNULL(1);
int virPidFileForceCleanupPath(const char *path) ATTRIBUTE_NONNULL(1); int virPidFileForceCleanupPath(const char *path) ATTRIBUTE_NONNULL(1);

View File

@ -406,15 +406,15 @@ pid_t virProcessGroupGet(pid_t pid)
* wait longer than the default. * wait longer than the default.
*/ */
int int
virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay) virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay, bool group)
{ {
size_t i; size_t i;
/* This is in 1/5th seconds since polling is on a 0.2s interval */ /* This is in 1/5th seconds since polling is on a 0.2s interval */
unsigned int polldelay = (force ? 200 : 75) + (extradelay*5); unsigned int polldelay = (force ? 200 : 75) + (extradelay*5);
const char *signame = "TERM"; const char *signame = "TERM";
VIR_DEBUG("vpid=%lld force=%d extradelay=%u", VIR_DEBUG("vpid=%lld force=%d extradelay=%u group=%d",
(long long)pid, force, extradelay); (long long)pid, force, extradelay, group);
/* This loop sends SIGTERM, then waits a few iterations (10 seconds) /* This loop sends SIGTERM, then waits a few iterations (10 seconds)
* to see if it dies. If the process still hasn't exited, and * to see if it dies. If the process still hasn't exited, and
@ -429,6 +429,8 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay)
*/ */
for (i = 0; i < polldelay; i++) { for (i = 0; i < polldelay; i++) {
int signum; int signum;
int rc;
if (i == 0) { if (i == 0) {
signum = SIGTERM; /* kindly suggest it should exit */ signum = SIGTERM; /* kindly suggest it should exit */
} else if (i == 50 && force) { } else if (i == 50 && force) {
@ -447,7 +449,12 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay)
signum = 0; /* Just check for existence */ signum = 0; /* Just check for existence */
} }
if (virProcessKill(pid, signum) < 0) { if (group)
rc = virProcessGroupKill(pid, signum);
else
rc = virProcessKill(pid, signum);
if (rc < 0) {
if (errno != ESRCH) { if (errno != ESRCH) {
virReportSystemError(errno, virReportSystemError(errno,
_("Failed to terminate process %lld with SIG%s"), _("Failed to terminate process %lld with SIG%s"),
@ -470,7 +477,7 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay)
int virProcessKillPainfully(pid_t pid, bool force) int virProcessKillPainfully(pid_t pid, bool force)
{ {
return virProcessKillPainfullyDelay(pid, force, 0); return virProcessKillPainfullyDelay(pid, force, 0, false);
} }
#if WITH_SCHED_GETAFFINITY #if WITH_SCHED_GETAFFINITY

View File

@ -58,7 +58,8 @@ pid_t virProcessGroupGet(pid_t pid);
int virProcessKillPainfully(pid_t pid, bool force); int virProcessKillPainfully(pid_t pid, bool force);
int virProcessKillPainfullyDelay(pid_t pid, int virProcessKillPainfullyDelay(pid_t pid,
bool force, bool force,
unsigned int extradelay); unsigned int extradelay,
bool group);
int virProcessSetAffinity(pid_t pid, virBitmap *map, bool quiet); int virProcessSetAffinity(pid_t pid, virBitmap *map, bool quiet);