X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fovs%2Fdaemon.py;h=650d2504034b6cced33c0e3d6f0f4e90861ff4f0;hb=a6f639f8080fe18120bb205609c6e364f6de7e70;hp=184e7832fc264f8d0bf52dd2df8d56d7c5695a2b;hpb=2a8859b0a4fe11c6418fe07dbb9b1c403a3986b4;p=sliver-openvswitch.git diff --git a/python/ovs/daemon.py b/python/ovs/daemon.py index 184e7832f..650d25040 100644 --- a/python/ovs/daemon.py +++ b/python/ovs/daemon.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010, 2011 Nicira Networks +# Copyright (c) 2010, 2011 Nicira, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ import errno import fcntl -import logging import os import resource import signal @@ -28,6 +27,9 @@ import ovs.process import ovs.socket_util import ovs.timeval import ovs.util +import ovs.vlog + +vlog = ovs.vlog.Vlog("daemon") # --detach: Should we run in the background? _detach = False @@ -121,7 +123,7 @@ def set_monitor(): def _fatal(msg): - logging.error(msg) + vlog.err(msg) sys.stderr.write("%s\n" % msg) sys.exit(1) @@ -139,7 +141,7 @@ def _make_pidfile(): # This is global to keep Python from garbage-collecting and # therefore closing our file after this function exits. That would # unlock the lock for us, and we don't want that. - global file + global file_handle file_handle = open(tmpfile, "w") except IOError, e: @@ -243,13 +245,19 @@ def _fork_and_wait_for_startup(): break if len(s) != 1: retval, status = _waitpid(pid, 0) - if (retval == pid and - os.WIFEXITED(status) and os.WEXITSTATUS(status)): - # Child exited with an error. Convey the same error to - # our parent process as a courtesy. - sys.exit(os.WEXITSTATUS(status)) + if retval == pid: + if os.WIFEXITED(status) and os.WEXITSTATUS(status): + # Child exited with an error. Convey the same error to + # our parent process as a courtesy. + sys.exit(os.WEXITSTATUS(status)) + else: + sys.stderr.write("fork child failed to signal " + "startup (%s)\n" + % ovs.process.status_msg(status)) else: - sys.stderr.write("fork child failed to signal startup\n") + assert retval < 0 + sys.stderr.write("waitpid failed (%s)\n" + % os.strerror(-retval)) sys.exit(1) os.close(rfd) @@ -306,13 +314,13 @@ def _monitor_daemon(daemon_pid): try: resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) except resource.error: - logging.warning("failed to disable core dumps") + vlog.warn("failed to disable core dumps") # Throttle restarts to no more than once every 10 seconds. if (last_restart is not None and ovs.timeval.msec() < last_restart + 10000): - logging.warning("%s, waiting until 10 seconds since last " - "restart" % status_msg) + vlog.warn("%s, waiting until 10 seconds since last " + "restart" % status_msg) while True: now = ovs.timeval.msec() wakeup = last_restart + 10000 @@ -322,12 +330,12 @@ def _monitor_daemon(daemon_pid): time.sleep((wakeup - now) / 1000.0) last_restart = ovs.timeval.msec() - logging.error("%s, restarting" % status_msg) + vlog.err("%s, restarting" % status_msg) daemon_pid = _fork_and_wait_for_startup() if not daemon_pid: break else: - logging.info("%s, exiting" % status_msg) + vlog.info("%s, exiting" % status_msg) sys.exit(0) # Running in new daemon process. @@ -411,7 +419,7 @@ def __read_pidfile(pidfile, delete_if_stale): except IOError, e: if e.errno == errno.ENOENT and delete_if_stale: return 0 - logging.warning("%s: open: %s" % (pidfile, e.strerror)) + vlog.warn("%s: open: %s" % (pidfile, e.strerror)) return -e.errno # Python fcntl doesn't directly support F_GETLK so we have to just try @@ -422,7 +430,7 @@ def __read_pidfile(pidfile, delete_if_stale): # pidfile exists but wasn't locked by anyone. Now we have the lock. if not delete_if_stale: file_handle.close() - logging.warning("%s: pid file is stale" % pidfile) + vlog.warn("%s: pid file is stale" % pidfile) return -errno.ESRCH # Is the file we have locked still named 'pidfile'? @@ -435,23 +443,23 @@ def __read_pidfile(pidfile, delete_if_stale): except IOError: raced = True if raced: - logging.warning("%s: lost race to delete pidfile" % pidfile) + vlog.warn("%s: lost race to delete pidfile" % pidfile) return -errno.EALREADY # We won the right to delete the stale pidfile. try: os.unlink(pidfile) except IOError, e: - logging.warning("%s: failed to delete stale pidfile (%s)" + vlog.warn("%s: failed to delete stale pidfile (%s)" % (pidfile, e.strerror)) return -e.errno else: - logging.debug("%s: deleted stale pidfile" % pidfile) + vlog.dbg("%s: deleted stale pidfile" % pidfile) file_handle.close() return 0 except IOError, e: if e.errno not in [errno.EACCES, errno.EAGAIN]: - logging.warn("%s: fcntl: %s" % (pidfile, e.strerror)) + vlog.warn("%s: fcntl: %s" % (pidfile, e.strerror)) return -e.errno # Someone else has the pidfile locked. @@ -459,10 +467,10 @@ def __read_pidfile(pidfile, delete_if_stale): try: error = int(file_handle.readline()) except IOError, e: - logging.warning("%s: read: %s" % (pidfile, e.strerror)) + vlog.warn("%s: read: %s" % (pidfile, e.strerror)) error = -e.errno except ValueError: - logging.warning("%s does not contain a pid" % pidfile) + vlog.warn("%s does not contain a pid" % pidfile) error = -errno.EINVAL return error @@ -487,26 +495,43 @@ def _check_already_running(): _fatal("%s: pidfile check failed (%s), aborting" % (_pidfile, os.strerror(pid))) -# XXX Python's getopt does not support options with optional arguments, so we -# have to separate --pidfile (with no argument) from --pidfile-name (with an -# argument). Need to write our own getopt I guess. -LONG_OPTIONS = ["detach", "no-chdir", "pidfile", "pidfile-name=", - "overwrite-pidfile", "monitor"] +def add_args(parser): + """Populates 'parser', an ArgumentParser allocated using the argparse + module, with the command line arguments required by the daemon module.""" + + pidfile = make_pidfile_name(None) + + group = parser.add_argument_group(title="Daemon Options") + group.add_argument("--detach", action="store_true", + help="Run in background as a daemon.") + group.add_argument("--no-chdir", action="store_true", + help="Do not chdir to '/'.") + group.add_argument("--monitor", action="store_true", + help="Monitor %s process." % ovs.util.PROGRAM_NAME) + group.add_argument("--pidfile", nargs="?", const=pidfile, + help="Create pidfile (default %s)." % pidfile) + group.add_argument("--overwrite-pidfile", action="store_true", + help="With --pidfile, start even if already running.") + + +def handle_args(args): + """Handles daemon module settings in 'args'. 'args' is an object + containing values parsed by the parse_args() method of ArgumentParser. The + parent ArgumentParser should have been prepared by add_args() before + calling parse_args().""" -def parse_opt(option, arg): - if option == '--detach': + if args.detach: set_detach() - elif option == '--no-chdir': + + if args.no_chdir: set_no_chdir() - elif option == '--pidfile': - set_pidfile(None) - elif option == '--pidfile-name': - set_pidfile(arg) - elif option == '--overwrite-pidfile': + + if args.pidfile: + set_pidfile(args.pidfile) + + if args.overwrite_pidfile: ignore_existing_pidfile() - elif option == '--monitor': + + if args.monitor: set_monitor() - else: - return False - return True