def test_still_running(): with timer(5): # Run something forever so we can kill it proc = util.startProgram(["/bin/sh", "-c", "while true; do sleep 1; done"]) WatchProcesses.watch_process(proc, "test1") proc.kill() # Wait for the SIGCHLD signal.pause()
def startX(argv, output_redirect=None, timeout=X_TIMEOUT): """ 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 :param timeout: Number of seconds to timing out. """ # 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 log.debug("Setting timeout %s seconds for starting X.", timeout) signal.alarm(timeout) childproc = startProgram(argv, stdout=output_redirect, stderr=output_redirect, preexec_fn=sigusr1_preexec) WatchProcesses.watch_process(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 start_user_systemd(): """Start the user instance of systemd. The service org.a11y.Bus runs the dbus-broker-launch in the user scope that requires the user instance of systemd. """ if not conf.system.can_start_user_systemd: log.debug("Don't start the user instance of systemd.") return childproc = util.startProgram(["/usr/lib/systemd/systemd", "--user"]) WatchProcesses.watch_process(childproc, "systemd")
def do_startup_x11_actions(): """Start the window manager. When metacity actually connects to the X server is unknowable, but fortunately it doesn't matter. metacity does not need to be the first connection to Xorg, and if anaconda starts up before metacity, metacity will just take over and maximize the window and make everything right, fingers crossed. Add XDG_DATA_DIRS to the environment to pull in our overridden schema files. """ datadir = os.environ.get('ANACONDA_DATADIR', '/usr/share/anaconda') if 'XDG_DATA_DIRS' in os.environ: xdg_data_dirs = datadir + '/window-manager:' + os.environ['XDG_DATA_DIRS'] else: xdg_data_dirs = datadir + '/window-manager:/usr/share' childproc = util.startProgram(["metacity", "--display", ":1", "--sm-disable"], env_add={'XDG_DATA_DIRS': xdg_data_dirs}) WatchProcesses.watch_process(childproc, "metacity")
def test_watch_process(self): """Test watchProcess""" def test_still_running(): with timer(5): # Run something forever so we can kill it proc = util.startProgram( ["/bin/sh", "-c", "while true; do sleep 1; done"]) WatchProcesses.watch_process(proc, "test1") proc.kill() # Wait for the SIGCHLD signal.pause() with pytest.raises(ExitError): test_still_running() # Make sure watchProcess checks that the process has not already exited with timer(5): proc = util.startProgram(["true"]) proc.communicate() with pytest.raises(ExitError): WatchProcesses.watch_process(proc, "test2")
def startX(argv, output_redirect=None, timeout=X_TIMEOUT): """ 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 :param timeout: Number of seconds to timing out. """ x11_status = X11Status() # Handle successful start before timeout def sigusr1_success_handler(num, frame): log.debug("X server has signalled a successful start.") x11_status.started = 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_status.started: return x11_status.timed_out = True log.error("Timeout trying to start %s", argv[0]) # Handle delayed start after timeout def sigusr1_too_late_handler(num, frame): if x11_status.timed_out: log.debug( "SIGUSR1 received after X server timeout. Switching back to tty1. " "SIGUSR1 now again initiates test of exception reporting.") signal.signal(signal.SIGUSR1, old_sigusr1_handler) # preexec_fn to add the SIGUSR1 handler in the child we are starting # see man page XServer(1), section "signals" def sigusr1_preexec(): signal.signal(signal.SIGUSR1, signal.SIG_IGN) try: old_sigusr1_handler = signal.signal(signal.SIGUSR1, sigusr1_success_handler) old_sigalrm_handler = signal.signal(signal.SIGALRM, sigalrm_handler) # Start the timer log.debug("Setting timeout %s seconds for starting X.", timeout) signal.alarm(timeout) childproc = startProgram(argv, stdout=output_redirect, stderr=output_redirect, preexec_fn=sigusr1_preexec) WatchProcesses.watch_process(childproc, argv[0]) # Wait for SIGUSR1 or SIGALRM while x11_status.needs_waiting(): signal.pause() finally: # Stop the timer signal.alarm(0) signal.signal(signal.SIGALRM, old_sigalrm_handler) # Handle outcome of X start attempt if x11_status.started: signal.signal(signal.SIGUSR1, old_sigusr1_handler) elif x11_status.timed_out: signal.signal(signal.SIGUSR1, sigusr1_too_late_handler) # Kill Xorg because from now on we will not use it. It will exit only after sending # the signal, but at least we don't have to track that. WatchProcesses.unwatch_process(childproc) childproc.terminate() log.debug( "Exception handler test suspended to prevent accidental activation by " "delayed Xorg start. Next SIGUSR1 will be handled as delayed Xorg start." ) # Raise an exception to notify the caller that things went wrong. This affects # particularly pyanaconda.display.do_startup_x11_actions(), where the window manager # is started immediately after this. The WM would just wait forever. raise TimeoutError("Timeout trying to start %s" % argv[0])