/*
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-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 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 command processor.

  To add commands to the daemon simply add a processor in do_command and return
  and messages back in buf and the length in *retlen. The initial value of
  buflen is the maximum size of the buffer. if buf is not large enough then it
  may be reallocated by the functions in here to a suitable size bearing in
  mind that anything larger than the passed-in size will have to be returned
  using the system LV and so performance will suffer.

  The status return will be negated and passed back to the originating node.

  pre- and post- command routines are called only on the local node. The
  purpose is primarily to get and release locks, though the pre- routine should
  also do any other local setups required by the command (if any) and can
  return a failure code that prevents the command from being distributed around
  the cluster

  The pre- and post- routines are run in their own thread so can block as long
  they like, do_command is run in the main clvmd thread so should not block for
  too long. If the pre-command returns an error code (!=0) then the command
  will not be propogated around the cluster but the post-command WILL be called

  Also note that the pre and post routine are *always* called on the local
  node, even if the command to be executed was only requested to run on a
  remote node. It may peek inside the client structure to check the status of
  the command.

  The clients of the daemon must, naturally, understand the return messages and
  codes.

  Routines in here may only READ the values in the client structure passed in
  apart from client->private which they are free to do what they like with.

*/

#include "clvmd-common.h"
#include "clvmd-comms.h"
#include "clvm.h"
#include "clvmd.h"
#include "lvm-globals.h"
#include "lvm-functions.h"

#include "locking.h"

#include <sys/utsname.h>

extern struct cluster_ops *clops;
static int restart_clvmd(void);

/* This is where all the real work happens:
   NOTE: client will be NULL when this is executed on a remote node */
int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
	       char **buf, int buflen, int *retlen)
{
	char *args = msg->node + strlen(msg->node) + 1;
	int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
	int status = 0;
	char *lockname;
	const char *locktype;
	struct utsname nodeinfo;
	unsigned char lock_cmd;
	unsigned char lock_flags;

	/* Do the command */
	switch (msg->cmd) {
		/* Just a test message */
	case CLVMD_CMD_TEST:
		if (arglen > buflen) {
			char *new_buf;
			buflen = arglen + 200;
			new_buf = realloc(*buf, buflen);
			if (new_buf == NULL) {
				status = errno;
				free (*buf);
			}
			*buf = new_buf;
		}
		if (*buf) {
			if (uname(&nodeinfo))
				memset(&nodeinfo, 0, sizeof(nodeinfo));

			*retlen = 1 + dm_snprintf(*buf, buflen,
						  "TEST from %s: %s v%s",
						  nodeinfo.nodename, args,
						  nodeinfo.release);
		}
		break;

	case CLVMD_CMD_LOCK_VG:
		lock_cmd = args[0];
		lock_flags = args[1];
		lockname = &args[2];
		/* Check to see if the VG is in use by LVM1 */
		status = do_check_lvm1(lockname);
		do_lock_vg(lock_cmd, lock_flags, lockname);
		break;

	case CLVMD_CMD_LOCK_LV:
		/* This is the biggie */
		lock_cmd = args[0];
		lock_flags = args[1];
		lockname = &args[2];
		status = do_lock_lv(lock_cmd, lock_flags, lockname);
		/* Replace EIO with something less scary */
		if (status == EIO) {
			*retlen = 1 + dm_snprintf(*buf, buflen, "%s",
						  get_last_lvm_error());
			return EIO;
		}
		break;

	case CLVMD_CMD_LOCK_QUERY:
		lockname = &args[2];
		if (buflen < 3)
			return EIO;
		if ((locktype = do_lock_query(lockname)))
			*retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
		break;

	case CLVMD_CMD_REFRESH:
		do_refresh_cache();
		break;

	case CLVMD_CMD_SYNC_NAMES:
		lvm_do_fs_unlock();
		break;

	case CLVMD_CMD_SET_DEBUG:
		clvmd_set_debug((debug_t) args[0]);
		break;

	case CLVMD_CMD_RESTART:
		status = restart_clvmd();
		break;

	case CLVMD_CMD_GET_CLUSTERNAME:
		status = clops->get_cluster_name(*buf, buflen);
		if (!status)
			*retlen = strlen(*buf)+1;
		break;

	case CLVMD_CMD_VG_BACKUP:
		/*
		 * Do not run backup on local node, caller should do that.
		 */
		if (!client)
			lvm_do_backup(&args[2]);
		break;

	default:
		/* Won't get here because command is validated in pre_command */
		break;
	}

	/* Check the status of the command and return the error text */
	if (status) {
		*retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
						    strerror(status)) : -1);
	}

	return status;
}

static int lock_vg(struct local_client *client)
{
	struct dm_hash_table *lock_hash;
	struct clvm_header *header =
		(struct clvm_header *) client->bits.localsock.cmd;
	unsigned char lock_cmd;
	int lock_mode;
	char *args = header->node + strlen(header->node) + 1;
	int lkid;
	int status;
	char *lockname;

	/*
	 * Keep a track of VG locks in our own hash table. In current
	 * practice there should only ever be more than two VGs locked
	 * if a user tries to merge lots of them at once
	 */
	if (!client->bits.localsock.private) {
		if (!(lock_hash = dm_hash_create(3)))
			return ENOMEM;
		client->bits.localsock.private = (void *) lock_hash;
	} else
		lock_hash = (struct dm_hash_table *) client->bits.localsock.private;

	lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
	lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
	/* lock_flags = args[1]; */
	lockname = &args[2];
	DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);

	if (lock_mode == LCK_UNLOCK) {
		if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
			return EINVAL;

		if ((status = sync_unlock(lockname, lkid)))
			status = errno;
		else
			dm_hash_remove(lock_hash, lockname);
	} else {
		/* Read locks need to be PR; other modes get passed through */
		if (lock_mode == LCK_READ)
			lock_mode = LCK_PREAD;

		if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
			status = errno;
		else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
			return ENOMEM;
	}

	return status;
}


