X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fvlog-socket.c;h=0dc836f53891691514dd0a2d3037ea971f18aaf5;hb=9ebcf1a3d7524aea36c506f7c0e37bfaa1908dae;hp=7fffc13170ad68db3d086e74394e3f2e0e34119c;hpb=26d6b159f3b9d624992f5da432fa8f7f9ac897c5;p=sliver-openvswitch.git diff --git a/lib/vlog-socket.c b/lib/vlog-socket.c index 7fffc1317..0dc836f53 100644 --- a/lib/vlog-socket.c +++ b/lib/vlog-socket.c @@ -33,6 +33,7 @@ #include #include "vlog-socket.h" +#include #include #include #include @@ -43,16 +44,19 @@ #include #include #include +#include "daemon.h" #include "fatal-signal.h" #include "poll-loop.h" #include "socket-util.h" #include "timeval.h" #include "util.h" -#include "vlog.h" #ifndef SCM_CREDENTIALS #include #endif + +#define THIS_MODULE VLM_vlog_socket +#include "vlog.h" /* Server for Vlog control connection. */ struct vlog_server { @@ -75,6 +79,11 @@ static void poll_server(int fd, short int events, void *server_); * - An absolute path (starting with '/') that gives the exact name of * the Unix domain socket to listen on. * + * A program that (optionally) daemonizes itself should call this function + * *after* daemonization, so that the socket name contains the pid of the + * daemon instead of the pid of the program that exited. (Otherwise, "vlogconf + * --target .pid" will fail.) + * * Returns 0 if successful, otherwise a positive errno value. If successful, * sets '*serverp' to the new vlog_server, otherwise to NULL. */ int @@ -256,6 +265,12 @@ poll_server(int fd UNUSED, short int events, void *server_) reply = msg ? msg : xstrdup("ack"); } else if (!strcmp(cmd_buf, "list")) { reply = vlog_get_levels(); + } else if (!strcmp(cmd_buf, "reopen")) { + int error = vlog_reopen_log_file(); + reply = (error + ? xasprintf("could not reopen log file \"%s\": %s", + vlog_get_log_file(), strerror(error)) + : xstrdup("ack")); } else { reply = xstrdup("nak"); } @@ -274,11 +289,18 @@ struct vlog_client { int fd; }; -/* Connects to a Vlog server socket. If 'path' does not start with '/', then - * it start with a PID as a string. If a non-null, non-absolute name was - * passed to Vlog_server_socket::listen(), then it must follow the PID in - * 'path'. If 'path' starts with '/', then it must be an absolute path that - * gives the exact name of the Unix domain socket to connect to. +/* Connects to a Vlog server socket. 'path' may be: + * + * - A string that starts with a PID. If a non-null, non-absolute name + * was passed to Vlog_server_socket::listen(), then it must follow the + * PID in 'path'. + * + * - An absolute path (starting with '/') to a Vlog server socket or a + * pidfile. If it is a pidfile, the pidfile will be read and translated + * into a Vlog server socket file name. + * + * - A relative path, which is translated into a pidfile name and then + * treated as above. * * Returns 0 if successful, otherwise a positive errno value. If successful, * sets '*clientp' to the new vlog_client, otherwise to NULL. */ @@ -287,29 +309,52 @@ vlog_client_connect(const char *path, struct vlog_client **clientp) { static int counter; struct vlog_client *client; - int fd; + struct stat s; + int error; client = xmalloc(sizeof *client); - client->connect_path = (path[0] == '/' - ? xstrdup(path) - : xasprintf("/tmp/vlogs.%s", path)); - - client->bind_path = xasprintf("/tmp/vlog.%ld.%d", - (long int) getpid(), counter++); - fd = make_unix_socket(SOCK_DGRAM, false, false, - client->bind_path, client->connect_path); - - if (fd >= 0) { - client->fd = fd; - *clientp = client; - return 0; + if (path[0] == '/') { + client->connect_path = xstrdup(path); + } else if (isdigit((unsigned char) path[0])) { + client->connect_path = xasprintf("/tmp/vlogs.%s", path); } else { + client->connect_path = make_pidfile_name(path); + } + client->bind_path = NULL; + + if (stat(client->connect_path, &s)) { + error = errno; + VLOG_WARN("could not stat \"%s\": %s", + client->connect_path, strerror(error)); + goto error; + } else if (S_ISREG(s.st_mode)) { + pid_t pid = read_pidfile(client->connect_path); + if (pid < 0) { + error = -pid; + VLOG_WARN("could not read pidfile \"%s\": %s", + client->connect_path, strerror(error)); + goto error; + } free(client->connect_path); - free(client->bind_path); - free(client); - *clientp = NULL; - return errno; + client->connect_path = xasprintf("/tmp/vlogs.%ld", (long int) pid); + } + client->bind_path = xasprintf("/tmp/vlog.%ld.%d", + (long int) getpid(), counter++); + client->fd = make_unix_socket(SOCK_DGRAM, false, false, + client->bind_path, client->connect_path); + if (client->fd < 0) { + error = -client->fd; + goto error; } + *clientp = client; + return 0; + +error: + free(client->connect_path); + free(client->bind_path); + free(client); + *clientp = NULL; + return error; } /* Destroys 'client'. */