/*
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2014 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 General Public License v.2.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * CLVMD: Cluster LVM daemon
 */

#include "clvmd-common.h"

#include "clvmd-comms.h"
#include "clvm.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include "lvm-version.h"
#include "refresh_clvmd.h"

#ifdef HAVE_COROSYNC_CONFDB_H
#include <corosync/confdb.h>
#endif

#include <pthread.h>
#include <getopt.h>
#include <ctype.h>
#include <stdarg.h>

#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stddef.h>
#include <syslog.h>
#include <sys/un.h>
#include <sys/utsname.h>

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define MAX_RETRIES 4
#define MAX_MISSING_LEN 8000 /* Max supported clvmd message size ? */

#define ISLOCAL_CSID(c) (memcmp(c, our_csid, max_csid_len) == 0)

/* Head of the fd list. Also contains
   the cluster_socket details */
static struct local_client local_client_head;

static unsigned short global_xid = 0;	/* Last transaction ID issued */

struct cluster_ops *clops = NULL;

static char our_csid[MAX_CSID_LEN];
static unsigned max_csid_len;
static unsigned max_cluster_message;
static unsigned max_cluster_member_name_len;

/* Structure of items on the LVM thread list */
struct lvm_thread_cmd {
	struct dm_list list;

	struct local_client *client;
	struct clvm_header *msg;
	char csid[MAX_CSID_LEN];
	int remote;		/* Flag */
	int msglen;
	unsigned short xid;
};

struct lvm_startup_params {
	struct dm_hash_table *excl_uuid;
};

static debug_t debug = DEBUG_OFF;
static int foreground_mode = 0;
static pthread_t lvm_thread;
/* Stack size 128KiB for thread, must be bigger then DEFAULT_RESERVED_STACK */
static const size_t STACK_SIZE = 128 * 1024;
static pthread_attr_t stack_attr;
static int lvm_thread_exit = 0;
static pthread_mutex_t lvm_thread_mutex;
static pthread_cond_t lvm_thread_cond;
static pthread_barrier_t lvm_start_barrier;
static struct dm_list lvm_cmd_head;
static volatile sig_atomic_t quit = 0;
static volatile sig_atomic_t reread_config = 0;
static int child_pipe[2];

/* Reasons the daemon failed initialisation */
#define DFAIL_INIT       1
#define DFAIL_LOCAL_SOCK 2
#define DFAIL_CLUSTER_IF 3
#define DFAIL_MALLOC     4
#define DFAIL_TIMEOUT    5
#define SUCCESS          0

typedef enum {IF_AUTO, IF_CMAN, IF_OPENAIS, IF_COROSYNC, IF_SINGLENODE} if_type_t;

/* Prototypes for code further down */
static void sigusr2_handler(int sig);
static void sighup_handler(int sig);
static void sigterm_handler(int sig);
static void send_local_reply(struct local_client *client, int status,
			     int clientid);
static void free_reply(struct local_client *client);
static void send_version_message(void);
static void *pre_and_post_thread(void *arg);
static int send_message(void *buf, int msglen, const char *csid, int fd,
			const char *errtext);
static int read_from_local_sock(struct local_client *thisfd);
static int cleanup_zombie(struct local_client *thisfd);
static int process_local_command(struct clvm_header *msg, int msglen,
				 struct local_client *client,
				 unsigned short xid);
static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
				   const char *csid);
static int process_reply(const struct clvm_header *msg, int msglen,
			 const char *csid);
static int open_local_sock(void);
static void close_local_sock(int local_socket);
static int check_local_clvmd(void);
static struct local_client *find_client(int clientid);
static void main_loop(int cmd_timeout);
static void be_daemon(int start_timeout);
static int check_all_clvmds_running(struct local_client *client);
static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
				     int len, const char *csid,
				     struct local_client **new_client);
static void *lvm_thread_fn(void *) __attribute__((noreturn));
static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
			   int msglen, const char *csid);
static int distribute_command(struct local_client *thisfd);
static void hton_clvm(struct clvm_header *hdr);
static void ntoh_clvm(struct clvm_header *hdr);
static void add_reply_to_list(struct local_client *client, int status,
			      const char *csid, const char *buf, int len);
static if_type_t parse_cluster_interface(char *ifname);
static if_type_t get_cluster_type(void);

static void usage(const char *prog, FILE *file)
{
	fprintf(file, "Usage: %s [options]\n"
		"   -C       Sets debug level (from -d) on all clvmd instances clusterwide\n"
		"   -d[<n>]  Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
		"   -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
		"   -f       Don't fork, run in the foreground\n"
		"   -h       Show this help information\n"
		"   -I<cmgr> Cluster manager (default: auto)\n"
		"            Available cluster managers: "
#ifdef USE_COROSYNC
		"corosync "
#endif
#ifdef USE_CMAN
		"cman "
#endif
#ifdef USE_OPENAIS
		"openais "
#endif
#ifdef USE_SINGLENODE
		"singlenode "
#endif
		"\n"
		"   -R       Tell all running clvmds in the cluster to reload their device cache\n"
		"   -S       Restart clvmd, preserving exclusive locks\n"
		"   -t<secs> Command timeout (default: 60 seconds)\n"
		"   -T<secs> Startup timeout (default:  0 seconds)\n"
		"   -V       Show version of clvmd\n"
		"\n", prog);
}

/* Called to signal the parent how well we got on during initialisation */
static void child_init_signal(int status)
{
	if (child_pipe[1]) {
		/* FIXME Use a proper wrapper around write */
		if (write(child_pipe[1], &status, sizeof(status)) < 0)
			log_sys_error("write", "child_pipe");
		if (close(child_pipe[1]))
			log_sys_error("close", "child_pipe");
	}
}

static __attribute__((noreturn)) void child_init_signal_and_exit(int status) 
{
	child_init_signal(status);
	exit(status);
}

static void safe_close(int *fd)
{
	if (*fd >= 0) {
		int to_close = *fd;
		*fd = -1;
		if (close(to_close))
			log_sys_error("close", ""); /* path */
	}
}

void debuglog(const char *fmt, ...)
{
	time_t P;
	va_list ap;
	static int syslog_init = 0;
	char buf_ctime[64];

	switch (clvmd_get_debug()) {
	case DEBUG_STDERR:
		va_start(ap,fmt);
		time(&P);
		fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime_r(&P, buf_ctime) + 4);
		vfprintf(stderr, fmt, ap);
		va_end(ap);
		fflush(stderr);
		break;
	case DEBUG_SYSLOG:
		if (!syslog_init) {
			openlog("clvmd", LOG_PID, LOG_DAEMON);
			syslog_init = 1;
		}

		va_start(ap,fmt);
		vsyslog(LOG_DEBUG, fmt, ap);
		va_end(ap);
		break;
	case DEBUG_OFF:
		break;
	}
}

void clvmd_set_debug(debug_t new_debug)
{
	if (!foreground_mode && new_debug == DEBUG_STDERR)
		new_debug = DEBUG_SYSLOG;

	if (new_debug > DEBUG_SYSLOG)
		new_debug = DEBUG_SYSLOG;

	debug = new_debug;
}

debug_t clvmd_get_debug(void)
{
	return debug;
}

int clvmd_get_foreground(void)
{
	return foreground_mode;
}

static const char *decode_cmd(unsigned char cmdl)
{
	static char buf[128];
	const char *command;

	switch (cmdl) {
	case CLVMD_CMD_TEST:
		command = "TEST";
		break;
	case CLVMD_CMD_LOCK_VG:
		command = "LOCK_VG";
		break;
	case CLVMD_CMD_LOCK_LV:
		command = "LOCK_LV";
		break;
	case CLVMD_CMD_REFRESH:
		command = "REFRESH";
		break;
	case CLVMD_CMD_SET_DEBUG:
		command = "SET_DEBUG";
		break;
	case CLVMD_CMD_GET_CLUSTERNAME:
		command = "GET_CLUSTERNAME";
		break;
	case CLVMD_CMD_VG_BACKUP:
		command = "VG_BACKUP";
		break;
	case CLVMD_CMD_REPLY:
		command = "REPLY";
		break;
	case CLVMD_CMD_VERSION:
		command = "VERSION";
		break;
	case CLVMD_CMD_GOAWAY:
		command = "GOAWAY";
		break;
	case CLVMD_CMD_LOCK:
		command = "LOCK";
		break;
	case CLVMD_CMD_UNLOCK:
		command = "UNLOCK";
		break;
	case CLVMD_CMD_LOCK_QUERY:
		command = "LOCK_QUERY";
		break;
	case CLVMD_CMD_RESTART:
		command = "RESTART";
		break;
	case CLVMD_CMD_SYNC_NAMES:
		command = "SYNC_NAMES";
		break;
	default:
		command = "unknown";
		break;
	}

	snprintf(buf, sizeof(buf), "%s (0x%x)", command, cmdl);

	return buf;
}

static void remove_lockfile(void)
{
	if (unlink(CLVMD_PIDFILE))
		log_sys_error("unlink", CLVMD_PIDFILE);
}

/*
 * clvmd require dm-ioctl capability for operation
 */
static void check_permissions(void)
{
	if (getuid() || geteuid()) {
		log_error("Cannot run as a non-root user.");

		 /*
		  * Fail cleanly here if not run as root, instead of failing
		  * later when attempting a root-only operation 
		  * Preferred exit code from an initscript for this.
		  */
		exit(4);
	}
}

