1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

Refactor vg allocation code

Create new function alloc_vg() to allocate VG structure.

It takes pool_name (for easier debugging).
and also take vg_name to futher simplify code.

Move remainder of _build_vg_from_pds  to _pool_vg_read
and use vg memory pool for import functions.
(it's been using smem -> fid mempool -> cmd mempool)
(FIXME: remove mempool parameter for import functions and use vg).

Move remainder of the _build_vg to _format1_vg_read
This commit is contained in:
Zdenek Kabelac 2011-03-10 12:43:29 +00:00
parent 9cfdf8031e
commit 3019419e95
7 changed files with 133 additions and 212 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.85 - Version 2.02.85 -
=================================== ===================================
Refactor allocation of VG structure, add alloc_vg().
Avoid possible endless loop in _free_vginfo when 4 or more VGs have same name. Avoid possible endless loop in _free_vginfo when 4 or more VGs have same name.
Use empty string instead of /dev// for LV path when there's no VG. Use empty string instead of /dev// for LV path when there's no VG.
Don't allocate unused VG mempool in _pvsegs_sub_single. Don't allocate unused VG mempool in _pvsegs_sub_single.

View File

@ -177,84 +177,58 @@ out:
return 0; return 0;
} }
static struct volume_group *_build_vg(struct format_instance *fid,
struct dm_list *pvs,
struct dm_pool *mem)
{
struct volume_group *vg = dm_pool_zalloc(mem, sizeof(*vg));
struct disk_list *dl;
if (!vg)
goto_bad;
if (dm_list_empty(pvs))
goto_bad;
vg->cmd = fid->fmt->cmd;
vg->vgmem = mem;
vg->fid = fid;
vg->seqno = 0;
dm_list_init(&vg->pvs);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
if (!_check_vgs(pvs, vg))
goto_bad;
dl = dm_list_item(pvs->n, struct disk_list);
if (!import_vg(mem, vg, dl))
goto_bad;
if (!import_pvs(fid->fmt, mem, vg, pvs))
goto_bad;
if (!import_lvs(mem, vg, pvs))
goto_bad;
if (!import_extents(fid->fmt->cmd, vg, pvs))
goto_bad;
if (!import_snapshots(mem, vg, pvs))
goto_bad;
/* Fix extents counts by adding missing PV if partial VG */
if ((vg->status & PARTIAL_VG) && !_fix_partial_vg(vg, pvs))
goto_bad;
return vg;
bad:
dm_pool_free(mem, vg);
return NULL;
}
static struct volume_group *_format1_vg_read(struct format_instance *fid, static struct volume_group *_format1_vg_read(struct format_instance *fid,
const char *vg_name, const char *vg_name,
struct metadata_area *mda __attribute__((unused))) struct metadata_area *mda __attribute__((unused)))
{ {
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", VG_MEMPOOL_CHUNK); struct volume_group *vg;
struct dm_list pvs; struct disk_list *dl;
struct volume_group *vg = NULL; DM_LIST_INIT(pvs);
dm_list_init(&pvs);
if (!mem)
return_NULL;
/* Strip dev_dir if present */ /* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir); vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
if (!read_pvs_in_vg if (!(vg = alloc_vg("format1_vg_read", fid->fmt->cmd, NULL)))
(fid->fmt, vg_name, fid->fmt->cmd->filter, mem, &pvs)) return_NULL;
if (!read_pvs_in_vg(fid->fmt, vg_name, fid->fmt->cmd->filter,
vg->vgmem, &pvs))
goto_bad; goto_bad;
if (!(vg = _build_vg(fid, &pvs, mem))) if (dm_list_empty(&pvs))
goto_bad;
vg->fid = fid;
if (!_check_vgs(&pvs, vg))
goto_bad;
dl = dm_list_item(pvs.n, struct disk_list);
if (!import_vg(vg->vgmem, vg, dl))
goto_bad;
if (!import_pvs(fid->fmt, vg->vgmem, vg, &pvs))
goto_bad;
if (!import_lvs(vg->vgmem, vg, &pvs))
goto_bad;
if (!import_extents(fid->fmt->cmd, vg, &pvs))
goto_bad;
if (!import_snapshots(vg->vgmem, vg, &pvs))
goto_bad;
/* Fix extents counts by adding missing PV if partial VG */
if ((vg->status & PARTIAL_VG) && !_fix_partial_vg(vg, &pvs))
goto_bad; goto_bad;
return vg; return vg;
bad: bad:
dm_pool_destroy(mem); free(vg);
return NULL; return NULL;
} }

