mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
o Changed
struct pv_list { struct list list; struct physical_volume pv; }; to struct pv_list { struct list list; struct physical_volume *pv; }; o New function in toollib 'create_pv_list', which creates a list of pv's from a given command line array of pv's. o Changed lvcreate/extend to use this (fixes lvextend [pv list] bug).
This commit is contained in:
parent
05c8c3abf2
commit
34458e0c57
@ -161,7 +161,7 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg,
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
pvl = list_item(pvh, struct pv_list);
|
||||
|
||||
if (!(data = _flatten_pv(mem, vg, &pvl->pv, dev_dir))) {
|
||||
if (!(data = _flatten_pv(mem, vg, pvl->pv, dev_dir))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -314,8 +314,8 @@ static struct list *_get_vgs(struct format_instance *fi)
|
||||
list_iterate(pvh, pvs) {
|
||||
struct pv_list *pvl = list_item(pvh, struct pv_list);
|
||||
|
||||
if (!(*pvl->pv.vg_name) ||
|
||||
_find_vg_name(names, pvl->pv.vg_name))
|
||||
if (!(*pvl->pv->vg_name) ||
|
||||
_find_vg_name(names, pvl->pv->vg_name))
|
||||
continue;
|
||||
|
||||
if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) {
|
||||
@ -323,7 +323,8 @@ static struct list *_get_vgs(struct format_instance *fi)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(nl->name = pool_strdup(fi->cmd->mem, pvl->pv.vg_name))) {
|
||||
if (!(nl->name = pool_strdup(fi->cmd->mem,
|
||||
pvl->pv->vg_name))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
@ -316,15 +316,16 @@ int import_pvs(struct pool *mem, struct list *pvds,
|
||||
|
||||
*count = 0;
|
||||
list_iterate(pvdh, pvds) {
|
||||
dl = list_item(pvdh, struct disk_list);
|
||||
pvl = pool_alloc(mem, sizeof(*pvl));
|
||||
|
||||
if (!pvl) {
|
||||
dl = list_item(pvdh, struct disk_list);
|
||||
|
||||
if (!(pvl = pool_alloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!import_pv(mem, dl->dev, &pvl->pv, &dl->pvd)) {
|
||||
if (!import_pv(mem, dl->dev, pvl->pv, &dl->pvd)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -440,7 +441,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
}
|
||||
|
||||
memset(ul->uuid, 0, sizeof(ul->uuid));
|
||||
memcpy(ul->uuid, pvl->pv.id.uuid, ID_LEN);
|
||||
memcpy(ul->uuid, pvl->pv->id.uuid, ID_LEN);
|
||||
|
||||
list_add(&dl->uuids, &ul->list);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
|
||||
list_iterate (pvh, &vg->pvs) {
|
||||
|
||||
pv = &(list_item(pvh, struct pv_list)->pv);
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if (!(name = _get_pv_name(f, pv))) {
|
||||
stack;
|
||||
@ -241,8 +241,6 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
_out(f, "%s {", name);
|
||||
_inc_indent(f);
|
||||
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if (!id_write_format(&pv->id, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
@ -396,7 +394,7 @@ static int _build_pv_names(struct formatter *f,
|
||||
}
|
||||
|
||||
list_iterate (pvh, &vg->pvs) {
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if (lvm_snprintf(buffer, sizeof(buffer),
|
||||
"pv%d", count++) < 0) {
|
||||
|
@ -56,12 +56,13 @@ static int _read_pv(struct pool *mem,
|
||||
struct pv_list *pvl;
|
||||
struct config_node *cn;
|
||||
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pv = &pvl->pv;
|
||||
pv = pvl->pv;
|
||||
|
||||
/*
|
||||
* Add the pv to the pv hash for quick lookup when we read
|
||||
|
@ -84,7 +84,7 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&pvl->pv, pv, sizeof(*pv));
|
||||
pvl->pv = pv;
|
||||
|
||||
list_add(&vg->pvs, &pvl->list);
|
||||
vg->pv_count++;
|
||||
@ -240,7 +240,7 @@ struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
pvl = list_item(pvh, struct pv_list);
|
||||
/* FIXME check dev not name */
|
||||
if (!strcmp(dev_name(pvl->pv.dev), pv_name))
|
||||
if (!strcmp(dev_name(pvl->pv->dev), pv_name))
|
||||
return pvl;
|
||||
}
|
||||
|
||||
@ -279,11 +279,10 @@ struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
|
||||
{
|
||||
struct list *pvh;
|
||||
struct physical_volume *pv;
|
||||
struct pv_list *pl;
|
||||
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
pl = list_item(pvh, struct pv_list);
|
||||
pv = &pl->pv;
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if (dev == pv->dev)
|
||||
return pv;
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ struct name_list {
|
||||
|
||||
struct pv_list {
|
||||
struct list list;
|
||||
struct physical_volume pv;
|
||||
struct physical_volume *pv;
|
||||
};
|
||||
|
||||
struct lv_list {
|
||||
|
@ -17,7 +17,7 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
|
||||
struct pv_map *pvm;
|
||||
|
||||
list_iterate(tmp, pvs) {
|
||||
pv = &(list_item(tmp, struct pv_list)->pv);
|
||||
pv = list_item(tmp, struct pv_list)->pv;
|
||||
|
||||
if (!(pv->status & ALLOCATABLE_PV))
|
||||
continue;
|
||||
@ -47,8 +47,12 @@ static int _set_allocated(struct hash_table *hash,
|
||||
struct pv_map *pvm;
|
||||
|
||||
if (!(pvm = (struct pv_map *) hash_lookup(hash, dev_name(pv->dev)))) {
|
||||
log_err("pv_map not present in hash table.");
|
||||
return 0;
|
||||
/*
|
||||
* it does matter that this fails, it just means
|
||||
* this part of the lv is on a pv that we're not
|
||||
* interested in allocating to.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
|
@ -129,34 +129,16 @@ int lvcreate(int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
/* Build up list of PVs */
|
||||
if (!(pvh = pool_alloc(fid->cmd->mem, sizeof(struct list)))) {
|
||||
log_error("pvh list allocation failed");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
list_init(pvh);
|
||||
for (; opt < argc; opt++) {
|
||||
if (!(pvl = find_pv_in_vg(vg, argv[opt]))) {
|
||||
log_error("Physical Volume %s not found in "
|
||||
"Volume Group %s", argv[opt],
|
||||
vg->name);
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (pvl->pv.pe_count == pvl->pv.pe_allocated) {
|
||||
log_error("No free extents on physical volume"
|
||||
" %s", argv[opt]);
|
||||
continue;
|
||||
/* FIXME But check not null at end! */
|
||||
}
|
||||
|
||||
// FIXME: pv_lists should be duplicated.
|
||||
list_add(pvh, &pvl->list);
|
||||
}
|
||||
} else {
|
||||
if (!argc)
|
||||
/* Use full list from VG */
|
||||
pvh = &vg->pvs;
|
||||
|
||||
else {
|
||||
if (!(pvh = create_pv_list(fid->cmd->mem, vg,
|
||||
argc - opt, argv + opt))) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc && argc < stripes ) {
|
||||
@ -166,7 +148,7 @@ int lvcreate(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (stripes < 1 || stripes > MAX_STRIPES) {
|
||||
log_error("Number of stripes (%d) must be between %d and %d",
|
||||
log_error("Number of stripes (%d) must be between %d and %d",
|
||||
stripes, 1, MAX_STRIPES);
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
@ -212,7 +194,7 @@ int lvcreate(int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
|
||||
if (!(lv = lv_create(lv_name, status, stripes, stripesize, extents,
|
||||
vg, pvh)))
|
||||
vg, pvh)))
|
||||
return ECMD_FAILED;
|
||||
|
||||
if (arg_count(readahead_ARG)) {
|
||||
@ -242,7 +224,7 @@ int lvcreate(int argc, char **argv)
|
||||
|
||||
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", fid->cmd->dev_dir,
|
||||
lv->vg->name, lv->name) < 0) {
|
||||
log_error("Name too long - device not zeroed (%s)",
|
||||
log_error("Name too long - device not zeroed (%s)",
|
||||
lv->name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ int lvresize(int argc, char **argv)
|
||||
const char *cmd_name;
|
||||
struct list *pvh, *segh;
|
||||
struct lv_list *lvl;
|
||||
struct pv_list *pvl;
|
||||
int opt = 0;
|
||||
|
||||
enum {
|
||||
@ -163,7 +162,7 @@ int lvresize(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* If extending, find stripes, stripesize & size of last segment */
|
||||
if (extents > lv->le_count &&
|
||||
if (extents > lv->le_count &&
|
||||
!(stripes == 1 || (stripes > 1 && stripesize))) {
|
||||
list_iterate(segh, &lv->segments) {
|
||||
struct stripe_segment *seg;
|
||||
@ -289,31 +288,11 @@ int lvresize(int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (resize == LV_EXTEND && argc) {
|
||||
/* Build up list of PVs */
|
||||
if (!(pvh = pool_alloc(fid->cmd->mem, sizeof(struct list)))) {
|
||||
log_error("pvh list allocation failed");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
list_init(pvh);
|
||||
for (; opt < argc; opt++) {
|
||||
if (!(pvl = find_pv_in_vg(vg, argv[opt]))) {
|
||||
log_error("Physical Volume %s not found in "
|
||||
"Volume Group %s", argv[opt],
|
||||
vg->name);
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (pvl->pv.pe_count == pvl->pv.pe_allocated) {
|
||||
log_error("No free extents on physical volume"
|
||||
" %s", argv[opt]);
|
||||
continue;
|
||||
/* FIXME Buy check not empty at end! */
|
||||
}
|
||||
|
||||
// FIXME: pv_list's need to be copied.
|
||||
list_add(pvh, &pvl->list);
|
||||
}
|
||||
if ((resize == LV_EXTEND && argc) &&
|
||||
!(pvh = create_pv_list(fid->cmd->mem, vg,
|
||||
argc - opt, argv + opt))) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (resize == LV_EXTEND) {
|
||||
|
@ -69,7 +69,7 @@ int pvchange(int argc, char **argv)
|
||||
list_iterate(pvh, pvs) {
|
||||
total++;
|
||||
done += pvchange_single(
|
||||
&list_item(pvh, struct pv_list)->pv);
|
||||
list_item(pvh, struct pv_list)->pv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ int pvchange_single(struct physical_volume *pv)
|
||||
pv_name, vg->name);
|
||||
return 0;
|
||||
}
|
||||
pv = &pvl->pv;
|
||||
pv = pvl->pv;
|
||||
if (!archive(vg))
|
||||
return 0;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ int pvdisplay(int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
|
||||
list_iterate(pvh, pvs)
|
||||
pvdisplay_single(&list_item(pvh, struct pv_list)->pv);
|
||||
pvdisplay_single(list_item(pvh, struct pv_list)->pv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -63,7 +63,7 @@ int pvscan(int argc, char **argv)
|
||||
/* eliminate exported/new if required */
|
||||
list_iterate(pvh, pvs) {
|
||||
pvl = list_item(pvh, struct pv_list);
|
||||
pv = &pvl->pv;
|
||||
pv = pvl->pv;
|
||||
|
||||
if ((arg_count(exported_ARG) && !(pv->status & EXPORTED_VG))
|
||||
|| (arg_count(novolumegroup_ARG) && (*pv->vg_name))) {
|
||||
@ -96,7 +96,7 @@ int pvscan(int argc, char **argv)
|
||||
/* find maximum pv name length */
|
||||
pv_max_name_len = vg_max_name_len = 0;
|
||||
list_iterate(pvh, pvs) {
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
len = strlen(dev_name(pv->dev));
|
||||
if (pv_max_name_len < len)
|
||||
pv_max_name_len = len;
|
||||
@ -108,7 +108,7 @@ int pvscan(int argc, char **argv)
|
||||
vg_max_name_len += 2;
|
||||
|
||||
list_iterate(pvh, pvs)
|
||||
pvscan_display_single(&list_item(pvh, struct pv_list)->pv);
|
||||
pvscan_display_single(list_item(pvh, struct pv_list)->pv);
|
||||
|
||||
if (!pvs_found) {
|
||||
log_print("No matching physical volumes found");
|
||||
|
@ -170,16 +170,16 @@ int process_each_pv_in_vg(struct volume_group *vg,
|
||||
int ret_max = 0;
|
||||
int ret = 0;
|
||||
struct list *pvh;
|
||||
struct physical_volume *pv;
|
||||
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if ((ret = process_single(vg, pv)) > ret_max)
|
||||
ret_max = ret;
|
||||
}
|
||||
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
ret = process_single(vg,
|
||||
&list_item(pvh,
|
||||
struct pv_list)->pv);
|
||||
if (ret > ret_max)
|
||||
ret_max = ret;
|
||||
}
|
||||
return ret_max;
|
||||
|
||||
}
|
||||
|
||||
int process_each_pv(int argc, char **argv, struct volume_group *vg,
|
||||
@ -201,7 +201,7 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg,
|
||||
vg->name);
|
||||
continue;
|
||||
}
|
||||
ret = process_single(vg, &pvl->pv);
|
||||
ret = process_single(vg, pvl->pv);
|
||||
if (ret > ret_max)
|
||||
ret_max = ret;
|
||||
}
|
||||
@ -284,3 +284,45 @@ char *default_vgname(struct format_instance *fi)
|
||||
|
||||
return pool_strdup(fid->cmd->mem, vg_path);
|
||||
}
|
||||
|
||||
struct list *create_pv_list(struct pool *mem,
|
||||
struct volume_group *vg,
|
||||
int argc, char **argv)
|
||||
{
|
||||
struct list *r;
|
||||
struct pv_list *pvl, *new_pvl;
|
||||
int i;
|
||||
|
||||
/* Build up list of PVs */
|
||||
if (!(r = pool_alloc(mem, sizeof(*r)))) {
|
||||
log_error("Allocation of list failed");
|
||||
return NULL;
|
||||
}
|
||||
list_init(r);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
||||
if (!(pvl = find_pv_in_vg(vg, argv[i]))) {
|
||||
log_err("Physical Volume %s not found in "
|
||||
"Volume Group %s", argv[i], vg->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pvl->pv->pe_count == pvl->pv->pe_allocated) {
|
||||
log_err("No free extents on physical volume %s",
|
||||
argv[i]);
|
||||
continue;
|
||||
/* FIXME Buy check not empty at end! */
|
||||
}
|
||||
|
||||
if (!(new_pvl = pool_alloc(mem, sizeof(*new_pvl)))) {
|
||||
log_err("Unable to allocate physical volume list.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(new_pvl, pvl, sizeof(*new_pvl));
|
||||
list_add(r, &new_pvl->list);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -49,4 +49,12 @@ int is_valid_chars(char *n);
|
||||
char *default_vgname(struct format_instance *fi);
|
||||
char *extract_vgname(struct format_instance *fi, char *lv_name);
|
||||
|
||||
/*
|
||||
* Builds a list of pv's from the names in argv. Used in
|
||||
* lvcreate/extend.
|
||||
*/
|
||||
struct list *create_pv_list(struct pool *mem,
|
||||
struct volume_group *vg,
|
||||
int argc, char **argv);
|
||||
|
||||
#endif
|
||||
|
@ -124,7 +124,7 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
|
||||
list_del(pvh);
|
||||
list_add(&vg_to->pvs, pvh);
|
||||
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
pv->vg_name = pool_strdup(fid->cmd->mem, vg_to->name);
|
||||
}
|
||||
vg_to->pv_count += vg_from->pv_count;
|
||||
|
@ -65,7 +65,7 @@ int vgreduce(int argc, char **argv)
|
||||
|
||||
/******* FIXME
|
||||
log_error ("no empty physical volumes found in volume group \"%s\"", vg_name);
|
||||
|
||||
|
||||
log_verbose
|
||||
("volume group \"%s\" will be reduced by %d physical volume%s",
|
||||
vg_name, np, np > 1 ? "s" : "");
|
||||
@ -108,7 +108,7 @@ static int vgreduce_single(struct volume_group *vg, struct physical_volume *pv)
|
||||
return ECMD_FAILED;
|
||||
|
||||
log_verbose("Removing %s from volume group %s", name, vg->name);
|
||||
|
||||
|
||||
if (pvl)
|
||||
list_del(&pvl->list);
|
||||
|
||||
|
@ -58,7 +58,7 @@ static int vgremove_single(const char *vg_name)
|
||||
|
||||
/* init physical volumes */
|
||||
list_iterate(pvh, &vg->pvs) {
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
pv = list_item(pvh, struct pv_list)->pv;
|
||||
log_verbose("Removing physical volume %s from volume group %s",
|
||||
dev_name(pv->dev), vg_name);
|
||||
*pv->vg_name = '\0';
|
||||
|
@ -97,7 +97,7 @@ int vgrename(int argc, char **argv)
|
||||
|
||||
/* FIXME Should vg_write fix these implicitly? It has to check them. */
|
||||
list_iterate(pvh, &vg_old->pvs) {
|
||||
strcpy(list_item(pvh, struct pv_list)->pv.vg_name,
|
||||
strcpy(list_item(pvh, struct pv_list)->pv->vg_name,
|
||||
vg_name_new);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user