Exemple #1
0
int import_pv(const struct format_type *fmt, struct dm_pool *mem,
	      struct device *dev, struct volume_group *vg,
	      struct physical_volume *pv, struct pv_disk *pvd,
	      struct vg_disk *vgd)
{
	uint64_t size;

	memset(pv, 0, sizeof(*pv));
	memcpy(&pv->id, pvd->pv_uuid, ID_LEN);

	pv->dev = dev;
	if (!*pvd->vg_name)
		pv->vg_name = fmt->orphan_vg_name;
	else if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) {
		log_error("Volume Group name allocation failed.");
		return 0;
	}

	memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id));

	/* Store system_id from first PV if PV belongs to a VG */
	if (vg && !*vg->lvm1_system_id)
		strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);

	if (vg &&
	    strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
		    log_very_verbose("System ID %s on %s differs from %s for "
				     "volume group", pvd->system_id,
				     pv_dev_name(pv), vg->lvm1_system_id);

	/*
	 * If exported, we still need to flag in pv->status too because
	 * we don't always have a struct volume_group when we need this.
	 */
	if (pvd->pv_status & VG_EXPORTED)
		pv->status |= EXPORTED_VG;

	if (pvd->pv_allocatable)
		pv->status |= ALLOCATABLE_PV;

	pv->size = pvd->pv_size;
	pv->pe_size = pvd->pe_size;
	pv->pe_start = pvd->pe_start;
	pv->pe_count = pvd->pe_total;
	pv->pe_alloc_count = 0;
	pv->pe_align = 0;
        pv->is_labelled = 0; /* format1 PVs have no label */
        pv->label_sector = 0;

	/* Fix up pv size if missing or impossibly large */
	if (!pv->size || pv->size > (1ULL << 62)) {
		if (!dev_get_size(dev, &pv->size)) {
			log_error("%s: Couldn't get size.", pv_dev_name(pv));
			return 0;
		}
		log_verbose("Fixing up missing format1 size (%s) "
			    "for PV %s", display_size(fmt->cmd, pv->size),
			    pv_dev_name(pv));
		if (vg) {
			size = pv->pe_count * (uint64_t) vg->extent_size +
			       pv->pe_start;
			if (size > pv->size)
				log_warn("WARNING: Physical Volume %s is too "
					 "large for underlying device",
					 pv_dev_name(pv));
		}
	}

	dm_list_init(&pv->tags);
	dm_list_init(&pv->segments);

	if (!alloc_pv_segment_whole_pv(mem, pv))
		return_0;

	return 1;
}
Exemple #2
0
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "tools.h"

static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
			    struct physical_volume *pv,
			    void *handle __attribute__((unused)))
{
	const char *pv_name = pv_dev_name(pv);
	char uuid[64] __attribute__((aligned(8)));

	int allocatable = 0;
	int tagargs = 0;
	int mda_ignore = 0;

	tagargs = arg_count(cmd, addtag_ARG) + arg_count(cmd, deltag_ARG);

	if (arg_count(cmd, allocatable_ARG))
		allocatable = !strcmp(arg_str_value(cmd, allocatable_ARG, "n"),
				      "y");
	if (arg_count(cmd, metadataignore_ARG))
		mda_ignore = !strcmp(arg_str_value(cmd, metadataignore_ARG, "n"),
				      "y");
Exemple #3
0
static int _pv_resize_single(struct cmd_context *cmd,
			     struct volume_group *vg,
			     struct physical_volume *pv,
			     const uint64_t new_size)
{
	struct pv_list *pvl;
	uint64_t size = 0;
	uint32_t new_pe_count = 0;
	int r = 0;
	struct dm_list mdas;
	const char *pv_name = pv_dev_name(pv);
	const char *vg_name;
	struct lvmcache_info *info;
	int mda_count = 0;
	struct volume_group *old_vg = vg;

	dm_list_init(&mdas);

	if (is_orphan_vg(pv_vg_name(pv))) {
		vg_name = VG_ORPHANS;
		if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
			log_error("Can't get lock for orphans");
			return 0;
		}

		if (!(pv = pv_read(cmd, pv_name, &mdas, NULL, 1, 0))) {
			unlock_vg(cmd, vg_name);
			log_error("Unable to read PV \"%s\"", pv_name);
			return 0;
		}

		mda_count = dm_list_size(&mdas);
	} else {
		vg_name = pv_vg_name(pv);

		vg = vg_read_for_update(cmd, vg_name, NULL, 0);

		if (vg_read_error(vg))
			goto bad;

		if (!(pvl = find_pv_in_vg(vg, pv_name))) {
			log_error("Unable to find \"%s\" in volume group \"%s\"",
				  pv_name, vg->name);
			goto bad;
		}

		pv = pvl->pv;

		if (!(info = info_from_pvid(pv->dev->pvid, 0))) {
			log_error("Can't get info for PV %s in volume group %s",
				  pv_name, vg->name);
			goto bad;
		}

		mda_count = dm_list_size(&info->mdas);

		if (!archive(vg))
			goto bad;
	}

	/* FIXME Create function to test compatibility properly */
	if (mda_count > 1) {
		log_error("%s: too many metadata areas for pvresize", pv_name);
		goto bad;
	}

	if (!(pv->fmt->features & FMT_RESIZE_PV)) {
		log_error("Physical volume %s format does not support resizing.",
			  pv_name);
		goto bad;
	}

	/* Get new size */
	if (!dev_get_size(pv_dev(pv), &size)) {
		log_error("%s: Couldn't get size.", pv_name);
		goto bad;
	}

	if (new_size) {
		if (new_size > size)
			log_warn("WARNING: %s: Overriding real size. "
				  "You could lose data.", pv_name);
		log_verbose("%s: Pretending size is %" PRIu64 " not %" PRIu64
			    " sectors.", pv_name, new_size, pv_size(pv));
		size = new_size;
	}

	if (size < PV_MIN_SIZE) {
		log_error("%s: Size must exceed minimum of %ld sectors.",
			  pv_name, PV_MIN_SIZE);
		goto bad;
	}

	if (size < pv_pe_start(pv)) {
		log_error("%s: Size must exceed physical extent start of "
			  "%" PRIu64 " sectors.", pv_name, pv_pe_start(pv));
		goto bad;
	}

	pv->size = size;

	if (vg) {
		pv->size -= pv_pe_start(pv);
		new_pe_count = pv_size(pv) / vg->extent_size;

 		if (!new_pe_count) {
			log_error("%s: Size must leave space for at "
				  "least one physical extent of "
				  "%" PRIu32 " sectors.", pv_name,
				  pv_pe_size(pv));
			goto bad;
		}

		if (!pv_resize(pv, vg, new_pe_count))
			goto_bad;
	}

	log_verbose("Resizing volume \"%s\" to %" PRIu64 " sectors.",
		    pv_name, pv_size(pv));

	log_verbose("Updating physical volume \"%s\"", pv_name);
	if (!is_orphan_vg(pv_vg_name(pv))) {
		if (!vg_write(vg) || !vg_commit(vg)) {
			log_error("Failed to store physical volume \"%s\" in "
				  "volume group \"%s\"", pv_name, vg->name);
			goto bad;
		}
		backup(vg);
	} else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
		log_error("Failed to store physical volume \"%s\"",
			  pv_name);
		goto bad;;
	}

	log_print("Physical volume \"%s\" changed", pv_name);
	r = 1;

bad:
	unlock_vg(cmd, vg_name);
	if (!old_vg)
		vg_release(vg);
	return r;
}