/*
 * Copyright (C) 2016 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"
#include "lvmcache.h"
#include "lvmetad-client.h"
#include "filter.h"

struct vgimportclone_params {
	unsigned done;
	unsigned total;

	int import_vg;
	int found_args;
	struct dm_list arg_import;
	const char *base_vgname;
	const char *old_vgname;
	const char *new_vgname;
};

struct vgimportclone_device {
	struct dm_list list;
	struct device *dev;
	unsigned found_in_vg : 1;
};

static int _vgimportclone_pv_single(struct cmd_context *cmd, struct volume_group *vg,
				    struct physical_volume *pv, struct processing_handle *handle)
{
	struct vgimportclone_params *vp = (struct vgimportclone_params *) handle->custom_handle;
	struct vgimportclone_device *vd;

	if (vg && is_orphan_vg(vg->name)) {
		log_error("Cannot import clone of orphan PV %s.", dev_name(pv->dev));
		return ECMD_FAILED;
	}

	if (!(vd = dm_pool_zalloc(cmd->mem, sizeof(*vd)))) {
		log_error("alloc failed.");
		return ECMD_FAILED;
	}

	vd->dev = pv->dev;
	dm_list_add(&vp->arg_import, &vd->list);

	log_debug("vgimportclone dev %s VG %s found to import",
		  dev_name(vd->dev), vg ? vg->name : "<none>");

	vp->found_args++;

	return ECMD_PROCESSED;
}

static int _vgimportclone_vg_single(struct cmd_context *cmd, const char *vg_name,
		                    struct volume_group *vg, struct processing_handle *handle)
{
	char uuid[64] __attribute__((aligned(8)));
	struct vgimportclone_params *vp = (struct vgimportclone_params *) handle->custom_handle;
	struct vgimportclone_device *vd;
	struct pv_list *pvl, *new_pvl;
	struct lv_list *lvl;
	int devs_used_for_lv = 0;
	int found;

	if (vg_is_exported(vg) && !vp->import_vg) {
		log_error("VG %s is exported, use the --import option.", vg->name);
		goto_bad;
	}

	if (vg_status(vg) & PARTIAL_VG) {
		log_error("VG %s is partial, it must be complete.", vg->name);
		goto_bad;
	}

	/*
	 * N.B. lvs_in_vg_activated() is not smart enough to distinguish
	 * between LVs that are active in the original VG vs the cloned VG
	 * that's being imported, so check DEV_USED_FOR_LV.
	 */
	dm_list_iterate_items(pvl, &vg->pvs) {
		if (pvl->pv->dev->flags & DEV_USED_FOR_LV) {
			log_error("Device %s has active LVs, deactivate first.", dev_name(pvl->pv->dev));
			devs_used_for_lv++;
		}
	}

	if (devs_used_for_lv)
		goto_bad;

	/*
	 * The arg_import list must match the PVs in VG.
	 */

	dm_list_iterate_items(pvl, &vg->pvs) {
		found = 0;

		dm_list_iterate_items(vd, &vp->arg_import) {
			if (pvl->pv->dev != vd->dev)
				continue;
			vd->found_in_vg = 1;
			found = 1;
			break;
		}

		if (!found) {
			if (!id_write_format(&pvl->pv->id, uuid, sizeof(uuid)))
				goto_bad;

			/* all PVs in the VG must be imported together, pvl is missing from args. */
			log_error("PV with UUID %s is part of VG %s, but is not included in the devices to import.",
				   uuid, vg->name);
			log_error("All PVs in the VG must be imported together.");
			goto_bad;
		}
	}

	dm_list_iterate_items(vd, &vp->arg_import) {
		if (!vd->found_in_vg) {
			/* device arg is not in the VG. */
			log_error("Device %s was not found in VG %s.", dev_name(vd->dev), vg->name);
			log_error("The devices to import must match the devices in the VG.");
			goto_bad;
		}
	}

	/*
	 * Write changes.
	 */

	if (!archive(vg))
		return_ECMD_FAILED;

	if (vp->import_vg)
		vg->status &= ~EXPORTED_VG;

	if (!id_create(&vg->id))
		goto_bad;

	/* Low level vg_write code needs old_name to be set! */
	vg->old_name = vg->name;

	if (!(vg->name = dm_pool_strdup(vg->vgmem, vp->new_vgname)))
		goto_bad;

	dm_list_iterate_items(pvl, &vg->pvs) {
		if (!(new_pvl = dm_pool_zalloc(vg->vgmem, sizeof(*new_pvl))))
			goto_bad;

		new_pvl->pv = pvl->pv;

		if (!(pvl->pv->vg_name = dm_pool_strdup(vg->vgmem, vp->new_vgname)))
			goto_bad;

		if (vp->import_vg)
			new_pvl->pv->status &= ~EXPORTED_VG;

		/* Low level pv_write code needs old_id to be set! */
		memcpy(&new_pvl->pv->old_id, &new_pvl->pv->id, sizeof(new_pvl->pv->id));

		if (!id_create(&new_pvl->pv->id))
			goto_bad;

		dm_list_add(&vg->pv_write_list, &new_pvl->list);
	}

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

	if (!vg_write(vg) || !vg_commit(vg))
		goto_bad;

	return ECMD_PROCESSED;
bad:
	return ECMD_FAILED;
}