View File

@ -98,93 +98,65 @@ static int _check_usp(const char *vgname, struct user_subpool *usp, int sp_count
return 1; return 1;
} }
static struct volume_group *_build_vg_from_pds(struct format_instance static struct volume_group *_pool_vg_read(struct format_instance *fid,
*fid, struct dm_pool *mem, const char *vg_name,
struct dm_list *pds) struct metadata_area *mda __attribute__((unused)))
{ {
struct dm_pool *smem = fid->fmt->cmd->mem; struct volume_group *vg;
struct volume_group *vg = NULL; struct user_subpool *usp;
struct user_subpool *usp = NULL;
int sp_count; int sp_count;
DM_LIST_INIT(pds);
if (!(vg = dm_pool_zalloc(smem, sizeof(*vg)))) { /* We can safely ignore the mda passed in */
log_error("Unable to allocate volume group structure");
return NULL; /* Strip dev_dir if present */
} vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
/* Set vg_name through read_pool_pds() */
if (!(vg = alloc_vg("pool_vg_read", fid->fmt->cmd, NULL)))
return_NULL;
/* Read all the pvs in the vg */
if (!read_pool_pds(fid->fmt, vg_name, vg->vgmem, &pds))
goto_bad;
vg->cmd = fid->fmt->cmd;
vg->vgmem = mem;
vg->fid = fid; vg->fid = fid;
vg->name = NULL; /* Setting pool seqno to 1 because the code always did this,
vg->status = 0; * although we don't think it's needed. */
vg->extent_count = 0;
vg->pv_count = 0;
vg->seqno = 1; vg->seqno = 1;
vg->system_id = NULL;
dm_list_init(&vg->pvs);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
if (!import_pool_vg(vg, smem, pds)) if (!import_pool_vg(vg, vg->vgmem, &pds))
return_NULL; goto_bad;
if (!import_pool_pvs(fid->fmt, vg, smem, pds)) if (!import_pool_pvs(fid->fmt, vg, vg->vgmem, &pds))
return_NULL; goto_bad;
if (!import_pool_lvs(vg, smem, pds)) if (!import_pool_lvs(vg, vg->vgmem, &pds))
return_NULL; goto_bad;
/* /*
* I need an intermediate subpool structure that contains all the * I need an intermediate subpool structure that contains all the
* relevant info for this. Then i can iterate through the subpool * relevant info for this. Then i can iterate through the subpool
* structures for checking, and create the segments * structures for checking, and create the segments
*/ */
if (!(usp = _build_usp(pds, mem, &sp_count))) if (!(usp = _build_usp(&pds, vg->vgmem, &sp_count)))
return_NULL; goto_bad;
/* /*
* check the subpool structures - we can't handle partial VGs in * check the subpool structures - we can't handle partial VGs in
* the pool format, so this will error out if we're missing PVs * the pool format, so this will error out if we're missing PVs
*/ */
if (!_check_usp(vg->name, usp, sp_count)) if (!_check_usp(vg->name, usp, sp_count))
return_NULL; goto_bad;
if (!import_pool_segments(&vg->lvs, smem, usp, sp_count)) if (!import_pool_segments(&vg->lvs, vg->vgmem, usp, sp_count))
return_NULL; goto_bad;
return vg; return vg;
}
static struct volume_group *_pool_vg_read(struct format_instance *fid, bad:
const char *vg_name, free_vg(vg);
struct metadata_area *mda __attribute__((unused)))
{
struct dm_pool *mem = dm_pool_create("pool vg_read", VG_MEMPOOL_CHUNK);
struct dm_list pds;
struct volume_group *vg = NULL;
dm_list_init(&pds);
/* We can safely ignore the mda passed in */
if (!mem)
return_NULL;
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
/* Read all the pvs in the vg */
if (!read_pool_pds(fid->fmt, vg_name, mem, &pds))
goto_out;
/* Do the rest of the vg stuff */
if (!(vg = _build_vg_from_pds(fid, mem, &pds)))
goto_out;
return vg;
out:
dm_pool_destroy(mem);
return NULL; return NULL;
} }

