mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 12:05:17 +00:00
command: avoid hanging on daemon processes
* src/util/command.c (virCommandRun): Don't capture output on daemons. * tests/commandtest.c (test18): Expose the bug. Reported by Laine Stump.
This commit is contained in:
parent
973ada0e0b
commit
c7f28dec60
@ -1008,17 +1008,21 @@ virCommandRun(virCommandPtr cmd, int *exitstatus)
|
||||
}
|
||||
|
||||
/* If caller hasn't requested capture of stdout/err, then capture
|
||||
* it ourselves so we can log it.
|
||||
* it ourselves so we can log it. But the intermediate child for
|
||||
* a daemon has no expected output, and we don't want our
|
||||
* capturing pipes passed on to the daemon grandchild.
|
||||
*/
|
||||
if (!cmd->outfdptr) {
|
||||
cmd->outfdptr = &cmd->outfd;
|
||||
cmd->outbuf = &outbuf;
|
||||
string_io = true;
|
||||
}
|
||||
if (!cmd->errfdptr) {
|
||||
cmd->errfdptr = &cmd->errfd;
|
||||
cmd->errbuf = &errbuf;
|
||||
string_io = true;
|
||||
if (!(cmd->flags & VIR_EXEC_DAEMON)) {
|
||||
if (!cmd->outfdptr) {
|
||||
cmd->outfdptr = &cmd->outfd;
|
||||
cmd->outbuf = &outbuf;
|
||||
string_io = true;
|
||||
}
|
||||
if (!cmd->errfdptr) {
|
||||
cmd->errfdptr = &cmd->errfd;
|
||||
cmd->errbuf = &errbuf;
|
||||
string_io = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (virCommandRunAsync(cmd, NULL) < 0) {
|
||||
|
@ -668,6 +668,47 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run long-running daemon, to ensure no hang.
|
||||
*/
|
||||
static int test18(const void *unused ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virCommandPtr cmd = virCommandNewArgList("sleep", "100", NULL);
|
||||
char *pidfile = virFilePid(abs_builddir, "commandhelper");
|
||||
pid_t pid;
|
||||
int ret = -1;
|
||||
|
||||
if (!pidfile)
|
||||
goto cleanup;
|
||||
|
||||
virCommandSetPidFile(cmd, pidfile);
|
||||
virCommandDaemonize(cmd);
|
||||
|
||||
alarm(5);
|
||||
if (virCommandRun(cmd, NULL) < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
printf("Cannot run child %s\n", err->message);
|
||||
goto cleanup;
|
||||
}
|
||||
alarm(0);
|
||||
|
||||
if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
|
||||
printf("cannot read pidfile\n");
|
||||
goto cleanup;
|
||||
}
|
||||
while (kill(pid, SIGINT) != -1)
|
||||
usleep(100*1000);
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virCommandFree(cmd);
|
||||
unlink(pidfile);
|
||||
VIR_FREE(pidfile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mymain(int argc, char **argv)
|
||||
{
|
||||
@ -732,6 +773,7 @@ mymain(int argc, char **argv)
|
||||
DO_TEST(test15);
|
||||
DO_TEST(test16);
|
||||
DO_TEST(test17);
|
||||
DO_TEST(test18);
|
||||
|
||||
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user