mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15: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
|
/* 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) {
|
if (!(cmd->flags & VIR_EXEC_DAEMON)) {
|
||||||
cmd->outfdptr = &cmd->outfd;
|
if (!cmd->outfdptr) {
|
||||||
cmd->outbuf = &outbuf;
|
cmd->outfdptr = &cmd->outfd;
|
||||||
string_io = true;
|
cmd->outbuf = &outbuf;
|
||||||
}
|
string_io = true;
|
||||||
if (!cmd->errfdptr) {
|
}
|
||||||
cmd->errfdptr = &cmd->errfd;
|
if (!cmd->errfdptr) {
|
||||||
cmd->errbuf = &errbuf;
|
cmd->errfdptr = &cmd->errfd;
|
||||||
string_io = true;
|
cmd->errbuf = &errbuf;
|
||||||
|
string_io = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virCommandRunAsync(cmd, NULL) < 0) {
|
if (virCommandRunAsync(cmd, NULL) < 0) {
|
||||||
|
@ -668,6 +668,47 @@ cleanup:
|
|||||||
return ret;
|
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
|
static int
|
||||||
mymain(int argc, char **argv)
|
mymain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -732,6 +773,7 @@ mymain(int argc, char **argv)
|
|||||||
DO_TEST(test15);
|
DO_TEST(test15);
|
||||||
DO_TEST(test16);
|
DO_TEST(test16);
|
||||||
DO_TEST(test17);
|
DO_TEST(test17);
|
||||||
|
DO_TEST(test18);
|
||||||
|
|
||||||
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user