View File

@ -652,35 +652,25 @@ static struct volume_group *_read_vg(struct format_instance *fid,
const struct config_node *vgn, *cn; const struct config_node *vgn, *cn;
struct volume_group *vg; struct volume_group *vg;
struct dm_hash_table *pv_hash = NULL, *lv_hash = NULL; struct dm_hash_table *pv_hash = NULL, *lv_hash = NULL;
struct dm_pool *mem = dm_pool_create("lvm2 vg_read", VG_MEMPOOL_CHUNK);
unsigned scan_done_once = use_cached_pvs; unsigned scan_done_once = use_cached_pvs;
if (!mem)
return_NULL;
/* skip any top-level values */ /* skip any top-level values */
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib)
; ;
if (!vgn) { if (!vgn) {
log_error("Couldn't find volume group in file."); log_error("Couldn't find volume group in file.");
goto bad; return NULL;
} }
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) if (!(vg = alloc_vg("read_vg", fid->fmt->cmd, vgn->key)))
goto_bad; return_NULL;
vg->vgmem = mem;
vg->cmd = fid->fmt->cmd;
/* FIXME Determine format type from file contents */ /* FIXME Determine format type from file contents */
/* eg Set to instance of fmt1 here if reading a format1 backup? */ /* eg Set to instance of fmt1 here if reading a format1 backup? */
vg->fid = fid; vg->fid = fid;
if (!(vg->name = dm_pool_strdup(mem, vgn->key))) if (!(vg->system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN)))
goto_bad;
if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN)))
goto_bad; goto_bad;
vgn = vgn->child; vgn = vgn->child;
@ -733,7 +723,6 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad; goto bad;
} }
vg->alloc = ALLOC_NORMAL;
if ((cn = find_config_node(vgn, "allocation_policy"))) { if ((cn = find_config_node(vgn, "allocation_policy"))) {
const struct config_value *cv = cn->v; const struct config_value *cv = cn->v;
if (!cv || !cv->v.str) { if (!cv || !cv->v.str) {
@ -761,21 +750,16 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad; goto bad;
} }
dm_list_init(&vg->pvs); if (!_read_sections(fid, "physical_volumes", _read_pv, vg->vgmem, vg,
if (!_read_sections(fid, "physical_volumes", _read_pv, mem, vg,
vgn, pv_hash, lv_hash, 0, &scan_done_once)) { vgn, pv_hash, lv_hash, 0, &scan_done_once)) {
log_error("Couldn't find all physical volumes for volume " log_error("Couldn't find all physical volumes for volume "
"group %s.", vg->name); "group %s.", vg->name);
goto bad; goto bad;
} }
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
/* Optional tags */ /* Optional tags */
if ((cn = find_config_node(vgn, "tags")) && if ((cn = find_config_node(vgn, "tags")) &&
!(read_tags(mem, &vg->tags, cn->v))) { !(read_tags(vg->vgmem, &vg->tags, cn->v))) {
log_error("Couldn't read tags for volume group %s.", vg->name); log_error("Couldn't read tags for volume group %s.", vg->name);
goto bad; goto bad;
} }
@ -789,15 +773,15 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad; goto bad;
} }
if (!_read_sections(fid, "logical_volumes", _read_lvnames, mem, vg, if (!_read_sections(fid, "logical_volumes", _read_lvnames, vg->vgmem,
vgn, pv_hash, lv_hash, 1, NULL)) { vg, vgn, pv_hash, lv_hash, 1, NULL)) {
log_error("Couldn't read all logical volume names for volume " log_error("Couldn't read all logical volume names for volume "
"group %s.", vg->name); "group %s.", vg->name);
goto bad; goto bad;
} }
if (!_read_sections(fid, "logical_volumes", _read_lvsegs, mem, vg, if (!_read_sections(fid, "logical_volumes", _read_lvsegs, vg->vgmem,
vgn, pv_hash, lv_hash, 1, NULL)) { vg, vgn, pv_hash, lv_hash, 1, NULL)) {
log_error("Couldn't read all logical volumes for " log_error("Couldn't read all logical volumes for "
"volume group %s.", vg->name); "volume group %s.", vg->name);
goto bad; goto bad;
@ -824,7 +808,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
if (lv_hash) if (lv_hash)
dm_hash_destroy(lv_hash); dm_hash_destroy(lv_hash);
dm_pool_destroy(mem); free_vg(vg);
return NULL; return NULL;
} }

