/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "tools.h"

struct vgchange_params {
	int lock_start_count;
	unsigned int lock_start_sanlock : 1;
};

/*
 * Increments *count by the number of _new_ monitored devices.
 */
static int _monitor_lvs_in_vg(struct cmd_context *cmd,
			      struct volume_group *vg, int reg, int *count)
{
	struct lv_list *lvl;
	struct logical_volume *lv;
	int r = 1;

	dm_list_iterate_items(lvl, &vg->lvs) {
		lv = lvl->lv;

		if (!lv_info(cmd, lv, lv_is_thin_pool(lv) ? 1 : 0,
			     NULL, 0, 0))
			continue;
		/*
		 * FIXME: Need to consider all cases... PVMOVE, etc
		 */
		if (lv_is_pvmove(lv))
			continue;

		if (!monitor_dev_for_events(cmd, lv, 0, reg)) {
			r = 0;
			continue;
		}

		(*count)++;
	}

	return r;
}

static int _poll_lvs_in_vg(struct cmd_context *cmd,
			   struct volume_group *vg)
{
	struct lv_list *lvl;
	struct logical_volume *lv;
	struct lvinfo info;
	int lv_active;
	int count = 0;

	dm_list_iterate_items(lvl, &vg->lvs) {
		lv = lvl->lv;

		if (!lv_info(cmd, lv, 0, &info, 0, 0))
			lv_active = 0;
		else
			lv_active = info.exists;

		if (lv_active &&
		    (lv_is_pvmove(lv) || lv_is_converting(lv) || lv_is_merging(lv))) {
			lv_spawn_background_polling(cmd, lv);
			count++;
		}
	}

	/*
	 * returns the number of polled devices
	 * - there is no way to know if lv is already being polled
	 */

	return count;
}

static int _activate_lvs_in_vg(struct cmd_context *cmd, struct volume_group *vg,
			       activation_change_t activate)
{
	struct lv_list *lvl;
	struct logical_volume *lv;
	int count = 0, expected_count = 0, r = 1;

	sigint_allow();
	dm_list_iterate_items(lvl, &vg->lvs) {
		if (sigint_caught())
			return_0;

		lv = lvl->lv;

		if (!lv_is_visible(lv))
			continue;

		/* If LV is sparse, activate origin instead */
		if (lv_is_cow(lv) && lv_is_virtual_origin(origin_from_cow(lv)))
			lv = origin_from_cow(lv);

		/* Only request activation of snapshot origin devices */
		if ((lv->status & SNAPSHOT) || lv_is_cow(lv))
			continue;

		/* Only request activation of mirror LV */
		if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG))
			continue;

		/* Only request activation of the first replicator-dev LV */
		/* Avoids retry with all heads in case of failure */
		if (lv_is_replicator_dev(lv) && (lv != first_replicator_dev(lv)))
			continue;

		if (lv_activation_skip(lv, activate, arg_is_set(cmd, ignoreactivationskip_ARG)))
			continue;

		if ((activate == CHANGE_AAY) &&
		    !lv_passes_auto_activation_filter(cmd, lv))
			continue;

		expected_count++;

		if (!lv_change_activate(cmd, lv, activate)) {
			if (!lv_is_active_exclusive_remotely(lv))
				stack;
			else {
				/*
				 * If the LV is active exclusive remotely,
				 * then ignore it here
				 */
				log_verbose("%s/%s is exclusively active on"
					    " a remote node", vg->name, lv->name);
				expected_count--; /* not accounted */
			}
			continue;
		}

		count++;
	}

	sigint_restore();

	/* Wait until devices are available */
	if (!sync_local_dev_names(vg->cmd)) {
		log_error("Failed to sync local devices for VG %s.", vg->name);
		r = 0;
	}

	if (expected_count)
		log_verbose("%s %d logical volumes in volume group %s",
			    is_change_activating(activate) ?
			    "Activated" : "Deactivated", count, vg->name);

	return (expected_count != count) ? 0 : r;
}

static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg)
{
	int r = 1;
	int monitored = 0;

	if (lvs_in_vg_activated(vg) &&
	    dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
		if (!_monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored))
			r = 0;
		log_print_unless_silent("%d logical volume(s) in volume group "
					"\"%s\" %smonitored",
					monitored, vg->name, (dmeventd_monitor_mode()) ? "" : "un");
	}

	return r;
}

int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg)
{
	int polled;

	if (lvs_in_vg_activated(vg) && background_polling()) {
	        polled = _poll_lvs_in_vg(cmd, vg);
		if (polled)
			log_print_unless_silent("Background polling started for %d logical volume(s) "
						"in volume group \"%s\"",
						polled, vg->name);
	}

	return 1;
}

