Exemplo n.º 1
0
int pvresize(struct cmd_context *cmd, int argc, char **argv)
{
	struct pvresize_params params;
	int ret;

	if (!argc) {
		log_error("Please supply physical volume(s)");
		return EINVALID_CMD_LINE;
	}

	if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
		log_error("Physical volume size may not be negative");
		return 0;
	}

	params.new_size = arg_uint64_value(cmd, physicalvolumesize_ARG,
					   UINT64_C(0));

	params.done = 0;
	params.total = 0;

	ret = process_each_pv(cmd, argc, argv, NULL, READ_FOR_UPDATE, 0, &params,
			      _pvresize_single);

	log_print("%d physical volume(s) resized / %d physical volume(s) "
		  "not resized", params.done, params.total - params.done);

	return ret;
}
Exemplo n.º 2
0
static int _read_size_params(struct lvcreate_params *lp,
			     struct lvcreate_cmdline_params *lcp,
			     struct cmd_context *cmd)
{
	if (arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) != 1) {
		log_error("Please specify either size or extents (not both)");
		return 0;
	}

	if (arg_count(cmd, extents_ARG)) {
		if (arg_sign_value(cmd, extents_ARG, 0) == SIGN_MINUS) {
			log_error("Negative number of extents is invalid");
			return 0;
		}
		lp->extents = arg_uint_value(cmd, extents_ARG, 0);
		lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
	}

	/* Size returned in kilobyte units; held in sectors */
	if (arg_count(cmd, size_ARG)) {
		if (arg_sign_value(cmd, size_ARG, 0) == SIGN_MINUS) {
			log_error("Negative size is invalid");
			return 0;
		}
		lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
		lcp->percent = PERCENT_NONE;
	}

	/* Size returned in kilobyte units; held in sectors */
	if (arg_count(cmd, virtualsize_ARG)) {
		if (arg_sign_value(cmd, virtualsize_ARG, 0) == SIGN_MINUS) {
			log_error("Negative virtual origin size is invalid");
			return 0;
		}
		lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
						   UINT64_C(0));
		if (!lp->voriginsize) {
			log_error("Virtual origin size may not be zero");
			return 0;
		}
	}

	return 1;
}
Exemplo n.º 3
0
int pvresize(struct cmd_context *cmd, int argc, char **argv)
{
	struct pvresize_params params;
	struct processing_handle *handle = NULL;
	int ret;

	if (!argc) {
		log_error("Please supply physical volume(s)");
		ret = EINVALID_CMD_LINE;
		goto out;
	}

	if (arg_sign_value(cmd, setphysicalvolumesize_ARG, SIGN_NONE) == SIGN_MINUS) {
		log_error("Physical volume size may not be negative");
		ret = EINVALID_CMD_LINE;
		goto out;
	}

	params.new_size = arg_uint64_value(cmd, setphysicalvolumesize_ARG,
					   UINT64_C(0));

	params.done = 0;
	params.total = 0;

	set_pv_notify(cmd);

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

	handle->custom_handle = &params;

	ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvresize_single);

	log_print_unless_silent("%d physical volume(s) resized or updated / %d physical volume(s) "
				"not resized", params.done, params.total - params.done);
out:
	destroy_processing_handle(cmd, handle);
	return ret;
}
Exemplo n.º 4
0
/*
 * Intial sanity checking of recovery-related command-line arguments.
 * These args are: --restorefile, --uuid, and --physicalvolumesize
 *
 * Output arguments:
 * pp: structure allocated by caller, fields written / validated here
 */
static int _pvcreate_restore_params_from_args(struct cmd_context *cmd, int argc,
					      struct pvcreate_params *pp)
{
	pp->restorefile = arg_str_value(cmd, restorefile_ARG, NULL);

	if (arg_is_set(cmd, restorefile_ARG) && !arg_is_set(cmd, uuidstr_ARG)) {
		log_error("--uuid is required with --restorefile");
		return 0;
	}