int main(int argc, char *argv[])
{
	int local_sock;
	struct local_client *newfd, *delfd;
	struct lvm_startup_params lvm_params;
	int opt;
	int cmd_timeout = DEFAULT_CMD_TIMEOUT;
	int start_timeout = 0;
	if_type_t cluster_iface = IF_AUTO;
	sigset_t ss;
	debug_t debug_opt = DEBUG_OFF;
	debug_t debug_arg = DEBUG_OFF;
	int clusterwide_opt = 0;
	mode_t old_mask;
	int ret = 1;

	struct option longopts[] = {
		{ "help", 0, 0, 'h' },
		{ NULL, 0, 0, 0 }
	};

	if (!(lvm_params.excl_uuid = dm_hash_create(128))) {
		fprintf(stderr, "Failed to allocate hash table\n");
		return 1;
	}

	/* Deal with command-line arguments */
	opterr = 0;
	optind = 0;
	while ((opt = getopt_long(argc, argv, "Vhfd:t:RST:CI:E:",
				  longopts, NULL)) != -1) {
		switch (opt) {
		case 'h':
			usage(argv[0], stdout);
			exit(0);

		case 'R':
			check_permissions();
			ret = (refresh_clvmd(1) == 1) ? 0 : 1;
			goto out;

		case 'S':
			check_permissions();
			ret = (restart_clvmd(clusterwide_opt) == 1) ? 0 : 1;
			goto out;

		case 'C':
			clusterwide_opt = 1;
			break;

		case 'd':
			debug_opt = DEBUG_STDERR;
			debug_arg = (debug_t) atoi(optarg);
			if (debug_arg == DEBUG_STDERR)
				foreground_mode = 1;
			break;

		case 'f':
			foreground_mode = 1;
			break;
		case 't':
			cmd_timeout = atoi(optarg);
			if (!cmd_timeout) {
				fprintf(stderr, "command timeout is invalid\n");
				usage(argv[0], stderr);
				exit(1);
			}
			break;
		case 'I':
			cluster_iface = parse_cluster_interface(optarg);
			break;
		case 'E':
			if (!dm_hash_insert(lvm_params.excl_uuid, optarg, optarg)) {
				fprintf(stderr, "Failed to allocate hash entry\n");
				goto out;
			}
			break;
		case 'T':
			start_timeout = atoi(optarg);
			if (start_timeout <= 0) {
				fprintf(stderr, "startup timeout is invalid\n");
				usage(argv[0], stderr);
				exit(1);
			}
			break;

		case 'V':
		        printf("Cluster LVM daemon version: %s\n", LVM_VERSION);
			printf("Protocol version:           %d.%d.%d\n",
			       CLVMD_MAJOR_VERSION, CLVMD_MINOR_VERSION,
			       CLVMD_PATCH_VERSION);
			exit(0);
			break;

		default:
			usage(argv[0], stderr);
			exit(2);
		}
	}

	check_permissions();

	/*
	 * Switch to C locale to avoid reading large locale-archive file
	 * used by some glibc (on some distributions it takes over 100MB).
	 * Daemon currently needs to use mlockall().
	 */
	if (setenv("LC_ALL", "C", 1))
		perror("Cannot set LC_ALL to C");

	/* Setting debug options on an existing clvmd */
	if (debug_opt && !check_local_clvmd()) {
		dm_hash_destroy(lvm_params.excl_uuid);
		return debug_clvmd(debug_arg, clusterwide_opt)==1?0:1;
	}

	clvmd_set_debug(debug_arg);

	/* Fork into the background (unless requested not to) */
	if (!foreground_mode)
		be_daemon(start_timeout);

        (void) dm_prepare_selinux_context(DEFAULT_RUN_DIR, S_IFDIR);
        old_mask = umask(0077);
        if (dm_create_dir(DEFAULT_RUN_DIR) == 0) {
                DEBUGLOG("clvmd: unable to create %s directory\n",
                          DEFAULT_RUN_DIR);
                umask(old_mask);
                exit(1);
        }
        umask(old_mask);

	/* Create pidfile */
	(void) dm_prepare_selinux_context(CLVMD_PIDFILE, S_IFREG);
	if (dm_create_lockfile(CLVMD_PIDFILE) == 0) {
		DEBUGLOG("clvmd: unable to create lockfile\n");
		exit(1);
	}
	(void) dm_prepare_selinux_context(NULL, 0);

	atexit(remove_lockfile);

	DEBUGLOG("CLVMD started\n");

	/* Open the Unix socket we listen for commands on.
	   We do this before opening the cluster socket so that
	   potential clients will block rather than error if we are running
	   but the cluster is not ready yet */
	local_sock = open_local_sock();
	if (local_sock < 0) {
		child_init_signal_and_exit(DFAIL_LOCAL_SOCK);
		/* NOTREACHED */
	}

	/* Set up signal handlers, USR1 is for cluster change notifications (in cman)
	   USR2 causes child threads to exit.
	   (HUP used to cause gulm to re-read the nodes list from CCS.)
	   PIPE should be ignored */
	signal(SIGUSR2, sigusr2_handler);
	signal(SIGHUP,  sighup_handler);
	signal(SIGPIPE, SIG_IGN);

	/* Block SIGUSR2/SIGINT/SIGTERM in process */
	sigemptyset(&ss);
	sigaddset(&ss, SIGUSR2);
	sigaddset(&ss, SIGINT);
	sigaddset(&ss, SIGTERM);
	sigprocmask(SIG_BLOCK, &ss, NULL);

	/* Initialise the LVM thread variables */
	dm_list_init(&lvm_cmd_head);
	if (pthread_attr_init(&stack_attr) ||
	    pthread_attr_setstacksize(&stack_attr, STACK_SIZE)) {
		log_sys_error("pthread_attr_init", "");
		exit(1);
	}
	pthread_mutex_init(&lvm_thread_mutex, NULL);
	pthread_cond_init(&lvm_thread_cond, NULL);
	pthread_barrier_init(&lvm_start_barrier, NULL, 2);
	init_lvhash();

	/* Start the cluster interface */
	if (cluster_iface == IF_AUTO)
		cluster_iface = get_cluster_type();

#ifdef USE_CMAN
	if ((cluster_iface == IF_AUTO || cluster_iface == IF_CMAN) &&
	    (clops = init_cman_cluster())) {
		max_csid_len = CMAN_MAX_CSID_LEN;
		max_cluster_message = CMAN_MAX_CLUSTER_MESSAGE;
		max_cluster_member_name_len = CMAN_MAX_NODENAME_LEN;
		syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to CMAN");
	}
#endif
#ifdef USE_COROSYNC
	if (!clops)
		if (((cluster_iface == IF_AUTO || cluster_iface == IF_COROSYNC) &&
		     (clops = init_corosync_cluster()))) {
			max_csid_len = COROSYNC_CSID_LEN;
			max_cluster_message = COROSYNC_MAX_CLUSTER_MESSAGE;
			max_cluster_member_name_len = COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN;
			syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to Corosync");
		}
#endif
#ifdef USE_OPENAIS
	if (!clops)
		if ((cluster_iface == IF_AUTO || cluster_iface == IF_OPENAIS) &&
		    (clops = init_openais_cluster())) {
			max_csid_len = OPENAIS_CSID_LEN;
			max_cluster_message = OPENAIS_MAX_CLUSTER_MESSAGE;
			max_cluster_member_name_len = OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN;
			syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to OpenAIS");
		}
#endif
#ifdef USE_SINGLENODE
	if (!clops)
		if (cluster_iface == IF_SINGLENODE && (clops = init_singlenode_cluster())) {
			max_csid_len = SINGLENODE_CSID_LEN;
			max_cluster_message = SINGLENODE_MAX_CLUSTER_MESSAGE;
			max_cluster_member_name_len = MAX_CLUSTER_MEMBER_NAME_LEN;
			syslog(LOG_NOTICE, "Cluster LVM daemon started - running in single-node mode");
		}
#endif

	if (!clops) {
		DEBUGLOG("Can't initialise cluster interface\n");
		log_error("Can't initialise cluster interface.");
		child_init_signal_and_exit(DFAIL_CLUSTER_IF);
		/* NOTREACHED */
	}
	DEBUGLOG("Cluster ready, doing some more initialisation\n");

	/* Save our CSID */
	clops->get_our_csid(our_csid);

	/* Initialise the FD list head */
	local_client_head.fd = clops->get_main_cluster_fd();
	local_client_head.type = CLUSTER_MAIN_SOCK;
	local_client_head.callback = clops->cluster_fd_callback;

	/* Add the local socket to the list */
	if (!(newfd = dm_zalloc(sizeof(struct local_client)))) {
		child_init_signal_and_exit(DFAIL_MALLOC);
		/* NOTREACHED */
	}

	newfd->fd = local_sock;
	newfd->type = LOCAL_RENDEZVOUS;
	newfd->callback = local_rendezvous_callback;
	newfd->next = local_client_head.next;
	local_client_head.next = newfd;

	/* This needs to be started after cluster initialisation
	   as it may need to take out locks */
	DEBUGLOG("Starting LVM thread\n");
	DEBUGLOG("Main cluster socket fd %d (%p) with local socket %d (%p)\n",
		 local_client_head.fd, &local_client_head, newfd->fd, newfd);

	/* Don't let anyone else to do work until we are started */
	if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
		log_sys_error("pthread_create", "");
		goto out;
	}

	/* Don't start until the LVM thread is ready */
	pthread_barrier_wait(&lvm_start_barrier);

	/* Tell the rest of the cluster our version number */
	if (clops->cluster_init_completed)
		clops->cluster_init_completed();

	DEBUGLOG("clvmd ready for work\n");
	child_init_signal(SUCCESS);

	/* Try to shutdown neatly */
	signal(SIGTERM, sigterm_handler);
	signal(SIGINT, sigterm_handler);

	/* Do some work */
	main_loop(cmd_timeout);

	pthread_mutex_lock(&lvm_thread_mutex);
	lvm_thread_exit = 1;
	pthread_cond_signal(&lvm_thread_cond);
	pthread_mutex_unlock(&lvm_thread_mutex);
	if ((errno = pthread_join(lvm_thread, NULL)))
		log_sys_error("pthread_join", "");

	close_local_sock(local_sock);

	while ((delfd = local_client_head.next)) {
		local_client_head.next = delfd->next;
		/* Failing cleanup_zombie leaks... */
		if (delfd->type == LOCAL_SOCK && !cleanup_zombie(delfd))
			cmd_client_cleanup(delfd); /* calls sync_unlock */
		if (delfd->fd != local_sock)
			safe_close(&(delfd->fd));
		dm_free(delfd);
	}

	DEBUGLOG("cluster_closedown\n");
	destroy_lvhash();
	clops->cluster_closedown();

	ret = 0;