int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
		      activation_change_t activate)
{
	int lv_open, active, monitored = 0, r = 1;
	const struct lv_list *lvl;
	int do_activate = is_change_activating(activate);

	/*
	 * We can get here in the odd case where an LV is already active in
	 * a foreign VG, which allows the VG to be accessed by vgchange -a
	 * so the LV can be deactivated.
	 */
	if (vg->system_id && vg->system_id[0] &&
	    cmd->system_id && cmd->system_id[0] &&
	    strcmp(vg->system_id, cmd->system_id) &&
	    do_activate) {
		log_error("Cannot activate LVs in a foreign VG.");
		return ECMD_FAILED;
	}

	/*
	 * Safe, since we never write out new metadata here. Required for
	 * partial activation to work.
	 */
        cmd->handles_missing_pvs = 1;

	/* FIXME: Force argument to deactivate them? */
	if (!do_activate && (lv_open = lvs_in_vg_opened(vg))) {
		dm_list_iterate_items(lvl, &vg->lvs)
			if (lv_is_visible(lvl->lv) &&
			    !lv_check_not_in_use(lvl->lv, 1)) {
				log_error("Can't deactivate volume group \"%s\" with %d open "
					  "logical volume(s)", vg->name, lv_open);
				return 0;
			}
	}

	/* FIXME Move into library where clvmd can use it */
	if (do_activate)
		check_current_backup(vg);

	if (do_activate && (active = lvs_in_vg_activated(vg))) {
		log_verbose("%d logical volume(s) in volume group \"%s\" "
			    "already active", active, vg->name);
		if (dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) {
			if (!_monitor_lvs_in_vg(cmd, vg, dmeventd_monitor_mode(), &monitored))
				r = 0;
			log_verbose("%d existing logical volume(s) in volume "
				    "group \"%s\" %smonitored",
				    monitored, vg->name,
				    dmeventd_monitor_mode() ? "" : "un");
		}
	}

	if (!_activate_lvs_in_vg(cmd, vg, activate)) {
		stack;
		r = 0;
	}

	/* Print message only if there was not found a missing VG */
	if (!vg->cmd_missing_vgs)
		log_print_unless_silent("%d logical volume(s) in volume group \"%s\" now active",
					lvs_in_vg_activated(vg), vg->name);
	return r;
}

static int _vgchange_refresh(struct cmd_context *cmd, struct volume_group *vg)
{
	log_verbose("Refreshing volume group \"%s\"", vg->name);

	if (!vg_refresh_visible(cmd, vg))
		return_0;

	return 1;
}

static int _vgchange_alloc(struct cmd_context *cmd, struct volume_group *vg)
{
	alloc_policy_t alloc;

	alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL);

	/* FIXME: make consistent with vg_set_alloc_policy() */
	if (alloc == vg->alloc) {
		log_error("Volume group allocation policy is already %s",
			  get_alloc_string(vg->alloc));
		return 0;
	}

	if (!vg_set_alloc_policy(vg, alloc))
		return_0;

	return 1;
}

static int _vgchange_resizeable(struct cmd_context *cmd,
				struct volume_group *vg)
{
	int resizeable = arg_int_value(cmd, resizeable_ARG, 0);

	if (resizeable && vg_is_resizeable(vg)) {
		log_error("Volume group \"%s\" is already resizeable",
			  vg->name);
		return 0;
	}

	if (!resizeable && !vg_is_resizeable(vg)) {
		log_error("Volume group \"%s\" is already not resizeable",
			  vg->name);
		return 0;
	}

	if (resizeable)
		vg->status |= RESIZEABLE_VG;
	else
		vg->status &= ~RESIZEABLE_VG;

	return 1;
}

static int _vgchange_clustered(struct cmd_context *cmd,
			       struct volume_group *vg)
{
	int clustered = arg_int_value(cmd, clustered_ARG, 0);
	const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
	struct lv_list *lvl;
	struct lv_segment *mirror_seg;

	if (find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL)) {
		log_error("lvmlockd requires using the vgchange --lock-type option.");
		return 0;
	}

	if (lock_type && !strcmp(lock_type, "clvm"))
		clustered = 1;

	if (clustered && vg_is_clustered(vg)) {
		if (vg->system_id && *vg->system_id)
			log_warn("WARNING: Clearing invalid system ID %s from volume group %s.",
				 vg->system_id, vg->name);
		else {
			log_error("Volume group \"%s\" is already clustered", vg->name);
			return 0;
		}
	}

	if (!clustered && !vg_is_clustered(vg)) {
		if ((!vg->system_id || !*vg->system_id) && cmd->system_id && *cmd->system_id)
			log_warn("Setting missing system ID on Volume Group %s to %s.",
				 vg->name, cmd->system_id);
		else {
			log_error("Volume group \"%s\" is already not clustered",
				  vg->name);
			return 0;
		}
	}

	if (clustered && !arg_is_set(cmd, yes_ARG)) {
		if (!clvmd_is_running()) {
			if (yes_no_prompt("LVM cluster daemon (clvmd) is not running. "
					  "Make volume group \"%s\" clustered "
					  "anyway? [y/n]: ", vg->name) == 'n') {
				log_error("No volume groups changed.");
				return 0;
			}

		} else if (!locking_is_clustered() &&
			   (yes_no_prompt("LVM locking type is not clustered. "
					  "Make volume group \"%s\" clustered "
					  "anyway? [y/n]: ", vg->name) == 'n')) {
			log_error("No volume groups changed.");
			return 0;
		}
#ifdef CMIRROR_REGION_COUNT_LIMIT
		dm_list_iterate_items(lvl, &vg->lvs) {
			if (!lv_is_mirror(lvl->lv))
				continue;
			mirror_seg = first_seg(lvl->lv);
			if ((lvl->lv->size / mirror_seg->region_size) >
			    CMIRROR_REGION_COUNT_LIMIT) {
				log_error("Unable to convert %s to clustered mode:"
					  " Mirror region size of %s is too small.",
					  vg->name, lvl->lv->name);
				return 0;
			}
		}
#endif
	}

	if (!vg_set_system_id(vg, clustered ? NULL : cmd->system_id))
		return_0;

	if (!vg_set_clustered(vg, clustered))
		return_0;

	return 1;
}