int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
{
	struct vgimportclone_params vp = { 0 };
	struct processing_handle *handle = NULL;
	struct dm_list vgnameids_on_system;     /* vgnameid_list */
	struct vgnameid_list *vgnl;
	struct vgimportclone_device *vd;
	struct lvmcache_info *info;
	const char *vgname;
	char base_vgname[NAME_LEN] = { 0 };
	char tmp_vgname[NAME_LEN] = { 0 };
	unsigned int vgname_count;
	int lvmetad_rescan = 0;
	int ret = ECMD_FAILED;

	if (!argc) {
		log_error("PV names required.");
		return EINVALID_CMD_LINE;
	}

	dm_list_init(&vgnameids_on_system);
	dm_list_init(&vp.arg_import);

	set_pv_notify(cmd);

	vp.import_vg = arg_is_set(cmd, import_ARG);

	if (lvmetad_used()) {
		lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
		lvmetad_disconnect();
		lvmetad_rescan = 1;
	}

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

	if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_WRITE, NULL)) {
		log_error("Unable to obtain global lock.");
		destroy_processing_handle(cmd, handle);
		return ECMD_FAILED;
	}

	if (!lockd_gl(cmd, "ex", 0))
		goto_out;
	cmd->lockd_gl_disable = 1;

	/*
	 * Find the devices being imported which are named on the command line.
	 * They may be in the list of unchosen duplicates.
	 */

	log_debug("Finding devices to import.");
	cmd->command->flags |= ENABLE_DUPLICATE_DEVS;
	process_each_pv(cmd, argc, argv, NULL, 0, READ_ALLOW_EXPORTED, handle, _vgimportclone_pv_single);

	if (vp.found_args != argc) {
		log_error("Failed to find all devices.");
		goto_out;
	}

	/*
	 * Find the VG name of the PVs being imported, save as old_vgname.
	 * N.B. If vd->dev is a duplicate, then it may not match info->dev.
	 */

	dm_list_iterate_items(vd, &vp.arg_import) {
		if (!(info = lvmcache_info_from_pvid(vd->dev->pvid, NULL, 0))) {
			log_error("Failed to find PVID for device %s in lvmcache.", dev_name(vd->dev));
			goto_out;
		}

		if (!(vgname = lvmcache_vgname_from_info(info))) {
			log_error("Failed to find VG name for device %s in lvmcache.", dev_name(vd->dev));
			goto_out;
		}

		if (!vp.old_vgname) {
			if (!(vp.old_vgname = dm_pool_strdup(cmd->mem, vgname)))
				goto_out;
		} else {
			if (strcmp(vp.old_vgname, vgname)) {
				log_error("Devices must be from the same VG.");
				goto_out;
			}
		}
	}

	/*
	 * Pick a new VG name, save as new_vgname.  The new name begins with
	 * the basevgname or old_vgname, plus a $i suffix, if necessary, to
	 * make it unique.  This requires comparing the old_vgname with all the
	 * VG names on the system.
	 */

	if (arg_is_set(cmd, basevgname_ARG)) {
		snprintf(base_vgname, sizeof(base_vgname) - 1, "%s", arg_str_value(cmd, basevgname_ARG, ""));
		memcpy(tmp_vgname, base_vgname, NAME_LEN);
		vgname_count = 0;
	} else {
		snprintf(base_vgname, sizeof(base_vgname) - 1, "%s", vp.old_vgname);
		snprintf(tmp_vgname, sizeof(tmp_vgname) - 1, "%s1", vp.old_vgname);
		vgname_count = 1;
	}

	if (!get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
		goto_out;

retry_name:
	dm_list_iterate_items(vgnl, &vgnameids_on_system) {
		if (!strcmp(vgnl->vg_name, tmp_vgname)) {
			vgname_count++;
			snprintf(tmp_vgname, sizeof(tmp_vgname) - 1, "%s%u", base_vgname, vgname_count);
			goto retry_name;
		}
	}

	if (!(vp.new_vgname = dm_pool_strdup(cmd->mem, tmp_vgname)))
		goto_out;
	log_debug("Using new VG name %s.", vp.new_vgname);

	/*
	 * Create a device filter so that we are only working with the devices
	 * in arg_import.  With the original devs hidden (that arg_import were
	 * cloned from), we can read and write the cloned PVs and VG without
	 * touching the original PVs/VG.
	 */

	init_internal_filtering(1);
	dm_list_iterate_items(vd, &vp.arg_import)
		internal_filter_allow(cmd->mem, vd->dev);
	lvmcache_destroy(cmd, 1, 0);
	dev_cache_full_scan(cmd->full_filter);

	log_debug("Changing VG %s to %s.", vp.old_vgname, vp.new_vgname);

	/* We don't care if the new name comes before the old in lock order. */
	lvmcache_lock_ordering(0);

	if (!lock_vol(cmd, vp.new_vgname, LCK_VG_WRITE, NULL)) {
		log_error("Can't get lock for new VG name %s", vp.new_vgname);
		goto out;
	}

	ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);

	unlock_vg(cmd, NULL, vp.new_vgname);
out:
	unlock_vg(cmd, NULL, VG_GLOBAL);
	internal_filter_clear();
	init_internal_filtering(0);
	lvmcache_lock_ordering(1);
	destroy_processing_handle(cmd, handle);

	/* Enable lvmetad again if no duplicates are left. */
	if (lvmetad_rescan) {
		if (!lvmetad_connect(cmd)) {
			log_warn("WARNING: Failed to connect to lvmetad.");
			log_warn("WARNING: Update lvmetad with pvscan --cache.");
			return ret;
		}

		if (!refresh_filters(cmd))
			stack;

		if (!lvmetad_pvscan_all_devs(cmd, 1)) {
			log_warn("WARNING: Failed to scan devices.");
			log_warn("WARNING: Update lvmetad with pvscan --cache.");
		}
	}

	return ret;
}

