2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-19 14:37:21 +00:00

daemon: Avoid redundant code in already_running().

This function substantially duplicated read_pidfile(), so reuse that
code instead.
This commit is contained in:
Ben Pfaff
2011-03-29 09:44:55 -07:00
parent 2159de8391
commit 18e124a20b
3 changed files with 48 additions and 60 deletions

View File

@@ -139,37 +139,17 @@ daemon_set_monitor(void)
monitor = true; monitor = true;
} }
/* If a pidfile has been configured and that pidfile already exists and is
* locked by a running process, returns the pid of the running process.
* Otherwise, returns 0. */
static pid_t
already_running(void)
{
pid_t pid = 0;
if (pidfile) {
int fd = open(pidfile, O_RDWR);
if (fd >= 0) {
struct flock lck;
lck.l_type = F_WRLCK;
lck.l_whence = SEEK_SET;
lck.l_start = 0;
lck.l_len = 0;
if (fcntl(fd, F_GETLK, &lck) != -1 && lck.l_type != F_UNLCK) {
pid = lck.l_pid;
}
close(fd);
}
}
return pid;
}
/* If a locked pidfile exists, issue a warning message and, unless /* If a locked pidfile exists, issue a warning message and, unless
* ignore_existing_pidfile() has been called, terminate the program. */ * ignore_existing_pidfile() has been called, terminate the program. */
void void
die_if_already_running(void) die_if_already_running(void)
{ {
pid_t pid = already_running(); pid_t pid;
if (pid) { if (!pidfile) {
return;
}
pid = read_pidfile_if_exists(pidfile);
if (pid > 0) {
if (!overwrite_pidfile) { if (!overwrite_pidfile) {
VLOG_ERR("%s: %s already running as pid %ld, aborting", VLOG_ERR("%s: %s already running as pid %ld, aborting",
get_pidfile(), program_name, (long int) pid); get_pidfile(), program_name, (long int) pid);
@@ -509,10 +489,8 @@ daemon_usage(void)
ovs_rundir(), program_name); ovs_rundir(), program_name);
} }
/* Opens and reads a PID from 'pidfile'. Returns the nonnegative PID if static pid_t
* successful, otherwise a negative errno value. */ read_pidfile__(const char *pidfile, bool must_exist)
pid_t
read_pidfile(const char *pidfile)
{ {
char line[128]; char line[128];
struct flock lck; struct flock lck;
@@ -533,6 +511,9 @@ read_pidfile(const char *pidfile)
file = fopen(pidfile, "r"); file = fopen(pidfile, "r");
if (!file) { if (!file) {
if (errno == ENOENT && !must_exist) {
return 0;
}
error = errno; error = errno;
VLOG_WARN("%s: open: %s", pidfile, strerror(error)); VLOG_WARN("%s: open: %s", pidfile, strerror(error));
goto error; goto error;
@@ -581,3 +562,21 @@ error:
} }
return -error; return -error;
} }
/* Opens and reads a PID from 'pidfile'. Returns the positive PID if
* successful, otherwise a negative errno value. */
pid_t
read_pidfile(const char *pidfile)
{
return read_pidfile__(pidfile, true);
}
/* Opens and reads a PID from 'pidfile', if it exists. Returns 0 if 'pidfile'
* doesn't exist, the positive PID if successful, otherwise a negative errno
* value. */
pid_t
read_pidfile_if_exists(const char *pidfile)
{
return read_pidfile__(pidfile, false);
}

View File

@@ -71,5 +71,6 @@ void die_if_already_running(void);
void ignore_existing_pidfile(void); void ignore_existing_pidfile(void);
void daemon_usage(void); void daemon_usage(void);
pid_t read_pidfile(const char *name); pid_t read_pidfile(const char *name);
pid_t read_pidfile_if_exists(const char *name);
#endif /* daemon.h */ #endif /* daemon.h */

View File

@@ -111,37 +111,15 @@ def set_monitor():
global _monitor global _monitor
_monitor = True _monitor = True
def _already_running():
"""If a pidfile has been configured and that pidfile already exists and is
locked by a running process, returns True. Otherwise, returns False."""
if _pidfile is not None:
try:
file = open(_pidfile, "r+")
try:
try:
fcntl.lockf(file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError, e:
if e.errno in [errno.EACCES, errno.EAGAIN]:
return True
logging.error("error locking %s (%s)"
% (_pidfile, os.strerror(e.errno)))
return False
finally:
# This releases the lock, which we don't really want.
file.close()
except IOError, e:
if e.errno == errno.ENOENT:
return False
logging.error("error opening %s (%s)"
% (_pidfile, os.strerror(e.errno)))
return False
def die_if_already_running(): def die_if_already_running():
"""If a locked pidfile exists, issue a warning message and, unless """If a locked pidfile exists, issue a warning message and, unless
ignore_existing_pidfile() has been called, terminate the program.""" ignore_existing_pidfile() has been called, terminate the program."""
if _already_running(): if _pidfile is None:
return
pid = read_pidfile_if_exists(_pidfile)
if pid > 0:
if not _overwrite_pidfile: if not _overwrite_pidfile:
msg = "%s: already running" % _pidfile msg = "%s: already running as pid %d" % (_pidfile, pid)
logging.error("%s, aborting" % msg) logging.error("%s, aborting" % msg)
sys.stderr.write("%s\n" % msg) sys.stderr.write("%s\n" % msg)
sys.exit(1) sys.exit(1)
@@ -382,9 +360,7 @@ Daemon options:
--overwrite-pidfile with --pidfile, start even if already running --overwrite-pidfile with --pidfile, start even if already running
""" % (ovs.dirs.RUNDIR, ovs.util.PROGRAM_NAME)) """ % (ovs.dirs.RUNDIR, ovs.util.PROGRAM_NAME))
def read_pidfile(pidfile): def __read_pidfile(pidfile, must_exist):
"""Opens and reads a PID from 'pidfile'. Returns the nonnegative PID if
successful, otherwise a negative errno value."""
if _pidfile_dev is not None: if _pidfile_dev is not None:
try: try:
s = os.stat(pidfile) s = os.stat(pidfile)
@@ -401,6 +377,8 @@ def read_pidfile(pidfile):
try: try:
file = open(pidfile, "r") file = open(pidfile, "r")
except IOError, e: except IOError, e:
if e.errno == errno.ENOENT and not must_exist:
return 0
logging.warning("%s: open: %s" % (pidfile, os.strerror(e.errno))) logging.warning("%s: open: %s" % (pidfile, os.strerror(e.errno)))
return -e.errno return -e.errno
@@ -437,6 +415,16 @@ def read_pidfile(pidfile):
except IOError: except IOError:
pass pass
def read_pidfile(pidfile):
"""Opens and reads a PID from 'pidfile'. Returns the positive PID if
successful, otherwise a negative errno value."""
return __read_pidfile(pidfile, True)
def read_pidfile_if_exists(pidfile):
"""Opens and reads a PID from 'pidfile'. Returns 0 if 'pidfile' does not
exist, the positive PID if successful, otherwise a negative errno value."""
return __read_pidfile(pidfile, False)
# XXX Python's getopt does not support options with optional arguments, so we # 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 # have to separate --pidfile (with no argument) from --pidfile-name (with an
# argument). Need to write our own getopt I guess. # argument). Need to write our own getopt I guess.