static int _vgchange_logicalvolume(struct cmd_context *cmd,
				   struct volume_group *vg)
{
	uint32_t max_lv = arg_uint_value(cmd, logicalvolume_ARG, 0);

	if (!vg_set_max_lv(vg, max_lv))
		return_0;

	return 1;
}

static int _vgchange_physicalvolumes(struct cmd_context *cmd,
				     struct volume_group *vg)
{
	uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);

	if (!vg_set_max_pv(vg, max_pv))
		return_0;

	return 1;
}

static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg)
{
	uint32_t extent_size;

	if (arg_uint64_value(cmd, physicalextentsize_ARG, 0) > MAX_EXTENT_SIZE) {
		log_warn("Physical extent size cannot be larger than %s.",
			 display_size(cmd, (uint64_t) MAX_EXTENT_SIZE));
		return 1;
	}

	extent_size = arg_uint_value(cmd, physicalextentsize_ARG, 0);
	/* FIXME: remove check - redundant with vg_change_pesize */
	if (extent_size == vg->extent_size) {
		log_warn("Physical extent size of VG %s is already %s.",
			 vg->name, display_size(cmd, (uint64_t) extent_size));
		return 1;
	}

	if (!vg_set_extent_size(vg, extent_size))
		return_0;

	if (!vg_check_pv_dev_block_sizes(vg)) {
		log_error("Failed to change physical extent size for VG %s.",
			   vg->name);
		return 0;
	}

	return 1;
}

static int _vgchange_addtag(struct cmd_context *cmd, struct volume_group *vg)
{
	return change_tag(cmd, vg, NULL, NULL, addtag_ARG);
}

static int _vgchange_deltag(struct cmd_context *cmd, struct volume_group *vg)
{
	return change_tag(cmd, vg, NULL, NULL, deltag_ARG);
}

static int _vgchange_uuid(struct cmd_context *cmd __attribute__((unused)),
			  struct volume_group *vg)
{
	struct lv_list *lvl;

	if (lvs_in_vg_activated(vg)) {
		log_error("Volume group has active logical volumes");
		return 0;
	}

	if (!id_create(&vg->id)) {
		log_error("Failed to generate new random UUID for VG %s.",
			  vg->name);
		return 0;
	}

	dm_list_iterate_items(lvl, &vg->lvs) {
		memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
	}

	return 1;
}

static int _vgchange_metadata_copies(struct cmd_context *cmd,
				     struct volume_group *vg)
{
	uint32_t mda_copies = arg_uint_value(cmd, vgmetadatacopies_ARG, DEFAULT_VGMETADATACOPIES);

	if (mda_copies == vg_mda_copies(vg)) {
		if (vg_mda_copies(vg) == VGMETADATACOPIES_UNMANAGED)
			log_warn("Number of metadata copies for VG %s is already unmanaged.",
				 vg->name);
		else
			log_warn("Number of metadata copies for VG %s is already %u.",
				 vg->name, mda_copies);
		return 1;
	}

	if (!vg_set_mda_copies(vg, mda_copies))
		return_0;

	return 1;
}

static int _vgchange_profile(struct cmd_context *cmd,
			     struct volume_group *vg)
{
	const char *old_profile_name, *new_profile_name;
	struct profile *new_profile;

	old_profile_name = vg->profile ? vg->profile->name : "(no profile)";

	if (arg_is_set(cmd, detachprofile_ARG)) {
		new_profile_name = "(no profile)";
		vg->profile = NULL;
	} else {
		if (arg_is_set(cmd, metadataprofile_ARG))
			new_profile_name = arg_str_value(cmd, metadataprofile_ARG, NULL);
		else
			new_profile_name = arg_str_value(cmd, profile_ARG, NULL);
		if (!(new_profile = add_profile(cmd, new_profile_name, CONFIG_PROFILE_METADATA)))
			return_0;
		vg->profile = new_profile;
	}

	log_verbose("Changing configuration profile for VG %s: %s -> %s.",
		    vg->name, old_profile_name, new_profile_name);

	return 1;
}

static int _vgchange_locktype(struct cmd_context *cmd,
			      struct volume_group *vg)
{
	const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
	struct lv_list *lvl;
	struct logical_volume *lv;
	int lv_lock_count = 0;

