Libvirtd has set SIGPIPE to ignored, and virFork resets all signal
handlers to the defaults. But child process may write logs to
stderr/stdout, that may generate SIGPIPE if journald has stopped.
So in virExec(), set SIGPIPE to ignored before invoke
virCommandMassClose, and revert it back to SIG_DFL after that.
In virProcessRunInFork(), just set SIGPIPE to ignored.
Signed-off-by: Wang Yechao <wang.yechao255(a)zte.com.cn>
---
v1 patch:
https://www.redhat.com/archives/libvir-list/2019-October/msg00720.html
Changes in v2:
- use pthread_sigmask to block SIGPIPE
Changes in v3:
- pass SIG_UNBLOCK(not SIG_SETMASK) to pthread_sigmask when unlock SIGPIPE
Changes in v4:
- don't block SIGPIPE, ignore it when invoke VIR_FORCE_CLOSE and
virCommandMassClose
---
src/util/vircommand.c | 16 ++++++++++++++++
src/util/virprocess.c | 10 ++++++++++
2 files changed, 26 insertions(+)
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 763bcb6..bb6e73b 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -653,9 +653,25 @@ virExec(virCommandPtr cmd)
umask(cmd->mask);
ret = EXIT_CANCELED;
+ memset(&waxoff, 0, sizeof(waxoff));
+ waxoff.sa_handler = SIG_IGN;
+ sigemptyset(&waxoff.sa_mask);
+ memset(&waxon, 0, sizeof(waxon));
+ if (sigaction(SIGPIPE, &waxoff, &waxon) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Could not disable SIGPIPE"));
+ goto fork_error;
+ }
+
if (virCommandMassClose(cmd, childin, childout, childerr) < 0)
goto fork_error;
+ if (sigaction(SIGPIPE, &waxon, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Could not re-enable SIGPIPE"));
+ goto fork_error;
+ }
+
if (prepareStdFd(childin, STDIN_FILENO) < 0) {
virReportSystemError(errno,
"%s", _("failed to setup stdin file
handle"));
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index e8d4ba0..da66dcf 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -1151,6 +1151,16 @@ virProcessRunInFork(virProcessForkCallback cb,
goto cleanup;
if (child == 0) {
+ struct sigaction waxoff;
+
+ memset(&waxoff, 0, sizeof(waxoff));
+ waxoff.sa_handler = SIG_IGN;
+ sigemptyset(&waxoff.sa_mask);
+ if (sigaction(SIGPIPE, &waxoff, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Could not disable SIGPIPE"));
+ }
+
VIR_FORCE_CLOSE(errfd[0]);
ret = virProcessRunInForkHelper(errfd[1], parent, cb, opaque);
VIR_FORCE_CLOSE(errfd[1]);
--
1.8.3.1