1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lvm2app: Add ability to create PV with args

Add a PV create which takes a paramters object that
has get/set method to configure PV creation.

Current get/set operations include:
- size
- pvmetadatacopies
- pvmetadatasize
- data_alignment
- data_alignment_offset
- zero

Reference: https://bugzilla.redhat.com/show_bug.cgi?id=880395

Signed-off-by: Tony Asleson <tasleson@redhat.com>
This commit is contained in:
Tony Asleson 2013-09-10 18:01:28 -05:00
parent ec7f632ce0
commit 04304ba735
11 changed files with 290 additions and 29 deletions

View File

@ -1455,6 +1455,30 @@ static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_create *pvc)
return 1; return 1;
} }
static int _verify_pv_create_params(struct pvcreate_params *pp)
{
/*
* FIXME: Some of these checks are duplicates in pvcreate_params_validate.
*/
if (pp->pvmetadatacopies > 2) {
log_error("Metadatacopies may only be 0, 1 or 2");
return 0;
}
if (pp->data_alignment > UINT32_MAX) {
log_error("Physical volume data alignment is too big.");
return 0;
}
if (pp->data_alignment_offset > UINT32_MAX) {
log_error("Physical volume data alignment offset is too big.");
return 0;
}
return 1;
}
/* /*
* pvcreate_vol() - initialize a device with PV label and metadata area * pvcreate_vol() - initialize a device with PV label and metadata area
* *
@ -1479,6 +1503,10 @@ struct physical_volume *pvcreate_vol(struct cmd_context *cmd, const char *pv_nam
if (!pp) if (!pp)
pp = &default_pp; pp = &default_pp;
if (!_verify_pv_create_params(pp)) {
goto bad;
}
if (pp->rp.idp) { if (pp->rp.idp) {
if ((dev = lvmcache_device_from_pvid(cmd, pp->rp.idp, NULL, NULL)) && if ((dev = lvmcache_device_from_pvid(cmd, pp->rp.idp, NULL, NULL)) &&
(dev != dev_cache_get(pv_name, cmd->filter))) { (dev != dev_cache_get(pv_name, cmd->filter))) {

View File

@ -161,6 +161,14 @@ typedef struct pv_segment *pvseg_t;
*/ */
typedef struct lvm_lv_create_params *lv_create_params_t; typedef struct lvm_lv_create_params *lv_create_params_t;
/**
* \class pv_create_params
*
* This pv_create_params represents the plethora of available options when
* creating a physical volume
*/
typedef struct lvm_pv_create_params *pv_create_params_t;
/** /**
* Logical Volume object list. * Logical Volume object list.
* *
@ -581,6 +589,62 @@ int lvm_list_pvs_free(struct dm_list *pvlist);
*/ */
int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size); int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size);
/**
* Create a physical volume parameter object for PV creation.
*
* \param libh Library handle
* \param pv_name Device name
*
* \return
* NULL on error, else valid parameter object to use.
*/
pv_create_params_t lvm_pv_params_create(lvm_t libh, const char *pv_name);
/**
* Create a parameter object to use in function lvm_pv_create_adv
*
* \param params The params object to get property value from
* \param name The name of the property to retrieve
*
* Available properties:
*
* size zero indicates use detected size of device
* (recommended and default)
* pvmetadatacopies Number of metadata copies (0,1,2)
* pvmetadatasize The approx. size to be to be set aside for metadata
* data_alignment Align the start of the data to a multiple of
* this number
* data_alignment_offset Shift the start of the data area by this addl.
* offset
* zero Set to 1 to zero out first 2048 bytes of
* device, 0 to not (default is 1)
*
* \return
* lvm_property_value
*/
struct lvm_property_value lvm_pv_params_get_property(
const pv_create_params_t params,
const char *name);
/**
* Sets a property of a PV parameter create object.
*
* \param params The parameter object
* \param name The name of the property to set (see get prop list)
* \param prop The property to set the value on.
*/
int lvm_pv_params_set_property(pv_create_params_t params, const char *name,
struct lvm_property_value *prop);
/**
* Creates a physical volume using the supplied params object.
*
* \param params The parameters to use for physical volume creation
*
* \return
* -1 on error, 0 on success.
*/
int lvm_pv_create_adv(pv_create_params_t params);
/** /**
* Remove a physical volume. * Remove a physical volume.
* Note: You cannot remove a PV while iterating through the list of PVs as * Note: You cannot remove a PV while iterating through the list of PVs as

View File

@ -71,13 +71,13 @@ const char *lvm_lv_get_origin(const lv_t lv)
struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name) struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name)
{ {
return get_property(NULL, NULL, lv, NULL, NULL, NULL, name); return get_property(NULL, NULL, lv, NULL, NULL, NULL, NULL, name);
} }
struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg, struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg,
const char *name) const char *name)
{ {
return get_property(NULL, NULL, NULL, lvseg, NULL, NULL, name); return get_property(NULL, NULL, NULL, lvseg, NULL, NULL, NULL, name);
} }
uint64_t lvm_lv_is_active(const lv_t lv) uint64_t lvm_lv_is_active(const lv_t lv)
@ -598,7 +598,7 @@ struct lvm_property_value lvm_lv_params_get_property(
}; };
if (params && params->magic == LV_CREATE_PARAMS_MAGIC) { if (params && params->magic == LV_CREATE_PARAMS_MAGIC) {
rc = get_property(NULL, NULL, NULL, NULL, NULL, &params->lvp, name); rc = get_property(NULL, NULL, NULL, NULL, NULL, &params->lvp, NULL, name);
} else { } else {
log_error("Invalid lv_create_params parameter"); log_error("Invalid lv_create_params parameter");
} }
@ -612,7 +612,7 @@ int lvm_lv_params_set_property(lv_create_params_t params, const char *name,
int rc = -1; int rc = -1;
if (params && params->magic == LV_CREATE_PARAMS_MAGIC) { if (params && params->magic == LV_CREATE_PARAMS_MAGIC) {
rc = set_property(NULL, NULL, NULL, &params->lvp, name, prop); rc = set_property(NULL, NULL, NULL, &params->lvp, NULL, name, prop);
} else { } else {
log_error("Invalid lv_create_params parameter"); log_error("Invalid lv_create_params parameter");
} }

View File

@ -51,6 +51,7 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
const lvseg_t lvseg, const lvseg_t lvseg,
const pvseg_t pvseg, const pvseg_t pvseg,
const struct lvcreate_params *lvcp, const struct lvcreate_params *lvcp,
const struct pvcreate_params *pvcp,
const char *name) const char *name)
{ {
struct lvm_property_type prop; struct lvm_property_type prop;
@ -76,6 +77,9 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
} else if (lvcp) { } else if (lvcp) {
if (!lv_create_param_get_property(lvcp, &prop)) if (!lv_create_param_get_property(lvcp, &prop))
return v; return v;
} else if (pvcp) {
if (!pv_create_param_get_property(pvcp, &prop))
return v;
} else { } else {
log_errno(EINVAL, "Invalid NULL handle passed to library function."); log_errno(EINVAL, "Invalid NULL handle passed to library function.");
return v; return v;
@ -95,6 +99,7 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
int set_property(const pv_t pv, const vg_t vg, const lv_t lv, int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
struct lvcreate_params *lvcp, struct lvcreate_params *lvcp,
struct pvcreate_params *pvcp,
const char *name, const char *name,
struct lvm_property_value *v) struct lvm_property_value *v)
{ {
@ -125,6 +130,11 @@ int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
v->is_valid = 0; v->is_valid = 0;
return -1; return -1;
} }
} else if (pvcp) {
if (!pv_create_param_set_property(pvcp, &prop)) {
v->is_valid = 0;
return -1;
}
} else { } else {
return -1; return -1;
} }

View File

@ -16,14 +16,19 @@
#include "libdevmapper.h" #include "libdevmapper.h"
#include "lvm2app.h" #include "lvm2app.h"
#include "metadata-exported.h"
struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list); struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list);
struct lvm_property_value get_property(const pv_t pv, const vg_t vg, struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
const lv_t lv, const lvseg_t lvseg, const lv_t lv, const lvseg_t lvseg,
const pvseg_t pvseg, const struct lvcreate_params *lvcp, const pvseg_t pvseg,
const struct lvcreate_params *lvcp,
const struct pvcreate_params *pvcp,
const char *name); const char *name);
int set_property(const pv_t pv, const vg_t vg, const lv_t lv, int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
struct lvcreate_params *lvcp, const char *name, struct lvcreate_params *lvcp,
struct pvcreate_params *pvcp,
const char *name,
struct lvm_property_value *value); struct lvm_property_value *value);
#endif #endif

View File

@ -21,6 +21,25 @@
GET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero) GET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero)
SET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero) SET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero)
/* PV create parameters */
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(size, pvcp->size)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(size, pvcp->size)
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatacopies, pvcp->pvmetadatacopies)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatacopies, pvcp->pvmetadatacopies)
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatasize, pvcp->pvmetadatasize)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatasize, pvcp->pvmetadatasize)
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment, pvcp->data_alignment)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment, pvcp->data_alignment)
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment_offset, pvcp->data_alignment_offset)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment_offset, pvcp->data_alignment_offset)
GET_PVCREATEPARAMS_NUM_PROPERTY_FN(zero, pvcp->zero)
SET_PVCREATEPARAMS_NUM_PROPERTY_FN(zero, pvcp->zero)
struct lvm_property_type _lib_properties[] = { struct lvm_property_type _lib_properties[] = {
#include "lvm_prop_fields.h" #include "lvm_prop_fields.h"
{ 0, "", 0, 0, 0, { .integer = 0 }, prop_not_implemented_get, { 0, "", 0, 0, 0, { .integer = 0 }, prop_not_implemented_get,
@ -42,3 +61,15 @@ int lv_create_param_set_property(struct lvcreate_params *lvcp,
{ {
return prop_set_property(_lib_properties, lvcp, prop, LV_CREATE_PARAMS); return prop_set_property(_lib_properties, lvcp, prop, LV_CREATE_PARAMS);
} }
int pv_create_param_get_property(const struct pvcreate_params *pvcp,
struct lvm_property_type *prop)
{
return prop_get_property(_lib_properties, pvcp, prop, PV_CREATE_PARAMS);
}
int pv_create_param_set_property(struct pvcreate_params *pvcp,
struct lvm_property_type *prop)
{
return prop_set_property(_lib_properties, pvcp, prop, PV_CREATE_PARAMS);
}

View File

@ -17,8 +17,10 @@
#define _LIB_LVM_PROP_H #define _LIB_LVM_PROP_H
typedef struct lvcreate_params type_lvcreate_params; typedef struct lvcreate_params type_lvcreate_params;
typedef struct pvcreate_params type_pvcreate_params;
#define LV_CREATE_PARAMS 1 #define LV_CREATE_PARAMS 1
#define PV_CREATE_PARAMS 2
#define GET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE)\ #define GET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE)\
GET_NUM_PROPERTY_FN(NAME, VALUE, lvcreate_params, lvcp) GET_NUM_PROPERTY_FN(NAME, VALUE, lvcreate_params, lvcp)
@ -26,10 +28,22 @@ typedef struct lvcreate_params type_lvcreate_params;
#define SET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE) \ #define SET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE) \
SET_NUM_PROPERTY(NAME, VALUE, lvcreate_params, lvcp) SET_NUM_PROPERTY(NAME, VALUE, lvcreate_params, lvcp)
#define GET_PVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE)\
GET_NUM_PROPERTY_FN(NAME, VALUE, pvcreate_params, pvcp)
#define SET_PVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE) \
SET_NUM_PROPERTY(NAME, VALUE, pvcreate_params, pvcp)
int lv_create_param_get_property(const struct lvcreate_params *lvcp, int lv_create_param_get_property(const struct lvcreate_params *lvcp,
struct lvm_property_type *prop); struct lvm_property_type *prop);
int lv_create_param_set_property(struct lvcreate_params *lvcp, int lv_create_param_set_property(struct lvcreate_params *lvcp,
struct lvm_property_type *prop); struct lvm_property_type *prop);
int pv_create_param_get_property(const struct pvcreate_params *pvcp,
struct lvm_property_type *prop);
int pv_create_param_set_property(struct pvcreate_params *pvcp,
struct lvm_property_type *prop);
#endif #endif

View File

@ -13,3 +13,10 @@
*/ */
FIELD(LV_CREATE_PARAMS, lvcreate_params, NUM, "skip_zero", zero, 2, uint32, skip_zero, "Skip zeroing on lv creation", 1) FIELD(LV_CREATE_PARAMS, lvcreate_params, NUM, "skip_zero", zero, 2, uint32, skip_zero, "Skip zeroing on lv creation", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "size", size, 2, uint64_t, size, "PV size", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "pvmetadatacopies", pvmetadatacopies, 2, uint64_t, pvmetadatacopies, "PV Metadata copies", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "pvmetadatasize", pvmetadatasize, 2, uint64_t, pvmetadatasize, "PV Metadata size", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "data_alignment", data_alignment, 2, uint64_t, data_alignment, "Start data to a multiple of value", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "data_alignment_offset", data_alignment_offset, 2, uint64_t, data_alignment_offset, "Shift the start of the data area", 1)
FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "zero", zero, 2, uint64_t, zero, "Zero first 2048 bytes of device", 1)

View File

@ -21,6 +21,16 @@
#include "locking.h" #include "locking.h"
#include "toolcontext.h" #include "toolcontext.h"
struct lvm_pv_create_params
{
uint32_t magic;
lvm_t libh;
const char *pv_name;
struct pvcreate_params pv_p;
};
#define PV_CREATE_PARAMS_MAGIC 0xFEED0002
const char *lvm_pv_get_uuid(const pv_t pv) const char *lvm_pv_get_uuid(const pv_t pv)
{ {
return pv_uuid_dup(pv); return pv_uuid_dup(pv);
@ -53,13 +63,13 @@ uint64_t lvm_pv_get_free(const pv_t pv)
struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name) struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name)
{ {
return get_property(pv, NULL, NULL, NULL, NULL, NULL, name); return get_property(pv, NULL, NULL, NULL, NULL, NULL, NULL, name);
} }
struct lvm_property_value lvm_pvseg_get_property(const pvseg_t pvseg, struct lvm_property_value lvm_pvseg_get_property(const pvseg_t pvseg,
const char *name) const char *name)
{ {
return get_property(NULL, NULL, NULL, NULL, pvseg, NULL, name); return get_property(NULL, NULL, NULL, NULL, pvseg, NULL, NULL, name);
} }
struct lvm_list_wrapper struct lvm_list_wrapper
@ -80,6 +90,8 @@ int lvm_pv_remove(lvm_t libh, const char *pv_name)
return 0; return 0;
} }
#define PV_LIST_MAGIC 0xF005BA11
struct dm_list *lvm_list_pvs(lvm_t libh) struct dm_list *lvm_list_pvs(lvm_t libh)
{ {
struct lvm_list_wrapper *rc = NULL; struct lvm_list_wrapper *rc = NULL;
@ -109,7 +121,7 @@ struct dm_list *lvm_list_pvs(lvm_t libh)
* pointer in the free call. * pointer in the free call.
*/ */
rc->cmd = cmd; rc->cmd = cmd;
rc->magic = 0xF005BA11; rc->magic = PV_LIST_MAGIC;
} }
return &rc->pvslist; return &rc->pvslist;
@ -123,7 +135,7 @@ int lvm_list_pvs_free(struct dm_list *pvlist)
if (pvlist) { if (pvlist) {
to_delete = dm_list_struct_base(pvlist, struct lvm_list_wrapper, pvslist); to_delete = dm_list_struct_base(pvlist, struct lvm_list_wrapper, pvslist);
if (to_delete->magic != 0xF005BA11) { if (to_delete->magic != PV_LIST_MAGIC) {
log_errno(EINVAL, "Not a correct pvlist structure"); log_errno(EINVAL, "Not a correct pvlist structure");
return -1; return -1;
} }
@ -224,26 +236,122 @@ int lvm_pv_resize(const pv_t pv, uint64_t new_size)
return 0; return 0;
} }
int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size) /*
* Common internal code to create a parameter passing object
*/
static struct lvm_pv_create_params *_lvm_pv_params_create(
lvm_t libh,
const char *pv_name,
struct lvm_pv_create_params *pvcp_in)
{ {
struct pvcreate_params pp; struct lvm_pv_create_params *pvcp = NULL;
const char *dev = NULL;
struct cmd_context *cmd = (struct cmd_context *)libh; struct cmd_context *cmd = (struct cmd_context *)libh;
uint64_t size_sectors = size;
pvcreate_params_set_defaults(&pp); if (!pv_name || strlen(pv_name) == 0) {
log_error("Invalid pv_name");
return NULL;
}
if (size_sectors != 0) { if (!pvcp_in) {
if (size_sectors % SECTOR_SIZE) { pvcp = dm_pool_zalloc(cmd->libmem, sizeof(struct lvm_pv_create_params));
} else {
pvcp = pvcp_in;
}
if (!pvcp) {
return NULL;
}
dev = dm_pool_strdup(cmd->libmem, pv_name);
if (!dev) {
return NULL;
}
pvcreate_params_set_defaults(&pvcp->pv_p);
pvcp->pv_p.yes = 1;
pvcp->pv_p.force = DONT_PROMPT;
pvcp->pv_name = dev;
pvcp->libh = libh;
pvcp->magic = PV_CREATE_PARAMS_MAGIC;
return pvcp;
}
pv_create_params_t lvm_pv_params_create(lvm_t libh, const char *pv_name)
{
return _lvm_pv_params_create(libh, pv_name, NULL);
}
struct lvm_property_value lvm_pv_params_get_property(
const pv_create_params_t params,
const char *name)
{
struct lvm_property_value rc = {
.is_valid = 0
};
if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
rc = get_property(NULL, NULL, NULL, NULL, NULL, NULL, &params->pv_p,
name);
} else {
log_error("Invalid pv_create_params parameter");
}
return rc;
}
int lvm_pv_params_set_property(pv_create_params_t params, const char *name,
struct lvm_property_value *prop)
{
int rc = -1;
if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
rc = set_property(NULL, NULL, NULL, NULL, &params->pv_p, name, prop);
} else {
log_error("Invalid pv_create_params parameter");
}
return rc;
}
static int _pv_create(pv_create_params_t params)
{
struct cmd_context *cmd = (struct cmd_context *)params->libh;
if (params->pv_p.size) {
if (params->pv_p.size % SECTOR_SIZE) {
log_errno(EINVAL, "Size not a multiple of 512"); log_errno(EINVAL, "Size not a multiple of 512");
return -1; return -1;
} }
size_sectors = size_sectors >> SECTOR_SHIFT; params->pv_p.size = params->pv_p.size >> SECTOR_SHIFT;
} }
pp.size = size_sectors; if (!pvcreate_single(cmd, params->pv_name, &params->pv_p))
if (!pvcreate_single(cmd, pv_name, &pp))
return -1; return -1;
return 0; return 0;
} }
int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size)
{
struct lvm_pv_create_params pp;
if (!_lvm_pv_params_create(libh, pv_name, &pp))
return -1;
pp.pv_p.size = size;
return _pv_create(&pp);
}
int lvm_pv_create_adv(pv_create_params_t params)
{
int rc = -1;
if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
rc = _pv_create(params);
} else {
log_error("Invalid pv_create_params parameter");
}
return rc;
}