	/*
	 * This is a special/forced exception to change the lock type to none.
	 * It's needed for recovery cases and skips the normal steps of undoing
	 * the current lock type.  It's a way to forcibly get access to a VG
	 * when the normal locking mechanisms are not working.
	 *
	 * It ignores: the current lvm locking config, lvmlockd, the state of
	 * the vg on other hosts, etc.  It is meant to just remove any locking
	 * related metadata from the VG (cluster/lock_type flags, lock_type,
	 * lock_args).
	 *
	 * This can be necessary when manually recovering from certain failures.
	 * e.g. when a pv is lost containing the lvmlock lv (holding sanlock
	 * leases), the vg lock_type needs to be changed to none, and then
	 * back to sanlock, which recreates the lvmlock lv and leases.
	 */
	if (!strcmp(lock_type, "none") && arg_is_set(cmd, force_ARG)) {
		if (yes_no_prompt("Forcibly change VG %s lock type to none? [y/n]: ", vg->name) == 'n') {
			log_error("VG lock type not changed.");
			return 0;
		}

		vg->status &= ~CLUSTERED;
		vg->lock_type = "none";
		vg->lock_args = NULL;

		dm_list_iterate_items(lvl, &vg->lvs)
			lvl->lv->lock_args = NULL;

		return 1;
	}

	if (!vg->lock_type) {
		if (vg_is_clustered(vg))
			vg->lock_type = "clvm";
		else
			vg->lock_type = "none";
	}

	if (!strcmp(vg->lock_type, lock_type)) {
		log_warn("New lock type %s matches the current lock type %s.",
			 lock_type, vg->lock_type);
		return 1;
	}

	if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
		log_error("Cannot change lock type directly from \"%s\" to \"%s\".",
			  vg->lock_type, lock_type);
		log_error("First change lock type to \"none\", then to \"%s\".",
			  lock_type);
		return 0;
	}

	/*
	 * When lvm is currently using clvm, this function is just an alternative
	 * to vgchange -c{y,n}, and can:
	 * - change none to clvm
	 * - change clvm to none
	 * - it CANNOT change to or from a lockd type
	 */
	if (locking_is_clustered()) {
		if (is_lockd_type(lock_type)) {
			log_error("Changing to lock type %s requires lvmlockd.", lock_type);
			return 0;
		}

		return _vgchange_clustered(cmd, vg);
	}

	/*
	 * When lvm is currently using lvmlockd, this function can:
	 * - change none to lockd type
	 * - change none to clvm (with warning about not being able to use it)
	 * - change lockd type to none
	 * - change lockd type to clvm (with warning about not being able to use it)
	 * - change clvm to none
	 * - change clvm to lockd type
	 */

	if (lvs_in_vg_activated(vg)) {
		log_error("Changing VG %s lock type not allowed with active LVs",
			  vg->name);
		return 0;
	}

	/* none to clvm */
	if (!strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
		log_warn("New clvm lock type will not be usable with lvmlockd.");
		vg->status |= CLUSTERED;
		vg->lock_type = "clvm"; /* this is optional */
		return 1;
	}

	/* clvm to none */
	if (!strcmp(vg->lock_type, "clvm") && !strcmp(lock_type, "none")) {
		vg->status &= ~CLUSTERED;
		vg->lock_type = "none";
		return 1;
	}

	/* clvm to ..., first undo clvm */
	if (!strcmp(vg->lock_type, "clvm")) {
		vg->status &= ~CLUSTERED;
	}

	/*
	 * lockd type to ..., first undo lockd type
	 */
	if (is_lockd_type(vg->lock_type)) {
		if (!lockd_free_vg_before(cmd, vg, 1))
			return 0;

		lockd_free_vg_final(cmd, vg);

		vg->status &= ~CLUSTERED;
		vg->lock_type = "none";
		vg->lock_args = NULL;

		dm_list_iterate_items(lvl, &vg->lvs)
			lvl->lv->lock_args = NULL;
	}

	/* ... to clvm */
	if (!strcmp(lock_type, "clvm")) {
		log_warn("New clvm lock type will not be usable with lvmlockd.");
		vg->status |= CLUSTERED;
		vg->lock_type = "clvm"; /* this is optional */
		vg->system_id = NULL;
		return 1;
	}

	/* ... to lockd type */
	if (is_lockd_type(lock_type)) {
		/*
		 * For lock_type dlm, lockd_init_vg() will do a single
		 * vg_write() that sets lock_type, sets lock_args, clears
		 * system_id, and sets all LV lock_args to dlm.
		 * For lock_type sanlock, lockd_init_vg() needs to know
		 * how many LV locks are needed so that it can make the
		 * sanlock lv large enough.
		 */
		dm_list_iterate_items(lvl, &vg->lvs) {
			lv = lvl->lv;

			if (lockd_lv_uses_lock(lv)) {
				lv_lock_count++;

				if (!strcmp(lock_type, "dlm"))
					lv->lock_args = "dlm";
			}
		}

		/*
		 * See below.  We cannot set valid LV lock_args until stage 1
		 * of the change is done, so we need to skip the validation of
		 * the lock_args during stage 1.
		 */
		if (!strcmp(lock_type, "sanlock"))
			vg->skip_validate_lock_args = 1;

		vg->system_id = NULL;

		if (!lockd_init_vg(cmd, vg, lock_type, lv_lock_count)) {
			log_error("Failed to initialize lock args for lock type %s", lock_type);
			return 0;
		}

		/*
		 * For lock_type sanlock, there must be multiple steps
		 * because the VG needs an active lvmlock LV before
		 * LV lock areas can be allocated, which must be done
		 * before LV lock_args are written.  So, the LV lock_args
		 * remain unset during the first stage of the conversion.
		 *
		 * Stage 1:
		 * lockd_init_vg() creates and activates the lvmlock LV,
		 * then sets lock_type, sets lock_args, and clears system_id.
		 *
		 * Stage 2:
		 * We get here, and can now set LV lock_args.  This uses
		 * the standard code path for allocating LV locks in
		 * vg_write() by setting LV lock_args to "pending",
		 * which tells vg_write() to call lockd_init_lv()
		 * and sets the lv->lock_args value before writing the VG.
		 */
		if (!strcmp(lock_type, "sanlock")) {
			dm_list_iterate_items(lvl, &vg->lvs) {
				lv = lvl->lv;
				if (lockd_lv_uses_lock(lv))
					lv->lock_args = "pending";
			}

			vg->skip_validate_lock_args = 0;
		}

		return 1;
	}

	/* ... to none */
	if (!strcmp(lock_type, "none")) {
		vg->lock_type = NULL;
		vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
		return 1;
	}

	log_error("Cannot change to unknown lock type %s", lock_type);
	return 0;
}

/*
 * This function will not be called unless the local host is allowed to use the
 * VG.  Either the VG has no system_id, or the VG and host have matching
 * system_ids, or the host has the VG's current system_id in its
 * extra_system_ids list.  This function is not allowed to change the system_id
 * of a foreign VG (VG owned by another host).
 */
static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg)
{
	const char *system_id;
	const char *system_id_arg_str = arg_str_value(cmd, systemid_ARG, NULL);

	/* FIXME Merge with vg_set_system_id() */
	if (systemid_on_pvs(vg)) {
		log_error("Metadata format %s does not support this type of system ID.",
			  vg->fid->fmt->name);
		return 0;
	}

	if (!(system_id = system_id_from_string(cmd, system_id_arg_str))) {
		log_error("Unable to set system ID.");
		return 0;
	}

	if (!strcmp(vg->system_id, system_id)) {
		log_error("Volume Group system ID is already \"%s\".", vg->system_id);
		return 0;
	}

	if (!*system_id && cmd->system_id && strcmp(system_id, cmd->system_id)) {
		log_warn("WARNING: Removing the system ID allows unsafe access from other hosts.");

		if (!arg_is_set(cmd, yes_ARG) &&
		    yes_no_prompt("Remove system ID %s from volume group %s? [y/n]: ",
				  vg->system_id, vg->name) == 'n') {
			log_error("System ID of volume group %s not changed.", vg->name);
			return 0;
		}
	}

	if (*system_id && (!cmd->system_id || strcmp(system_id, cmd->system_id))) {
		if (lvs_in_vg_activated(vg)) {
			log_error("Logical Volumes in VG %s must be deactivated before system ID can be changed.",
				  vg->name);
			return 0;
		}

		if (cmd->system_id)
			log_warn("WARNING: Requested system ID %s does not match local system ID %s.",
				 system_id, cmd->system_id ? : "");
		else
			log_warn("WARNING: No local system ID is set.");
		log_warn("WARNING: Volume group %s might become inaccessible from this machine.",
			 vg->name);

		if (!arg_is_set(cmd, yes_ARG) &&
		    yes_no_prompt("Set foreign system ID %s on volume group %s? [y/n]: ",
				  system_id, vg->name) == 'n') {
			log_error("Volume group %s system ID not changed.", vg->name);
			return 0;
		}
	}

	log_verbose("Changing system ID for VG %s from \"%s\" to \"%s\".",
		    vg->name, vg->system_id, system_id);

	vg->system_id = system_id;
	
	if (vg->lvm1_system_id)
		*vg->lvm1_system_id = '\0';

	return 1;
}

static int _passes_lock_start_filter(struct cmd_context *cmd,
				     struct volume_group *vg,
				     const int cfg_id)
{
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	const char *str;

	/* undefined list means no restrictions, all vg names pass */

	cn = find_config_tree_array(cmd, cfg_id, NULL);
	if (!cn)
		return 1;

	/* with a defined list, the vg name must be included to pass */

	for (cv = cn->v; cv; cv = cv->next) {
		if (cv->type == DM_CFG_EMPTY_ARRAY)
			break;
		if (cv->type != DM_CFG_STRING) {
			log_error("Ignoring invalid string in lock_start list");
			continue;
		}
		str = cv->v.str;
		if (!*str) {
			log_error("Ignoring empty string in config file");
			continue;
		}

		/* ignoring tags for now */

		if (!strcmp(str, vg->name))
			return 1;
	}

	return 0;
}

static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg,
				struct vgchange_params *vp)
{
	const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
	int auto_opt = 0;
	int r;

	if (!is_lockd_type(vg->lock_type))
		return 1;

	if (arg_is_set(cmd, force_ARG))
		goto do_start;