out:
	dm_hash_destroy(lvm_params.excl_uuid);

	return ret;
}

/* Called when the cluster layer has completed initialisation.
   We send the version message */
void clvmd_cluster_init_completed(void)
{
	send_version_message();
}

/* Data on a connected socket */
static int local_sock_callback(struct local_client *thisfd, char *buf, int len,
			       const char *csid,
			       struct local_client **new_client)
{
	*new_client = NULL;
	return read_from_local_sock(thisfd);
}

/* Data on a connected socket */
static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
				     int len, const char *csid,
				     struct local_client **new_client)
{
	/* Someone connected to our local socket, accept it. */

	struct sockaddr_un socka;
	struct local_client *newfd;
	socklen_t sl = sizeof(socka);
	int client_fd = accept(thisfd->fd, (struct sockaddr *) &socka, &sl);

	if (client_fd == -1 && errno == EINTR)
		return 1;

	if (client_fd >= 0) {
		if (!(newfd = dm_zalloc(sizeof(*newfd)))) {
			if (close(client_fd))
				log_sys_error("close", "socket");
			return 1;
		}

		pthread_cond_init(&newfd->bits.localsock.cond, NULL);
		pthread_mutex_init(&newfd->bits.localsock.mutex, NULL);

		if (fcntl(client_fd, F_SETFD, 1))
			DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));

		newfd->fd = client_fd;
		newfd->type = LOCAL_SOCK;
		newfd->callback = local_sock_callback;
		newfd->bits.localsock.all_success = 1;
		DEBUGLOG("Got new connection on fd %d (%p)\n", newfd->fd, newfd);
		*new_client = newfd;
	}
	return 1;
}

static int local_pipe_callback(struct local_client *thisfd, char *buf,
			       int maxlen, const char *csid,
			       struct local_client **new_client)
{
	int len;
	char buffer[PIPE_BUF];
	struct local_client *sock_client = thisfd->bits.pipe.client;
	int status = -1;	/* in error by default */

	len = read(thisfd->fd, buffer, sizeof(int));
	if (len == -1 && errno == EINTR)
		return 1;

	if (len == sizeof(int))
		memcpy(&status, buffer, sizeof(int));

	DEBUGLOG("Read on pipe %d, %d bytes, status %d\n",
		 thisfd->fd, len, status);

	/* EOF on pipe or an error, close it */
	if (len <= 0) {
		void *ret = &status;
		if (close(thisfd->fd))
			log_sys_error("close", "local_pipe");

		/* Clear out the cross-link */
		if (thisfd->bits.pipe.client)
			thisfd->bits.pipe.client->bits.localsock.pipe_client = NULL;

		/* Reap child thread */
		if (thisfd->bits.pipe.threadid) {
			if ((errno = pthread_join(thisfd->bits.pipe.threadid, &ret)))
				log_sys_error("pthread_join", "");

			thisfd->bits.pipe.threadid = 0;
			if (thisfd->bits.pipe.client)
				thisfd->bits.pipe.client->bits.localsock.threadid = 0;
		}
		return -1;
	} else {
		DEBUGLOG("Background routine status was %d, sock_client (%p)\n",
			 status, sock_client);
		/* But has the client gone away ?? */
		if (!sock_client) {
			DEBUGLOG("Got pipe response for dead client, ignoring it\n");
		} else {
			/* If error then just return that code */
			if (status)
				send_local_reply(sock_client, status,
						 sock_client->fd);
			else {
				/* FIXME: closer inspect this code since state is write thread protected */
				pthread_mutex_lock(&sock_client->bits.localsock.mutex);
				if (sock_client->bits.localsock.state == POST_COMMAND) {
					pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
					send_local_reply(sock_client, 0,
							 sock_client->fd);
				} else {
					/* PRE_COMMAND finished. */
					pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
					if ((status = distribute_command(sock_client)))
						send_local_reply(sock_client, EFBIG,
								 sock_client->fd);
				}
			}
		}
	}
	return len;
}

/* If a noed is up, look for it in the reply array, if it's not there then
   add one with "ETIMEDOUT".
   NOTE: This won't race with real replies because they happen in the same thread.
*/
static void timedout_callback(struct local_client *client, const char *csid,
			      int node_up)
{
	struct node_reply *reply;
	char nodename[max_cluster_member_name_len];

	if (!node_up)
		return;

	clops->name_from_csid(csid, nodename);
	DEBUGLOG("Checking for a reply from %s\n", nodename);
	pthread_mutex_lock(&client->bits.localsock.mutex);

	reply = client->bits.localsock.replies;
	while (reply && strcmp(reply->node, nodename) != 0)
		reply = reply->next;

	pthread_mutex_unlock(&client->bits.localsock.mutex);

	if (!reply) {
		DEBUGLOG("Node %s timed-out\n", nodename);
		add_reply_to_list(client, ETIMEDOUT, csid,
				  "Command timed out", 18);
	}
}

/* Called when the request has timed out on at least one node. We fill in
   the remaining node entries with ETIMEDOUT and return.

   By the time we get here the node that caused
   the timeout could have gone down, in which case we will never get the expected
   number of replies that triggers the post command so we need to do it here
*/
static void request_timed_out(struct local_client *client)
{
	DEBUGLOG("Request timed-out. padding\n");
	clops->cluster_do_node_callback(client, timedout_callback);

	if (!client->bits.localsock.threadid)
		return;

	pthread_mutex_lock(&client->bits.localsock.mutex);

	if (!client->bits.localsock.finished &&
	    (client->bits.localsock.num_replies !=
	     client->bits.localsock.expected_replies)) {
		/* Post-process the command */
		client->bits.localsock.state = POST_COMMAND;
		pthread_cond_signal(&client->bits.localsock.cond);
	}

	pthread_mutex_unlock(&client->bits.localsock.mutex);
}

