summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-09-03 14:17:12 -0700
committerZac Medico <zmedico@gentoo.org>2010-09-03 14:17:12 -0700
commit12d2ff4f018c826c750896e8085cd53a589a8521 (patch)
treea065800cd53b724709a1698cf84fe2c892ce8c53
parentd0204abde7fef329e45f0db78b3e7cff8fca0465 (diff)
downloadportage-12d2ff4f018c826c750896e8085cd53a589a8521.tar.gz
portage-12d2ff4f018c826c750896e8085cd53a589a8521.tar.bz2
portage-12d2ff4f018c826c750896e8085cd53a589a8521.zip
Bug #335777 - Add a 40 second timeout in ebuild-ipc.py, so that if an
orphan is left for any reason then it will exit with an error message instead of hanging indefinitely.
-rwxr-xr-xbin/ebuild-ipc.py21
-rw-r--r--pym/portage/exception.py14
2 files changed, 34 insertions, 1 deletions
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py
index 52fb08226..b4a1f7767 100755
--- a/bin/ebuild-ipc.py
+++ b/bin/ebuild-ipc.py
@@ -5,11 +5,13 @@
# This is a helper which ebuild processes can use
# to communicate with portage's main python process.
+import logging
import os
import pickle
import select
import signal
import sys
+import time
def debug_signal(signum, frame):
import pdb
@@ -30,6 +32,8 @@ import portage
class EbuildIpc(object):
+ _COMMUNICATE_TIMEOUT_SECONDS = 40
+
def __init__(self):
self.fifo_dir = os.environ['PORTAGE_BUILDDIR']
self.ipc_in_fifo = os.path.join(self.fifo_dir, '.ipc_in')
@@ -37,13 +41,28 @@ class EbuildIpc(object):
self.ipc_lock_file = os.path.join(self.fifo_dir, '.ipc_lock')
def communicate(self, args):
+
# Make locks quiet since unintended locking messages displayed on
# stdout could corrupt the intended output of this program.
portage.locks._quiet = True
lock_obj = portage.locks.lockfile(self.ipc_lock_file, unlinkfile=True)
+ start_time = time.time()
+
try:
- return self._communicate(args)
+ signal.signal(signal.SIGALRM, portage.exception.AlarmSignal.signal_handler)
+ signal.alarm(self._COMMUNICATE_TIMEOUT_SECONDS)
+ returncode = self._communicate(args)
+ signal.alarm(0)
+ return returncode
+ except portage.exception.AlarmSignal:
+ time_elapsed = time.time() - start_time
+ portage.util.writemsg_level(
+ ('ebuild-ipc timed out after %d seconds\n') % \
+ (time_elapsed,),
+ level=logging.ERROR, noiselevel=-1)
+ return 1
finally:
+ signal.alarm(0)
portage.locks.unlockfile(lock_obj)
def _communicate(self, args):
diff --git a/pym/portage/exception.py b/pym/portage/exception.py
index 9564af98a..b0f9ad8eb 100644
--- a/pym/portage/exception.py
+++ b/pym/portage/exception.py
@@ -80,6 +80,20 @@ class TryAgain(PortageException):
from errno import EAGAIN as errno
"""Try again"""
+class TimeoutException(PortageException):
+ from errno import ETIME as errno
+
+class AlarmSignal(TimeoutException):
+ def __init__(self, value, signum=None, frame=None):
+ TimeoutException.__init__(self, value)
+ self.signum = signum
+ self.frame = frame
+
+ @classmethod
+ def signal_handler(cls, signum, frame):
+ raise AlarmSignal("alarm signal",
+ signum=signum, frame=frame)
+
class ReadOnlyFileSystem(PortageException):
"""Read-only file system"""