From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id A547B1384B4 for ; Sun, 22 Nov 2015 00:00:53 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B30E821C00B; Sun, 22 Nov 2015 00:00:50 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1E28221C007 for ; Sun, 22 Nov 2015 00:00:49 +0000 (UTC) Received: from localhost.localdomain (ip174-67-193-3.oc.oc.cox.net [174.67.193.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: zmedico) by smtp.gentoo.org (Postfix) with ESMTPSA id 934FF340861; Sun, 22 Nov 2015 00:00:47 +0000 (UTC) From: Zac Medico To: gentoo-portage-dev@lists.gentoo.org Cc: Zac Medico Subject: [gentoo-portage-dev] [PATCH v2] SpawnProcess: re-check cgroup.procs until empty (bug 566420) Date: Sat, 21 Nov 2015 16:00:31 -0800 Message-Id: <1448150431-22661-1-git-send-email-zmedico@gentoo.org> X-Mailer: git-send-email 2.4.9 In-Reply-To: <1448134928-17323-1-git-send-email-zmedico@gentoo.org> References: <1448134928-17323-1-git-send-email-zmedico@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-portage-dev@lists.gentoo.org Reply-to: gentoo-portage-dev@lists.gentoo.org X-Archives-Salt: 7cfd918d-ee95-4060-8c7f-635651dbfaf2 X-Archives-Hash: 82f532742e0fcce12daa7b4a33d1123b For subshell die support (bug 465008), re-check cgroup.procs until it's empty, in case any of the listed processes fork before we've had a chance to kill them. X-Gentoo-Bug: 566420 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=566420 --- [PATCH v2] limits the cleanup loop to 8 iterations, and logs an eerror message if there are any lingering pids. pym/_emerge/SpawnProcess.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/pym/_emerge/SpawnProcess.py b/pym/_emerge/SpawnProcess.py index 5ab2e67..4ab646d 100644 --- a/pym/_emerge/SpawnProcess.py +++ b/pym/_emerge/SpawnProcess.py @@ -16,6 +16,8 @@ from _emerge.SubProcess import SubProcess import portage from portage import os from portage.const import BASH_BINARY +from portage.localization import _ +from portage.output import EOutput from portage.util import writemsg_level from portage.util._async.PipeLogger import PipeLogger @@ -35,6 +37,10 @@ class SpawnProcess(SubProcess): __slots__ = ("args",) + \ _spawn_kwarg_names + ("_pipe_logger", "_selinux_type",) + # Max number of attempts to kill the processes listed in cgroup.procs, + # given that processes may fork before they can be killed. + _CGROUP_CLEANUP_RETRY_MAX = 8 + def _start(self): if self.fd_pipes is None: @@ -203,10 +209,24 @@ class SpawnProcess(SubProcess): elif e.errno != errno.ESRCH: raise - # step 1: kill all orphans - pids = get_pids(self.cgroup) + # step 1: kill all orphans (loop in case of new forks) + remaining = self._CGROUP_CLEANUP_RETRY_MAX + while remaining: + remaining -= 1 + pids = get_pids(self.cgroup) + if pids: + kill_all(pids, signal.SIGKILL) + else: + break + if pids: - kill_all(pids, signal.SIGKILL) + msg = [] + msg.append( + _("Failed to kill pid(s) in '%(cgroup)s': %(pids)s") % dict( + cgroup=os.path.join(self.cgroup, 'cgroup.procs'), + pids=' '.join(str(pid) for pid in pids))) + + self._elog('eerror', msg) # step 2: remove the cgroup try: @@ -215,3 +235,8 @@ class SpawnProcess(SubProcess): # it may be removed already, or busy # we can't do anything good about it pass + + def _elog(self, elog_funcname, lines): + elog_func = getattr(EOutput(), elog_funcname) + for line in lines: + elog_func(line) -- 2.4.9