From 00b66ec21bf0a4c148e31e90231695c220aa0a8a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 14 Aug 2010 20:11:57 -0700 Subject: Disable EbuildIpcDaemon for now, since it seems to be triggering intermittent build failures in my stage builds. For testing purposes set PORTAGE_IPC_DAEMON_ENABLE=1 to enable EbuildIpcDaemon. --- bin/ebuild.sh | 4 +- bin/isolated-functions.sh | 3 +- bin/misc-functions.sh | 1 + pym/_emerge/AbstractEbuildProcess.py | 101 ++++++++++++++++++----- pym/portage/package/ebuild/config.py | 2 +- pym/portage/package/ebuild/prepare_build_dirs.py | 19 ----- 6 files changed, 88 insertions(+), 42 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 18f96b655..c8161773b 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -748,7 +748,8 @@ dyn_clean() { rm -f "$PORTAGE_BUILDDIR"/.{ebuild_changed,logid,unpacked,prepared} \ "$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged} \ "$PORTAGE_BUILDDIR"/.die_hooks \ - "$PORTAGE_BUILDDIR"/.ipc_{in,out,lock} + "$PORTAGE_BUILDDIR"/.ipc_{in,out,lock} \ + "$PORTAGE_BUILDDIR"/.exit_status rm -rf "${PORTAGE_BUILDDIR}/build-info" rm -rf "${WORKDIR}" @@ -2227,6 +2228,7 @@ elif [[ -n $EBUILD_SH_ARGS ]] ; then chown portage:portage "$T/environment" &>/dev/null chmod g+w "$T/environment" &>/dev/null fi + [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE" [[ -n $PORTAGE_IPC_DAEMON ]] && "$PORTAGE_BIN_PATH"/ebuild-ipc exit 0 exit 0 ) diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index d484be1b6..53312dba8 100644 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -192,6 +192,7 @@ die() { fi eerror "S: '${S}'" + [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE" [[ -n $PORTAGE_IPC_DAEMON ]] && "$PORTAGE_BIN_PATH"/ebuild-ipc exit 1 # subshell die support @@ -570,7 +571,7 @@ save_ebuild_env() { PORTAGE_BASHRC PM_EBUILD_HOOK_DIR PORTAGE_BASHRCS_SOURCED \ PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE PORTAGE_BUILDDIR \ PORTAGE_COLORMAP PORTAGE_CONFIGROOT PORTAGE_DEBUG \ - PORTAGE_DEPCACHEDIR PORTAGE_GID \ + PORTAGE_DEPCACHEDIR PORTAGE_EBUILD_EXIT_FILE PORTAGE_GID \ PORTAGE_GRPNAME PORTAGE_INST_GID \ PORTAGE_INST_UID PORTAGE_IPC_DAEMON \ PORTAGE_LOG_FILE PORTAGE_MASTER_PID \ diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index 0108b001f..3a199bdf7 100755 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -872,6 +872,7 @@ if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then ${x} done unset x + [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE" [[ -n $PORTAGE_IPC_DAEMON ]] && "$PORTAGE_BIN_PATH"/ebuild-ipc exit 0 fi diff --git a/pym/_emerge/AbstractEbuildProcess.py b/pym/_emerge/AbstractEbuildProcess.py index de120e8ad..444feb7f4 100644 --- a/pym/_emerge/AbstractEbuildProcess.py +++ b/pym/_emerge/AbstractEbuildProcess.py @@ -2,9 +2,11 @@ # Distributed under the terms of the GNU General Public License v2 import codecs +import stat import textwrap from _emerge.SpawnProcess import SpawnProcess from _emerge.EbuildIpcDaemon import EbuildIpcDaemon +import portage from portage.elog.messages import eerror from portage.localization import _ from portage.package.ebuild._ipc.ExitCommand import ExitCommand @@ -15,7 +17,7 @@ from portage import _encodings from portage import _unicode_decode from portage import _unicode_encode from portage.util._pty import _create_pty_or_pipe -from portage.util import writemsg_stdout +from portage.util import apply_secpass_permissions, writemsg_stdout class AbstractEbuildProcess(SpawnProcess): @@ -38,30 +40,84 @@ class AbstractEbuildProcess(SpawnProcess): # since we're not displaying to a terminal anyway. self.settings['NOCOLOR'] = 'true' - if self.phase not in self._phases_without_builddir: - self.settings['PORTAGE_IPC_DAEMON'] = "1" - self._exit_command = ExitCommand() - self._exit_command.reply_hook = self._exit_command_callback - input_fifo = os.path.join( - self.settings['PORTAGE_BUILDDIR'], '.ipc_in') - output_fifo = os.path.join( - self.settings['PORTAGE_BUILDDIR'], '.ipc_out') - query_command = QueryCommand(self.settings) - commands = { - 'best_version' : query_command, - 'exit' : self._exit_command, - 'has_version' : query_command, - } - self._ipc_daemon = EbuildIpcDaemon(commands=commands, - input_fifo=input_fifo, - output_fifo=output_fifo, - scheduler=self.scheduler) - self._ipc_daemon.start() + enable_ipc_daemon = \ + self.settings.get('PORTAGE_IPC_DAEMON_ENABLE') == '1' + + if enable_ipc_daemon: + self.settings.pop('PORTAGE_EBUILD_EXIT_FILE', None) + if self.phase not in self._phases_without_builddir: + self.settings['PORTAGE_IPC_DAEMON'] = "1" + self._start_ipc_daemon() + else: + self.settings.pop('PORTAGE_IPC_DAEMON', None) else: + # Since the IPC daemon is disabled, use a simple tempfile based + # approach to detect unexpected exit like in bug #190128. self.settings.pop('PORTAGE_IPC_DAEMON', None) + if self.phase not in self._phases_without_builddir: + exit_file = os.path.join( + self.settings['PORTAGE_BUILDDIR'], + '.exit_status') + self.settings['PORTAGE_EBUILD_EXIT_FILE'] = exit_file + try: + os.unlink(exit_file) + except OSError: + if os.path.exists(exit_file): + # make sure it doesn't exist + raise + else: + self.settings.pop('PORTAGE_EBUILD_EXIT_FILE', None) SpawnProcess._start(self) + def _init_ipc_fifos(self): + + input_fifo = os.path.join( + self.settings['PORTAGE_BUILDDIR'], '.ipc_in') + output_fifo = os.path.join( + self.settings['PORTAGE_BUILDDIR'], '.ipc_out') + + for x in (input_fifo, output_fifo): + + p = os.path.join(self.settings['PORTAGE_BUILDDIR'], x) + + st = None + try: + st = os.lstat(p) + except OSError: + os.mkfifo(p) + else: + if not stat.S_ISFIFO(st.st_mode): + st = None + try: + os.unlink(p) + except OSError: + pass + os.mkfifo(p) + + apply_secpass_permissions(p, + uid=os.getuid(), + gid=portage.data.portage_gid, + mode=0o770, stat_cached=st) + + return (input_fifo, output_fifo) + + def _start_ipc_daemon(self): + self._exit_command = ExitCommand() + self._exit_command.reply_hook = self._exit_command_callback + query_command = QueryCommand(self.settings) + commands = { + 'best_version' : query_command, + 'exit' : self._exit_command, + 'has_version' : query_command, + } + input_fifo, output_fifo = self._init_ipc_fifos() + self._ipc_daemon = EbuildIpcDaemon(commands=commands, + input_fifo=input_fifo, + output_fifo=output_fifo, + scheduler=self.scheduler) + self._ipc_daemon.start() + def _exit_command_callback(self): if self._registered: # Let the process exit naturally, if possible. This @@ -154,3 +210,8 @@ class AbstractEbuildProcess(SpawnProcess): else: self.returncode = 1 self._unexpected_exit() + else: + exit_file = self.settings.get('PORTAGE_EBUILD_EXIT_FILE') + if exit_file and not os.path.exists(exit_file): + self.returncode = 1 + self._unexpected_exit() diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 20b3186ec..9089ffb45 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -181,7 +181,7 @@ class config(object): "PORTAGE_BIN_PATH", "PORTAGE_BUILDDIR", "PORTAGE_COLORMAP", "PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR", - "PORTAGE_GID", "PORTAGE_GRPNAME", + "PORTAGE_EBUILD_EXIT_FILE", "PORTAGE_GID", "PORTAGE_GRPNAME", "PORTAGE_INST_GID", "PORTAGE_INST_UID", "PORTAGE_IPC_DAEMON", "PORTAGE_IUSE", "PORTAGE_LOG_FILE", "PORTAGE_MASTER_PID", diff --git a/pym/portage/package/ebuild/prepare_build_dirs.py b/pym/portage/package/ebuild/prepare_build_dirs.py index 5e591047f..dc29eeeb8 100644 --- a/pym/portage/package/ebuild/prepare_build_dirs.py +++ b/pym/portage/package/ebuild/prepare_build_dirs.py @@ -85,25 +85,6 @@ def prepare_build_dirs(myroot, mysettings, cleanup): writemsg(_("File Not Found: '%s'\n") % str(e), noiselevel=-1) return 1 - for x in ('.ipc_in', '.ipc_out'): - p = os.path.join(mysettings['PORTAGE_BUILDDIR'], x) - st = None - try: - st = os.lstat(p) - except OSError: - os.mkfifo(p) - else: - if not stat.S_ISFIFO(st.st_mode): - st = None - try: - os.unlink(p) - except OSError: - pass - os.mkfifo(p) - apply_secpass_permissions(p, - uid=portage_uid, gid=portage_gid, - mode=0o770, stat_cached=st) - # Reset state for things like noauto and keepwork in FEATURES. for x in ('.die_hooks',): try: -- cgit v1.2.3-1-g7c22