/* Pre-command is a good place to get locks that are needed only for the duration
   of the commands around the cluster (don't forget to free them in post-command),
   and to sanity check the command arguments */
int do_pre_command(struct local_client *client)
{
	struct clvm_header *header =
	    (struct clvm_header *) client->bits.localsock.cmd;
	unsigned char lock_cmd;
	unsigned char lock_flags;
	char *args = header->node + strlen(header->node) + 1;
	int lockid = 0;
	int status = 0;
	char *lockname;

	switch (header->cmd) {
	case CLVMD_CMD_TEST:
		status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
		client->bits.localsock.private = (void *)(long)lockid;
		break;

	case CLVMD_CMD_LOCK_VG:
		lockname = &args[2];
		/* We take out a real lock unless LCK_CACHE was set */
		if (!strncmp(lockname, "V_", 2) ||
		    !strncmp(lockname, "P_#", 3))
			status = lock_vg(client);
		break;

	case CLVMD_CMD_LOCK_LV:
		lock_cmd = args[0];
		lock_flags = args[1];
		lockname = &args[2];
		status = pre_lock_lv(lock_cmd, lock_flags, lockname);
		break;

	case CLVMD_CMD_REFRESH:
	case CLVMD_CMD_GET_CLUSTERNAME:
	case CLVMD_CMD_SET_DEBUG:
	case CLVMD_CMD_VG_BACKUP:
	case CLVMD_CMD_SYNC_NAMES:
	case CLVMD_CMD_LOCK_QUERY:
	case CLVMD_CMD_RESTART:
		break;

	default:
		log_error("Unknown command %d received\n", header->cmd);
		status = EINVAL;
	}
	return status;
}

/* Note that the post-command routine is called even if the pre-command or the real command
   failed */
int do_post_command(struct local_client *client)
{
	struct clvm_header *header =
	    (struct clvm_header *) client->bits.localsock.cmd;
	int status = 0;
	unsigned char lock_cmd;
	unsigned char lock_flags;
	char *args = header->node + strlen(header->node) + 1;
	char *lockname;

	switch (header->cmd) {
	case CLVMD_CMD_TEST:
		status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
		client->bits.localsock.private = NULL;
		break;

	case CLVMD_CMD_LOCK_LV:
		lock_cmd = args[0];
		lock_flags = args[1];
		lockname = &args[2];
		status = post_lock_lv(lock_cmd, lock_flags, lockname);
		break;

	default:
		/* Nothing to do here */
		break;
	}
	return status;
}


/* Called when the client is about to be deleted */
void cmd_client_cleanup(struct local_client *client)
{
	struct dm_hash_node *v;
	struct dm_hash_table *lock_hash;
	int lkid;
	char *lockname;

	DEBUGLOG("Client thread cleanup (%p)\n", client);
	if (!client->bits.localsock.private)
		return;

	lock_hash = (struct dm_hash_table *)client->bits.localsock.private;

	dm_hash_iterate(v, lock_hash) {
		lkid = (int)(long)dm_hash_get_data(lock_hash, v);
		lockname = dm_hash_get_key(lock_hash, v);
		DEBUGLOG("Cleanup (%p): Unlocking lock %s %x\n", client, lockname, lkid);
		(void) sync_unlock(lockname, lkid);
	}

	dm_hash_destroy(lock_hash);
	client->bits.localsock.private = NULL;
}

static int restart_clvmd(void)
{
	const char **argv;
	char *lv_name;
	int argc = 0, max_locks = 0;
	struct dm_hash_node *hn = NULL;
	char debug_arg[16];
	const char *clvmd = getenv("LVM_CLVMD_BINARY") ? : CLVMD_PATH;

	DEBUGLOG("clvmd restart requested\n");

	/* Count exclusively-open LVs */
	do {
		hn = get_next_excl_lock(hn, &lv_name);
		if (lv_name) {
			max_locks++;
			if (!*lv_name)
				break; /* FIXME: Is this error ? */
		}
	} while (hn);

	/* clvmd + locks (-E uuid) + debug (-d X) + NULL */
	if (!(argv = malloc((max_locks * 2 + 6) * sizeof(*argv))))
		goto_out;

	/*
	 * Build the command-line
	 */
	argv[argc++] = "clvmd";

	/* Propagate debug options */
	if (clvmd_get_debug()) {
		if (dm_snprintf(debug_arg, sizeof(debug_arg), "-d%u", clvmd_get_debug()) < 0)
			goto_out;
		argv[argc++] = debug_arg;
	}

	/* Propagate foreground options */
	if (clvmd_get_foreground())
		argv[argc++] = "-f";

	argv[argc++] = "-I";
	argv[argc++] = clops->name;

	/* Now add the exclusively-open LVs */
	hn = NULL;
	do {
		hn = get_next_excl_lock(hn, &lv_name);
		if (lv_name) {
			if (!*lv_name)
				break; /* FIXME: Is this error ? */
			argv[argc++] = "-E";
			argv[argc++] = lv_name;
			DEBUGLOG("excl lock: %s\n", lv_name);
		}
	} while (hn);
	argv[argc] = NULL;

	/* Exec new clvmd */
	DEBUGLOG("--- Restarting %s ---\n", clvmd);
	for (argc = 1; argv[argc]; argc++) DEBUGLOG("--- %d: %s\n", argc, argv[argc]);

	/* NOTE: This will fail when downgrading! */
	execvp(clvmd, (char **)argv);
out:
	/* We failed */
	DEBUGLOG("Restart of clvmd failed.\n");

	free(argv);

	return EIO;
}