/* This is where the real work happens */
static void main_loop(int cmd_timeout)
{
	sigset_t ss;

	DEBUGLOG("Using timeout of %d seconds\n", cmd_timeout);

	sigemptyset(&ss);
	sigaddset(&ss, SIGINT);
	sigaddset(&ss, SIGTERM);
	pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
	/* Main loop */
	while (!quit) {
		fd_set in;
		int select_status;
		struct local_client *thisfd;
		struct timeval tv = { cmd_timeout, 0 };
		int quorate = clops->is_quorate();
		int client_count = 0;
		int max_fd = 0;
		struct local_client *lastfd = &local_client_head;
		struct local_client *nextfd = local_client_head.next;

		/* Wait on the cluster FD and all local sockets/pipes */
		local_client_head.fd = clops->get_main_cluster_fd();
		FD_ZERO(&in);

		for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
			client_count++;
			max_fd = max(max_fd, thisfd->fd);
		}

		if (max_fd > FD_SETSIZE - 32) {
			fprintf(stderr, "WARNING: There are too many connections to clvmd.  Investigate and take action now!\n");
 			fprintf(stderr, "WARNING: Your cluster may freeze up if the number of clvmd file descriptors (%d) exceeds %d.\n", max_fd + 1, FD_SETSIZE);
		}

		for (thisfd = &local_client_head; thisfd; thisfd = nextfd, nextfd = thisfd ? thisfd->next : NULL) {

			if (thisfd->removeme && !cleanup_zombie(thisfd)) {
				struct local_client *free_fd = thisfd;
				lastfd->next = nextfd;
				DEBUGLOG("removeme set for %p with %d monitored fds remaining\n", free_fd, client_count - 1);

				/* Queue cleanup, this also frees the client struct */
				add_to_lvmqueue(free_fd, NULL, 0, NULL);

				continue;
			}

			lastfd = thisfd;

			if (thisfd->removeme)
				continue;

			/* if the cluster is not quorate then don't listen for new requests */
			if ((thisfd->type != LOCAL_RENDEZVOUS &&
			     thisfd->type != LOCAL_SOCK) || quorate)
				if (thisfd->fd < FD_SETSIZE)
					FD_SET(thisfd->fd, &in);
		}

		select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv);

		if (reread_config) {
			int saved_errno = errno;

			reread_config = 0;
			DEBUGLOG("got SIGHUP\n");
			if (clops->reread_config)
				clops->reread_config();
			errno = saved_errno;
		}

		if (select_status > 0) {
			char csid[MAX_CSID_LEN];
			char buf[max_cluster_message];

			for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
				if (thisfd->fd < FD_SETSIZE && FD_ISSET(thisfd->fd, &in)) {
					struct local_client *newfd = NULL;
					int ret;

					/* FIXME Remove from main thread in case it blocks! */
					/* Do callback */
					ret = thisfd->callback(thisfd, buf, sizeof(buf),
							       csid, &newfd);
					/* Ignore EAGAIN */
					if (ret < 0 && (errno == EAGAIN || errno == EINTR)) {
						continue;
                                        }

					/* Got error or EOF: Remove it from the list safely */
					if (ret <= 0) {
						int type = thisfd->type;

						/* If the cluster socket shuts down, so do we */
						if (type == CLUSTER_MAIN_SOCK ||
						    type == CLUSTER_INTERNAL)
							goto closedown;

						DEBUGLOG("ret == %d, errno = %d. removing client\n",
							 ret, errno);
						thisfd->removeme = 1;
						continue;
					}

					/* New client...simply add it to the list */
					if (newfd) {
						newfd->next = thisfd->next;
						thisfd->next = newfd;
						thisfd = newfd;
					}
				}
			}
		}

		/* Select timed out. Check for clients that have been waiting too long for a response */
		if (select_status == 0) {
			time_t the_time = time(NULL);

			for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
				if (thisfd->type == LOCAL_SOCK &&
				    thisfd->bits.localsock.sent_out &&
				    (thisfd->bits.localsock.sent_time + cmd_timeout) < the_time &&
				    thisfd->bits.localsock.expected_replies !=
				    thisfd->bits.localsock.num_replies) {
					/* Send timed out message + replies we already have */
					DEBUGLOG("Request timed-out (send: %ld, now: %ld)\n",
						 thisfd->bits.localsock.sent_time, the_time);

					thisfd->bits.localsock.all_success = 0;

					request_timed_out(thisfd);
				}
			}
		}
		if (select_status < 0) {
			if (errno == EINTR)
				continue;

#ifdef DEBUG
			perror("select error");
			exit(-1);
#endif
		}
	}

      closedown:
	if (quit)
		DEBUGLOG("SIGTERM received\n");
}

static __attribute__ ((noreturn)) void wait_for_child(int c_pipe, int timeout)
{
	int child_status;
	fd_set fds;
	struct timeval tv = {timeout, 0};

	FD_ZERO(&fds);
	FD_SET(c_pipe, &fds);

	switch (select(c_pipe+1, &fds, NULL, NULL, timeout? &tv: NULL)) {
	case 0:
		fprintf(stderr, "clvmd startup timed out\n");
		exit(DFAIL_TIMEOUT);
	case 1:
		if (read(c_pipe, &child_status, sizeof(child_status)) !=
		    sizeof(child_status)) {
			fprintf(stderr, "clvmd failed in initialisation\n");
			exit(DFAIL_INIT);
		}

		switch (child_status) {
		case SUCCESS:
			break;
		case DFAIL_INIT:
			fprintf(stderr, "clvmd failed in initialisation\n");
			break;
		case DFAIL_LOCAL_SOCK:
			fprintf(stderr, "clvmd could not create local socket\n");
			fprintf(stderr, "Another clvmd is probably already running\n");
			break;
		case DFAIL_CLUSTER_IF:
			fprintf(stderr, "clvmd could not connect to cluster manager\n");
			fprintf(stderr, "Consult syslog for more information\n");
			break;
		case DFAIL_MALLOC:
			fprintf(stderr, "clvmd failed, not enough memory\n");
			break;
		default:
			fprintf(stderr, "clvmd failed, error was %d\n", child_status);
			break;
		}
		exit(child_status);
	default:
		fprintf(stderr, "clvmd startup, select failed: %s\n", strerror(errno));
		exit(DFAIL_INIT);
	}
}

/*
 * Fork into the background and detach from our parent process.
 * In the interests of user-friendliness we wait for the daemon
 * to complete initialisation before returning its status
 * the the user.
 */
static void be_daemon(int timeout)
{
	int devnull = open("/dev/null", O_RDWR);
	if (devnull == -1) {
		perror("Can't open /dev/null");
		exit(3);
	}

	if (pipe(child_pipe)) {
		perror("Error creating pipe");
		exit(3);
	}

	switch (fork()) {
	case -1:
		perror("clvmd: can't fork");
		exit(2);

	case 0:		/* Child */
		(void) close(child_pipe[0]);
		break;

	default:       /* Parent */
		(void) close(child_pipe[1]);
		wait_for_child(child_pipe[0], timeout);
	}

	/* Detach ourself from the calling environment */
	if (close(0) || close(1) || close(2)) {
		perror("Error closing terminal FDs");
		exit(4);
	}
	setsid();

	if (dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0
	    || dup2(devnull, 2) < 0) {
		perror("Error setting terminal FDs to /dev/null");
		log_error("Error setting terminal FDs to /dev/null: %m");
		exit(5);
	}
	if ((devnull > STDERR_FILENO) && close(devnull)) {
		log_sys_error("close", "/dev/null");
		exit(7);
	}
	if (chdir("/")) {
		log_error("Error setting current directory to /: %m");
		exit(6);
	}
}

static int verify_message(char *buf, int len)
{
	struct clvm_header *h = (struct clvm_header *)buf;

	if (len < (int)sizeof(struct clvm_header)) {
		log_error("verify_message short len %d.", len);
		return -1;
	}

	switch (h->cmd) {
	case CLVMD_CMD_REPLY:
	case CLVMD_CMD_VERSION:
	case CLVMD_CMD_GOAWAY:
	case CLVMD_CMD_TEST:
	case CLVMD_CMD_LOCK:
	case CLVMD_CMD_UNLOCK:
	case CLVMD_CMD_LOCK_LV:
	case CLVMD_CMD_LOCK_VG:
	case CLVMD_CMD_LOCK_QUERY:
	case CLVMD_CMD_REFRESH:
	case CLVMD_CMD_GET_CLUSTERNAME:
	case CLVMD_CMD_SET_DEBUG:
	case CLVMD_CMD_VG_BACKUP:
	case CLVMD_CMD_RESTART:
	case CLVMD_CMD_SYNC_NAMES:
		break;
	default:
		log_error("verify_message bad cmd %x.", h->cmd);
		return -1;
	}

	/* TODO: we may be able to narrow len/flags/clientid/arglen checks based on cmd */

	if (h->flags & ~(CLVMD_FLAG_LOCAL | CLVMD_FLAG_SYSTEMLV | CLVMD_FLAG_NODEERRS | CLVMD_FLAG_REMOTE)) {
		log_error("verify_message bad flags %x.", h->flags);
		return -1;
	}

	if (h->arglen > max_cluster_message) {
		log_error("verify_message bad arglen %x max %d.", h->arglen, max_cluster_message);
		return -1;
	}

	return 0;
}

static void dump_message(char *buf, int len)
{
	unsigned char row[8];
	char str[9];
	int i, j = 0;

	str[8] = '\0';
	if (len > 128)
		len = 128;

	for (i = 0; i < len; ++i) {
		row[j] = buf[i];
		str[j] = (isprint(buf[i])) ? buf[i] : ' ';

		if (i + 1 == len) {
			for (;j < 8; ++j) {
				row[j] = 0;
				str[j] = ' ';
			}

			log_error("%02x %02x %02x %02x %02x %02x %02x %02x [%s]",
				  row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], str);
			j = 0;
		}
	}
}

