Disable EbuildIpcDaemon for now, since it seems to be triggering
authorZac Medico <zmedico@gentoo.org>
Sun, 15 Aug 2010 03:11:57 +0000 (20:11 -0700)
committerZac Medico <zmedico@gentoo.org>
Sun, 15 Aug 2010 03:11:57 +0000 (20:11 -0700)
intermittent build failures in my stage builds. For testing purposes
set PORTAGE_IPC_DAEMON_ENABLE=1 to enable EbuildIpcDaemon.

bin/ebuild.sh
bin/isolated-functions.sh
bin/misc-functions.sh
pym/_emerge/AbstractEbuildProcess.py
pym/portage/package/ebuild/config.py
pym/portage/package/ebuild/prepare_build_dirs.py

index 18f96b6555cd4309a9c9258359fe7235739091ae..c8161773b4c256f863cbfaea8996b83af150f2fc 100755 (executable)
@@ -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
        )
index d484be1b6139a44510ab425da9d6ab17b106374b..53312dba8c251419826e96c7babb9fb0e9631f03 100644 (file)
@@ -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 \
index 0108b001f8e953d9b4a4ebc6c66105ff2e30527f..3a199bdf7a72421430a6e46744f97d769481b28d 100755 (executable)
@@ -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
 
index de120e8adf4d909730615dacf2ea978e7069ceda..444feb7f450763cbd5c0a8282c57a264c64a4652 100644 (file)
@@ -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()
index 20b3186ec64770254ebbeebe378a737c4ca7e0b1..9089ffb4504eea1210a25f72c585ab3c9c1c809c 100644 (file)
@@ -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",
index 5e591047fab41d6d4ab724cf5c9b7a107ed4cf86..dc29eeeb83aec3854378277736022b508accf1bf 100644 (file)
@@ -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: