static int do_drop(void)
{
	daemon_reply reply;
	int result;
	int rv;

	syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name);

	/*
	 * Check for misuse by looking for any active LVs in the VG
	 * and refusing this operation if found?  One possible way
	 * to kill LVs (e.g. if fs cannot be unmounted) is to suspend
	 * them, or replace them with the error target.  In that
	 * case the LV will still appear to be active, but it is
	 * safe to release the lock.
	 */

	reply = _lvmlockd_send("drop_vg",
				"cmd = %s", "lvmlockctl",
				"pid = " FMTd64, (int64_t) getpid(),
				"vg_name = %s", arg_vg_name,
				NULL);

	if (!_lvmlockd_result(reply, &result)) {
		log_error("lvmlockd result %d", result);
		rv = result;
	} else {
		rv = 0;
	}

	daemon_reply_destroy(reply);
	return rv;
}
static int do_stop_lockspaces(void)
{
	daemon_reply reply;
	char opts[32];
	int result;
	int rv;

	memset(opts, 0, sizeof(opts));

	if (wait_opt)
		strcat(opts, "wait ");
	if (force_opt)
		strcat(opts, "force ");

	reply = _lvmlockd_send("stop_all",
				"cmd = %s", "lvmlockctl",
				"pid = " FMTd64, (int64_t) getpid(),
				"opts = %s", opts[0] ? opts : "none",
				NULL);

	if (!_lvmlockd_result(reply, &result)) {
		log_error("lvmlockd result %d", result);
		rv = result;
	} else {
		rv = 0;
	}

	daemon_reply_destroy(reply);
	return rv;
}
static int do_dump(const char *req_name)
{
	daemon_reply reply;
	int result;
	int fd, rv = 0;
	int count = 0;

	fd = setup_dump_socket();
	if (fd < 0) {
		log_error("socket error %d", fd);
		return fd;
	}

	reply = daemon_send_simple(_lvmlockd, req_name, NULL);

	if (reply.error) {
		log_error("reply error %d", reply.error);
		rv = reply.error;
		goto out;
	}

	result = daemon_reply_int(reply, "result", 0);
	dump_len = daemon_reply_int(reply, "dump_len", 0);

	daemon_reply_destroy(reply);

	if (result < 0) {
		rv = result;
		log_error("result %d", result);
	}

	if (!dump_len)
		goto out;

	memset(dump_buf, 0, sizeof(dump_buf));

retry:
	rv = recvfrom(fd, dump_buf + count, dump_len - count, MSG_WAITALL,
		      (struct sockaddr *)&dump_addr, &dump_addrlen);
	if (rv < 0) {
		log_error("recvfrom error %d %d", rv, errno);
		rv = -errno;
		goto out;
	}
	count += rv;

	if (count < dump_len)
		goto retry;

	rv = 0;
	if ((info && dump) || !strcmp(req_name, "dump"))
		printf("%s\n", dump_buf);
	else
		format_info();
out:
	if (close(fd))
		log_error("failed to close dump socket %d", fd);
	return rv;
}
static int do_quit(void)
{
	daemon_reply reply;
	int rv = 0;

	reply = daemon_send_simple(_lvmlockd, "quit", NULL);

	if (reply.error) {
		log_error("reply error %d", reply.error);
		rv = reply.error;
	}

	daemon_reply_destroy(reply);
	return rv;
}
static int do_kill(void)
{
	daemon_reply reply;
	int result;
	int rv;

	syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name);
	/* These two lines explain the manual alternative to the FIXME below. */
	syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name);
	syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);

	/*
	 * It may not be strictly necessary to notify lvmlockd of the kill, but
	 * lvmlockd can use this information to avoid attempting any new lock
	 * requests in the VG (which would fail anyway), and can return an
	 * error indicating that the VG has been killed.
	 */

	reply = _lvmlockd_send("kill_vg",
				"cmd = %s", "lvmlockctl",
				"pid = " FMTd64, (int64_t) getpid(),
				"vg_name = %s", arg_vg_name,
				NULL);

	if (!_lvmlockd_result(reply, &result)) {
		log_error("lvmlockd result %d", result);
		rv = result;
	} else {
		rv = 0;
	}

	daemon_reply_destroy(reply);

	/*
	 * FIXME: here is where we should implement a strong form of
	 * blkdeactivate, and if it completes successfully, automatically call
	 * do_drop() afterward.  (The drop step may not always be necessary
	 * if the lvm commands run while shutting things down release all the
	 * leases.)
	 *
	 * run_strong_blkdeactivate();
	 * do_drop();
	 */

	return rv;
}
static int do_able(const char *req_name)
{
	daemon_reply reply;
	int result;
	int rv;

	reply = _lvmlockd_send(req_name,
				"cmd = %s", "lvmlockctl",
				"pid = " FMTd64, (int64_t) getpid(),
				"vg_name = %s", arg_vg_name,
				NULL);

	if (!_lvmlockd_result(reply, &result)) {
		log_error("lvmlockd result %d", result);
		rv = result;
	} else {
		rv = 0;
	}

	daemon_reply_destroy(reply);
	return rv;
}
Example #7
0
int main(int argc, char **argv)
{
	daemon_reply reply;
	char *cmd;
	char *uuid;
	char *name;
	int val;
	int ver;

	if (argc < 2) {
		printf("lvmetactl dump\n");
		printf("lvmetactl pv_list\n");
		printf("lvmetactl vg_list\n");
		printf("lvmetactl vg_lookup_name <name>\n");
		printf("lvmetactl vg_lookup_uuid <uuid>\n");
		printf("lvmetactl pv_lookup_uuid <uuid>\n");
		printf("lvmetactl set_global_invalid 0|1\n");
		printf("lvmetactl get_global_invalid\n");
		printf("lvmetactl set_vg_version <uuid> <name> <version>\n");
		printf("lvmetactl vg_lock_type <uuid>\n");
		return -1;
	}

	cmd = argv[1];

	h = lvmetad_open(NULL);

	if (!strcmp(cmd, "dump")) {
		reply = daemon_send_simple(h, "dump",
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "pv_list")) {
		reply = daemon_send_simple(h, "pv_list",
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "vg_list")) {
		reply = daemon_send_simple(h, "vg_list",
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "set_global_invalid")) {
		if (argc < 3) {
			printf("set_global_invalid 0|1\n");
			return -1;
		}
		val = atoi(argv[2]);

		reply = daemon_send_simple(h, "set_global_info",
					   "global_invalid = %d", val,
					   "token = %s", "skip",
					   NULL);
		print_reply(reply);

	} else if (!strcmp(cmd, "get_global_invalid")) {
		reply = daemon_send_simple(h, "get_global_info",
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "set_vg_version")) {
		if (argc < 5) {
			printf("set_vg_version <uuid> <name> <ver>\n");
			return -1;
		}
		uuid = argv[2];
		name = argv[3];
		ver = atoi(argv[4]);

		if ((strlen(uuid) == 1) && (uuid[0] == '-'))
			uuid = NULL;
		if ((strlen(name) == 1) && (name[0] == '-'))
			name = NULL;

		if (uuid && name) {
			reply = daemon_send_simple(h, "set_vg_info",
						   "uuid = %s", uuid,
						   "name = %s", name,
						   "version = %d", ver,
						    "token = %s", "skip",
						    NULL);
		} else if (uuid) {
			reply = daemon_send_simple(h, "set_vg_info",
						   "uuid = %s", uuid,
						   "version = %d", ver,
						    "token = %s", "skip",
						    NULL);
		} else if (name) {
			reply = daemon_send_simple(h, "set_vg_info",
						   "name = %s", name,
						   "version = %d", ver,
						    "token = %s", "skip",
						    NULL);
		} else {
			printf("name or uuid required\n");
			return -1;
		}

		print_reply(reply);

	} else if (!strcmp(cmd, "vg_lookup_name")) {
		if (argc < 3) {
			printf("vg_lookup_name <name>\n");
			return -1;
		}
		name = argv[2];

		reply = daemon_send_simple(h, "vg_lookup",
					   "name = %s", name,
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "vg_lookup_uuid")) {
		if (argc < 3) {
			printf("vg_lookup_uuid <uuid>\n");
			return -1;
		}
		uuid = argv[2];

		reply = daemon_send_simple(h, "vg_lookup",
					   "uuid = %s", uuid,
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else if (!strcmp(cmd, "vg_lock_type")) {
		struct dm_config_node *metadata;
		const char *lock_type;

		if (argc < 3) {
			printf("vg_lock_type <uuid>\n");
			return -1;
		}
		uuid = argv[2];

		reply = daemon_send_simple(h, "vg_lookup",
					   "uuid = %s", uuid,
					   "token = %s", "skip",
					   NULL);
		/* printf("%s\n", reply.buffer.mem); */

		metadata = dm_config_find_node(reply.cft->root, "metadata");
		if (!metadata) {
			printf("no metadata\n");
			goto out;
		}

		lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL);
		if (!lock_type) {
			printf("no lock_type\n");
			goto out;
		}
		printf("lock_type %s\n", lock_type);

	} else if (!strcmp(cmd, "pv_lookup_uuid")) {
		if (argc < 3) {
			printf("pv_lookup_uuid <uuid>\n");
			return -1;
		}
		uuid = argv[2];

		reply = daemon_send_simple(h, "pv_lookup",
					   "uuid = %s", uuid,
					   "token = %s", "skip",
					   NULL);
		printf("%s\n", reply.buffer.mem);

	} else {
		printf("unknown command\n");
		goto out_close;
	}
out:
	daemon_reply_destroy(reply);
out_close:
	daemon_close(h);
	return 0;
}