static int cleanup_zombie(struct local_client *thisfd)
{
	int *status;
	struct local_client *pipe_client;

	if (thisfd->type != LOCAL_SOCK)
		return 0;

	if (!thisfd->bits.localsock.cleanup_needed)
		return 0;

	DEBUGLOG("EOF on local socket: inprogress=%d\n",
		 thisfd->bits.localsock.in_progress);

	if ((pipe_client = thisfd->bits.localsock.pipe_client))
		pipe_client = pipe_client->bits.pipe.client;

	/* If the client went away in mid command then tidy up */
	if (thisfd->bits.localsock.in_progress) {
		DEBUGLOG("Sending SIGUSR2 to pre&post thread (%p in-progress)\n", pipe_client);
		pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
		if (pthread_mutex_trylock(&thisfd->bits.localsock.mutex))
			return 1;
		thisfd->bits.localsock.state = POST_COMMAND;
		thisfd->bits.localsock.finished = 1;
		pthread_cond_signal(&thisfd->bits.localsock.cond);
		pthread_mutex_unlock(&thisfd->bits.localsock.mutex);

		/* Free any unsent buffers */
		free_reply(thisfd);
	}

	/* Kill the subthread & free resources */
	if (thisfd->bits.localsock.threadid) {
		DEBUGLOG("Waiting for pre&post thread (%p)\n", pipe_client);
		pthread_mutex_lock(&thisfd->bits.localsock.mutex);
		thisfd->bits.localsock.state = PRE_COMMAND;
		thisfd->bits.localsock.finished = 1;
		pthread_cond_signal(&thisfd->bits.localsock.cond);
		pthread_mutex_unlock(&thisfd->bits.localsock.mutex);

		if ((errno = pthread_join(thisfd->bits.localsock.threadid,
					  (void **) &status)))
			log_sys_error("pthread_join", "");

		DEBUGLOG("Joined pre&post thread\n");

		thisfd->bits.localsock.threadid = 0;

		/* Remove the pipe client */
		if (thisfd->bits.localsock.pipe_client) {
			struct local_client *delfd;
			struct local_client *lastfd;

			(void) close(thisfd->bits.localsock.pipe_client->fd);	/* Close pipe */
			(void) close(thisfd->bits.localsock.pipe);

			/* Remove pipe client */
			for (lastfd = &local_client_head; (delfd = lastfd->next); lastfd = delfd)
				if (thisfd->bits.localsock.pipe_client == delfd) {
					thisfd->bits.localsock.pipe_client = NULL;
					lastfd->next = delfd->next;
					dm_free(delfd);
					break;
				}
		}
	}

	/* Free the command buffer */
	dm_free(thisfd->bits.localsock.cmd);

	safe_close(&(thisfd->fd));
	thisfd->bits.localsock.cleanup_needed = 0;

	return 0;
}

/* Called when we have a read from the local socket.
   was in the main loop but it's grown up and is a big girl now */
static int read_from_local_sock(struct local_client *thisfd)
{
	int len;
	int argslen;
	int missing_len;
	char buffer[PIPE_BUF + 1];
	char csid[MAX_CSID_LEN];
	int comms_pipe[2];
	struct local_client *newfd;
	struct clvm_header *inheader = (struct clvm_header *) buffer;
	int status;

	len = read(thisfd->fd, buffer, sizeof(buffer) - 1);
	if (len == -1 && errno == EINTR)
		return 1;

	DEBUGLOG("Read on local socket %d, len = %d\n", thisfd->fd, len);

	if (len && verify_message(buffer, len) < 0) {
		log_error("read_from_local_sock from %d len %d bad verify.",
			  thisfd->fd, len);
		dump_message(buffer, len);
		/* force error handling below */
		len = 0;
	}

	/* EOF or error on socket */
	if (len <= 0) {
		thisfd->bits.localsock.cleanup_needed = 1;
		(void) cleanup_zombie(thisfd); /* ignore errors here */
		return 0;
	}

	buffer[len] = 0; /* Ensure \0 terminated */

	/* Fill in the client ID */
	inheader->clientid = htonl(thisfd->fd);

	/* If we are already busy then return an error */
	if (thisfd->bits.localsock.in_progress) {
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = EBUSY
		};
		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending EBUSY reply to local user");
		return len;
	}

	/* See if we have the whole message */
	argslen = len - strlen(inheader->node) - sizeof(struct clvm_header);
	missing_len = inheader->arglen - argslen;

	if (missing_len < 0)
		missing_len = 0;

	/* We need at least sizeof(struct clvm_header) bytes in buffer */
	if (len < (int)sizeof(struct clvm_header) || /* Already handled in verify_message() */
	    argslen < 0 || missing_len > MAX_MISSING_LEN) {
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = EINVAL
		};
		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending EINVAL reply to local user");
		return 0;
	}

	/* Free any old buffer space */
	dm_free(thisfd->bits.localsock.cmd);

	/* Save the message */
	if (!(thisfd->bits.localsock.cmd = dm_malloc(len + missing_len))) {
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = ENOMEM
		};
		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending ENOMEM reply to local user");
		return 0;
	}
	memcpy(thisfd->bits.localsock.cmd, buffer, len);
	thisfd->bits.localsock.cmd_len = len + missing_len;
	inheader = (struct clvm_header *) thisfd->bits.localsock.cmd;

	/* If we don't have the full message then read the rest now */
	if (missing_len) {
		char *argptr = inheader->node + strlen(inheader->node) + 1;

		while (missing_len > 0) {
			DEBUGLOG("got %d bytes, need another %d (total %d)\n",
				 argslen, missing_len, inheader->arglen);
			len = read(thisfd->fd, argptr + argslen, missing_len);
			if (len == -1 && errno == EINTR)
				continue;

			if (len <= 0) {
				/* EOF or error on socket */
				DEBUGLOG("EOF on local socket\n");
				dm_free(thisfd->bits.localsock.cmd);
				thisfd->bits.localsock.cmd = NULL;
				return 0;
			}

			missing_len -= len;
			argslen += len;
		}
	}

	/* Only run the command if all the cluster nodes are running CLVMD */
	if (((inheader->flags & CLVMD_FLAG_LOCAL) == 0) &&
	    (check_all_clvmds_running(thisfd) == -1)) {
		thisfd->bits.localsock.expected_replies = 0;
		thisfd->bits.localsock.num_replies = 0;
		send_local_reply(thisfd, EHOSTDOWN, thisfd->fd);
		return len;
	}

	/* Check the node name for validity */
	if (inheader->node[0] && clops->csid_from_name(csid, inheader->node)) {
		/* Error, node is not in the cluster */
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = ENOENT
		};

		DEBUGLOG("Unknown node: '%s'\n", inheader->node);
		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending ENOENT reply to local user");
		thisfd->bits.localsock.expected_replies = 0;
		thisfd->bits.localsock.num_replies = 0;
		thisfd->bits.localsock.in_progress = FALSE;
		thisfd->bits.localsock.sent_out = FALSE;
		return len;
	}

	/* If we already have a subthread then just signal it to start */
	if (thisfd->bits.localsock.threadid) {
		pthread_mutex_lock(&thisfd->bits.localsock.mutex);
		thisfd->bits.localsock.state = PRE_COMMAND;
		pthread_cond_signal(&thisfd->bits.localsock.cond);
		pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
		return len;
	}

	/* Create a pipe and add the reading end to our FD list */
	if (pipe(comms_pipe)) {
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = EBUSY
		};

		DEBUGLOG("Creating pipe failed: %s\n", strerror(errno));
		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending EBUSY reply to local user");
		return len;
	}

	if (!(newfd = dm_zalloc(sizeof(*newfd)))) {
		struct clvm_header reply = {
			.cmd = CLVMD_CMD_REPLY,
			.status = ENOMEM
		};

		(void) close(comms_pipe[0]);
		(void) close(comms_pipe[1]);

		send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
			     "Error sending ENOMEM reply to local user");
		return len;
	}

	DEBUGLOG("Creating pipe, [%d, %d]\n", comms_pipe[0], comms_pipe[1]);

	if (fcntl(comms_pipe[0], F_SETFD, 1))
		DEBUGLOG("setting CLOEXEC on pipe[0] failed: %s\n", strerror(errno));
	if (fcntl(comms_pipe[1], F_SETFD, 1))
		DEBUGLOG("setting CLOEXEC on pipe[1] failed: %s\n", strerror(errno));

	newfd->fd = comms_pipe[0];
	newfd->type = THREAD_PIPE;
	newfd->callback = local_pipe_callback;
	newfd->bits.pipe.client = thisfd;
	newfd->next = thisfd->next;
	thisfd->next = newfd;

	/* Store a cross link to the pipe */
	thisfd->bits.localsock.pipe_client = newfd;
	thisfd->bits.localsock.pipe = comms_pipe[1];

	/* Make sure the thread has a copy of it's own ID */
	newfd->bits.pipe.threadid = thisfd->bits.localsock.threadid;

	/* Run the pre routine */
	thisfd->bits.localsock.in_progress = TRUE;
	thisfd->bits.localsock.state = PRE_COMMAND;
	thisfd->bits.localsock.cleanup_needed = 1;
	DEBUGLOG("Creating pre&post thread for pipe fd %d (%p)\n", newfd->fd, newfd);
	status = pthread_create(&thisfd->bits.localsock.threadid,
				&stack_attr, pre_and_post_thread, thisfd);
	DEBUGLOG("Created pre&post thread, state = %d\n", status);

	return len;
}

/* Add a file descriptor from the cluster or comms interface to
   our list of FDs for select
*/
int add_client(struct local_client *new_client)
{
	new_client->next = local_client_head.next;
	local_client_head.next = new_client;

	return 0;
}

/* Called when the pre-command has completed successfully - we
   now execute the real command on all the requested nodes */