View File

@ -340,7 +340,7 @@ const char *lvm_vg_get_name(const vg_t vg)
struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name) struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name)
{ {
return get_property(NULL, vg, NULL, NULL, NULL, NULL, name); return get_property(NULL, vg, NULL, NULL, NULL, NULL, NULL, name);
} }
int lvm_vg_set_property(const vg_t vg, const char *name, int lvm_vg_set_property(const vg_t vg, const char *name,
@ -357,7 +357,7 @@ int lvm_vg_set_property(const vg_t vg, const char *name,
strlen(value->value.string) + 1); strlen(value->value.string) + 1);
} }
return set_property(NULL, vg, NULL, NULL, name, value); return set_property(NULL, vg, NULL, NULL, NULL, name, value);
} }
struct dm_list *lvm_list_vg_names(lvm_t libh) struct dm_list *lvm_list_vg_names(lvm_t libh)

View File

@ -1541,12 +1541,6 @@ int pvcreate_params_validate(struct cmd_context *cmd,
return 0; return 0;
} }
if (arg_count(cmd, pvmetadatacopies_ARG) &&
arg_int_value(cmd, pvmetadatacopies_ARG, -1) > 2) {
log_error("Metadatacopies may only be 0, 1 or 2");
return 0;
}
if (arg_count(cmd, metadataignore_ARG)) if (arg_count(cmd, metadataignore_ARG))
pp->metadataignore = arg_int_value(cmd, metadataignore_ARG, pp->metadataignore = arg_int_value(cmd, metadataignore_ARG,
DEFAULT_PVMETADATAIGNORE); DEFAULT_PVMETADATAIGNORE);