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:
59
lib/daemon.c
59
lib/daemon.c
@@ -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);
|
||||||
|
}
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user