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

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 global g_desktop
412 assert(g_desktop is None)
413 g_desktop = self
412 414
413 @staticmethod 415 @staticmethod
414 def get_unused_display_number(): 416 def get_unused_display_number():
415 """Return a candidate display number for which there is currently no 417 """Return a candidate display number for which there is currently no
416 X Server lock file""" 418 X Server lock file"""
417 display = FIRST_X_DISPLAY_NUMBER 419 display = FIRST_X_DISPLAY_NUMBER
418 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): 420 while os.path.exists(X_LOCK_FILE_TEMPLATE % display):
419 display += 1 421 display += 1
420 return display 422 return display
421 423
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 if self.ssh_auth_sockname: 746 if self.ssh_auth_sockname:
745 args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname) 747 args.append("--ssh-auth-sockname=%s" % self.ssh_auth_sockname)
746 748
747 args.extend(extra_start_host_args) 749 args.extend(extra_start_host_args)
748 750
749 # Have the host process use SIGUSR1 to signal a successful start. 751 # Have the host process use SIGUSR1 to signal a successful start.
750 def sigusr1_handler(signum, frame): 752 def sigusr1_handler(signum, frame):
751 _ = signum, frame 753 _ = signum, frame
752 logging.info("Host ready to receive connections.") 754 logging.info("Host ready to receive connections.")
753 self.host_ready = True 755 self.host_ready = True
754 if (ParentProcessLogger.instance() and 756 if (ParentProcessLogger.instance() and g_desktop is not None and
755 False not in [desktop.host_ready for desktop in g_desktops]): 757 g_desktop.host_ready):
756 ParentProcessLogger.instance().release_parent(True) 758 ParentProcessLogger.instance().release_parent(True)
757 759
758 signal.signal(signal.SIGUSR1, sigusr1_handler) 760 signal.signal(signal.SIGUSR1, sigusr1_handler)
759 args.append("--signal-parent") 761 args.append("--signal-parent")
760 762
761 logging.info(args) 763 logging.info(args)
762 self.host_proc = subprocess.Popen(args, env=self.child_env, 764 self.host_proc = subprocess.Popen(args, env=self.child_env,
763 stdin=subprocess.PIPE) 765 stdin=subprocess.PIPE)
764 if not self.host_proc.pid: 766 if not self.host_proc.pid:
765 raise Exception("Could not start Chrome Remote Desktop host") 767 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()) 1058 os.dup2(log_fd, sys.stderr.fileno())
1057 1059
1058 # Close the temporary file-descriptors. 1060 # Close the temporary file-descriptors.
1059 os.close(devnull_fd) 1061 os.close(devnull_fd)
1060 os.close(log_fd) 1062 os.close(log_fd)
1061 1063
1062 1064
1063 def cleanup(): 1065 def cleanup():
1064 logging.info("Cleanup.") 1066 logging.info("Cleanup.")
1065 1067
1066 global g_desktops 1068 global g_desktop
1067 for desktop in g_desktops: 1069 if g_desktop is not None:
1068 for proc, name in [(desktop.x_proc, "X server"), 1070 for proc, name in [(g_desktop.x_proc, "X server"),
1069 (desktop.session_proc, "session"), 1071 (g_desktop.session_proc, "session"),
1070 (desktop.host_proc, "host")]: 1072 (g_desktop.host_proc, "host")]:
1071 if proc is not None: 1073 if proc is not None:
1072 logging.info("Terminating " + name) 1074 logging.info("Terminating " + name)
1073 try: 1075 try:
1074 psutil_proc = psutil.Process(proc.pid) 1076 psutil_proc = psutil.Process(proc.pid)
1075 psutil_proc.terminate() 1077 psutil_proc.terminate()
1076 1078
1077 # Use a short timeout, to avoid delaying service shutdown if the 1079 # Use a short timeout, to avoid delaying service shutdown if the
1078 # process refuses to die for some reason. 1080 # process refuses to die for some reason.
1079 psutil_proc.wait(timeout=10) 1081 psutil_proc.wait(timeout=10)
1080 except psutil.TimeoutExpired: 1082 except psutil.TimeoutExpired:
1081 logging.error("Timed out - sending SIGKILL") 1083 logging.error("Timed out - sending SIGKILL")
1082 psutil_proc.kill() 1084 psutil_proc.kill()
1083 except psutil.Error: 1085 except psutil.Error:
1084 logging.error("Error terminating process") 1086 logging.error("Error terminating process")
1085 if desktop.xorg_conf is not None: 1087 if g_desktop.xorg_conf is not None:
1086 os.remove(desktop.xorg_conf) 1088 os.remove(g_desktop.xorg_conf)
1087 1089
1088 g_desktops = [] 1090 g_desktop = None
1089 if ParentProcessLogger.instance(): 1091 if ParentProcessLogger.instance():
1090 ParentProcessLogger.instance().release_parent(False) 1092 ParentProcessLogger.instance().release_parent(False)
1091 1093
1092 class SignalHandler: 1094 class SignalHandler:
1093 """Reload the config file on SIGHUP. Since we pass the configuration to the 1095 """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 1096 host processes via stdin, they can't reload it, so terminate them. They will
1095 be relaunched automatically with the new config.""" 1097 be relaunched automatically with the new config."""
1096 1098
1097 def __init__(self, host_config): 1099 def __init__(self, host_config):
1098 self.host_config = host_config 1100 self.host_config = host_config
1099 1101
1100 def __call__(self, signum, _stackframe): 1102 def __call__(self, signum, _stackframe):
1101 if signum == signal.SIGHUP: 1103 if signum == signal.SIGHUP:
1102 logging.info("SIGHUP caught, restarting host.") 1104 logging.info("SIGHUP caught, restarting host.")
1103 try: 1105 try:
1104 self.host_config.load() 1106 self.host_config.load()
1105 except (IOError, ValueError) as e: 1107 except (IOError, ValueError) as e:
1106 logging.error("Failed to load config: " + str(e)) 1108 logging.error("Failed to load config: " + str(e))
1107 for desktop in g_desktops: 1109 if g_desktop is not None and g_desktop.host_proc:
1108 if desktop.host_proc: 1110 g_desktop.host_proc.send_signal(signal.SIGTERM)
1109 desktop.host_proc.send_signal(signal.SIGTERM)
1110 else: 1111 else:
1111 # Exit cleanly so the atexit handler, cleanup(), gets called. 1112 # Exit cleanly so the atexit handler, cleanup(), gets called.
1112 raise SystemExit 1113 raise SystemExit
1113 1114
1114 1115
1115 class RelaunchInhibitor: 1116 class RelaunchInhibitor:
1116 """Helper class for inhibiting launch of a child process before a timeout has 1117 """Helper class for inhibiting launch of a child process before a timeout has
1117 elapsed. 1118 elapsed.
1118 1119
1119 A managed process can be in one of these states: 1120 A managed process can be in one of these states:
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 else: 1622 else:
1622 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) 1623 logging.info("Host exited with status %s." % os.WEXITSTATUS(status))
1623 elif os.WIFSIGNALED(status): 1624 elif os.WIFSIGNALED(status):
1624 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) 1625 logging.info("Host terminated by signal %s." % os.WTERMSIG(status))
1625 1626
1626 1627
1627 if __name__ == "__main__": 1628 if __name__ == "__main__":
1628 logging.basicConfig(level=logging.DEBUG, 1629 logging.basicConfig(level=logging.DEBUG,
1629 format="%(asctime)s:%(levelname)s:%(message)s") 1630 format="%(asctime)s:%(levelname)s:%(message)s")
1630 sys.exit(main()) 1631 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