[Spice-devel] [PATCH] Handle SIGUSR1 from and SIGHUP to X

Alon Levy alevy at redhat.com
Mon Jan 27 00:41:58 PST 2014


From: Anonymous <wishes at to.remain>

Relevant excerpt from Xserver(1) man page:

/SIGUSR1/
    This signal is used quite differently from either of the above.
    When the server starts, it checks to see if it has inherited
    SIGUSR1 as SIG_IGN instead of the usual SIG_DFL. In this case, the
    server sends a SIGUSR1 to its parent process after it has set up
    the various connection schemes. /Xdm/ uses this feature to
    recognize when connecting to the server is possible.

With this patch KDM works correctly when launching Xspice instead of Xorg.

Problem reported and patch provided by anonymous.
---
 scripts/Xspice | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/scripts/Xspice b/scripts/Xspice
index b8a7b78..d2b2b81 100755
--- a/scripts/Xspice
+++ b/scripts/Xspice
@@ -22,7 +22,7 @@ import sys
 import tempfile
 import atexit
 import time
-import signal
+from signal import getsignal, signal, SIGTERM, SIGUSR1, SIGHUP
 from subprocess import Popen, PIPE
 
 def which(x):
@@ -178,7 +178,12 @@ def launch(*args, **kw):
     cleanup_processes.append(p)
     return p
 
-signal.signal(signal.SIGTERM, cleanup)
+# Save signal values to reset them when starting X
+saved_sigterm = getsignal(SIGTERM)
+saved_sighup = getsignal(SIGHUP)
+saved_sigusr1 = getsignal(SIGUSR1)
+
+signal(SIGTERM, cleanup)
 atexit.register(cleanup)
 
 if args.auto:
@@ -279,7 +284,35 @@ if args.vdagent_enabled:
         if os.path.exists(f):
             os.unlink(f)
     cleanup_files.extend([args.vdagent_virtio_path, args.vdagent_uinput_path])
-xorg = launch(executable=args.xorg, args=exec_args + xorg_args)
+
+# X gives special meaning to SIGUSR1 and SIGHUP (SIGTERM is already handled)
+xorg = None
+
+# SIGUSR1 needs to propagate to parent
+def sigusr1(*args):
+    os.kill(os.getppid(), SIGUSR1)
+
+# SIGHUP needs to propagate to X
+def sighup(*args):
+    if xorg is None:
+        return
+    # xorg.pid might not be valid anymore when a signal arrives after
+    # xorg.wait() returns, but the script did not yet exit
+    try:
+        os.kill(xorg.pid, SIGHUP)
+    except Exception:
+        pass
+
+def reset_handlers():
+    signal(SIGTERM, saved_sigterm)
+    signal(SIGHUP, saved_sighup)
+    signal(SIGUSR1, saved_sigusr1)
+
+signal(SIGUSR1, sigusr1)
+signal(SIGHUP, sighup)
+
+# use preexec_fn to reset the signal handlers for the X process back to the original values
+xorg = launch(executable=args.xorg, args=exec_args + xorg_args, preexec_fn=reset_handlers)
 time.sleep(2)
 
 retpid,rc = os.waitpid(xorg.pid, os.WNOHANG)
@@ -289,11 +322,13 @@ else:
     if args.vdagent_enabled and args.vdagent_launch:
         # XXX use systemd --user for this?
         vdagentd = launch(args=[args.vdagentd_exec, '-x', '-S', vdagentd_uds,
-                          '-s', args.vdagent_virtio_path, '-u', args.vdagent_uinput_path])
+                          '-s', args.vdagent_virtio_path, '-u', args.vdagent_uinput_path],
+                          preexec_fn=reset_handlers)
         time.sleep(1)
         # TODO wait for uinput pipe open for write
         vdagent = launch(args=[args.vdagent_exec, '-x', '-s', args.vdagent_virtio_path, '-S',
-                         vdagentd_uds])
+                         vdagentd_uds],
+                         preexec_fn=reset_handlers)
     if args.xsession:
         environ = os.environ
         os.spawnlpe(os.P_NOWAIT, args.xsession, environ)
-- 
1.8.4.2



More information about the Spice-devel mailing list