	/*
	 * Recognize both "auto" and "autonowait" options.
	 * Any waiting is done at the end of vgchange.
	 */
	if (start_opt && !strncmp(start_opt, "auto", 4))
		auto_opt = 1;

	if (!_passes_lock_start_filter(cmd, vg, activation_lock_start_list_CFG)) {
		log_verbose("Not starting %s since it does not pass lock_start_list", vg->name);
		return 1;
	}

	if (auto_opt && !_passes_lock_start_filter(cmd, vg, activation_auto_lock_start_list_CFG)) {
		log_verbose("Not starting %s since it does not pass auto_lock_start_list", vg->name);
		return 1;
	}

do_start:
	r = lockd_start_vg(cmd, vg, 0);

	if (r)
		vp->lock_start_count++;
	if (!strcmp(vg->lock_type, "sanlock"))
		vp->lock_start_sanlock = 1;

	return r;
}

static int _vgchange_lock_stop(struct cmd_context *cmd, struct volume_group *vg)
{
	return lockd_stop_vg(cmd, vg);
}

static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
			   struct volume_group *vg,
			   struct processing_handle *handle)
{
	struct vgchange_params *vp = (struct vgchange_params *)handle->custom_handle;
	int ret = ECMD_PROCESSED;
	unsigned i;
	struct lv_list *lvl;

	static const struct {
		int arg;
		int (*fn)(struct cmd_context *cmd, struct volume_group *vg);
	} _vgchange_args[] = {
		{ logicalvolume_ARG, &_vgchange_logicalvolume },
		{ maxphysicalvolumes_ARG, &_vgchange_physicalvolumes },
		{ resizeable_ARG, &_vgchange_resizeable },
		{ deltag_ARG, &_vgchange_deltag },
		{ addtag_ARG, &_vgchange_addtag },
		{ physicalextentsize_ARG, &_vgchange_pesize },
		{ uuid_ARG, &_vgchange_uuid },
		{ alloc_ARG, &_vgchange_alloc },
		{ clustered_ARG, &_vgchange_clustered },
		{ vgmetadatacopies_ARG, &_vgchange_metadata_copies },
		{ metadataprofile_ARG, &_vgchange_profile },
		{ profile_ARG, &_vgchange_profile },
		{ detachprofile_ARG, &_vgchange_profile },
		{ locktype_ARG, &_vgchange_locktype },
		{ systemid_ARG, &_vgchange_system_id },
	};

	if (vg_is_exported(vg) &&
	    !(arg_is_set(cmd, lockstop_ARG) || arg_is_set(cmd, lockstart_ARG))) {
		log_error("Volume group \"%s\" is exported", vg_name);
		return ECMD_FAILED;
	}

	/*
	 * FIXME: DEFAULT_BACKGROUND_POLLING should be "unspecified".
	 * If --poll is explicitly provided use it; otherwise polling
	 * should only be started if the LV is not already active. So:
	 * 1) change the activation code to say if the LV was actually activated
	 * 2) make polling of an LV tightly coupled with LV activation
	 *
	 * Do not initiate any polling if --sysinit option is used.
	 */
	init_background_polling(arg_is_set(cmd, sysinit_ARG) ? 0 :
						arg_int_value(cmd, poll_ARG,
						DEFAULT_BACKGROUND_POLLING));

	for (i = 0; i < DM_ARRAY_SIZE(_vgchange_args); ++i) {
		if (arg_is_set(cmd, _vgchange_args[i].arg)) {
			if (!archive(vg))
				return_ECMD_FAILED;
			if (!_vgchange_args[i].fn(cmd, vg))
				return_ECMD_FAILED;
		}
	}

	if (vg_is_archived(vg)) {
		if (!vg_write(vg) || !vg_commit(vg))
			return_ECMD_FAILED;

		backup(vg);

		log_print_unless_silent("Volume group \"%s\" successfully changed", vg->name);

		/* FIXME: fix clvmd bug and take DLM lock for non clustered VGs. */
		if (arg_is_set(cmd, clustered_ARG) &&
		    vg_is_clustered(vg) && /* just switched to clustered */
		    locking_is_clustered() &&
		    locking_supports_remote_queries())
			dm_list_iterate_items(lvl, &vg->lvs) {
				if ((lv_lock_holder(lvl->lv) != lvl->lv) ||
				    !lv_is_active(lvl->lv))
					continue;

				if (!activate_lv_excl_local(cmd, lvl->lv) ||
				    !lv_is_active_exclusive_locally(lvl->lv)) {
					log_error("Can't reactive logical volume %s, "
						  "please fix manually.",
						  display_lvname(lvl->lv));
					ret = ECMD_FAILED;
				}

				if (lv_is_mirror(lvl->lv))
					/* Give hint for clustered mirroring */
					log_print_unless_silent("For clustered mirroring of %s "
								"deactivation and activation is needed.",
								display_lvname(lvl->lv));
			}
	}