static int distribute_command(struct local_client *thisfd)
{
	struct clvm_header *inheader =
		(struct clvm_header *) thisfd->bits.localsock.cmd;
	int len = thisfd->bits.localsock.cmd_len;

	thisfd->xid = global_xid++;
	DEBUGLOG("distribute command: XID = %d, flags=0x%x (%s%s)\n",
		 thisfd->xid, inheader->flags,
		(inheader->flags & CLVMD_FLAG_LOCAL) ? "LOCAL" : "",
		(inheader->flags & CLVMD_FLAG_REMOTE) ? "REMOTE" : "");

	/* Forward it to other nodes in the cluster if needed */
	if (!(inheader->flags & CLVMD_FLAG_LOCAL)) {
		/* if node is empty then do it on the whole cluster */
		if (inheader->node[0] == '\0') {
			thisfd->bits.localsock.expected_replies =
				clops->get_num_nodes();
			thisfd->bits.localsock.num_replies = 0;
			thisfd->bits.localsock.sent_time = time(NULL);
			thisfd->bits.localsock.in_progress = TRUE;
			thisfd->bits.localsock.sent_out = TRUE;

			/*
			 * Send to local node first, even if CLVMD_FLAG_REMOTE
			 * is set so we still get a reply if this is the
			 * only node.
			 */
			add_to_lvmqueue(thisfd, inheader, len, NULL);

			DEBUGLOG("Sending message to all cluster nodes\n");
			inheader->xid = thisfd->xid;
			send_message(inheader, len, NULL, -1,
				     "Error forwarding message to cluster");
		} else {
			/* Do it on a single node */
			char csid[MAX_CSID_LEN];

			if (clops->csid_from_name(csid, inheader->node))
				/* This has already been checked so should not happen */
				return 0;

			/* OK, found a node... */
			thisfd->bits.localsock.in_progress = TRUE;
			thisfd->bits.localsock.expected_replies = 1;
			thisfd->bits.localsock.num_replies = 0;

			/* Are we the requested node ?? */
			if (memcmp(csid, our_csid, max_csid_len) == 0) {
				DEBUGLOG("Doing command on local node only\n");
				add_to_lvmqueue(thisfd, inheader, len, NULL);
			} else {
				DEBUGLOG("Sending message to single node: %s\n",
					 inheader->node);
				inheader->xid = thisfd->xid;
				send_message(inheader, len, csid, -1,
					     "Error forwarding message to cluster node");
			}
		}
	} else {
		/* Local explicitly requested, ignore nodes */
		thisfd->bits.localsock.in_progress = TRUE;
		thisfd->bits.localsock.expected_replies = 1;
		thisfd->bits.localsock.num_replies = 0;
		DEBUGLOG("Doing command explicitly on local node only\n");
		add_to_lvmqueue(thisfd, inheader, len, NULL);
	}

	return 0;
}

/* Process a command from a remote node and return the result */
static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
			    	   const char *csid)
{
	char *replyargs;
	char nodename[max_cluster_member_name_len];
	int replylen = 0;
	int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
	int status;

	/* Get the node name as we /may/ need it later */
	clops->name_from_csid(csid, nodename);

	DEBUGLOG("process_remote_command %s for clientid 0x%x XID %d on node %s\n",
		 decode_cmd(msg->cmd), msg->clientid, msg->xid, nodename);

	/* Check for GOAWAY and sulk */
	if (msg->cmd == CLVMD_CMD_GOAWAY) {
		DEBUGLOG("Told to go away by %s\n", nodename);
		log_error("Told to go away by %s.", nodename);
		exit(99);
	}

	/* Version check is internal - don't bother exposing it in clvmd-command.c */
	if (msg->cmd == CLVMD_CMD_VERSION) {
		int version_nums[3];
		char node[256];

		memcpy(version_nums, msg->args, sizeof(version_nums));

		clops->name_from_csid(csid, node);
		DEBUGLOG("Remote node %s is version %d.%d.%d\n",
			 node, ntohl(version_nums[0]),
			 ntohl(version_nums[1]), ntohl(version_nums[2]));

		if (ntohl(version_nums[0]) != CLVMD_MAJOR_VERSION) {
			struct clvm_header byebyemsg = {
				.cmd = CLVMD_CMD_GOAWAY
			};

			DEBUGLOG("Telling node %s to go away because of incompatible version number\n",
				 node);
			log_notice("Telling node %s to go away because of incompatible version number %d.%d.%d\n",
				   node, ntohl(version_nums[0]),
				   ntohl(version_nums[1]), ntohl(version_nums[2]));

			clops->cluster_send_message(&byebyemsg, sizeof(byebyemsg), our_csid,
						    "Error Sending GOAWAY message");
		} else
			clops->add_up_node(csid);

		return;
	}

	/* Allocate a default reply buffer */
	if ((replyargs = dm_malloc(max_cluster_message - sizeof(struct clvm_header))))
		/* Run the command */
		/* FIXME: usage of init_test() is unprotected */
		status = do_command(NULL, msg, msglen, &replyargs,
				    buflen, &replylen);
	else
		status = ENOMEM;

	/* If it wasn't a reply, then reply */
	if (msg->cmd != CLVMD_CMD_REPLY) {
		char *aggreply;

		aggreply = dm_realloc(replyargs, replylen + sizeof(struct clvm_header));
		if (aggreply) {
			struct clvm_header *agghead =
			    (struct clvm_header *) aggreply;

			replyargs = aggreply;
			/* Move it up so there's room for a header in front of the data */
			memmove(aggreply + offsetof(struct clvm_header, args),
				replyargs, replylen);

			agghead->xid = msg->xid;
			agghead->cmd = CLVMD_CMD_REPLY;
			agghead->status = status;
			agghead->flags = 0;
			agghead->clientid = msg->clientid;
			agghead->arglen = replylen;
			agghead->node[0] = '\0';
			send_message(aggreply, sizeof(struct clvm_header) + replylen,
				     csid, fd, "Error sending command reply");
		} else {
			/* Return a failure response */
			struct clvm_header reply = {
				.cmd = CLVMD_CMD_REPLY,
				.status = ENOMEM,
				.clientid = msg->clientid
			};
			DEBUGLOG("Error attempting to realloc return buffer\n");
			send_message(&reply, sizeof(reply), csid, fd,
				     "Error sending ENOMEM command reply");
		}
	}

	dm_free(replyargs);
}

/* Add a reply to a command to the list of replies for this client.
   If we have got a full set then send them to the waiting client down the local
   socket */
static void add_reply_to_list(struct local_client *client, int status,
			      const char *csid, const char *buf, int len)
{
	struct node_reply *reply;

	/* Add it to the list of replies */
	if (!(reply = dm_zalloc(sizeof(*reply)))) {
		/* It's all gone horribly wrong... */
		send_local_reply(client, ENOMEM, client->fd);
		return;
	}

	reply->status = status;
	clops->name_from_csid(csid, reply->node);
	DEBUGLOG("Reply from node %s: %d bytes\n", reply->node, len);

	if (len > 0) {
		if (!(reply->replymsg = dm_malloc(len)))
			reply->status = ENOMEM;
		else
			memcpy(reply->replymsg, buf, len);
	} else
		reply->replymsg = NULL;

	pthread_mutex_lock(&client->bits.localsock.mutex);

	if (client->bits.localsock.finished) {
		dm_free(reply->replymsg);
		dm_free(reply);
	} else {
		/* Hook it onto the reply chain */
		reply->next = client->bits.localsock.replies;
		client->bits.localsock.replies = reply;

		/* If we have the whole lot then do the post-process */
		/* Post-process the command */
		if (++client->bits.localsock.num_replies ==
		    client->bits.localsock.expected_replies) {
			client->bits.localsock.state = POST_COMMAND;
			pthread_cond_signal(&client->bits.localsock.cond);
		}
		DEBUGLOG("Got %d replies, expecting: %d\n",
			 client->bits.localsock.num_replies,
			 client->bits.localsock.expected_replies);
	}
	pthread_mutex_unlock(&client->bits.localsock.mutex);
}

/* This is the thread that runs the PRE and post commands for a particular connection */
static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
{
	struct local_client *client = (struct local_client *) arg;
	int status;
	int write_status;
	sigset_t ss;
	int pipe_fd = client->bits.localsock.pipe;

	DEBUGLOG("Pre&post thread (%p), pipe fd %d\n", client, pipe_fd);
	pthread_mutex_lock(&client->bits.localsock.mutex);

	/* Ignore SIGUSR1 (handled by master process) but enable
	   SIGUSR2 (kills subthreads) */
	sigemptyset(&ss);
	sigaddset(&ss, SIGUSR1);
	pthread_sigmask(SIG_BLOCK, &ss, NULL);

	sigdelset(&ss, SIGUSR1);
	sigaddset(&ss, SIGUSR2);
	pthread_sigmask(SIG_UNBLOCK, &ss, NULL);

	/* Loop around doing PRE and POST functions until the client goes away */
	while (!client->bits.localsock.finished) {
		/* Execute the code */
		/* FIXME: usage of init_test() is unprotected as in do_command() */
		if ((status = do_pre_command(client)))
			client->bits.localsock.all_success = 0;

		DEBUGLOG("Pre&post thread (%p) writes status %d down to pipe fd %d\n",
			 client, status, pipe_fd);

		/* Tell the parent process we have finished this bit */
		while ((write_status = write(pipe_fd, &status, sizeof(int))) != sizeof(int))
			if (write_status >=0 || (errno != EINTR && errno != EAGAIN)) {
				log_error("Error sending to pipe: %m");
				break;
			}

		if (status) {
			client->bits.localsock.state = POST_COMMAND;
			goto next_pre;
		}

		/* We may need to wait for the condition variable before running the post command */
		if (client->bits.localsock.state != POST_COMMAND &&
		    !client->bits.localsock.finished) {
			DEBUGLOG("Pre&post thread (%p) waiting to do post command, state = %d\n",
				 client, client->bits.localsock.state);
			pthread_cond_wait(&client->bits.localsock.cond,
					  &client->bits.localsock.mutex);
		}

		DEBUGLOG("Pre&post thread (%p) got post command condition...\n", client);

		/* POST function must always run, even if the client aborts */
		status = 0;
		do_post_command(client);

		while ((write_status = write(pipe_fd, &status, sizeof(int))) != sizeof(int))
			if (write_status >=0 || (errno != EINTR && errno != EAGAIN)) {
				log_error("Error sending to pipe: %m");
				break;
			}
next_pre:
		if (client->bits.localsock.state != PRE_COMMAND &&
		    !client->bits.localsock.finished) {
			DEBUGLOG("Pre&post thread (%p) waiting for next pre command\n", client);
			pthread_cond_wait(&client->bits.localsock.cond,
					  &client->bits.localsock.mutex);
		}

		DEBUGLOG("Pre&post thread (%p) got pre command condition...\n", client);
	}
	pthread_mutex_unlock(&client->bits.localsock.mutex);
	DEBUGLOG("Pre&post thread (%p) finished\n", client);

	pthread_exit(NULL);
}

