diff options
Diffstat (limited to 'libdaemon/server/daemon-server.h')
-rw-r--r-- | libdaemon/server/daemon-server.h | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h new file mode 100644 index 0000000..f184853 --- /dev/null +++ b/libdaemon/server/daemon-server.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2011-2012 Red Hat, Inc. + * + * 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_SERVER_H +#define _LVM_DAEMON_COMMON_SERVER_H + +#include "daemon-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 { + struct dm_config_tree *cft; + struct buffer buffer; +} request; + +typedef struct { + int error; + struct dm_config_tree *cft; + struct buffer buffer; +} response; + +struct daemon_state; + +/* + * Craft a simple reply, without the need to construct a config_tree. See + * daemon_send_simple in daemon-client.h for the description of the parameters. + */ +response daemon_reply_simple(const char *id, ...); + +static inline int daemon_request_int(request r, const char *path, int def) { + if (!r.cft) + return def; + return dm_config_find_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 dm_config_find_str(r.cft->root, path, def); +} + +/* + * 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 { + uint32_t log_config[32]; + void *backend_state[32]; + const char *name; +} log_state; + +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 + * pthread's default is 10M per thread. + */ + int thread_stack_size; + + /* Flags & attributes affecting the behaviour of the daemon. */ + unsigned avoid_oom:1; + unsigned foreground:1; + const char *name; + const char *pidfile; + const char *socket_path; + const char *protocol; + int protocol_version; + + handle_request handler; + int (*daemon_init)(struct daemon_state *st); + int (*daemon_fini)(struct daemon_state *st); + + /* Global runtime info maintained by the framework. */ + int socket_fd; + + log_state *log; + void *private; /* the global daemon state */ +} daemon_state; + +/* + * 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); + +/* + * 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(void); + +enum { DAEMON_LOG_OUTLET_SYSLOG = 1, + DAEMON_LOG_OUTLET_STDERR = 2, + DAEMON_LOG_OUTLET_SOCKET = 4 }; + +/* Log a message of a given type. */ +void daemon_log(log_state *s, int type, const char *message); + +/* Log a config (sub)tree, using a given message type, each line prefixed with "prefix". */ +void daemon_log_cft(log_state *s, int type, const char *prefix, + const struct dm_config_node *n); + +/* Log a multi-line block, prefixing each line with "prefix". */ +void daemon_log_multi(log_state *s, int type, const char *prefix, const char *message); + +/* Log a formatted message as "type". See also daemon-log.h. */ +void daemon_logf(log_state *s, int type, const char *format, ...); + +/* + * Configure log_state to send messages of type "type" to the log outlet + * "outlet", iff "enable" is true. + */ +void daemon_log_enable(log_state *s, int outlet, int type, int enable); + +/* + * Set up logging on a given outlet using a list of message types (comma + * separated) to log using that outlet. The list is expected to look like this, + * "all,wire,debug". Returns 0 upon encountering an unknown message type. + */ +int daemon_log_parse(log_state *s, int outlet, const char *types, int enable); + +#endif |