	if (!arg_is_set(cmd, restorefile_ARG) && arg_is_set(cmd, uuidstr_ARG)) {
		if (!arg_is_set(cmd, norestorefile_ARG) &&
		    find_config_tree_bool(cmd, devices_require_restorefile_with_uuid_CFG, NULL)) {
			log_error("--restorefile is required with --uuid");
			return 0;
		}
	}

	if (arg_is_set(cmd, uuidstr_ARG) && argc != 1) {
		log_error("Can only set uuid on one volume at once");
		return 0;
	}

	if (arg_is_set(cmd, uuidstr_ARG)) {
		pp->uuid_str = arg_str_value(cmd, uuidstr_ARG, "");
		if (!id_read_format(&pp->pva.id, pp->uuid_str))
			return 0;
		pp->pva.idp = &pp->pva.id;
	}

	if (arg_sign_value(cmd, setphysicalvolumesize_ARG, SIGN_NONE) == SIGN_MINUS) {
		log_error("Physical volume size may not be negative");
		return 0;
	}
	pp->pva.size = arg_uint64_value(cmd, setphysicalvolumesize_ARG, UINT64_C(0));

	if (arg_is_set(cmd, restorefile_ARG) || arg_is_set(cmd, uuidstr_ARG))
		pp->zero = 0;
	return 1;
}
Exemplo n.º 5
0
/*
 * Intial sanity checking of recovery-related command-line arguments.
 * These args are: --restorefile, --uuid, and --physicalvolumesize
 *
 * Output arguments:
 * pp: structure allocated by caller, fields written / validated here
 */
static int pvcreate_restore_params_validate(struct cmd_context *cmd,
					    int argc, char **argv,
					    struct pvcreate_params *pp)
{
	const char *uuid = NULL;
	struct volume_group *vg;
	struct pv_list *existing_pvl;

	if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) {
		log_error("--uuid is required with --restorefile");
		return 0;
	}

	if (!arg_count(cmd, restorefile_ARG) && arg_count(cmd, uuidstr_ARG)) {
		if (!arg_count(cmd, norestorefile_ARG) &&
		    find_config_tree_bool(cmd, devices_require_restorefile_with_uuid_CFG, NULL)) {
			log_error("--restorefile is required with --uuid");
			return 0;
		}
	}

	if (arg_count(cmd, uuidstr_ARG) && argc != 1) {
		log_error("Can only set uuid on one volume at once");
		return 0;
	}

 	if (arg_count(cmd, uuidstr_ARG)) {
		uuid = arg_str_value(cmd, uuidstr_ARG, "");
		if (!id_read_format(&pp->rp.id, uuid))
			return 0;
		pp->rp.idp = &pp->rp.id;
		lvmcache_seed_infos_from_lvmetad(cmd); /* need to check for UUID dups */
	}

	if (arg_count(cmd, restorefile_ARG)) {
		pp->rp.restorefile = arg_str_value(cmd, restorefile_ARG, "");
		/* The uuid won't already exist */
		if (!(vg = backup_read_vg(cmd, NULL, pp->rp.restorefile))) {
			log_error("Unable to read volume group from %s",
				  pp->rp.restorefile);
			return 0;
		}
		if (!(existing_pvl = find_pv_in_vg_by_uuid(vg, pp->rp.idp))) {
			release_vg(vg);
			log_error("Can't find uuid %s in backup file %s",
				  uuid, pp->rp.restorefile);
			return 0;
		}
		pp->rp.ba_start = pv_ba_start(existing_pvl->pv);
		pp->rp.ba_size = pv_ba_size(existing_pvl->pv);
		pp->rp.pe_start = pv_pe_start(existing_pvl->pv);
		pp->rp.extent_size = pv_pe_size(existing_pvl->pv);
		pp->rp.extent_count = pv_pe_count(existing_pvl->pv);

		release_vg(vg);
	}

	if (arg_sign_value(cmd, physicalvolumesize_ARG, SIGN_NONE) == SIGN_MINUS) {
		log_error("Physical volume size may not be negative");
		return 0;
	}
	pp->size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0));

	if (arg_count(cmd, restorefile_ARG) || arg_count(cmd, uuidstr_ARG))
		pp->zero = 0;
	return 1;
}
Exemplo n.º 6
0
static int _read_size_params(struct lvcreate_params *lp,
			     struct lvcreate_cmdline_params *lcp,
			     struct cmd_context *cmd)
{
	if (arg_count(cmd, extents_ARG) && arg_count(cmd, size_ARG)) {
		log_error("Please specify either size or extents (not both)");
		return 0;
	}