	if (arg_is_set(cmd, activate_ARG)) {
		if (!vgchange_activate(cmd, vg, (activation_change_t)
				       arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
			return_ECMD_FAILED;
	}

	if (arg_is_set(cmd, refresh_ARG)) {
		/* refreshes the visible LVs (which starts polling) */
		if (!_vgchange_refresh(cmd, vg))
			return_ECMD_FAILED;
	}

	if (!arg_is_set(cmd, activate_ARG) &&
	    !arg_is_set(cmd, refresh_ARG) &&
	    arg_is_set(cmd, monitor_ARG)) {
		/* -ay* will have already done monitoring changes */
		if (!_vgchange_monitoring(cmd, vg))
			return_ECMD_FAILED;
	}

	if (!arg_is_set(cmd, refresh_ARG) &&
	    !vgchange_background_polling(cmd, vg))
			return_ECMD_FAILED;

	if (arg_is_set(cmd, lockstart_ARG)) {
		if (!_vgchange_lock_start(cmd, vg, vp))
			return_ECMD_FAILED;
	} else if (arg_is_set(cmd, lockstop_ARG)) {
		if (!_vgchange_lock_stop(cmd, vg))
			return_ECMD_FAILED;
	}

        return ret;
}

/*
 * vgchange can do different things that require different
 * locking, so look at each of those things here.
 *
 * Set up overrides for the default VG locking for various special cases.
 * The VG lock will be acquired in process_each_vg.
 *
 * Acquire the gl lock according to which kind of vgchange command this is.
 */

static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
{
	/* The default vg lock mode is ex, but these options only need sh. */

	if (!lvmlockd_use() && arg_is_set(cmd, locktype_ARG)) {
		log_error("Using lock type requires lvmlockd.");
		return 0;
	}

	if (!lvmlockd_use() && (arg_is_set(cmd, lockstart_ARG) || arg_is_set(cmd, lockstop_ARG))) {
		log_error("Using lock start and lock stop requires lvmlockd.");
		return 0;
	}

	if (arg_is_set(cmd, activate_ARG) || arg_is_set(cmd, refresh_ARG)) {
		cmd->lockd_vg_default_sh = 1;
		/* Allow deactivating if locks fail. */
		if (is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
			cmd->lockd_vg_enforce_sh = 1;
	}

	if (arg_is_set(cmd, lockstop_ARG))
		cmd->lockd_vg_default_sh = 1;

	/*
	 * Starting lockspaces.  For VGs not yet started, locks are not
	 * available to acquire, and for VGs already started, there's nothing
	 * to do, so disable VG locks.  Try to acquire the global lock sh to
	 * validate the cache (if no gl is available, lockd_gl will force a
	 * cache validation).  If the global lock is available, it can be
	 * benficial to hold sh to serialize lock-start with vgremove of the
	 * same VG from another host.
	 */
	if (arg_is_set(cmd, lockstart_ARG)) {
		cmd->lockd_vg_disable = 1;

		if (!lockd_gl(cmd, "sh", 0))
			log_debug("No global lock for lock start");

		/* Disable the lockd_gl in process_each_vg. */
		cmd->lockd_gl_disable = 1;
		return 1;
	}

	/*
	 * Changing system_id or lock_type must only be done on explicitly
	 * named vgs.
	 */

	if (arg_is_set(cmd, systemid_ARG) || arg_is_set(cmd, locktype_ARG))
		cmd->command->flags &= ~ALL_VGS_IS_DEFAULT;

	if (arg_is_set(cmd, systemid_ARG) || arg_is_set(cmd, locktype_ARG)) {
		/*
		 * This is a special case where taking the global lock is
		 * not needed to protect global state, because the change is
		 * only to an existing VG.  But, taking the global lock ex is
		 * helpful in this case to trigger a global cache validation
		 * on other hosts, to cause them to see the new system_id or
		 * lock_type.
		 */
		if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES))
			return 0;
	}

	return 1;
}

int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
	struct processing_handle *handle;
	struct vgchange_params vp = { 0 };
	uint32_t flags = 0;
	int ret;

	int noupdate =
		arg_is_set(cmd, activate_ARG) ||
		arg_is_set(cmd, lockstart_ARG) ||
		arg_is_set(cmd, lockstop_ARG) ||
		arg_is_set(cmd, monitor_ARG) ||
		arg_is_set(cmd, poll_ARG) ||
		arg_is_set(cmd, refresh_ARG);

	int update_partial_safe =
		arg_is_set(cmd, deltag_ARG) ||
		arg_is_set(cmd, addtag_ARG) ||
		arg_is_set(cmd, metadataprofile_ARG) ||
		arg_is_set(cmd, profile_ARG) ||
		arg_is_set(cmd, detachprofile_ARG);

	int update_partial_unsafe =
		arg_is_set(cmd, logicalvolume_ARG) ||
		arg_is_set(cmd, maxphysicalvolumes_ARG) ||
		arg_is_set(cmd, resizeable_ARG) ||
		arg_is_set(cmd, uuid_ARG) ||
		arg_is_set(cmd, physicalextentsize_ARG) ||
		arg_is_set(cmd, clustered_ARG) ||
		arg_is_set(cmd, alloc_ARG) ||
		arg_is_set(cmd, vgmetadatacopies_ARG) ||
		arg_is_set(cmd, locktype_ARG) ||
		arg_is_set(cmd, systemid_ARG);

	int update = update_partial_safe || update_partial_unsafe;

