[libvirt] [PATCH v4] util: Ignore SIGPIPE before write logs to stderr in child process

Wang Yechao posted 1 patch 4 years, 5 months ago
Test syntax-check passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/1571212038-4291-1-git-send-email-wang.yechao255@zte.com.cn
src/util/vircommand.c | 16 ++++++++++++++++
src/util/virprocess.c | 10 ++++++++++
2 files changed, 26 insertions(+)
[libvirt] [PATCH v4] util: Ignore SIGPIPE before write logs to stderr in child process
Posted by Wang Yechao 4 years, 5 months ago
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@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list