View File

@ -839,22 +839,13 @@ static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
uint32_t failure) uint32_t failure)
{ {
struct dm_pool *vgmem; if (!vg && !(vg = alloc_vg("vg_make_handle", cmd, NULL)))
if (!vg) {
if (!(vgmem = dm_pool_create("lvm2 vg_handle", VG_MEMPOOL_CHUNK)) ||
!(vg = dm_pool_zalloc(vgmem, sizeof(*vg)))) {
log_error("Error allocating vg handle.");
if (vgmem)
dm_pool_destroy(vgmem);
return_NULL; return_NULL;
}
vg->vgmem = vgmem;
}
if (vg->read_status != failure)
vg->read_status = failure; vg->read_status = failure;
return (struct volume_group *)vg; return vg;
} }
int lv_has_unknown_segments(const struct logical_volume *lv) int lv_has_unknown_segments(const struct logical_volume *lv)
@ -891,7 +882,6 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
struct volume_group *vg; struct volume_group *vg;
struct format_instance_ctx fic; struct format_instance_ctx fic;
int consistent = 0; int consistent = 0;
struct dm_pool *mem;
uint32_t rc; uint32_t rc;
if (!validate_name(vg_name)) { if (!validate_name(vg_name)) {
@ -914,10 +904,10 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
return _vg_make_handle(cmd, NULL, FAILED_EXIST); return _vg_make_handle(cmd, NULL, FAILED_EXIST);
} }
if (!(mem = dm_pool_create("lvm2 vg_create", VG_MEMPOOL_CHUNK))) /* Strip dev_dir if present */
goto_bad; vg_name = strip_dir(vg_name, cmd->dev_dir);
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) if (!(vg = alloc_vg("vg_create", cmd, vg_name)))
goto_bad; goto_bad;
if (!id_create(&vg->id)) { if (!id_create(&vg->id)) {
@ -926,19 +916,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
goto bad; goto bad;
} }
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, cmd->dev_dir);
vg->vgmem = mem;
vg->cmd = cmd;
if (!(vg->name = dm_pool_strdup(mem, vg_name)))
goto_bad;
vg->seqno = 0;
vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE); vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) if (!(vg->system_id = dm_pool_alloc(vg->vgmem, NAME_LEN)))
goto_bad; goto_bad;
*vg->system_id = '\0'; *vg->system_id = '\0';
@ -954,14 +933,6 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
vg->mda_copies = DEFAULT_VGMETADATACOPIES; vg->mda_copies = DEFAULT_VGMETADATACOPIES;
vg->pv_count = 0; vg->pv_count = 0;
dm_list_init(&vg->pvs);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
/* initialize removed_pvs list */
dm_list_init(&vg->removed_pvs);
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS; fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = vg_name; fic.context.vg_ref.vg_name = vg_name;
@ -2614,31 +2585,15 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
struct pv_list *pvl; struct pv_list *pvl;
struct volume_group *vg; struct volume_group *vg;
struct physical_volume *pv; struct physical_volume *pv;
struct dm_pool *mem;
lvmcache_label_scan(cmd, 0); lvmcache_label_scan(cmd, 0);
if (!(vginfo = vginfo_from_vgname(orphan_vgname, NULL))) if (!(vginfo = vginfo_from_vgname(orphan_vgname, NULL)))
return_NULL; return_NULL;
if (!(mem = dm_pool_create("vg_read orphan", VG_MEMPOOL_CHUNK))) if (!(vg = alloc_vg("vg_read_orphans", cmd, orphan_vgname)))
return_NULL; return_NULL;
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
log_error("vg allocation failed");
goto bad;
}
dm_list_init(&vg->pvs);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
vg->vgmem = mem;
vg->cmd = cmd;
if (!(vg->name = dm_pool_strdup(mem, orphan_vgname))) {
log_error("vg name allocation failed");
goto bad;
}
/* create format instance with appropriate metadata area */ /* create format instance with appropriate metadata area */
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS; fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = orphan_vgname; fic.context.vg_ref.vg_name = orphan_vgname;
@ -2649,11 +2604,11 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
} }
dm_list_iterate_items(info, &vginfo->infos) { dm_list_iterate_items(info, &vginfo->infos) {
if (!(pv = _pv_read(cmd, mem, dev_name(info->dev), if (!(pv = _pv_read(cmd, vg->vgmem, dev_name(info->dev),
vg->fid, NULL, warnings, 0))) { vg->fid, NULL, warnings, 0))) {
continue; continue;
} }
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) { if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl)))) {
log_error("pv_list allocation failed"); log_error("pv_list allocation failed");
goto bad; goto bad;
} }
@ -2663,7 +2618,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
return vg; return vg;
bad: bad:
dm_pool_destroy(mem); free_vg(vg);
return NULL; return NULL;
} }

