File pacemaker-libservices-no-zombie-left.patch of Package pacemaker.14737

commit 142169da59518ee17bbf885dfbf42525fd2c1d0b
Author: Jan Pokorný <jpokorny@redhat.com>
Date:   Tue Jan 31 20:06:21 2017 +0100

    Low: libservices (sync): ensure no zombie is left behind
    
    It could happen because this parent that is to wait for its
    not-well-behaved child is knowlingly not blocking any signal (beside
    SIGCHLD explicitly in case of using signalfd facility) and delivery of
    such signal can interrupt waitpid, at least on paper, so protect
    against this accordingly.
    
    Speaking of SIGCHLD in plain self-pipe (not signalfd one) context, while
    there's no clash with other synchronous actions, it may be the case with
    asynchronous ones (or for that matter, arbitrary other fork-related
    activities in the main program a library can have no idea about), and
    this is exactly what could interrupt waitpid for real.

diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c
index cd7fd3f21..ffb74ef42 100644
--- a/lib/services/services_linux.c
+++ b/lib/services/services_linux.c
@@ -517,7 +517,7 @@ action_synced_wait(svc_action_t * op, sigset_t *mask)
                 if (1) {
                     /* Clear out the sigchld pipe. */
                     char ch;
-                    while (read(sfd, &ch, 1) == 1);
+                    while (read(sfd, &ch, 1) == 1) /*omit*/;
 #endif
                     wait_rc = waitpid(op->pid, &status, WNOHANG);
 
@@ -567,7 +567,7 @@ action_synced_wait(svc_action_t * op, sigset_t *mask)
          *
          * This makes it safe to skip WNOHANG here
          */
-        waitpid(op->pid, &status, 0);
+        while (waitpid(op->pid, &status, 0) == (pid_t) -1 && errno == EINTR) /*omit*/;
 
     } else if (WIFEXITED(status)) {
         op->status = PCMK_LRM_OP_DONE;
openSUSE Build Service is sponsored by