public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2/daemons/common daemon-client.h daemon-ser ...
@ 2011-05-13 8:07 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-05-13 8:07 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-05-13 08:07:29
Added files:
daemons/common : daemon-client.h daemon-server.h
Log message:
First stab at the prototypes of the daemon-common functionality (to be
eventually shared by dmeventd, lvmetad and clvmd).
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-client.h.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.h.diff?cvsroot=lvm2&r1=NONE&r2=1.1
/cvs/lvm2/LVM2/daemons/common/daemon-client.h,v --> standard output
revision 1.1
--- LVM2/daemons/common/daemon-client.h
+++ - 2011-05-13 08:07:30.026952000 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_DAEMON_COMMON_CLIENT_H
+#define _LVM_DAEMON_COMMON_CLIENT_H
+
+typedef struct {
+ int socket_fd; /* the fd we use to talk to the daemon */
+ int protocol; /* version of the protocol the daemon uses */
+ char *read_buf;
+} daemon_handle;
+
+typedef struct {
+ const char *path; /* the binary of the daemon */
+ const char *socket; /* path to the comms socket */
+ unsigned autostart:1; /* start the daemon if not running? */
+} daemon_info;
+
+typedef struct {
+ char *request;
+} daemon_request;
+
+typedef struct {
+ int errno; /* 0 for success */
+ char *reply; /* textual reply */
+ struct config_tree *cft; /* parsed reply, if available */
+} daemon_reply;
+
+/*
+ * Open the communication channel to the daemon. If the daemon is not running,
+ * it may be autostarted based on the binary path provided in the info (this
+ * will only happen if autostart is set to true). If the call fails for any
+ * reason, daemon_handle_valid(h) for the response will return false. Otherwise,
+ * the connection is good to start serving requests.
+ */
+daemon_handle daemon_open(daemon_info i);
+
+/*
+ * Send a request to the daemon, waiting for the reply. All communication with
+ * the daemon is synchronous. The function handles the IO details and parses the
+ * response, handling common error conditions. See "daemon_reply" for details.
+ */
+daemon_reply daemon_request(daemon_handle h, daemon_request r);
+
+/* Shut down the communication to the daemon. Compulsory. */
+void daemon_close(daemon_handle h);
+
+#endif
/cvs/lvm2/LVM2/daemons/common/daemon-server.h,v --> standard output
revision 1.1
--- LVM2/daemons/common/daemon-server.h
+++ - 2011-05-13 08:07:30.411524000 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LVM_DAEMON_COMMON_CLIENT_H
+#define _LVM_DAEMON_COMMON_CLIENT_H
+
+typedef struct {
+ int socket_fd; /* the fd we use to talk to the client */
+ pthread_t thread_id;
+ char *read_buf;
+ void *private; /* this holds per-client state */
+} client_handle;
+
+typedef struct {
+ void *private; /* the global daemon state */
+} daemon_state;
+
+typedef struct {
+ struct config_tree *cft;
+} request;
+
+typedef struct {
+ struct config_tree *cft;
+} response;
+
+/*
+ * The callback. Called once per request issued, in the respective client's
+ * thread. It is presented by a parsed request (in the form of a config tree).
+ * The output is a new config tree that is serialised and sent back to the
+ * client. The client blocks until the request processing is done and reply is
+ * sent.
+ */
+typedef response (*handle_request)(daemon_state s, client_handle h, request r);
+
+/*
+ * Start serving the requests. This does all the daemonisation, socket setup
+ * work and so on.
+ */
+void daemon_start(daemon_state s, handle_request r);
+
+/*
+ * Take over from an already running daemon. This function handles connecting
+ * to the running daemon and telling it we are going to take over. The takeover
+ * request may be customised by passing in a non-NULL request.
+ *
+ * The takeover sequence: the old daemon stops accepting new clients, then it
+ * waits until all current client connections are closed. When that happens, it
+ * serializes its current state and sends that as a reply, which is then
+ * returned by this function (therefore, this function won't return until the
+ * previous instance has shut down).
+ *
+ * The daemon, after calling daemon_takeover is expected to set up its
+ * daemon_state using the reply from this function and call daemon_start as
+ * usual.
+ */
+daemon_reply daemon_takeover(daemon_info i, daemon_request r);
+
+/* Call this to request a clean shutdown of the daemon. Async safe. */
+void daemon_stop();
+
+#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2/daemons/common daemon-client.h daemon-ser ...
@ 2011-05-15 11:02 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-05-15 11:02 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-05-15 11:02:29
Modified files:
daemons/common : daemon-client.h daemon-server.c daemon-server.h
Log message:
More work on the common daemon framework. Make things compile, too.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-client.h.diff?cvsroot=lvm2&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.h.diff?cvsroot=lvm2&r1=1.3&r2=1.4
--- LVM2/daemons/common/daemon-client.h 2011/05/13 08:07:28 1.1
+++ LVM2/daemons/common/daemon-client.h 2011/05/15 11:02:29 1.2
@@ -32,7 +32,7 @@
} daemon_request;
typedef struct {
- int errno; /* 0 for success */
+ int error; /* 0 for success */
char *reply; /* textual reply */
struct config_tree *cft; /* parsed reply, if available */
} daemon_reply;
@@ -51,7 +51,7 @@
* the daemon is synchronous. The function handles the IO details and parses the
* response, handling common error conditions. See "daemon_reply" for details.
*/
-daemon_reply daemon_request(daemon_handle h, daemon_request r);
+daemon_reply daemon_send(daemon_handle h, daemon_request r);
/* Shut down the communication to the daemon. Compulsory. */
void daemon_close(daemon_handle h);
--- LVM2/daemons/common/daemon-server.c 2011/05/13 09:34:12 1.2
+++ LVM2/daemons/common/daemon-server.c 2011/05/15 11:02:29 1.3
@@ -18,11 +18,16 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <netinet/in.h>
+#include <sys/un.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
+#include "daemon-server.h"
+#include "libdevmapper.h"
+#if 0
/* Create a device monitoring thread. */
static int _pthread_create(pthread_t *t, void *(*fun)(void *), void *arg, int stacksize)
{
@@ -34,6 +39,7 @@
pthread_attr_setstacksize(&attr, stacksize);
return pthread_create(t, &attr, fun, arg);
}
+#endif
static volatile sig_atomic_t _shutdown_requested = 0;
@@ -44,6 +50,7 @@
#ifdef linux
# define OOM_ADJ_FILE "/proc/self/oom_adj"
+# include <stdio.h>
/* From linux/oom.h */
# define OOM_DISABLE (-17)
@@ -72,7 +79,7 @@
}
fprintf(fp, "%i", val);
- if (dm_fclose(fp))
+ if (fclose(fp))
perror(OOM_ADJ_FILE ": fclose failed");
return 1;
@@ -91,13 +98,13 @@
/* Open local socket */
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
- log_error("Can't create local socket: %m");
+ perror("Can't create local socket.");
goto error;
}
/* Set Close-on-exec & non-blocking */
if (fcntl(fd, F_SETFD, 1))
- DEBUGLOG("setting CLOEXEC on socket fd %d failed: %s\n", fd, strerror(errno));
+ fprintf(stderr, "setting CLOEXEC on socket fd %d failed: %s\n", fd, strerror(errno));
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
memset(&sockaddr, 0, sizeof(sockaddr));
@@ -105,11 +112,11 @@
sockaddr.sun_family = AF_UNIX;
if (bind(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
- log_error("can't bind local socket: %m");
+ perror("can't bind local socket.");
goto error;
}
if (listen(fd, 1) != 0) {
- log_error("listen local: %m");
+ perror("listen local");
goto error;
}
@@ -129,7 +136,7 @@
static void remove_lockfile(const char *file)
{
if (unlink(file))
- perror(file ": unlink failed");
+ perror("unlink failed");
}
static void _daemonise(void)
@@ -158,7 +165,7 @@
default:
/* Wait for response from child */
- while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
+ while (!waitpid(pid, &child_status, WNOHANG) && !_shutdown_requested) {
tval.tv_sec = 0;
tval.tv_usec = 250000; /* .25 sec */
select(0, NULL, NULL, NULL, &tval);
@@ -168,16 +175,7 @@
exit(0);
/* Problem with child. Determine what it is by exit code */
- switch (WEXITSTATUS(child_status)) {
- case EXIT_DESC_CLOSE_FAILURE:
- case EXIT_DESC_OPEN_FAILURE:
- case EXIT_FIFO_FAILURE:
- case EXIT_CHDIR_FAILURE:
- default:
- fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
- break;
- }
-
+ fprintf(stderr, "Child exited with code %d\n", WEXITSTATUS(child_status));
exit(WEXITSTATUS(child_status));
}
@@ -200,7 +198,7 @@
setsid();
}
-void daemon_start(daemon_state s, handle_request r)
+void daemon_start(daemon_state s)
{
int failed = 0;
/*
--- LVM2/daemons/common/daemon-server.h 2011/05/13 09:34:12 1.3
+++ LVM2/daemons/common/daemon-server.h 2011/05/15 11:02:29 1.4
@@ -12,8 +12,10 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _LVM_DAEMON_COMMON_CLIENT_H
-#define _LVM_DAEMON_COMMON_CLIENT_H
+#include "daemon-client.h"
+
+#ifndef _LVM_DAEMON_COMMON_SERVER_H
+#define _LVM_DAEMON_COMMON_SERVER_H
typedef struct {
int socket_fd; /* the fd we use to talk to the client */
@@ -23,6 +25,26 @@
} client_handle;
typedef struct {
+ struct config_tree *cft;
+} request;
+
+typedef struct {
+ int error;
+ struct config_tree *cft;
+} response;
+
+struct daemon_state;
+
+/*
+ * The callback. Called once per request issued, in the respective client's
+ * thread. It is presented by a parsed request (in the form of a config tree).
+ * The output is a new config tree that is serialised and sent back to the
+ * client. The client blocks until the request processing is done and reply is
+ * sent.
+ */
+typedef response (*handle_request)(struct daemon_state s, client_handle h, request r);
+
+typedef struct daemon_state {
/*
* The maximal stack size for individual daemon threads. This is
* essential for daemons that need to be locked into memory, since
@@ -36,6 +58,9 @@
const char *name;
const char *pidfile;
const char *socket_path;
+ int log_level;
+ handle_request handler;
+ int (*setup_post)(struct daemon_state *st);
/* Global runtime info maintained by the framework. */
int socket_fd;
@@ -43,29 +68,12 @@
void *private; /* the global daemon state */
} daemon_state;
-typedef struct {
- struct config_tree *cft;
-} request;
-
-typedef struct {
- struct config_tree *cft;
-} response;
-
-/*
- * The callback. Called once per request issued, in the respective client's
- * thread. It is presented by a parsed request (in the form of a config tree).
- * The output is a new config tree that is serialised and sent back to the
- * client. The client blocks until the request processing is done and reply is
- * sent.
- */
-typedef response (*handle_request)(daemon_state s, client_handle h, request r);
-
/*
* Start serving the requests. This does all the daemonisation, socket setup
* work and so on. This function takes over the process, and upon failure, it
* will terminate execution. It may be called at most once.
*/
-void daemon_start(daemon_state s, handle_request r);
+void daemon_start(daemon_state s);
/*
* Take over from an already running daemon. This function handles connecting
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2/daemons/common daemon-client.h daemon-ser ...
@ 2011-06-14 2:34 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-06-14 2:34 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-06-14 02:34:18
Modified files:
daemons/common : daemon-client.h daemon-server.c daemon-server.h
Added files:
daemons/common : daemon-client.c daemon-shared.c daemon-shared.h
Log message:
Common daemon code: Implement basic socket-based communication infrastructure
(both client and server side). The server handles each connection in a separate
thread.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-client.c.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-shared.c.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-shared.h.diff?cvsroot=lvm2&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-client.h.diff?cvsroot=lvm2&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.h.diff?cvsroot=lvm2&r1=1.4&r2=1.5
/cvs/lvm2/LVM2/daemons/common/daemon-client.c,v --> standard output
revision 1.1
--- LVM2/daemons/common/daemon-client.c
+++ - 2011-06-14 02:34:19.031404000 +0000
@@ -0,0 +1,54 @@
+#include "daemon-client.h"
+#include "daemon-shared.h"
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+daemon_handle daemon_open(daemon_info i) {
+ daemon_handle h;
+ struct sockaddr_un sockaddr;
+ if ((h.socket_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) {
+ perror("socket");
+ goto error;
+ }
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ fprintf(stderr, "connecting to %s\n", i.socket);
+ strcpy(sockaddr.sun_path, i.socket);
+ sockaddr.sun_family = AF_UNIX;
+ if (connect(h.socket_fd,(struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
+ perror("connect");
+ goto error;
+ }
+ h.protocol = 0;
+ return h;
+error:
+ if (h.socket_fd >= 0)
+ close(h.socket_fd);
+ h.socket_fd = -1;
+ return h;
+}
+
+daemon_reply daemon_send(daemon_handle h, daemon_request rq)
+{
+ daemon_reply reply;
+ assert(h.socket_fd >= 0);
+
+ if (!rq.buffer) {
+ /* TODO: build the buffer from rq.cft */
+ }
+
+ assert(rq.buffer);
+ write_buffer(h.socket_fd, rq.buffer, strlen(rq.buffer));
+
+ if (read_buffer(h.socket_fd, &reply.buffer)) {
+ /* TODO: parse reply.buffer into reply.cft */
+ } else
+ reply.error = 1;
+
+ return reply;
+}
+
+void daemon_close(daemon_handle h) {
+}
/cvs/lvm2/LVM2/daemons/common/daemon-shared.c,v --> standard output
revision 1.1
--- LVM2/daemons/common/daemon-shared.c
+++ - 2011-06-14 02:34:19.142467000 +0000
@@ -0,0 +1,68 @@
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+
+/*
+ * Read a single message from a (socket) filedescriptor. Messages are delimited
+ * by blank lines. This call will block until all of a message is received. The
+ * memory will be allocated from heap. Upon error, all memory is freed and the
+ * buffer pointer is set to NULL.
+ */
+int read_buffer(int fd, char **buffer) {
+ int bytes = 0;
+ int buffersize = 32;
+ *buffer = malloc(buffersize + 1);
+
+ while (1) {
+ int result = read(fd, (*buffer) + bytes, buffersize - bytes);
+ if (result > 0)
+ bytes += result;
+ if (result == 0)
+ goto fail; /* we should never encounter EOF here */
+ if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
+ goto fail;
+
+ if (bytes == buffersize) {
+ buffersize += 1024;
+ char *new = realloc(*buffer, buffersize + 1);
+ if (new)
+ *buffer = new;
+ else
+ goto fail;
+ } else {
+ (*buffer)[bytes] = 0;
+ char *end;
+ if ((end = strstr((*buffer) + bytes - 2, "\n\n"))) {
+ *end = 0;
+ break; /* success, we have the full message now */
+ }
+ /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
+ }
+ }
+ return 1;
+fail:
+ free(*buffer);
+ *buffer = NULL;
+ return 0;
+}
+
+/*
+ * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
+ * SOCK_NONBLOCK) until all of the write went through.
+ *
+ * TODO use select on EWOULDBLOCK/EAGAIN to avoid useless spinning
+ */
+int write_buffer(int fd, char *buffer, int length) {
+ int written = 0;
+ while (1) {
+ int result = write(fd, buffer + written, length - written);
+ if (result > 0)
+ written += result;
+ if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
+ break; /* too bad */
+ if (written == length)
+ return 1; /* done */
+ }
+ return 0;
+}
/cvs/lvm2/LVM2/daemons/common/daemon-shared.h,v --> standard output
revision 1.1
--- LVM2/daemons/common/daemon-shared.h
+++ - 2011-06-14 02:34:19.240114000 +0000
@@ -0,0 +1,2 @@
+int read_buffer(int fd, char **buffer);
+int write_buffer(int fd, char *buffer, int length);
--- LVM2/daemons/common/daemon-client.h 2011/05/15 11:02:29 1.2
+++ LVM2/daemons/common/daemon-client.h 2011/06/14 02:34:18 1.3
@@ -12,6 +12,8 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h" // should become part of libdevmapper later
+
#ifndef _LVM_DAEMON_COMMON_CLIENT_H
#define _LVM_DAEMON_COMMON_CLIENT_H
@@ -28,13 +30,14 @@
} daemon_info;
typedef struct {
- char *request;
+ char *buffer;
+ struct config_node *cft;
} daemon_request;
typedef struct {
int error; /* 0 for success */
- char *reply; /* textual reply */
- struct config_tree *cft; /* parsed reply, if available */
+ char *buffer; /* textual reply */
+ struct config_node *cft; /* parsed reply, if available */
} daemon_reply;
/*
--- LVM2/daemons/common/daemon-server.c 2011/05/15 11:02:29 1.3
+++ LVM2/daemons/common/daemon-server.c 2011/06/14 02:34:18 1.4
@@ -107,8 +107,9 @@
fprintf(stderr, "setting CLOEXEC on socket fd %d failed: %s\n", fd, strerror(errno));
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
+ fprintf(stderr, "creating %s\n", s.socket_path);
memset(&sockaddr, 0, sizeof(sockaddr));
- memcpy(sockaddr.sun_path, s.socket_path, strlen(s.socket_path));
+ strcpy(sockaddr.sun_path, s.socket_path);
sockaddr.sun_family = AF_UNIX;
if (bind(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
@@ -128,6 +129,7 @@
error:
if (fd >= 0) {
close(fd);
+ unlink(s.socket_path);
fd = -1;
}
goto out;
@@ -198,6 +200,60 @@
setsid();
}
+struct thread_baton {
+ daemon_state s;
+ client_handle client;
+};
+
+void *client_thread(void *baton)
+{
+ struct thread_baton *b = baton;
+ request req;
+ while (1) {
+ if (!read_buffer(b->client.socket_fd, &req.buffer))
+ goto fail;
+
+ /* TODO parse the buffer into req.cft */
+ response res = b->s.handler(b->s, b->client, req);
+
+ if (!res.buffer) {
+ /* TODO fill in the buffer from res.cft */
+ }
+
+ write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
+
+ free(res.buffer);
+ free(req.buffer);
+ }
+fail:
+ /* TODO what should we really do here? */
+ return NULL;
+}
+
+int handle_connect(daemon_state s)
+{
+ struct sockaddr_un sockaddr;
+ client_handle client;
+ socklen_t sl = sizeof(sockaddr);
+ int client_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
+ if (client_fd < 0)
+ return 0;
+
+ struct thread_baton *baton = malloc(sizeof(struct thread_baton));
+ if (!baton)
+ return 0;
+
+ client.socket_fd = client_fd;
+ client.read_buf = 0;
+ client.private = 0;
+ baton->s = s;
+ baton->client = client;
+
+ if (pthread_create(&baton->client.thread_id, NULL, client_thread, baton))
+ return 0;
+ return 1;
+}
+
void daemon_start(daemon_state s)
{
int failed = 0;
@@ -230,6 +286,8 @@
signal(SIGINT, &_exit_handler);
signal(SIGHUP, &_exit_handler);
signal(SIGQUIT, &_exit_handler);
+ signal(SIGTERM, &_exit_handler);
+ signal(SIGPIPE, SIG_IGN);
#ifdef linux
if (s.avoid_oom && !_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
@@ -247,9 +305,20 @@
kill(getppid(), SIGTERM);
while (!_shutdown_requested && !failed) {
- /* TODO: do work */
+ int status;
+ fd_set in;
+ FD_ZERO(&in);
+ FD_SET(s.socket_fd, &in);
+ if (select(FD_SETSIZE, &in, NULL, NULL, NULL) < 0 && errno != EINTR)
+ perror("select error");
+ if (FD_ISSET(s.socket_fd, &in))
+ if (!handle_connect(s))
+ syslog(LOG_ERR, "Failed to handle a client connection.");
}
+ if (s.socket_fd >= 0)
+ unlink(s.socket_path);
+
syslog(LOG_NOTICE, "%s shutting down", s.name);
closelog();
remove_lockfile(s.pidfile);
--- LVM2/daemons/common/daemon-server.h 2011/05/15 11:02:29 1.4
+++ LVM2/daemons/common/daemon-server.h 2011/06/14 02:34:18 1.5
@@ -13,6 +13,7 @@
*/
#include "daemon-client.h"
+#include "config.h" // XXX will be in libdevmapper.h later
#ifndef _LVM_DAEMON_COMMON_SERVER_H
#define _LVM_DAEMON_COMMON_SERVER_H
@@ -25,12 +26,14 @@
} client_handle;
typedef struct {
- struct config_tree *cft;
+ struct config_node *cft;
+ char *buffer;
} request;
typedef struct {
int error;
- struct config_tree *cft;
+ struct config_node *cft;
+ char *buffer;
} response;
struct daemon_state;
^ permalink raw reply [flat|nested] 4+ messages in thread
* LVM2/daemons/common daemon-client.h daemon-ser ...
@ 2011-07-18 14:46 mornfall
0 siblings, 0 replies; 4+ messages in thread
From: mornfall @ 2011-07-18 14:46 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: mornfall@sourceware.org 2011-07-18 14:46:54
Modified files:
daemons/common : daemon-client.h daemon-server.c daemon-server.h
Log message:
Various improvements to the daemon-common code, including automated response
formatting from config trees provided by the daemon implementation.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-client.h.diff?cvsroot=lvm2&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.c.diff?cvsroot=lvm2&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/daemons/common/daemon-server.h.diff?cvsroot=lvm2&r1=1.8&r2=1.9
--- LVM2/daemons/common/daemon-client.h 2011/06/27 14:03:58 1.6
+++ LVM2/daemons/common/daemon-client.h 2011/07/18 14:46:54 1.7
@@ -12,6 +12,7 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "libdevmapper.h" // for dm_list, needed by config.h
#include "config.h" // should become part of libdevmapper later
#ifndef _LVM_DAEMON_COMMON_CLIENT_H
--- LVM2/daemons/common/daemon-server.c 2011/06/29 22:20:14 1.7
+++ LVM2/daemons/common/daemon-server.c 2011/07/18 14:46:54 1.8
@@ -218,6 +218,22 @@
client_handle client;
};
+int buffer_rewrite(char **buf, const char *format, const char *string) {
+ char *old = *buf;
+ dm_asprintf(buf, format, *buf, string);
+ dm_free(old);
+ return 0;
+}
+
+int buffer_line(const char *line, void *baton) {
+ response *r = baton;
+ if (r->buffer)
+ buffer_rewrite(&r->buffer, "%s\n%s", line);
+ else
+ dm_asprintf(&r->buffer, "%s\n", line);
+ return 0;
+}
+
void *client_thread(void *baton)
{
struct thread_baton *b = baton;
@@ -227,12 +243,16 @@
goto fail;
req.cft = create_config_tree_from_string(req.buffer);
+ if (!req.cft)
+ fprintf(stderr, "error parsing request:\n %s\n", req.buffer);
response res = b->s.handler(b->s, b->client, req);
- destroy_config_tree(req.cft);
+ if (req.cft)
+ destroy_config_tree(req.cft);
dm_free(req.buffer);
if (!res.buffer) {
- /* TODO fill in the buffer from res.cft */
+ write_config_node(res.cft->root, buffer_line, &res);
+ buffer_rewrite(&res.buffer, "%s\n\n", NULL);
}
write_buffer(b->client.socket_fd, res.buffer, strlen(res.buffer));
@@ -318,6 +338,9 @@
if (!s.foreground)
kill(getppid(), SIGTERM);
+ if (s.daemon_init)
+ s.daemon_init(&s);
+
while (!_shutdown_requested && !failed) {
int status;
fd_set in;
@@ -333,6 +356,9 @@
if (s.socket_fd >= 0)
unlink(s.socket_path);
+ if (s.daemon_fini)
+ s.daemon_fini(&s);
+
syslog(LOG_NOTICE, "%s shutting down", s.name);
closelog();
remove_lockfile(s.pidfile);
--- LVM2/daemons/common/daemon-server.h 2011/06/27 14:03:59 1.8
+++ LVM2/daemons/common/daemon-server.h 2011/07/18 14:46:54 1.9
@@ -45,10 +45,14 @@
response daemon_reply_simple(char *id, ...);
static inline int daemon_request_int(request r, const char *path, int def) {
+ if (!r.cft)
+ return def;
return find_config_int(r.cft->root, path, def);
}
static inline const char *daemon_request_str(request r, const char *path, const char *def) {
+ if (!r.cft)
+ return def;
return find_config_str(r.cft->root, path, def);
}
@@ -77,7 +81,8 @@
const char *socket_path;
int log_level;
handle_request handler;
- int (*setup_post)(struct daemon_state *st);
+ int (*daemon_init)(struct daemon_state *st);
+ int (*daemon_fini)(struct daemon_state *st);
/* Global runtime info maintained by the framework. */
int socket_fd;
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-07-18 14:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-13 8:07 LVM2/daemons/common daemon-client.h daemon-ser mornfall
2011-05-15 11:02 mornfall
2011-06-14 2:34 mornfall
2011-07-18 14:46 mornfall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).