	if (!update && !noupdate) {
		log_error("Need one or more command options.");
		return EINVALID_CMD_LINE;
	}

	if ((arg_is_set(cmd, profile_ARG) || arg_is_set(cmd, metadataprofile_ARG)) &&
	     arg_is_set(cmd, detachprofile_ARG)) {
		log_error("Only one of --metadataprofile and --detachprofile permitted.");
		return EINVALID_CMD_LINE;
	}

	if (arg_is_set(cmd, activate_ARG) && arg_is_set(cmd, refresh_ARG)) {
		log_error("Only one of -a and --refresh permitted.");
		return EINVALID_CMD_LINE;
	}

	if ((arg_is_set(cmd, ignorelockingfailure_ARG) ||
	     arg_is_set(cmd, sysinit_ARG)) && update) {
		log_error("Only -a permitted with --ignorelockingfailure and --sysinit");
		return EINVALID_CMD_LINE;
	}

	if (arg_is_set(cmd, activate_ARG) &&
	    (arg_is_set(cmd, monitor_ARG) || arg_is_set(cmd, poll_ARG))) {
		if (!is_change_activating((activation_change_t) arg_uint_value(cmd, activate_ARG, 0))) {
			log_error("Only -ay* allowed with --monitor or --poll.");
			return EINVALID_CMD_LINE;
		}
	}

	if (arg_is_set(cmd, poll_ARG) && arg_is_set(cmd, sysinit_ARG)) {
		log_error("Only one of --poll and --sysinit permitted.");
		return EINVALID_CMD_LINE;
	}

	if (arg_is_set(cmd, activate_ARG) &&
	    arg_is_set(cmd, autobackup_ARG)) {
		log_error("-A option not necessary with -a option");
		return EINVALID_CMD_LINE;
	}

	if (arg_is_set(cmd, maxphysicalvolumes_ARG) &&
	    arg_sign_value(cmd, maxphysicalvolumes_ARG, SIGN_NONE) == SIGN_MINUS) {
		log_error("MaxPhysicalVolumes may not be negative");
		return EINVALID_CMD_LINE;
	}

	if (arg_is_set(cmd, physicalextentsize_ARG) &&
	    arg_sign_value(cmd, physicalextentsize_ARG, SIGN_NONE) == SIGN_MINUS) {
		log_error("Physical extent size may not be negative");
		return EINVALID_CMD_LINE;
	}

	/*
	 * If --sysinit -aay is used and at the same time lvmetad is used,
	 * we want to rely on autoactivation to take place. Also, we
	 * need to take special care here as lvmetad service does
	 * not neet to be running at this moment yet - it could be
	 * just too early during system initialization time.
	 */
	if (arg_is_set(cmd, sysinit_ARG) && (arg_uint_value(cmd, activate_ARG, 0) == CHANGE_AAY)) {
		if (lvmetad_used()) {
			log_warn("WARNING: lvmetad is active, skipping direct activation during sysinit");
			return ECMD_PROCESSED;
		}
	}

	if (arg_is_set(cmd, clustered_ARG) && !argc && !arg_is_set(cmd, yes_ARG) &&
	    (yes_no_prompt("Change clustered property of all volumes groups? [y/n]: ") == 'n')) {
		log_error("No volume groups changed.");
		return ECMD_FAILED;
	}

	if (!update || !update_partial_unsafe)
		cmd->handles_missing_pvs = 1;

	/*
	 * Include foreign VGs that contain active LVs.
	 * That shouldn't happen in general, but if it does by some
	 * mistake, then we want to allow those LVs to be deactivated.
	 */
	if (arg_is_set(cmd, activate_ARG))
		cmd->include_active_foreign_vgs = 1;

	if (!_lockd_vgchange(cmd, argc, argv))
		return_ECMD_FAILED;

	if (update)
		flags |= READ_FOR_UPDATE;
	if (arg_is_set(cmd, lockstart_ARG) || arg_is_set(cmd, lockstop_ARG))
		flags |= READ_ALLOW_EXPORTED;

	if (!(handle = init_processing_handle(cmd, NULL))) {
		log_error("Failed to initialize processing handle.");
		return ECMD_FAILED;
	}

	handle->custom_handle = &vp;

	ret = process_each_vg(cmd, argc, argv, NULL, NULL, flags, 0, handle, &vgchange_single);

	/* Wait for lock-start ops that were initiated in vgchange_lockstart. */

	if (arg_is_set(cmd, lockstart_ARG) && vp.lock_start_count) {
		const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);

		if (!lockd_gl(cmd, "un", 0))
			stack;

		if (!start_opt || !strcmp(start_opt, "auto")) {
			if (vp.lock_start_sanlock)
				log_print_unless_silent("Starting locking.  Waiting for sanlock may take 20 sec to 3 min...");
			else
				log_print_unless_silent("Starting locking.  Waiting until locks are ready...");
			lockd_start_wait(cmd);
		} else if (!strcmp(start_opt, "nowait") || !strcmp(start_opt, "autonowait")) {
			log_print_unless_silent("Starting locking.  VG can only be read until locks are ready.");
		}
	}

	destroy_processing_handle(cmd, handle);
	return ret;
}