/* Process a command on the local node and store the result */
static int process_local_command(struct clvm_header *msg, int msglen,
				 struct local_client *client,
				 unsigned short xid)
{
	char *replybuf;
	int buflen = max_cluster_message - sizeof(struct clvm_header) - 1;
	int replylen = 0;
	int status;

	if (!(replybuf = dm_malloc(max_cluster_message)))
		return -1;

	DEBUGLOG("process_local_command: %s msg=%p, msglen =%d, client=%p\n",
		 decode_cmd(msg->cmd), msg, msglen, client);

	/* If remote flag is set, just set a successful status code. */
	if (msg->flags & CLVMD_FLAG_REMOTE)
		status = 0;
	else
		status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);

	if (status)
		client->bits.localsock.all_success = 0;

	/* If we took too long then discard the reply */
	if (xid == client->xid)
		add_reply_to_list(client, status, our_csid, replybuf, replylen);
	else
		DEBUGLOG("Local command took too long, discarding xid %d, current is %d\n",
			 xid, client->xid);

	dm_free(replybuf);

	return status;
}

static int process_reply(const struct clvm_header *msg, int msglen, const char *csid)
{
	struct local_client *client;

	if (!(client = find_client(msg->clientid))) {
		DEBUGLOG("Got message for unknown client 0x%x\n",
			 msg->clientid);
		log_error("Got message for unknown client 0x%x.",
			  msg->clientid);
		return -1;
	}

	if (msg->status)
		client->bits.localsock.all_success = 0;

	/* Gather replies together for this client id */
	if (msg->xid == client->xid)
		add_reply_to_list(client, msg->status, csid, msg->args,
				  msg->arglen);
	else
		DEBUGLOG("Discarding reply with old XID %d, current = %d\n",
			 msg->xid, client->xid);

	return 0;
}

/* Send an aggregated reply back to the client */
static void send_local_reply(struct local_client *client, int status, int fd)
{
	struct clvm_header *clientreply;
	struct node_reply *thisreply = client->bits.localsock.replies;
	char *replybuf;
	char *ptr;
	int message_len = 0;

	DEBUGLOG("Send local reply\n");

	/* Work out the total size of the reply */
	while (thisreply) {
		if (thisreply->replymsg)
			message_len += strlen(thisreply->replymsg) + 1;
		else
			message_len++;

		message_len += strlen(thisreply->node) + 1 + sizeof(int);

		thisreply = thisreply->next;
	}

	/* Add in the size of our header */
	message_len = message_len + sizeof(struct clvm_header);
	if (!(replybuf = dm_malloc(message_len))) {
		DEBUGLOG("Memory allocation fails\n");
		return;
	}

	clientreply = (struct clvm_header *) replybuf;
	clientreply->status = status;
	clientreply->cmd = CLVMD_CMD_REPLY;
	clientreply->node[0] = '\0';
	clientreply->xid = 0;
	clientreply->clientid = 0;
	clientreply->flags = 0;

	ptr = clientreply->args;

	/* Add in all the replies, and free them as we go */
	thisreply = client->bits.localsock.replies;
	while (thisreply) {
		struct node_reply *tempreply = thisreply;

		strcpy(ptr, thisreply->node);
		ptr += strlen(thisreply->node) + 1;

		if (thisreply->status)
			clientreply->flags |= CLVMD_FLAG_NODEERRS;

		memcpy(ptr, &thisreply->status, sizeof(int));
		ptr += sizeof(int);

		if (thisreply->replymsg) {
			strcpy(ptr, thisreply->replymsg);
			ptr += strlen(thisreply->replymsg) + 1;
		} else {
			ptr[0] = '\0';
			ptr++;
		}
		thisreply = thisreply->next;

		dm_free(tempreply->replymsg);
		dm_free(tempreply);
	}

	/* Terminate with an empty node name */
	*ptr = '\0';

	clientreply->arglen = ptr - clientreply->args;

	/* And send it */
	send_message(replybuf, message_len, our_csid, fd,
		     "Error sending REPLY to client");
	dm_free(replybuf);

	/* Reset comms variables */
	client->bits.localsock.replies = NULL;
	client->bits.localsock.expected_replies = 0;
	client->bits.localsock.in_progress = FALSE;
	client->bits.localsock.sent_out = FALSE;
}

/* Just free a reply chain baceuse it wasn't used. */
static void free_reply(struct local_client *client)
{
	/* Add in all the replies, and free them as we go */
	struct node_reply *thisreply = client->bits.localsock.replies;
	while (thisreply) {
		struct node_reply *tempreply = thisreply;

		thisreply = thisreply->next;

		dm_free(tempreply->replymsg);
		dm_free(tempreply);
	}
	client->bits.localsock.replies = NULL;
}

/* Send our version number to the cluster */
static void send_version_message(void)
{
	char message[sizeof(struct clvm_header) + sizeof(int) * 3];
	struct clvm_header *msg = (struct clvm_header *) message;
	int version_nums[3] = {
		htonl(CLVMD_MAJOR_VERSION),
		htonl(CLVMD_MINOR_VERSION),
		htonl(CLVMD_PATCH_VERSION)
	};

	msg->cmd = CLVMD_CMD_VERSION;
	msg->status = 0;
	msg->flags = 0;
	msg->clientid = 0;
	msg->arglen = sizeof(version_nums);

	memcpy(&msg->args, version_nums, sizeof(version_nums));

	hton_clvm(msg);

	clops->cluster_send_message(message, sizeof(message), NULL,
				    "Error Sending version number");
}

/* Send a message to either a local client or another server */
static int send_message(void *buf, int msglen, const char *csid, int fd,
			const char *errtext)
{
	int len = 0;
	int ptr;
	struct timespec delay;
	struct timespec remtime;
	int retry_cnt = 0;

	/* Send remote messages down the cluster socket */
	if (!csid || !ISLOCAL_CSID(csid)) {
		hton_clvm((struct clvm_header *) buf);
		return clops->cluster_send_message(buf, msglen, csid, errtext);
	}

	/* Make sure it all goes */
	for (ptr = 0; ptr < msglen;) {
		if ((len = write(fd, (char*)buf + ptr, msglen - ptr)) <= 0) {
			if (errno == EINTR)
				continue;
			if ((errno == EAGAIN || errno == EIO || errno == ENOSPC) &&
			    ++retry_cnt < MAX_RETRIES) {
				delay.tv_sec = 0;
				delay.tv_nsec = 100000;
				remtime.tv_sec = 0;
				remtime.tv_nsec = 0;
				(void) nanosleep (&delay, &remtime);
				continue;
			}
			log_error("%s", errtext);
			break;
		}
		ptr += len;
	}

	return len;
}

static int process_work_item(struct lvm_thread_cmd *cmd)
{
	/* If msg is NULL then this is a cleanup request */
	if (cmd->msg == NULL) {
		DEBUGLOG("process_work_item: free %p\n", cmd->client);
		cmd_client_cleanup(cmd->client);
		pthread_mutex_destroy(&cmd->client->bits.localsock.mutex);
		pthread_cond_destroy(&cmd->client->bits.localsock.cond);
		dm_free(cmd->client);
		return 0;
	}

	if (!cmd->remote) {
		DEBUGLOG("process_work_item: local\n");
		process_local_command(cmd->msg, cmd->msglen, cmd->client,
				      cmd->xid);
	} else {
		DEBUGLOG("process_work_item: remote\n");
		process_remote_command(cmd->msg, cmd->msglen, cmd->client->fd,
				       cmd->csid);
	}

	return 0;
}

/*
 * Routine that runs in the "LVM thread".
 */