View File

@ -18,6 +18,38 @@
#include "display.h" #include "display.h"
#include "activate.h" #include "activate.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
{
struct dm_pool *vgmem;
struct volume_group *vg;
if (!(vgmem = dm_pool_create(pool_name, VG_MEMPOOL_CHUNK)) ||
!(vg = dm_pool_zalloc(vgmem, sizeof(*vg)))) {
log_error("Failed to allocate volume group structure");
if (vgmem)
dm_pool_destroy(vgmem);
return NULL;
}
if (vg_name && !(vg->name = dm_pool_strdup(vgmem, vg_name))) {
log_error("Failed to allocate VG name.");
dm_pool_destroy(vgmem);
return NULL;
}
vg->cmd = cmd;
vg->vgmem = vgmem;
vg->alloc = ALLOC_NORMAL;
dm_list_init(&vg->pvs);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
return vg;
}
char *vg_fmt_dup(const struct volume_group *vg) char *vg_fmt_dup(const struct volume_group *vg)
{ {
if (!vg->fid || !vg->fid->fmt) if (!vg->fid || !vg->fid->fmt)

View File

@ -95,6 +95,9 @@ struct volume_group {
uint32_t mda_copies; /* target number of mdas for this VG */ uint32_t mda_copies; /* target number of mdas for this VG */
}; };
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name);
char *vg_fmt_dup(const struct volume_group *vg); char *vg_fmt_dup(const struct volume_group *vg);
char *vg_name_dup(const struct volume_group *vg); char *vg_name_dup(const struct volume_group *vg);
char *vg_system_id_dup(const struct volume_group *vg); char *vg_system_id_dup(const struct volume_group *vg);