Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: remoting/host/linux/linux_me2me_host.py

Issue 2891913003: Simplify Linux host startup script. (Closed)
Patch Set: Simplify Linux host startup script. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # Virtual Me2Me implementation. This script runs and manages the processes 6 # Virtual Me2Me implementation. This script runs and manages the processes
7 # required for a Virtual Me2Me desktop, which are: X server, X desktop 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop
8 # session, and Host process. 8 # session, and Host process.
9 # This script is intended to run continuously as a background daemon 9 # This script is intended to run continuously as a background daemon
10 # process, running under an ordinary (non-root) user account. 10 # process, running under an ordinary (non-root) user account.
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 124
125 # Thresholds for switching from fast- to slow-restart and for giving up 125 # Thresholds for switching from fast- to slow-restart and for giving up
126 # trying to restart entirely. 126 # trying to restart entirely.
127 SHORT_BACKOFF_THRESHOLD = 5 127 SHORT_BACKOFF_THRESHOLD = 5
128 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 128 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10
129 129
130 # Number of seconds to save session output to the log. 130 # Number of seconds to save session output to the log.
131 SESSION_OUTPUT_TIME_LIMIT_SECONDS = 30 131 SESSION_OUTPUT_TIME_LIMIT_SECONDS = 30
132 132
133 # Globals needed by the atexit cleanup() handler. 133 # Globals needed by the atexit cleanup() handler.
134 g_desktops = [] 134 g_desktop = None
135 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() 135 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest()
136 136
137 def gen_xorg_config(sizes): 137 def gen_xorg_config(sizes):
138 return ( 138 return (
139 # This causes X to load the default GLX module, even if a proprietary one 139 # This causes X to load the default GLX module, even if a proprietary one
140 # is installed in a different directory. 140 # is installed in a different directory.
141 'Section "Files"\n' 141 'Section "Files"\n'
142 ' ModulePath "/usr/lib/xorg/modules"\n' 142 ' ModulePath "/usr/lib/xorg/modules"\n'
143 'EndSection\n' 143 'EndSection\n'
144 '\n' 144 '\n'
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 self.host_proc = None 401 self.host_proc = None
402 self.child_env = None 402 self.child_env = None
403 self.sizes = sizes 403 self.sizes = sizes
404 self.xorg_conf = None 404 self.xorg_conf = None
405 self.pulseaudio_pipe = None 405 self.pulseaudio_pipe = None
406 self.server_supports_exact_resize = False 406 self.server_supports_exact_resize = False
407 self.server_supports_randr = False 407 self.server_supports_randr = False
408 self.randr_add_sizes = False 408 self.randr_add_sizes = False
409 self.host_ready = False 409 self.host_ready = False
410 self.ssh_auth_sockname = None 410 self.ssh_auth_sockname = None
411 g_desktops.append(self) 411 g_desktop = self
Lambros 2017/05/18 20:39:59 optional: Maybe assert() or raise an error if g_de
412 412
413 @staticmethod 413 @staticmethod
414 def get_unused_display_number(): 414 def get_unused_display_number():
415 """Return a candidate display number for which there is currently no 415 """Return a candidate display number for which there is currently no
416 X Server lock file""" 416 X Server lock file"""
417 display = FIRST_X_DISPLAY_NUMBER 417 display = FIRST_X_DISPLAY_NUMBER
418 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): 418 while os.path.exists(X_LOCK_FILE_TEMPLATE % display):
419 display += 1 419 display += 1
420 return display 420 return display
421 421
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 if self.ssh_auth_sockname: 744 if self.ssh_auth_sockname:
745 args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname) 745 args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname)
746 746
747 args.extend(extra_start_host_args) 747 args.extend(extra_start_host_args)
748 748
749 # Have the host process use SIGUSR1 to signal a successful start. 749 # Have the host process use SIGUSR1 to signal a successful start.
750 def sigusr1_handler(signum, frame): 750 def sigusr1_handler(signum, frame):
751 _ = signum, frame 751 _ = signum, frame
752 logging.info("Host ready to receive connections.") 752 logging.info("Host ready to receive connections.")
753 self.host_ready = True 753 self.host_ready = True
754 if (ParentProcessLogger.instance() and 754 if (ParentProcessLogger.instance() and g_desktop is not None and
755 False not in [desktop.host_ready for desktop in g_desktops]): 755 g_desktop.host_ready):
756 ParentProcessLogger.instance().release_parent(True) 756 ParentProcessLogger.instance().release_parent(True)
757 757
758 signal.signal(signal.SIGUSR1, sigusr1_handler) 758 signal.signal(signal.SIGUSR1, sigusr1_handler)
759 args.append("--signal-parent") 759 args.append("--signal-parent")
760 760
761 logging.info(args) 761 logging.info(args)
762 self.host_proc = subprocess.Popen(args, env=self.child_env, 762 self.host_proc = subprocess.Popen(args, env=self.child_env,
763 stdin=subprocess.PIPE) 763 stdin=subprocess.PIPE)
764 if not self.host_proc.pid: 764 if not self.host_proc.pid:
765 raise Exception("Could not start Chrome Remote Desktop host") 765 raise Exception("Could not start Chrome Remote Desktop host")
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 os.dup2(log_fd, sys.stderr.fileno()) 1056 os.dup2(log_fd, sys.stderr.fileno())
1057 1057
1058 # Close the temporary file-descriptors. 1058 # Close the temporary file-descriptors.
1059 os.close(devnull_fd) 1059 os.close(devnull_fd)
1060 os.close(log_fd) 1060 os.close(log_fd)
1061 1061
1062 1062
1063 def cleanup(): 1063 def cleanup():
1064 logging.info("Cleanup.") 1064 logging.info("Cleanup.")
1065 1065
1066 global g_desktops 1066 global g_desktop
1067 for desktop in g_desktops: 1067 if g_desktop is not None:
1068 for proc, name in [(desktop.x_proc, "X server"), 1068 for proc, name in [(g_desktop.x_proc, "X server"),
1069 (desktop.session_proc, "session"), 1069 (g_desktop.session_proc, "session"),
1070 (desktop.host_proc, "host")]: 1070 (g_desktop.host_proc, "host")]:
1071 if proc is not None: 1071 if proc is not None:
1072 logging.info("Terminating " + name) 1072 logging.info("Terminating " + name)
1073 try: 1073 try:
1074 psutil_proc = psutil.Process(proc.pid) 1074 psutil_proc = psutil.Process(proc.pid)
1075 psutil_proc.terminate() 1075 psutil_proc.terminate()
1076 1076
1077 # Use a short timeout, to avoid delaying service shutdown if the 1077 # Use a short timeout, to avoid delaying service shutdown if the
1078 # process refuses to die for some reason. 1078 # process refuses to die for some reason.
1079 psutil_proc.wait(timeout=10) 1079 psutil_proc.wait(timeout=10)
1080 except psutil.TimeoutExpired: 1080 except psutil.TimeoutExpired:
1081 logging.error("Timed out - sending SIGKILL") 1081 logging.error("Timed out - sending SIGKILL")
1082 psutil_proc.kill() 1082 psutil_proc.kill()
1083 except psutil.Error: 1083 except psutil.Error:
1084 logging.error("Error terminating process") 1084 logging.error("Error terminating process")
1085 if desktop.xorg_conf is not None: 1085 if g_desktop.xorg_conf is not None:
1086 os.remove(desktop.xorg_conf) 1086 os.remove(g_desktop.xorg_conf)
1087 1087
1088 g_desktops = [] 1088 g_desktop = None
1089 if ParentProcessLogger.instance(): 1089 if ParentProcessLogger.instance():
1090 ParentProcessLogger.instance().release_parent(False) 1090 ParentProcessLogger.instance().release_parent(False)
1091 1091
1092 class SignalHandler: 1092 class SignalHandler:
1093 """Reload the config file on SIGHUP. Since we pass the configuration to the 1093 """Reload the config file on SIGHUP. Since we pass the configuration to the
1094 host processes via stdin, they can't reload it, so terminate them. They will 1094 host processes via stdin, they can't reload it, so terminate them. They will
1095 be relaunched automatically with the new config.""" 1095 be relaunched automatically with the new config."""
1096 1096
1097 def __init__(self, host_config): 1097 def __init__(self, host_config):
1098 self.host_config = host_config 1098 self.host_config = host_config
1099 1099
1100 def __call__(self, signum, _stackframe): 1100 def __call__(self, signum, _stackframe):
1101 if signum == signal.SIGHUP: 1101 if signum == signal.SIGHUP:
1102 logging.info("SIGHUP caught, restarting host.") 1102 logging.info("SIGHUP caught, restarting host.")
1103 try: 1103 try:
1104 self.host_config.load() 1104 self.host_config.load()
1105 except (IOError, ValueError) as e: 1105 except (IOError, ValueError) as e:
1106 logging.error("Failed to load config: " + str(e)) 1106 logging.error("Failed to load config: " + str(e))
1107 for desktop in g_desktops: 1107 if g_desktop is not None:
1108 if desktop.host_proc: 1108 if g_desktop.host_proc:
1109 desktop.host_proc.send_signal(signal.SIGTERM) 1109 g_desktop.host_proc.send_signal(signal.SIGTERM)
1110 else: 1110 else:
1111 # Exit cleanly so the atexit handler, cleanup(), gets called. 1111 # Exit cleanly so the atexit handler, cleanup(), gets called.
1112 raise SystemExit 1112 raise SystemExit
1113 1113
1114 1114
1115 class RelaunchInhibitor: 1115 class RelaunchInhibitor:
1116 """Helper class for inhibiting launch of a child process before a timeout has 1116 """Helper class for inhibiting launch of a child process before a timeout has
1117 elapsed. 1117 elapsed.
1118 1118
1119 A managed process can be in one of these states: 1119 A managed process can be in one of these states:
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 else: 1621 else:
1622 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) 1622 logging.info("Host exited with status %s." % os.WEXITSTATUS(status))
1623 elif os.WIFSIGNALED(status): 1623 elif os.WIFSIGNALED(status):
1624 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) 1624 logging.info("Host terminated by signal %s." % os.WTERMSIG(status))
1625 1625
1626 1626
1627 if __name__ == "__main__": 1627 if __name__ == "__main__":
1628 logging.basicConfig(level=logging.DEBUG, 1628 logging.basicConfig(level=logging.DEBUG,
1629 format="%(asctime)s:%(levelname)s:%(message)s") 1629 format="%(asctime)s:%(levelname)s:%(message)s")
1630 sys.exit(main()) 1630 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698