[PATCH 16/17] Move the X startup logic to iutil

David Shea dshea at redhat.com
Sun Sep 21 19:37:08 UTC 2014


Move all the parts that set up signal handlers and wait for SIGUSR1 to
iutil.startX. Use startX for starting Xvnc since it does the same thing
as Xorg.
---
 anaconda            | 56 +++++++++--------------------------------------------
 pyanaconda/iutil.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
 pyanaconda/vnc.py   | 12 ++----------
 3 files changed, 63 insertions(+), 57 deletions(-)

diff --git a/anaconda b/anaconda
index f9807cd..c2a17f2 100755
--- a/anaconda
+++ b/anaconda
@@ -107,55 +107,17 @@ def startSpiceVDAgent():
         log.info("Started spice-vdagent.")
 
 def startX11():
-    # Start X11 with its USR1 handler set to ignore, which will make it send
-    # us SIGUSR1 if it succeeds. If it fails, catch SIGCHLD and bomb out.
-    # Use a list so the value can be modified from the handler
-    x11_started = [False]
-    def sigusr1_handler(num, frame):
-        log.debug("X server has signalled a successful start.")
-        x11_started[0] = True
+    # Open /dev/tty5 for stdout and stderr redirects
+    xfd = open("/dev/tty5", "a")
 
-    # Fail after, let's say a minute, in case something weird happens
-    # and we don't receive SIGUSR1
-    def sigalrm_handler(num, frame):
-        # Check that it didn't make it under the wire
-        if x11_started[0]:
-            return
-        log.error("Timeout trying to start the X server")
-        raise iutil.ExitError("Timeout trying to start the X server")
+    # Start Xorg and wait for it become ready
+    iutil.startX(["Xorg", "-br", "-logfile", "/tmp/X.log",
+                  ":1", "vt6", "-s", "1440", "-ac",
+                  "-nolisten", "tcp", "-dpi", "96",
+                  "-noreset"], output_redirect=xfd)
 
-    # preexec_fn to add the SIGUSR1 handler in the child
-    def sigusr1_preexec():
-        signal.signal(signal.SIGUSR1, signal.SIG_IGN)
-
-    try:
-        old_sigusr1_handler = signal.signal(signal.SIGUSR1, sigusr1_handler)
-        old_sigalrm_handler = signal.signal(signal.SIGALRM, sigalrm_handler)
-
-        # Open /dev/tty5 for stdout and stderr redirects
-        xfd = open("/dev/tty5", "a")
-
-        # Start the timer
-        signal.alarm(60)
-
-        childproc = iutil.startProgram(["Xorg", "-br", "-logfile", "/tmp/X.log",
-                                        ":1", "vt6", "-s", "1440", "-ac",
-                                        "-nolisten", "tcp", "-dpi", "96",
-                                        "-noreset"], stdout=xfd, stderr=xfd,
-                                        preexec_fn=sigusr1_preexec)
-        iutil.watchProcess(childproc, "Xorg")
-
-        # Wait for SIGUSR1
-        while not x11_started[0]:
-            signal.pause()
-
-        # Now that X is started, make $DISPLAY available
-        os.environ["DISPLAY"] = ":1"
-    finally:
-        # Put everything back where it was
-        signal.alarm(0)
-        signal.signal(signal.SIGUSR1, old_sigusr1_handler)
-        signal.signal(signal.SIGALRM, old_sigalrm_handler)
+    # Now that X is started, make $DISPLAY available
+    os.environ["DISPLAY"] = ":1"
 
 # function to handle X startup special issues for anaconda
 def doStartupX11Actions():
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index e09b791..f135d6f 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -161,6 +161,58 @@ def startProgram(argv, root='/', stdin=None, stdout=subprocess.PIPE, stderr=subp
                             close_fds=True,
                             preexec_fn=preexec, cwd=root, env=env, **kwargs)
 
+def startX(argv, output_redirect=None):
+    """ Start X and return once X is ready to accept connections.
+
+        X11, if SIGUSR1 is set to SIG_IGN, will send SIGUSR1 to the parent
+        process once it is ready to accept client connections. This method
+        sets that up and waits for the signal or bombs out if nothing happens
+        for a minute. The process will also be added to the list of watched
+        processes.
+
+        :param argv: The command line to run, as a list
+        :param output_redirect: file or file descriptor to redirect stdout and stderr to
+    """
+    # Use a list so the value can be modified from the handler function
+    x11_started = [False]
+    def sigusr1_handler(num, frame):
+        log.debug("X server has signalled a successful start.")
+        x11_started[0] = True
+
+    # Fail after, let's say a minute, in case something weird happens
+    # and we don't receive SIGUSR1
+    def sigalrm_handler(num, frame):
+        # Check that it didn't make it under the wire
+        if x11_started[0]:
+            return
+        log.error("Timeout trying to start %s", argv[0])
+        raise ExitError("Timeout trying to start %s" % argv[0])
+
+    # preexec_fn to add the SIGUSR1 handler in the child
+    def sigusr1_preexec():
+        signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+
+    try:
+        old_sigusr1_handler = signal.signal(signal.SIGUSR1, sigusr1_handler)
+        old_sigalrm_handler = signal.signal(signal.SIGALRM, sigalrm_handler)
+
+        # Start the timer
+        signal.alarm(60)
+
+        childproc = startProgram(argv, stdout=output_redirect, stderr=output_redirect,
+                preexec_fn=sigusr1_preexec)
+        watchProcess(childproc, argv[0])
+
+        # Wait for SIGUSR1
+        while not x11_started[0]:
+            signal.pause()
+
+    finally:
+        # Put everything back where it was
+        signal.alarm(0)
+        signal.signal(signal.SIGUSR1, old_sigusr1_handler)
+        signal.signal(signal.SIGALRM, old_sigalrm_handler)
+
 def _run_program(argv, root='/', stdin=None, stdout=None, env_prune=None, log_output=True,
         binary_output=False, filter_stderr=False):
     """ Run an external program, log the output and return it to the caller
diff --git a/pyanaconda/vnc.py b/pyanaconda/vnc.py
index 16a3faf..7eedbf8 100644
--- a/pyanaconda/vnc.py
+++ b/pyanaconda/vnc.py
@@ -221,21 +221,13 @@ class VncServer:
                         "SecurityTypes=%s" % SecurityTypes, "rfbauth=%s" % rfbauth ]
 
         try:
-            xvncp = subprocess.Popen(xvnccommand, stdout=self.openlogfile(), stderr=subprocess.STDOUT)
+            iutil.startX(xvnccommand, output_redirect=self.openlogfile())
         except OSError:
             stdoutLog.critical("Could not start the VNC server.  Aborting.")
             iutil.ipmi_report(constants.IPMI_ABORTED)
             sys.exit(1)
 
-        # Lets give the xvnc time to initialize
-        time.sleep(1)
-
-        # Make sure it hasn't blown up
-        if xvncp.poll() != None:
-            iutil.ipmi_report(constants.IPMI_ABORTED)
-            sys.exit(1)
-        else:
-            self.log.info(_("The VNC server is now running."))
+        self.log.info(_("The VNC server is now running."))
 
         # Lets tell the user what we are going to do.
         if self.vncconnecthost != "":
-- 
1.9.3



More information about the anaconda-patches mailing list