static void *lvm_thread_fn(void *arg)
{
	sigset_t ss;
	struct lvm_startup_params *lvm_params = arg;
	struct lvm_thread_cmd *cmd;

	DEBUGLOG("LVM thread function started\n");

	/* Ignore SIGUSR1 & 2 */
	sigemptyset(&ss);
	sigaddset(&ss, SIGUSR1);
	sigaddset(&ss, SIGUSR2);
	pthread_sigmask(SIG_BLOCK, &ss, NULL);

	/* Initialise the interface to liblvm */
	init_clvm(lvm_params->excl_uuid);

	/* Allow others to get moving */
	pthread_barrier_wait(&lvm_start_barrier);
	DEBUGLOG("LVM thread ready for work.\n");

	/* Now wait for some actual work */
	pthread_mutex_lock(&lvm_thread_mutex);

	for (;;) {
		while (!dm_list_empty(&lvm_cmd_head)) {
			cmd = dm_list_item(dm_list_first(&lvm_cmd_head),
					   struct lvm_thread_cmd);
			dm_list_del(&cmd->list);
			pthread_mutex_unlock(&lvm_thread_mutex);

			process_work_item(cmd);
			dm_free(cmd->msg);
			dm_free(cmd);

			pthread_mutex_lock(&lvm_thread_mutex);
		}

		if  (lvm_thread_exit)
			break;

		DEBUGLOG("LVM thread waiting for work\n");
		pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
	}

	pthread_mutex_unlock(&lvm_thread_mutex);
	DEBUGLOG("LVM thread exits\n");

	destroy_lvm();

	pthread_exit(NULL);
}

/* Pass down some work to the LVM thread */
static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
			   int msglen, const char *csid)
{
	struct lvm_thread_cmd *cmd;

	if (!(cmd = dm_malloc(sizeof(*cmd))))
		return ENOMEM;

	if (msglen) {
		if (!(cmd->msg = dm_malloc(msglen))) {
			log_error("Unable to allocate buffer space.");
			dm_free(cmd);
			return -1;
		}
		memcpy(cmd->msg, msg, msglen);
	}
	else
		cmd->msg = NULL;

	cmd->client = client;
	cmd->msglen = msglen;
	cmd->xid = client->xid;

	if (csid) {
		memcpy(cmd->csid, csid, max_csid_len);
		cmd->remote = 1;
	} else
		cmd->remote = 0;

	DEBUGLOG("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
		 cmd, client, msg, msglen, csid, cmd->xid);
	pthread_mutex_lock(&lvm_thread_mutex);
	if (lvm_thread_exit) {
		pthread_mutex_unlock(&lvm_thread_mutex);
		dm_free(cmd->msg);
		dm_free(cmd);
		return -1; /* We are about to exit */
	}
	dm_list_add(&lvm_cmd_head, &cmd->list);
	pthread_cond_signal(&lvm_thread_cond);
	pthread_mutex_unlock(&lvm_thread_mutex);

	return 0;
}

/* Return 0 if we can talk to an existing clvmd */
static int check_local_clvmd(void)
{
	int local_socket;
	int ret = 0;
	struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };

	if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
		log_error("%s: clvmd socket name too long.", CLVMD_SOCKNAME);
		return -1;
	}

	/* Open local socket */
	if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
		log_sys_error("socket", "local socket");
		return -1;
	}

	if (connect(local_socket,(struct sockaddr *) &sockaddr,
		    sizeof(sockaddr))) {
		log_sys_error("connect", "local socket");
		ret = -1;
	}

	if (close(local_socket))
		log_sys_error("close", "local socket");

	return ret;
}

static void close_local_sock(int local_socket)
{
	if (local_socket != -1 && close(local_socket))
		log_sys_error("close", CLVMD_SOCKNAME);

	if (CLVMD_SOCKNAME[0] != '\0' && unlink(CLVMD_SOCKNAME))
		stack;
}

/* Open the local socket, that's the one we talk to libclvm down */
static int open_local_sock(void)
{
	mode_t old_mask;
	int local_socket = -1;
	struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };

	if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
		log_error("%s: clvmd socket name too long.", CLVMD_SOCKNAME);
		return -1;
	}

	close_local_sock(local_socket);

	(void) dm_prepare_selinux_context(CLVMD_SOCKNAME, S_IFSOCK);
	old_mask = umask(0077);

	/* Open local socket */
	if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
		log_error("Can't create local socket: %m");
		goto error;
	}

	/* Set Close-on-exec & non-blocking */
	if (fcntl(local_socket, F_SETFD, 1))
		DEBUGLOG("setting CLOEXEC on local_socket failed: %s\n", strerror(errno));
	if (fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK))
		DEBUGLOG("setting O_NONBLOCK on local_socket failed: %s\n", strerror(errno));


	if (bind(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
		log_error("can't bind local socket: %m");
		goto error;
	}
	if (listen(local_socket, 1) != 0) {
		log_error("listen local: %m");
		goto error;
	}

	umask(old_mask);
	(void) dm_prepare_selinux_context(NULL, 0);
	return local_socket;
error:
	close_local_sock(local_socket);
	umask(old_mask);
	(void) dm_prepare_selinux_context(NULL, 0);
	return -1;
}

void process_message(struct local_client *client, char *buf, int len,
		     const char *csid)
{
	char nodename[max_cluster_member_name_len];
	struct clvm_header *inheader = (struct clvm_header *) buf;
	ntoh_clvm(inheader);	/* Byteswap fields */

	if (verify_message(buf, len) < 0) {
		clops->name_from_csid(csid, nodename);
		log_error("process_message from %s len %d bad verify.", nodename, len);
		dump_message(buf, len);
		return;
	}

	if (inheader->cmd == CLVMD_CMD_REPLY)
		process_reply(inheader, len, csid);
	else
		add_to_lvmqueue(client, inheader, len, csid);
}


static void check_all_callback(struct local_client *client, const char *csid,
			       int node_up)
{
	if (!node_up)
		add_reply_to_list(client, EHOSTDOWN, csid, "CLVMD not running", 18);
}

/* Check to see if all CLVMDs are running (ie one on
   every node in the cluster).
   If not, returns -1 and prints out a list of errant nodes */
static int check_all_clvmds_running(struct local_client *client)
{
	DEBUGLOG("check_all_clvmds_running\n");
	return clops->cluster_do_node_callback(client, check_all_callback);
}

/* Return a local_client struct given a client ID.
   client IDs are in network byte order */
static struct local_client *find_client(int clientid)
{
	struct local_client *thisfd;

	for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next)
		if (thisfd->fd == (int)ntohl(clientid))
			return thisfd;

	return NULL;
}

/* Byte-swapping routines for the header so we
   work in a heterogeneous environment */
static void hton_clvm(struct clvm_header *hdr)
{
	hdr->status = htonl(hdr->status);
	hdr->arglen = htonl(hdr->arglen);
	hdr->xid = htons(hdr->xid);
	/* Don't swap clientid as it's only a token as far as
	   remote nodes are concerned */
}

static void ntoh_clvm(struct clvm_header *hdr)
{
	hdr->status = ntohl(hdr->status);
	hdr->arglen = ntohl(hdr->arglen);
	hdr->xid = ntohs(hdr->xid);
}

/* Handler for SIGUSR2 - sent to kill subthreads */
static void sigusr2_handler(int sig)
{
	DEBUGLOG("SIGUSR2 received\n");
	return;
}

static void sigterm_handler(int sig)
{
	quit = 1;
	return;
}

static void sighup_handler(int sig)
{
	reread_config = 1;
}

int sync_lock(const char *resource, int mode, int flags, int *lockid)
{
	return clops->sync_lock(resource, mode, flags, lockid);
}

int sync_unlock(const char *resource, int lockid)
{
	return clops->sync_unlock(resource, lockid);
}

static if_type_t parse_cluster_interface(char *ifname)
{
	if_type_t iface = IF_AUTO;

	if (!strcmp(ifname, "auto"))
		iface = IF_AUTO;
	else if (!strcmp(ifname, "cman"))
		iface = IF_CMAN;
	else if (!strcmp(ifname, "openais"))
		iface = IF_OPENAIS;
	else if (!strcmp(ifname, "corosync"))
		iface = IF_COROSYNC;
	else if (!strcmp(ifname, "singlenode"))
		iface = IF_SINGLENODE;

	return iface;
}

/*
 * Try and find a cluster system in corosync's objdb, if it is running. This is
 * only called if the command-line option is not present, and if it fails
 * we still try the interfaces in order.
 */
static if_type_t get_cluster_type(void)
{
#ifdef HAVE_COROSYNC_CONFDB_H
	confdb_handle_t handle;
	if_type_t type = IF_AUTO;
	int result;
	char buf[255];
	size_t namelen = sizeof(buf);
	hdb_handle_t cluster_handle;
	hdb_handle_t clvmd_handle;
	confdb_callbacks_t callbacks = { 0 };

	result = confdb_initialize (&handle, &callbacks);
	if (result != CS_OK)
		return type;

	result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
	if (result != CS_OK)
		goto out;

	result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
	if (result != CS_OK)
		goto out;

	result = confdb_object_find_start(handle, cluster_handle);
	if (result != CS_OK)
		goto out;

	result = confdb_object_find(handle, cluster_handle, (void *)"clvmd", strlen("clvmd"), &clvmd_handle);
	if (result != CS_OK)
		goto out;

	result = confdb_key_get(handle, clvmd_handle, (void *)"interface", strlen("interface"), buf, &namelen);
	if (result != CS_OK)
		goto out;

	if (namelen >= sizeof(buf))
		namelen = sizeof(buf) - 1;

	buf[namelen] = '\0';
	type = parse_cluster_interface(buf);
	DEBUGLOG("got interface type '%s' from confdb\n", buf);
out:
	confdb_finalize(handle);
	return type;
#else
	return IF_AUTO;
#endif
}
