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

Keep a global (per-format) orphan_vg and keep any and all orphan PVs linked to

it. Avoids the need for FMT_INSTANCE_PV and enables further simplifications. No
functional change, internal refactor only.
This commit is contained in:
Petr Rockai 2012-02-10 02:53:03 +00:00
parent 0fbbc6ce13
commit 6e41729eb8
7 changed files with 110 additions and 75 deletions

View File

@ -1322,8 +1322,6 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
{
log_error("lvmcache_update_vgname_and_id: %s -> %s", dev_name(info->dev), vgname);
if (!vgname && !info->vginfo) {
log_error(INTERNAL_ERROR "NULL vgname handed to cache");
/* FIXME Remove this */

View File

@ -546,6 +546,13 @@ static void _format1_destroy_instance(struct format_instance *fid)
static void _format1_destroy(struct format_type *fmt)
{
/* FIXME out of place, but the main (cmd) pool has been already
* destroyed and touching the fid (also via release_vg) will crash the
* program */
dm_hash_destroy(fmt->orphan_vg->hostnames);
dm_pool_destroy(fmt->orphan_vg->fid->mem);
dm_pool_destroy(fmt->orphan_vg->vgmem);
dm_free(fmt);
}
@ -570,6 +577,8 @@ struct format_type *init_format(struct cmd_context *cmd)
#endif
{
struct format_type *fmt = dm_malloc(sizeof(*fmt));
struct format_instance_ctx fic;
struct format_instance *fid;
if (!fmt)
return_NULL;
@ -596,6 +605,19 @@ struct format_type *init_format(struct cmd_context *cmd)
return NULL;
}
if (!(fmt->orphan_vg = alloc_vg("text_orphan", cmd, fmt->orphan_vg_name))) {
log_error("Couldn't create lvm1 orphan VG.");
return NULL;
}
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = fmt->orphan_vg_name;
fic.context.vg_ref.vg_id = NULL;
if (!(fid = _format1_create_instance(fmt, &fic))) {
log_error("Couldn't create lvm1 orphan VG format instance.");
return NULL;
}
vg_set_fid(fmt->orphan_vg, fid);
log_very_verbose("Initialised format: %s", fmt->name);
return fmt;

View File

@ -259,6 +259,13 @@ static void _pool_destroy_instance(struct format_instance *fid)
static void _pool_destroy(struct format_type *fmt)
{
/* FIXME out of place, but the main (cmd) pool has been already
* destroyed and touching the fid (also via release_vg) will crash the
* program */
dm_hash_destroy(fmt->orphan_vg->hostnames);
dm_pool_destroy(fmt->orphan_vg->fid->mem);
dm_pool_destroy(fmt->orphan_vg->vgmem);
dm_free(fmt);
}
@ -281,6 +288,8 @@ struct format_type *init_format(struct cmd_context *cmd)
#endif
{
struct format_type *fmt = dm_malloc(sizeof(*fmt));
struct format_instance_ctx fic;
struct format_instance *fid;
if (!fmt) {
log_error("Unable to allocate format type structure for pool "
@ -309,6 +318,19 @@ struct format_type *init_format(struct cmd_context *cmd)
return NULL;
}
if (!(fmt->orphan_vg = alloc_vg("text_orphan", cmd, fmt->orphan_vg_name))) {
log_error("Couldn't create lvm1 orphan VG.");
return NULL;
}
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = fmt->orphan_vg_name;
fic.context.vg_ref.vg_id = NULL;
if (!(fid = _pool_create_instance(fmt, &fic))) {
log_error("Couldn't create lvm1 orphan VG format instance.");
return NULL;
}
vg_set_fid(fmt->orphan_vg, fid);
log_very_verbose("Initialised format: %s", fmt->name);
return fmt;

View File

@ -1513,8 +1513,8 @@ static int _text_pv_initialise(const struct format_type *fmt,
static void _text_destroy_instance(struct format_instance *fid)
{
if (--fid->ref_count <= 1) {
if (fid->type & FMT_INSTANCE_VG && fid->metadata_areas_index.hash)
dm_hash_destroy(fid->metadata_areas_index.hash);
if (fid->type & FMT_INSTANCE_VG && fid->metadata_areas_index)
dm_hash_destroy(fid->metadata_areas_index);
dm_pool_destroy(fid->mem);
}
}
@ -1541,6 +1541,14 @@ static void _free_raws(struct dm_list *raw_list)
static void _text_destroy(struct format_type *fmt)
{
/* FIXME out of place, but the main (cmd) pool has been already
* destroyed and touching the fid (also via release_vg) will crash the
* program */
dm_hash_destroy(fmt->orphan_vg->fid->metadata_areas_index);
dm_hash_destroy(fmt->orphan_vg->hostnames);
dm_pool_destroy(fmt->orphan_vg->fid->mem);
dm_pool_destroy(fmt->orphan_vg->vgmem);
if (fmt->private) {
_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
_free_raws(&((struct mda_lists *) fmt->private)->raws);
@ -1666,22 +1674,7 @@ static int _text_pv_setup(const struct format_type *fmt,
static int _create_pv_text_instance(struct format_instance *fid,
const struct format_instance_ctx *fic)
{
struct lvmcache_info *info;
fid->private = NULL;
if (!(fid->metadata_areas_index.array = dm_pool_zalloc(fid->mem,
FMT_TEXT_MAX_MDAS_PER_PV *
sizeof(struct metadata_area *)))) {
log_error("Couldn't allocate format instance metadata index.");
return 0;
}
if (fic->type & FMT_INSTANCE_MDAS &&
(info = lvmcache_info_from_pvid(fic->context.pv_id, 0)))
lvmcache_fid_add_mdas_pv(info, fid);
return 1;
return 0; /* just fail */
}
static void *_create_text_context(struct dm_pool *mem, struct text_context *tc)
@ -1760,13 +1753,13 @@ static int _create_vg_text_instance(struct format_instance *fid,
mda->ops = &_metadata_text_file_backup_ops;
mda->metadata_locn = _create_text_context(fid->mem, fic->context.private);
mda->status = 0;
fid->metadata_areas_index.hash = NULL;
fid->metadata_areas_index = NULL;
fid_add_mda(fid, mda, NULL, 0, 0);
} else {
vg_name = fic->context.vg_ref.vg_name;
vg_id = fic->context.vg_ref.vg_id;
if (!(fid->metadata_areas_index.hash = dm_hash_create(128))) {
if (!(fid->metadata_areas_index = dm_hash_create(128))) {
log_error("Couldn't create metadata index for format "
"instance of VG %s.", vg_name);
return 0;
@ -1872,6 +1865,10 @@ static int _add_metadata_area_to_pv(struct physical_volume *pv,
return 1;
}
static int _text_pv_remove_metadata_area(const struct format_type *fmt,
struct physical_volume *pv,
unsigned mda_index);
static int _text_pv_add_metadata_area(const struct format_type *fmt,
struct physical_volume *pv,
int pe_start_locked,
@ -1908,9 +1905,12 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
mda_size = mda_size << SECTOR_SHIFT;
if (fid_get_mda_indexed(fid, pvid, ID_LEN, mda_index)) {
log_error(INTERNAL_ERROR "metadata area with index %u already "
"exists on PV %s.", mda_index, pv_dev_name(pv));
return 0;
if (!_text_pv_remove_metadata_area(fmt, pv, mda_index)) {
log_error(INTERNAL_ERROR "metadata area with index %u already "
"exists on PV %s and removal failed.",
mda_index, pv_dev_name(pv));
return 0;
}
}
/* First metadata area at the start of the device. */
@ -2270,6 +2270,8 @@ static int _get_config_disk_area(struct cmd_context *cmd,
struct format_type *create_text_format(struct cmd_context *cmd)
{
struct format_instance_ctx fic;
struct format_instance *fid;
struct format_type *fmt;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
@ -2335,6 +2337,21 @@ struct format_type *create_text_format(struct cmd_context *cmd)
}
}
if (!(fmt->orphan_vg = alloc_vg("text_orphan", cmd, fmt->orphan_vg_name))) {
dm_free(fmt);
return NULL;
}
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = fmt->orphan_vg_name;
fic.context.vg_ref.vg_id = NULL;
if (!(fid = _text_create_text_instance(fmt, &fic))) {
log_error("Failed to create format instance");
release_vg(fmt->orphan_vg);
goto err;
}
vg_set_fid(fmt->orphan_vg, fid);
log_very_verbose("Initialised format: %s", fmt->name);
return fmt;

View File

@ -178,6 +178,7 @@ struct format_type {
const char *name;
const char *alias;
const char *orphan_vg_name;
struct volume_group *orphan_vg; /* Only one ever exists. */
uint32_t features;
void *library;
void *private;
@ -237,10 +238,7 @@ struct format_instance {
/* FIXME: Try to use the index only. Remove these lists. */
struct dm_list metadata_areas_in_use;
struct dm_list metadata_areas_ignored;
union {
struct metadata_area **array;
struct dm_hash_table *hash;
} metadata_areas_index;
struct dm_hash_table *metadata_areas_index;
void *private;
};

View File

@ -170,22 +170,18 @@ void add_pvl_to_vgs(struct volume_group *vg, struct pv_list *pvl)
void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl)
{
struct format_instance_ctx fic;
struct format_instance *fid;
struct lvmcache_info *info;
vg->pv_count--;
dm_list_del(&pvl->list);
pvl->pv->vg = NULL; /* orphan */
/* Use a new PV-based format instance since the PV is orphan now. */
fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
fic.context.pv_id = (const char *) &pvl->pv->id;
fid = pvl->pv->fid->fmt->ops->create_instance(pvl->pv->fid->fmt, &fic);
pv_set_fid(pvl->pv, fid);
pvl->pv->vg = vg->fid->fmt->orphan_vg; /* orphan */
if ((info = lvmcache_info_from_pvid((const char *) &pvl->pv->id, 0)))
lvmcache_fid_add_mdas(info, vg->fid->fmt->orphan_vg->fid,
(const char *) &pvl->pv->id, ID_LEN);
pv_set_fid(pvl->pv, vg->fid->fmt->orphan_vg->fid);
}
/**
* add_pv_to_vg - Add a physical volume to a volume group
* @vg - volume group to add to
@ -1663,13 +1659,16 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,
goto bad;
}
fic.type = FMT_INSTANCE_PV;
fic.context.pv_id = (const char *) &pv->id;
if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
log_error("Couldn't create format instance for PV %s.", pv_dev_name(pv));
struct pv_list *pvl;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
log_error("pv_list allocation in pv_create failed");
goto bad;
}
pv_set_fid(pv, fid);
pvl->pv = pv;
add_pvl_to_vgs(fmt->orphan_vg, pvl);
fmt->orphan_vg->extent_count += pv->pe_count;
fmt->orphan_vg->free_count += pv->pe_count;
pv->fmt = fmt;
pv->vg_name = fmt->orphan_vg_name;
@ -2762,18 +2761,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
if (!(fmt = lvmcache_fmt_from_vgname(orphan_vgname, NULL, 0)))
return_NULL;
if (!(vg = alloc_vg("vg_read_orphans", cmd, orphan_vgname)))
return_NULL;
/* create format instance with appropriate metadata area */
fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = orphan_vgname;
fic.context.vg_ref.vg_id = NULL;
if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
log_error("Failed to create format instance");
goto bad;
}
vg_set_fid(vg, fid);
vg = fmt->orphan_vg;
baton.warnings = warnings;
baton.vg = vg;
@ -2781,7 +2769,6 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
return vg;
bad:
release_vg(vg);
return NULL;
}
@ -3574,6 +3561,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
struct label *label;
struct lvmcache_info *info;
struct device *dev;
const struct format_type *fmt;
if (!(dev = dev_cache_get(pv_name, cmd->filter)))
return_NULL;
@ -3586,6 +3574,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
}
info = (struct lvmcache_info *) label->info;
fmt = lvmcache_fmt(info);
pv = _alloc_pv(pvmem, dev);
if (!pv) {
@ -3611,14 +3600,8 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,
if (fid)
lvmcache_fid_add_mdas(info, fid, (const char *) &pv->id, ID_LEN);
else {
fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
fic.context.pv_id = (const char *) &pv->id;
if (!(fid = pv->fmt->ops->create_instance(pv->fmt, &fic))) {
log_error("_pv_read: Couldn't create format instance "
"for PV %s", pv_name);
goto bad;
}
pv_set_fid(pv, fid);
lvmcache_fid_add_mdas(info, fmt->orphan_vg->fid, (const char *) &pv->id, ID_LEN);
pv_set_fid(pv, fmt->orphan_vg->fid);
}
return pv;
@ -4236,11 +4219,9 @@ int fid_add_mda(struct format_instance *fid, struct metadata_area *mda,
full_key, sizeof(full_key)))
return_0;
dm_hash_insert(fid->metadata_areas_index.hash,
dm_hash_insert(fid->metadata_areas_index,
full_key, mda);
}
else
fid->metadata_areas_index.array[sub_key] = mda;
return 1;
}
@ -4275,11 +4256,9 @@ struct metadata_area *fid_get_mda_indexed(struct format_instance *fid,
if (!_convert_key_to_string(key, key_len, sub_key,
full_key, sizeof(full_key)))
return_NULL;
mda = (struct metadata_area *) dm_hash_lookup(fid->metadata_areas_index.hash,
mda = (struct metadata_area *) dm_hash_lookup(fid->metadata_areas_index,
full_key);
}
else
mda = fid->metadata_areas_index.array[sub_key];
return mda;
}
@ -4311,9 +4290,8 @@ int fid_remove_mda(struct format_instance *fid, struct metadata_area *mda,
full_key, sizeof(full_key)))
return_0;
dm_hash_remove(fid->metadata_areas_index.hash, full_key);
} else
fid->metadata_areas_index.array[sub_key] = NULL;
dm_hash_remove(fid->metadata_areas_index, full_key);
}
}
dm_list_del(&mda->list);

View File

@ -79,7 +79,7 @@ static void _free_vg(struct volume_group *vg)
void release_vg(struct volume_group *vg)
{
if (!vg)
if (!vg || (vg->fid && vg == vg->fid->fmt->orphan_vg))
return;
/* Check if there are any vginfo holders */