	if (!lp->thin && !lp->snapshot && !arg_count(cmd, extents_ARG) && !arg_count(cmd, size_ARG)) {
		log_error("Please specify either size or extents");
		return 0;
	}

	if (arg_count(cmd, extents_ARG)) {
		if (arg_sign_value(cmd, extents_ARG, SIGN_NONE) == SIGN_MINUS) {
			log_error("Negative number of extents is invalid");
			return 0;
		}
		lp->extents = arg_uint_value(cmd, extents_ARG, 0);
		lcp->percent = arg_percent_value(cmd, extents_ARG, PERCENT_NONE);
	}

	/* Size returned in kilobyte units; held in sectors */
	if (arg_count(cmd, size_ARG)) {
		if (arg_sign_value(cmd, size_ARG, SIGN_NONE) == SIGN_MINUS) {
			log_error("Negative size is invalid");
			return 0;
		}
		lcp->size = arg_uint64_value(cmd, size_ARG, UINT64_C(0));
		lcp->percent = PERCENT_NONE;
	}

	/* If size/extents given with thin, then we are creating a thin pool */
	if (seg_is_thin(lp) && (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG)))
		lp->create_pool = 1;

	if (!lp->create_pool && arg_count(cmd, poolmetadatasize_ARG)) {
		log_error("--poolmetadatasize may only be specified when allocating the pool.");
		return 0;
	}

	if (arg_count(cmd, virtualsize_ARG)) {
		if (seg_is_thin_pool(lp)) {
			log_error("Virtual size in incompatible with thin_pool segment type.");
			return 0;
		}
		if (arg_sign_value(cmd, virtualsize_ARG, SIGN_NONE) == SIGN_MINUS) {
			log_error("Negative virtual origin size is invalid");
			return 0;
		}
		/* Size returned in kilobyte units; held in sectors */
		lp->voriginsize = arg_uint64_value(cmd, virtualsize_ARG,
						   UINT64_C(0));
		if (!lp->voriginsize) {
			log_error("Virtual origin size may not be zero");
			return 0;
		}
	} else {
		/* No virtual size given and no snapshot, so no thin LV to create. */
		if (seg_is_thin_volume(lp) && !lp->snapshot &&
		    !(lp->segtype = get_segtype_from_string(cmd, "thin-pool")))
			return_0;

		lp->thin = 0;
	}

	return 1;
}
Exemplo n.º 7
0
static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
			   void *handle)
{
	struct pvcreate_params *pp = (struct pvcreate_params *) handle;
	void *pv;
	void *existing_pv;
	struct id id, *idp = NULL;
	const char *uuid = NULL;
	uint64_t size = 0;
	struct device *dev;
	struct list mdas;
	int pvmetadatacopies;
	uint64_t pvmetadatasize;
	struct volume_group *vg;
	const char *restorefile;
	uint64_t pe_start = 0;
	uint32_t extent_count = 0, extent_size = 0;

	if (arg_count(cmd, uuidstr_ARG)) {
		uuid = arg_str_value(cmd, uuidstr_ARG, "");
		if (!id_read_format(&id, uuid))
			return EINVALID_CMD_LINE;
		if ((dev = device_from_pvid(cmd, &id)) &&
		    (dev != dev_cache_get(pv_name, cmd->filter))) {
			log_error("uuid %s already in use on \"%s\"", uuid,
				  dev_name(dev));
			return ECMD_FAILED;
		}
		idp = &id;
	}

	if (arg_count(cmd, restorefile_ARG)) {
		restorefile = arg_str_value(cmd, restorefile_ARG, "");
		/* The uuid won't already exist */
		init_partial(1);
		if (!(vg = backup_read_vg(cmd, NULL, restorefile))) {
			log_error("Unable to read volume group from %s",
				  restorefile);
			return ECMD_FAILED;
		}
		init_partial(0);
		if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) {
			log_error("Can't find uuid %s in backup file %s",
				  uuid, restorefile);
			return ECMD_FAILED;
		}
		pe_start = pv_pe_start(existing_pv);
		extent_size = pv_pe_size(existing_pv);
		extent_count = pv_pe_count(existing_pv);
	}

	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
		log_error("Can't get lock for orphan PVs");
		return ECMD_FAILED;
	}

	if (!pvcreate_check(cmd, pv_name))
		goto error;

	if (sigint_caught())
		goto error;

	if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
		log_error("Physical volume size may not be negative");
		goto error;
	}
	size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0)) * 2;

	if (arg_sign_value(cmd, metadatasize_ARG, 0) == SIGN_MINUS) {
		log_error("Metadata size may not be negative");
		goto error;
	}
	pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0))
	    * 2;
	if (!pvmetadatasize)
		pvmetadatasize = find_config_tree_int(cmd,
						 "metadata/pvmetadatasize",
						 DEFAULT_PVMETADATASIZE);

	pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1);
	if (pvmetadatacopies < 0)
		pvmetadatacopies = find_config_tree_int(cmd,
						   "metadata/pvmetadatacopies",
						   DEFAULT_PVMETADATACOPIES);

	if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
		log_error("%s: Couldn't find device.  Check your filters?",
			  pv_name);
		goto error;
	}

	list_init(&mdas);
	if (!(pv = pv_create(cmd->fmt, dev, idp, size, pe_start,
			     extent_count, extent_size,
			     pvmetadatacopies, pvmetadatasize, &mdas))) {
		log_error("Failed to setup physical volume \"%s\"", pv_name);
		goto error;
	}

	log_verbose("Set up physical volume for \"%s\" with %" PRIu64
		    " available sectors", pv_name, pv_size(pv));

	/* Wipe existing label first */
	if (!label_remove(pv_dev(pv))) {
		log_error("Failed to wipe existing label on %s", pv_name);
		goto error;
	}

	if (pp->zero) {
		log_verbose("Zeroing start of device %s", pv_name);
		if (!dev_open_quiet(dev)) {
			log_error("%s not opened: device not zeroed", pv_name);
			goto error;
		}

		if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
			log_error("%s not wiped: aborting", pv_name);
			dev_close(dev);
			goto error;
		}
		dev_close(dev);
	}

	log_very_verbose("Writing physical volume data to disk \"%s\"",
			 pv_name);
	if (!(pv_write(cmd, (struct physical_volume *)pv, &mdas,
		       arg_int64_value(cmd, labelsector_ARG,
						       DEFAULT_LABELSECTOR)))) {
		log_error("Failed to write physical volume \"%s\"", pv_name);
		goto error;
	}

	log_print("Physical volume \"%s\" successfully created", pv_name);

	unlock_vg(cmd, ORPHAN);
	return ECMD_PROCESSED;

      error:
	unlock_vg(cmd, ORPHAN);
	return ECMD_FAILED;
}
Exemplo n.º 8
0
int vgcreate(struct cmd_context *cmd, int argc, char **argv)
{
    size_t max_lv, max_pv;
    uint32_t extent_size;
    char *vg_name;
    struct volume_group *vg;
    const char *tag;
    alloc_policy_t alloc;
    int clustered;

    if (!argc) {
        log_error("Please provide volume group name and "
                  "physical volumes");
        return EINVALID_CMD_LINE;
    }

    if (argc == 1) {
        log_error("Please enter physical volume name(s)");
        return EINVALID_CMD_LINE;
    }

    vg_name = skip_dev_dir(cmd, argv[0], NULL);
    max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG, 0);
    max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
    alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL);

    if (alloc == ALLOC_INHERIT) {
        log_error("Volume Group allocation policy cannot inherit "
                  "from anything");
        return EINVALID_CMD_LINE;
    }

    if (!(cmd->fmt->features & FMT_UNLIMITED_VOLS)) {
        if (!max_lv)
            max_lv = 255;
        if (!max_pv)
            max_pv = 255;
        if (max_lv > 255 || max_pv > 255) {
            log_error("Number of volumes may not exceed 255");
            return EINVALID_CMD_LINE;
        }
    }

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

    if (arg_sign_value(cmd, maxlogicalvolumes_ARG, 0) == SIGN_MINUS) {
        log_error("Max Logical Volumes may not be negative");
        return EINVALID_CMD_LINE;
    }

    if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
        log_error("Max Physical Volumes may not be negative");
        return EINVALID_CMD_LINE;
    }

    /* Units of 512-byte sectors */
    extent_size =
        arg_uint_value(cmd, physicalextentsize_ARG, DEFAULT_EXTENT) * 2;

    if (!extent_size) {
        log_error("Physical extent size may not be zero");
        return EINVALID_CMD_LINE;
    }

    if (!validate_vg_name(cmd, vg_name)) {
        log_error("New volume group name \"%s\" is invalid", vg_name);
        return ECMD_FAILED;
    }

    /* Create the new VG */
    if (!(vg = vg_create(cmd, vg_name, extent_size, max_pv, max_lv, alloc,
                         argc - 1, argv + 1)))
        return ECMD_FAILED;

    if (max_lv != vg->max_lv)
        log_warn("WARNING: Setting maxlogicalvolumes to %d "
                 "(0 means unlimited)", vg->max_lv);

    if (max_pv != vg->max_pv)
        log_warn("WARNING: Setting maxphysicalvolumes to %d "
                 "(0 means unlimited)", vg->max_pv);

    if (arg_count(cmd, addtag_ARG)) {
        if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) {
            log_error("Failed to get tag");
            return ECMD_FAILED;
        }

        if (!(vg->fid->fmt->features & FMT_TAGS)) {
            log_error("Volume group format does not support tags");
            return ECMD_FAILED;
        }

        if (!str_list_add(cmd->mem, &vg->tags, tag)) {
            log_error("Failed to add tag %s to volume group %s",
                      tag, vg_name);
            return ECMD_FAILED;
        }
    }

    if (arg_count(cmd, clustered_ARG))
        clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
    else
        /* Default depends on current locking type */
        clustered = locking_is_clustered();

    if (clustered)
        vg->status |= CLUSTERED;
    else
        vg->status &= ~CLUSTERED;

    if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
        log_error("Can't get lock for orphan PVs");
        return ECMD_FAILED;
    }

    if (!lock_vol(cmd, vg_name, LCK_VG_WRITE | LCK_NONBLOCK)) {
        log_error("Can't get lock for %s", vg_name);
        unlock_vg(cmd, ORPHAN);
        return ECMD_FAILED;
    }

    if (!archive(vg)) {
        unlock_vg(cmd, vg_name);
        unlock_vg(cmd, ORPHAN);
        return ECMD_FAILED;
    }

    /* Store VG on disk(s) */
    if (!vg_write(vg) || !vg_commit(vg)) {
        unlock_vg(cmd, vg_name);
        unlock_vg(cmd, ORPHAN);
        return ECMD_FAILED;
    }

    unlock_vg(cmd, vg_name);
    unlock_vg(cmd, ORPHAN);

    backup(vg);

    log_print("Volume group \"%s\" successfully created", vg->name);

    return ECMD_PROCESSED;
}