From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <gentoo-commits+bounces-1189859-garchives=archives.gentoo.org@lists.gentoo.org> Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id E5AB4138359 for <garchives@archives.gentoo.org>; Wed, 22 Jul 2020 17:47:03 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 05FD9E093B; Wed, 22 Jul 2020 17:47:03 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id CB548E093B for <gentoo-commits@lists.gentoo.org>; Wed, 22 Jul 2020 17:47:02 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 35F8234EE1C for <gentoo-commits@lists.gentoo.org>; Wed, 22 Jul 2020 17:47:01 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 14DC22D3 for <gentoo-commits@lists.gentoo.org>; Wed, 22 Jul 2020 17:46:55 +0000 (UTC) From: "Zac Medico" <zmedico@gentoo.org> To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" <zmedico@gentoo.org> Message-ID: <1595436933.3561071e07ad47db91bf0f2c2c2b02e2061b217c.zmedico@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: lib/portage/dbapi/ X-VCS-Repository: proj/portage X-VCS-Files: lib/portage/dbapi/_MergeProcess.py X-VCS-Directories: lib/portage/dbapi/ X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico X-VCS-Revision: 3561071e07ad47db91bf0f2c2c2b02e2061b217c X-VCS-Branch: master Date: Wed, 22 Jul 2020 17:46:55 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 3b81d2b4-3cbf-4d0f-9de5-f7265be27d8a X-Archives-Hash: 65472a30aa6d478d60601059a4cb5f35 commit: 3561071e07ad47db91bf0f2c2c2b02e2061b217c Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sun Jul 19 06:31:37 2020 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Wed Jul 22 16:55:33 2020 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=3561071e MergeProcess: replace os.fork with multiprocessing.Process (bug 730192) Fix the MergeProcess _spawn method to call the superclass _spawn method, in order to replace os.fork with multiprocessing.Process, promoting a healthy state for the forked interpreter. Bug: https://bugs.gentoo.org/730192 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/portage/dbapi/_MergeProcess.py | 106 +++++++++++-------------------------- 1 file changed, 30 insertions(+), 76 deletions(-) diff --git a/lib/portage/dbapi/_MergeProcess.py b/lib/portage/dbapi/_MergeProcess.py index 274ef586f..6924c8b0e 100644 --- a/lib/portage/dbapi/_MergeProcess.py +++ b/lib/portage/dbapi/_MergeProcess.py @@ -3,9 +3,6 @@ import io import platform -import signal -import sys -import traceback import fcntl import portage @@ -24,7 +21,7 @@ class MergeProcess(ForkProcess): 'vartree', 'blockers', 'pkgloc', 'infloc', 'myebuild', 'mydbapi', 'postinst_failure', 'prev_mtimes', 'unmerge', '_elog_reader_fd', - '_buf', '_elog_keys', '_locked_vdb') + '_buf', '_counter', '_dblink', '_elog_keys', '_locked_vdb') def _start(self): # Portage should always call setcpv prior to this @@ -103,8 +100,8 @@ class MergeProcess(ForkProcess): def _spawn(self, args, fd_pipes, **kwargs): """ - Fork a subprocess, apply local settings, and call - dblink.merge(). TODO: Share code with ForkProcess. + Extend the superclass _spawn method to perform some pre-fork and + post-fork actions. """ elog_reader_fd, elog_writer_fd = os.pipe() @@ -132,57 +129,31 @@ class MergeProcess(ForkProcess): # FEATURES=parallel-install skips this lock in order to # improve performance, and the risk is practically negligible. self._lock_vdb() - counter = None if not self.unmerge: - counter = self.vartree.dbapi.counter_tick() - - parent_pid = os.getpid() - pid = None - try: - pid = os.fork() - - if pid != 0: - if not isinstance(pid, int): - raise AssertionError( - "fork returned non-integer: %s" % (repr(pid),)) - - os.close(elog_writer_fd) - self._elog_reader_fd = elog_reader_fd - self._buf = "" - self._elog_keys = set() - # Discard messages which will be collected by the subprocess, - # in order to avoid duplicates (bug #446136). - portage.elog.messages.collect_messages(key=mylink.mycpv) - - # invalidate relevant vardbapi caches - if self.vartree.dbapi._categories is not None: - self.vartree.dbapi._categories = None - self.vartree.dbapi._pkgs_changed = True - self.vartree.dbapi._clear_pkg_cache(mylink) - - return [pid] - - os.close(elog_reader_fd) - - # Use default signal handlers in order to avoid problems - # killing subprocesses as reported in bug #353239. - signal.signal(signal.SIGINT, signal.SIG_DFL) - signal.signal(signal.SIGTERM, signal.SIG_DFL) - - # Unregister SIGCHLD handler and wakeup_fd for the parent - # process's event loop (bug 655656). - signal.signal(signal.SIGCHLD, signal.SIG_DFL) - try: - wakeup_fd = signal.set_wakeup_fd(-1) - if wakeup_fd > 0: - os.close(wakeup_fd) - except (ValueError, OSError): - pass - - portage.locks._close_fds() - # We don't exec, so use close_fds=False - # (see _setup_pipes docstring). - portage.process._setup_pipes(fd_pipes, close_fds=False) + self._counter = self.vartree.dbapi.counter_tick() + + self._dblink = mylink + self._elog_reader_fd = elog_reader_fd + pids = super(MergeProcess, self)._spawn(args, fd_pipes, **kwargs) + os.close(elog_writer_fd) + self._buf = "" + self._elog_keys = set() + # Discard messages which will be collected by the subprocess, + # in order to avoid duplicates (bug #446136). + portage.elog.messages.collect_messages(key=mylink.mycpv) + + # invalidate relevant vardbapi caches + if self.vartree.dbapi._categories is not None: + self.vartree.dbapi._categories = None + self.vartree.dbapi._pkgs_changed = True + self.vartree.dbapi._clear_pkg_cache(mylink) + + return pids + + def _run(self): + os.close(self._elog_reader_fd) + counter = self._counter + mylink = self._dblink portage.output.havecolor = self.settings.get('NOCOLOR') \ not in ('yes', 'true') @@ -207,8 +178,7 @@ class MergeProcess(ForkProcess): self.settings.backup_changes("PORTAGE_BACKGROUND") rval = 1 - try: - if self.unmerge: + if self.unmerge: if not mylink.exists(): rval = os.EX_OK elif mylink.unmerge( @@ -219,27 +189,11 @@ class MergeProcess(ForkProcess): finally: mylink.unlockdb() rval = os.EX_OK - else: + else: rval = mylink.merge(self.pkgloc, self.infloc, myebuild=self.myebuild, mydbapi=self.mydbapi, prev_mtimes=self.prev_mtimes, counter=counter) - except SystemExit: - raise - except: - traceback.print_exc() - # os._exit() skips stderr flush! - sys.stderr.flush() - finally: - os._exit(rval) - - finally: - if pid == 0 or (pid is None and os.getpid() != parent_pid): - # Call os._exit() from a finally block in order - # to suppress any finally blocks from earlier - # in the call stack (see bug #345289). This - # finally block has to be setup before the fork - # in order to avoid a race condition. - os._exit(1) + return rval def _async_waitpid_cb(self, *args, **kwargs): """