[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