Change in vdsm[master]: supervdsm: don't let _runAs return early due to EINTR

gpadgett at redhat.com gpadgett at redhat.com
Fri Sep 4 13:30:05 UTC 2015


Greg Padgett has uploaded a new change for review.

Change subject: supervdsm: don't let _runAs return early due to EINTR
......................................................................

supervdsm: don't let _runAs return early due to EINTR

When _runAs executes a command, it polls a pipe to determine status of
that command.  The poll has a timeout, also allowing the child to be
killed if execution takes too long.  If a stray signal is received by
the parent process, it may cause the poll to return early, prematurely
ending child command execution ending in unintentional failure.

This is particularly prevalant when subsequent _runAs executions are
performed.  Termination of the first will result in a SIGCHLD which
interrupts polling for the second, as exposed by commit 777c36d6.

Because poll will return early without an exception if the low-level
call is interrupted, NoIntrCall() cannot be used and thus a new helper
function is provided that retries based on the time elapsed since the
call started.

PEP-475 will handle this in Python 3.5, but in the meantime this
workaround is needed.

Change-Id: I25af73a8fe67e7bc434f60a7d8492e33dc3b2ffa
Bug-Url: https://bugzilla.redhat.com/1259310
Signed-off-by: Greg Padgett <gpadgett at redhat.com>
---
M lib/vdsm/utils.py
M vdsm/supervdsmServer
2 files changed, 19 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/52/45752/1

diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index d847a23..4ba6452 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -348,6 +348,24 @@
         break
 
 
+def NoIntrMPConnPoll(mpConnection, timeout):
+    """
+    This is a workaround until we get the PEP-475 fix for EINTR.  It
+    ensures that a multiprocessing.connection.poll() will not return
+    before the timeout due to an interruption.
+    """
+    end = monotonic_time() + timeout
+    remaining = timeout
+
+    while not mpConnection.poll(remaining):
+        remaining = end - monotonic_time()
+        if remaining > 0:
+            continue
+        return False
+
+    return True
+
+
 class CommandStream(object):
     def __init__(self, command, stdoutcb, stderrcb):
         self._command = command
diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer
index 3d64843..276a694 100755
--- a/vdsm/supervdsmServer
+++ b/vdsm/supervdsmServer
@@ -245,7 +245,7 @@
 
         needReaping = True
         try:
-            if not pipe.poll(RUN_AS_TIMEOUT):
+            if not utils.NoIntrMPConnPoll(pipe, RUN_AS_TIMEOUT):
                 try:
 
                     os.kill(proc.pid, signal.SIGKILL)


-- 
To view, visit https://gerrit.ovirt.org/45752
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I25af73a8fe67e7bc434f60a7d8492e33dc3b2ffa
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Greg Padgett <gpadgett at redhat.com>


More information about the vdsm-patches mailing list