Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env 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 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 os.dup2(log_fd, sys.stderr.fileno()) | 627 os.dup2(log_fd, sys.stderr.fileno()) |
| 628 | 628 |
| 629 # Close the temporary file-descriptors. | 629 # Close the temporary file-descriptors. |
| 630 os.close(devnull_fd) | 630 os.close(devnull_fd) |
| 631 os.close(log_fd) | 631 os.close(log_fd) |
| 632 | 632 |
| 633 | 633 |
| 634 def cleanup(): | 634 def cleanup(): |
| 635 logging.info("Cleanup.") | 635 logging.info("Cleanup.") |
| 636 | 636 |
| 637 global g_pidfile | |
| 637 if g_pidfile: | 638 if g_pidfile: |
| 638 try: | 639 try: |
| 639 g_pidfile.delete_file() | 640 g_pidfile.delete_file() |
| 641 g_pidfile = None | |
| 640 except Exception, e: | 642 except Exception, e: |
| 641 logging.error("Unexpected error deleting PID file: " + str(e)) | 643 logging.error("Unexpected error deleting PID file: " + str(e)) |
| 642 | 644 |
| 645 global g_desktops | |
| 643 for desktop in g_desktops: | 646 for desktop in g_desktops: |
| 644 if desktop.x_proc: | 647 if desktop.x_proc: |
| 645 logging.info("Terminating Xvfb") | 648 logging.info("Terminating Xvfb") |
| 646 desktop.x_proc.terminate() | 649 desktop.x_proc.terminate() |
| 650 g_desktops = [] | |
| 647 | 651 |
| 648 | 652 |
| 649 def reload_config(): | 653 def reload_config(): |
| 650 for desktop in g_desktops: | 654 for desktop in g_desktops: |
| 651 if desktop.host_proc: | 655 if desktop.host_proc: |
| 652 # Terminating the Host will cause the main loop to spawn another | 656 # Terminating the Host will cause the main loop to spawn another |
| 653 # instance, which will read any changes made to the Host config file. | 657 # instance, which will read any changes made to the Host config file. |
| 654 desktop.host_proc.terminate() | 658 desktop.host_proc.terminate() |
| 655 | 659 |
| 656 | 660 |
| 657 def signal_handler(signum, stackframe): | 661 def signal_handler(signum, stackframe): |
| 658 if signum == signal.SIGUSR1: | 662 if signum == signal.SIGUSR1: |
| 659 logging.info("SIGUSR1 caught, reloading configuration.") | 663 logging.info("SIGUSR1 caught, reloading configuration.") |
| 660 reload_config() | 664 reload_config() |
| 661 else: | 665 else: |
| 662 # Exit cleanly so the atexit handler, cleanup(), gets called. | 666 # Exit cleanly so the atexit handler, cleanup(), gets called. |
| 663 raise SystemExit | 667 raise SystemExit |
| 664 | 668 |
| 665 | 669 |
| 670 def relaunch_self(): | |
| 671 cleanup() | |
| 672 os.execvp(sys.argv[0], sys.argv) | |
| 673 | |
| 674 | |
| 666 def main(): | 675 def main(): |
| 667 DEFAULT_SIZE = "1280x800" | 676 DEFAULT_SIZE = "1280x800" |
| 668 parser = optparse.OptionParser( | 677 parser = optparse.OptionParser( |
| 669 "Usage: %prog [options] [ -- [ X server options ] ]") | 678 "Usage: %prog [options] [ -- [ X server options ] ]") |
| 670 parser.add_option("-s", "--size", dest="size", action="append", | 679 parser.add_option("-s", "--size", dest="size", action="append", |
| 671 help="dimensions of virtual desktop (default: %s). " | 680 help="dimensions of virtual desktop (default: %s). " |
| 672 "This can be specified multiple times to make multiple " | 681 "This can be specified multiple times to make multiple " |
| 673 "screen resolutions available (if the Xvfb server " | 682 "screen resolutions available (if the Xvfb server " |
| 674 "supports this)" % DEFAULT_SIZE) | 683 "supports this)" % DEFAULT_SIZE) |
| 675 parser.add_option("-f", "--foreground", dest="foreground", default=False, | 684 parser.add_option("-f", "--foreground", dest="foreground", default=False, |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 | 875 |
| 867 desktop = Desktop(sizes) | 876 desktop = Desktop(sizes) |
| 868 | 877 |
| 869 # Remember the time when the last session was launched, in order to enforce | 878 # Remember the time when the last session was launched, in order to enforce |
| 870 # a minimum time between launches. This avoids spinning in case of a | 879 # a minimum time between launches. This avoids spinning in case of a |
| 871 # misconfigured system, or other error that prevents a session from starting | 880 # misconfigured system, or other error that prevents a session from starting |
| 872 # properly. | 881 # properly. |
| 873 last_launch_time = 0 | 882 last_launch_time = 0 |
| 874 | 883 |
| 875 while True: | 884 while True: |
| 876 # If the session process stops running (e.g. because the user logged out), | 885 # If the session process or X server stops running (e.g. because the user |
| 877 # the X server should be reset and the session restarted, to provide a | 886 # logged out), re-run this script with its original arguments. Since the |
| 878 # completely clean new session. | 887 # user's desktop is already gone at this point, there's no state to lose |
| 888 # so now is a good time to pick up any updates to this script that might | |
| 889 # have been installed. | |
| 879 if desktop.session_proc is None and desktop.x_proc is not None: | 890 if desktop.session_proc is None and desktop.x_proc is not None: |
| 880 logging.info("Terminating X server") | 891 logging.info("Terminating X server") |
| 881 desktop.x_proc.terminate() | 892 desktop.x_proc.terminate() |
| 893 relaunch_self() | |
| 894 elif desktop.x_proc is None and desktop.session_proc is not None: | |
| 895 logging.info("Terminating X session") | |
| 896 desktop.session_proc.terminate() | |
| 897 relaunch_self() | |
|
Lambros
2012/08/18 00:06:50
Unfortunately, calling relaunch_self() here (or ab
Jamie
2012/08/20 19:46:05
Good catch! Done.
| |
| 882 | 898 |
| 883 if desktop.x_proc is None: | 899 if desktop.x_proc is None and desktop.session_proc is None: |
| 884 if desktop.session_proc is not None: | 900 # Neither X server nor X session are running. |
| 885 # The X session would probably die soon if the X server is not | 901 elapsed = time.time() - last_launch_time |
| 886 # running (because of the loss of the X connection). Terminate it | 902 if elapsed < 60: |
| 887 # anyway, to be sure. | 903 logging.error("The session lasted less than 1 minute. Waiting " + |
| 888 logging.info("Terminating X session") | 904 "before starting new session.") |
| 889 desktop.session_proc.terminate() | 905 time.sleep(60 - elapsed) |
| 890 else: | |
| 891 # Neither X server nor X session are running. | |
| 892 elapsed = time.time() - last_launch_time | |
| 893 if elapsed < 60: | |
| 894 logging.error("The session lasted less than 1 minute. Waiting " + | |
| 895 "before starting new session.") | |
| 896 time.sleep(60 - elapsed) | |
| 897 | 906 |
| 898 logging.info("Launching X server and X session") | 907 logging.info("Launching X server and X session") |
| 899 last_launch_time = time.time() | 908 last_launch_time = time.time() |
| 900 desktop.launch_x_server(args) | 909 desktop.launch_x_server(args) |
| 901 desktop.launch_x_session() | 910 desktop.launch_x_session() |
| 902 | 911 |
| 903 if desktop.host_proc is None: | 912 if desktop.host_proc is None: |
| 904 logging.info("Launching host process") | 913 logging.info("Launching host process") |
| 905 desktop.launch_host(host_config) | 914 desktop.launch_host(host_config) |
| 906 | 915 |
| 907 try: | 916 try: |
| 908 pid, status = os.wait() | 917 pid, status = os.wait() |
| 909 except OSError, e: | 918 except OSError, e: |
| 910 if e.errno == errno.EINTR: | 919 if e.errno == errno.EINTR: |
| 911 # Retry on EINTR, which can happen if a signal such as SIGUSR1 is | 920 # Retry on EINTR, which can happen if a signal such as SIGUSR1 is |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 return 0 | 964 return 0 |
| 956 elif os.WEXITSTATUS(status) == 5: | 965 elif os.WEXITSTATUS(status) == 5: |
| 957 logging.info("Host domain is blocked by policy - exiting.") | 966 logging.info("Host domain is blocked by policy - exiting.") |
| 958 os.remove(host.config_file) | 967 os.remove(host.config_file) |
| 959 return 0 | 968 return 0 |
| 960 # Nothing to do for Mac-only status 6 (login screen unsupported) | 969 # Nothing to do for Mac-only status 6 (login screen unsupported) |
| 961 | 970 |
| 962 if __name__ == "__main__": | 971 if __name__ == "__main__": |
| 963 logging.basicConfig(level=logging.DEBUG) | 972 logging.basicConfig(level=logging.DEBUG) |
| 964 sys.exit(main()) | 973 sys.exit(main()) |
| OLD | NEW |