mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
ovsdb-server: Maintain the database lock with --detach.
Before this commit, "ovsdb-server --detach" would detach after it opened the database file, which meant that the child process did not hold the file lock on the database file (because a forked child process does not inherit its parents' locks). This commit fixes the problem by making ovsdb-server open the database only after it has detached. This fix, in turn, required that daemonize() not chdir to /, because this would break databases whose names are given relative to the current directory, and so this commit also changes ovsdb-server to do so later.
This commit is contained in:
14
lib/daemon.c
14
lib/daemon.c
@@ -81,6 +81,13 @@ set_no_chdir(void)
|
|||||||
chdir_ = false;
|
chdir_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Will we chdir to "/" as part of daemonizing? */
|
||||||
|
bool
|
||||||
|
is_chdir_enabled(void)
|
||||||
|
{
|
||||||
|
return chdir_;
|
||||||
|
}
|
||||||
|
|
||||||
/* Normally, die_if_already_running() will terminate the program with a message
|
/* Normally, die_if_already_running() will terminate the program with a message
|
||||||
* if a locked pidfile already exists. If this function is called,
|
* if a locked pidfile already exists. If this function is called,
|
||||||
* die_if_already_running() will merely log a warning. */
|
* die_if_already_running() will merely log a warning. */
|
||||||
@@ -98,6 +105,13 @@ set_detach(void)
|
|||||||
detach = true;
|
detach = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Will daemonize() really detach? */
|
||||||
|
bool
|
||||||
|
get_detach(void)
|
||||||
|
{
|
||||||
|
return detach;
|
||||||
|
}
|
||||||
|
|
||||||
/* If a pidfile has been configured and that pidfile already exists and is
|
/* 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.
|
* locked by a running process, returns the pid of the running process.
|
||||||
* Otherwise, returns 0. */
|
* Otherwise, returns 0. */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Nicira Networks.
|
* Copyright (c) 2008, 2009 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -55,7 +55,9 @@ char *make_pidfile_name(const char *name);
|
|||||||
void set_pidfile(const char *name);
|
void set_pidfile(const char *name);
|
||||||
const char *get_pidfile(void);
|
const char *get_pidfile(void);
|
||||||
void set_no_chdir(void);
|
void set_no_chdir(void);
|
||||||
|
bool is_chdir_enabled(void);
|
||||||
void set_detach(void);
|
void set_detach(void);
|
||||||
|
bool get_detach(void);
|
||||||
void daemonize(void);
|
void daemonize(void);
|
||||||
void die_if_already_running(void);
|
void die_if_already_running(void);
|
||||||
void ignore_existing_pidfile(void);
|
void ignore_existing_pidfile(void);
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "command-line.h"
|
#include "command-line.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
@@ -59,6 +60,7 @@ main(int argc, char *argv[])
|
|||||||
struct ovsdb *db;
|
struct ovsdb *db;
|
||||||
const char *name;
|
const char *name;
|
||||||
char *file_name;
|
char *file_name;
|
||||||
|
bool do_chdir;
|
||||||
int retval;
|
int retval;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@@ -71,6 +73,20 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
parse_options(argc, argv, &file_name, &active, &passive);
|
parse_options(argc, argv, &file_name, &active, &passive);
|
||||||
|
|
||||||
|
if (get_detach() && is_chdir_enabled()) {
|
||||||
|
/* We need to skip chdir("/") in daemonize() and do it later, because
|
||||||
|
* we need to open the database and possible set up up Unix domain
|
||||||
|
* sockets in the current working directory after we daemonize. We
|
||||||
|
* can't open the database before we daemonize because file locks
|
||||||
|
* aren't inherited by child processes. */
|
||||||
|
do_chdir = true;
|
||||||
|
set_no_chdir();
|
||||||
|
} else {
|
||||||
|
do_chdir = false;
|
||||||
|
}
|
||||||
|
die_if_already_running();
|
||||||
|
daemonize();
|
||||||
|
|
||||||
error = ovsdb_file_open(file_name, false, &db);
|
error = ovsdb_file_open(file_name, false, &db);
|
||||||
if (error) {
|
if (error) {
|
||||||
ovs_fatal(0, "%s", ovsdb_error_to_string(error));
|
ovs_fatal(0, "%s", ovsdb_error_to_string(error));
|
||||||
@@ -89,14 +105,14 @@ main(int argc, char *argv[])
|
|||||||
svec_destroy(&active);
|
svec_destroy(&active);
|
||||||
svec_destroy(&passive);
|
svec_destroy(&passive);
|
||||||
|
|
||||||
die_if_already_running();
|
|
||||||
daemonize();
|
|
||||||
|
|
||||||
retval = unixctl_server_create(NULL, &unixctl);
|
retval = unixctl_server_create(NULL, &unixctl);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
ovs_fatal(retval, "could not listen for control connections");
|
ovs_fatal(retval, "could not listen for control connections");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_chdir) {
|
||||||
|
chdir("/");
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ovsdb_jsonrpc_server_run(jsonrpc);
|
ovsdb_jsonrpc_server_run(jsonrpc);
|
||||||
unixctl_server_run(unixctl);
|
unixctl_server_run(unixctl);
|
||||||
|
Reference in New Issue
Block a user