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

metadata: use radix tree to find lv_names

Replace usage of dm_hash with radix_tree to quickly find LV name
with a vg and also index PV names with set of available PVs.
This PV index is only needed during the import, but instead
of passing 'radix_tree *' everywhere, just keep this within
a VG struct as well and once the parsing is finished, release
this PV index radix_tree.

This also makes it easier to replace this structure
in the future if needed.

lv_set_name now uses  radix_tree remove+insert to keep lv_names
tree in-sync and usable for  find_lv queries.
This commit is contained in:
Zdenek Kabelac 2024-10-24 16:12:18 +02:00
parent 1825e782cc
commit 21517c2bd5
19 changed files with 100 additions and 96 deletions

View File

@ -202,8 +202,7 @@ static int _settings_text_export(const struct lv_segment *seg,
} }
static int _cache_pool_text_import(struct lv_segment *seg, static int _cache_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct logical_volume *data_lv, *meta_lv; struct logical_volume *data_lv, *meta_lv;
const char *str = NULL; const char *str = NULL;
@ -438,8 +437,7 @@ static const struct segtype_handler _cache_pool_ops = {
}; };
static int _cache_text_import(struct lv_segment *seg, static int _cache_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct logical_volume *pool_lv, *origin_lv; struct logical_volume *pool_lv, *origin_lv;
const char *name; const char *name;

View File

@ -26,6 +26,7 @@
#include "lib/format_text/text_import.h" #include "lib/format_text/text_import.h"
#include "lib/config/defaults.h" #include "lib/config/defaults.h"
#include "lib/datastruct/str_list.h" #include "lib/datastruct/str_list.h"
#include "base/data-struct/radix-tree.h"
typedef int (*section_fn) (struct cmd_context *cmd, typedef int (*section_fn) (struct cmd_context *cmd,
struct format_type *fmt, struct format_type *fmt,
@ -34,9 +35,7 @@ typedef int (*section_fn) (struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *pvn, const struct dm_config_node *pvn,
const struct dm_config_node *vgn, const struct dm_config_node *vgn);
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash);
#define _read_int32(root, path, result) \ #define _read_int32(root, path, result) \
dm_config_get_uint32(root, path, (uint32_t *) (result)) dm_config_get_uint32(root, path, (uint32_t *) (result))
@ -180,9 +179,7 @@ static int _read_pv(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *pvn, const struct dm_config_node *pvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash __attribute__((unused)))
{ {
struct physical_volume *pv; struct physical_volume *pv;
struct pv_list *pvl; struct pv_list *pvl;
@ -200,8 +197,8 @@ static int _read_pv(struct cmd_context *cmd,
* Add the pv to the pv hash for quick lookup when we read * Add the pv to the pv hash for quick lookup when we read
* the lv segments. * the lv segments.
*/ */
if (!dm_hash_insert(pv_hash, pvn->key, pv)) if (!radix_tree_insert_ptr(vg->pv_names, pvn->key, strlen(pvn->key), pv))
return_0; return_0;
if (!(pvn = pvn->child)) { if (!(pvn = pvn->child)) {
log_error("Empty pv section."); log_error("Empty pv section.");
@ -310,9 +307,7 @@ static int _read_pvsummary(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *pvn, const struct dm_config_node *pvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
{ {
struct physical_volume *pv; struct physical_volume *pv;
struct pv_list *pvl; struct pv_list *pvl;
@ -395,8 +390,7 @@ static int _read_segment(struct cmd_context *cmd,
struct format_type *fmt, struct format_type *fmt,
struct format_instance *fid, struct format_instance *fid,
struct dm_pool *mem, struct dm_pool *mem,
struct logical_volume *lv, const struct dm_config_node *sn, struct logical_volume *lv, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash)
{ {
uint32_t area_count = 0u; uint32_t area_count = 0u;
struct lv_segment *seg; struct lv_segment *seg;
@ -456,7 +450,7 @@ static int _read_segment(struct cmd_context *cmd,
} }
if (seg->segtype->ops->text_import && if (seg->segtype->ops->text_import &&
!seg->segtype->ops->text_import(seg, sn_child, pv_hash)) !seg->segtype->ops->text_import(seg, sn_child))
return_0; return_0;
/* Optional tags */ /* Optional tags */
@ -491,7 +485,7 @@ static int _read_segment(struct cmd_context *cmd,
} }
int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn, int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
const struct dm_config_value *cv, struct dm_hash_table *pv_hash, const struct dm_config_value *cv,
uint64_t status) uint64_t status)
{ {
unsigned int s; unsigned int s;
@ -523,7 +517,7 @@ int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
} }
/* FIXME Cope if LV not yet read in */ /* FIXME Cope if LV not yet read in */
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) { if ((pv = find_pv_by_pv_name(seg->lv->vg, cv->v.str))) {
if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i)) if (!set_lv_segment_area_pv(seg, s, pv, (uint32_t) cv->next->v.i))
return_0; return_0;
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) { } else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
@ -557,8 +551,7 @@ static int _read_segments(struct cmd_context *cmd,
struct format_type *fmt, struct format_type *fmt,
struct format_instance *fid, struct format_instance *fid,
struct dm_pool *mem, struct dm_pool *mem,
struct logical_volume *lv, const struct dm_config_node *lvn, struct logical_volume *lv, const struct dm_config_node *lvn)
struct dm_hash_table *pv_hash)
{ {
const struct dm_config_node *sn; const struct dm_config_node *sn;
int count = 0, seg_count; int count = 0, seg_count;
@ -569,7 +562,7 @@ static int _read_segments(struct cmd_context *cmd,
* All sub-sections are assumed to be segments. * All sub-sections are assumed to be segments.
*/ */
if (!sn->v) { if (!sn->v) {
if (!_read_segment(cmd, fmt, fid, mem, lv, sn, pv_hash)) if (!_read_segment(cmd, fmt, fid, mem, lv, sn))
return_0; return_0;
count++; count++;
@ -615,9 +608,7 @@ static int _read_lvnames(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *lvn, const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash)
{ {
struct logical_volume *lv; struct logical_volume *lv;
const char *str; const char *str;
@ -740,9 +731,6 @@ static int _read_lvnames(struct cmd_context *cmd,
return 0; return 0;
} }
if (!dm_hash_insert(lv_hash, lv->name, lv))
return_0;
if (timestamp && !lv_set_creation(lv, hostname, timestamp)) if (timestamp && !lv_set_creation(lv, hostname, timestamp))
return_0; return_0;
@ -775,9 +763,7 @@ static int _read_historical_lvnames(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *hlvn, const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
{ {
struct generic_logical_volume *glv; struct generic_logical_volume *glv;
struct glv_list *glvl; struct glv_list *glvl;
@ -848,9 +834,7 @@ static int _read_historical_lvnames_interconnections(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *hlvn, const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
{ {
const char *historical_lv_name, *origin_name = NULL; const char *historical_lv_name, *origin_name = NULL;
struct generic_logical_volume *glv, *origin_glv, *descendant_glv; struct generic_logical_volume *glv, *origin_glv, *descendant_glv;
@ -962,13 +946,11 @@ static int _read_lvsegs(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *lvn, const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)), const struct dm_config_node *vgn __attribute__((unused)))
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash)
{ {
struct logical_volume *lv; struct logical_volume *lv;
if (!(lv = dm_hash_lookup(lv_hash, lvn->key))) { if (!(lv = find_lv(vg, lvn->key))) {
log_error("Lost logical volume reference %s", lvn->key); log_error("Lost logical volume reference %s", lvn->key);
return 0; return 0;
} }
@ -987,7 +969,7 @@ static int _read_lvsegs(struct cmd_context *cmd,
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0])); memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
if (!_read_segments(cmd, fmt, fid, mem, lv, lvn, pv_hash)) if (!_read_segments(cmd, fmt, fid, mem, lv, lvn))
return_0; return_0;
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size; lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
@ -1028,8 +1010,6 @@ static int _read_sections(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvmcache_vgsummary *vgsummary, struct lvmcache_vgsummary *vgsummary,
const struct dm_config_node *vgn, const struct dm_config_node *vgn,
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash,
int optional) int optional)
{ {
const struct dm_config_node *n; const struct dm_config_node *n;
@ -1044,7 +1024,7 @@ static int _read_sections(struct cmd_context *cmd,
} }
for (n = n->child; n; n = n->sib) { for (n = n->child; n; n = n->sib) {
if (!fn(cmd, (struct format_type *)fmt, fid, mem, vg, vgsummary, n, vgn, pv_hash, lv_hash)) if (!fn(cmd, (struct format_type *)fmt, fid, mem, vg, vgsummary, n, vgn))
return_0; return_0;
} }
@ -1061,7 +1041,6 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
const struct dm_config_value *cv; const struct dm_config_value *cv;
const char *str, *format_str, *system_id; const char *str, *format_str, *system_id;
struct volume_group *vg; struct volume_group *vg;
struct dm_hash_table *pv_hash = NULL, *lv_hash = NULL;
uint64_t vgstatus; uint64_t vgstatus;
/* skip any top-level values */ /* skip any top-level values */
@ -1079,20 +1058,20 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
mem = vg->vgmem; mem = vg->vgmem;
/* /*
* The pv hash memorizes the pv section names -> pv * The pv_names memorizes the pv section names -> pv
* structures. * structures.
*/ */
if (!(pv_hash = dm_hash_create(59))) { if (!(vg->pv_names = radix_tree_create(NULL, NULL))) {
log_error("Couldn't create pv hash table."); log_error("Couldn't create pv_names radix tree.");
goto bad; goto bad;
} }
/* /*
* The lv hash memorizes the lv section names -> lv * The lv_names radix_tree memorizes the lv section names -> lv
* structures. * structures.
*/ */
if (!(lv_hash = dm_hash_create(1023))) { if (!(vg->lv_names = radix_tree_create(NULL, NULL))) {
log_error("Couldn't create lv hash table."); log_error("Couldn't create lv_names radix tree.");
goto bad; goto bad;
} }
@ -1211,7 +1190,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
} }
if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg, NULL, if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg, NULL,
vgn, pv_hash, lv_hash, 0)) { vgn, 0)) {
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;
@ -1225,28 +1204,28 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
} }
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg, NULL, if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg, NULL,
vgn, pv_hash, lv_hash, 1)) { vgn, 1)) {
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(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg, NULL, if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg, NULL,
vgn, pv_hash, lv_hash, 1)) { vgn, 1)) {
log_error("Couldn't read all historical logical volumes for volume " log_error("Couldn't read all historical logical volumes for volume "
"group %s.", vg->name); "group %s.", vg->name);
goto bad; goto bad;
} }
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg, NULL, if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg, NULL,
vgn, pv_hash, lv_hash, 1)) { vgn, 1)) {
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;
} }
if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames_interconnections, if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames_interconnections,
vg, NULL, vgn, pv_hash, lv_hash, 1)) { vg, NULL, vgn, 1)) {
log_error("Couldn't read all removed logical volume interconnections " log_error("Couldn't read all removed logical volume interconnections "
"for volume group %s.", vg->name); "for volume group %s.", vg->name);
goto bad; goto bad;
@ -1259,24 +1238,20 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
goto bad; goto bad;
} }
dm_hash_destroy(pv_hash);
dm_hash_destroy(lv_hash);
if (fid) if (fid)
vg_set_fid(vg, fid); vg_set_fid(vg, fid);
if (vg->pv_names) {
radix_tree_destroy(vg->pv_names);
vg->pv_names = NULL; /* PV names are no longer valid outside of _read_vg() */
}
/* /*
* Finished. * Finished.
*/ */
return vg; return vg;
bad: bad:
if (pv_hash)
dm_hash_destroy(pv_hash);
if (lv_hash)
dm_hash_destroy(lv_hash);
release_vg(vg); release_vg(vg);
return NULL; return NULL;
} }
@ -1360,7 +1335,7 @@ static int _read_vgsummary(const struct format_type *fmt, const struct dm_config
} }
if (!_read_sections(fmt->cmd, NULL, NULL, mem, "physical_volumes", _read_pvsummary, NULL, vgsummary, if (!_read_sections(fmt->cmd, NULL, NULL, mem, "physical_volumes", _read_pvsummary, NULL, vgsummary,
vgn, NULL, NULL, 0)) { vgn, 0)) {
log_debug("Couldn't read pv summaries"); log_debug("Couldn't read pv summaries");
} }

View File

@ -23,7 +23,6 @@ struct lv_segment;
struct dm_config_node; struct dm_config_node;
int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn, int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
const struct dm_config_value *cv, struct dm_hash_table *pv_hash, const struct dm_config_value *cv, uint64_t status);
uint64_t status);
#endif #endif

View File

@ -36,8 +36,7 @@ static void _integrity_display(const struct lv_segment *seg)
} }
static int _integrity_text_import(struct lv_segment *seg, static int _integrity_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct integrity_settings *set; struct integrity_settings *set;
struct logical_volume *origin_lv = NULL; struct logical_volume *origin_lv = NULL;

View File

@ -21,6 +21,7 @@
#include "lib/metadata/segtype.h" #include "lib/metadata/segtype.h"
#include "lib/datastruct/str_list.h" #include "lib/datastruct/str_list.h"
#include "lib/locking/lvmlockd.h" #include "lib/locking/lvmlockd.h"
#include "base/data-struct/radix-tree.h"
#include <time.h> #include <time.h>
#include <sys/utsname.h> #include <sys/utsname.h>
@ -1577,10 +1578,26 @@ int lv_set_creation(struct logical_volume *lv,
return 1; return 1;
} }
/*
* As we keep now vg->lv_names for quick looking of an LV by name
* when the LV name is changed, we need to also update our lookup tree
*/
int lv_set_name(struct logical_volume *lv, const char *lv_name) int lv_set_name(struct logical_volume *lv, const char *lv_name)
{ {
if (lv->vg->lv_names && lv->name &&
!radix_tree_remove(lv->vg->lv_names, lv->name, strlen(lv->name))) {
log_error("Cannot remove from lv_names LV %s", lv->name);
return 0;
}
lv->name = lv_name; /* NULL -> LV is removed from tree */ lv->name = lv_name; /* NULL -> LV is removed from tree */
if (lv->vg->lv_names && lv->name &&
!radix_tree_insert_ptr(lv->vg->lv_names, lv->name, strlen(lv->name), lv)) {
log_error("Cannot insert to lv_names LV %s", lv->name);
return 0;
}
return 1; return 1;
} }

View File

@ -32,6 +32,7 @@
#include "lib/label/label.h" #include "lib/label/label.h"
#include "lib/misc/lvm-signal.h" #include "lib/misc/lvm-signal.h"
#include "lib/device/filesystem.h" #include "lib/device/filesystem.h"
#include "base/data-struct/radix-tree.h"
#ifdef HAVE_BLKZEROOUT #ifdef HAVE_BLKZEROOUT
#include <sys/ioctl.h> #include <sys/ioctl.h>

View File

@ -1671,8 +1671,7 @@ struct logical_volume *find_lv_in_vg_by_lvid(const struct volume_group *vg,
struct logical_volume *find_lv(const struct volume_group *vg, struct logical_volume *find_lv(const struct volume_group *vg,
const char *lv_name) const char *lv_name)
{ {
struct lv_list *lvl = find_lv_in_vg(vg, lv_name); return radix_tree_lookup_ptr(vg->lv_names, lv_name, strlen(lv_name));
return lvl ? lvl->lv : NULL;
} }
struct generic_logical_volume *find_historical_glv(const struct volume_group *vg, struct generic_logical_volume *find_historical_glv(const struct volume_group *vg,
@ -1734,6 +1733,16 @@ struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
return NULL; return NULL;
} }
struct physical_volume *find_pv_by_pv_name(struct volume_group *vg, const char *pv_name)
{
if (!vg->pv_names) {
log_error(INTERNAL_ERROR "Cannot find pv name %s outside of _read_vg()", pv_name);
return NULL;
}
return radix_tree_lookup_ptr(vg->pv_names, pv_name, strlen(pv_name));
}
/* Find segment at a given logical extent in an LV */ /* Find segment at a given logical extent in an LV */
struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le) struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le)
{ {

View File

@ -395,6 +395,7 @@ struct logical_volume *find_lv_in_vg_by_lvid(const struct volume_group *vg,
/* FIXME Merge these functions with ones above */ /* FIXME Merge these functions with ones above */
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev); struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
struct physical_volume *find_pv_by_pv_name(struct volume_group *vg, const char *pv_name);
struct pv_list *find_pv_in_pv_list(const struct dm_list *pl, struct pv_list *find_pv_in_pv_list(const struct dm_list *pl,
const struct physical_volume *pv); const struct physical_volume *pv);

View File

@ -254,8 +254,7 @@ struct segtype_handler {
int (*text_import_area_count) (const struct dm_config_node * sn, int (*text_import_area_count) (const struct dm_config_node * sn,
uint32_t *area_count); uint32_t *area_count);
int (*text_import) (struct lv_segment * seg, int (*text_import) (struct lv_segment * seg,
const struct dm_config_node * sn, const struct dm_config_node * sn);
struct dm_hash_table * pv_hash);
int (*merge_segments) (struct lv_segment * seg1, int (*merge_segments) (struct lv_segment * seg1,
struct lv_segment * seg2); struct lv_segment * seg2);
int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem, int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem,

View File

@ -19,6 +19,7 @@
#include "lib/activate/activate.h" #include "lib/activate/activate.h"
#include "lib/commands/toolcontext.h" #include "lib/commands/toolcontext.h"
#include "lib/format_text/archiver.h" #include "lib/format_text/archiver.h"
#include "base/data-struct/radix-tree.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd, struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name) const char *vg_name)
@ -76,6 +77,13 @@ static void _free_vg(struct volume_group *vg)
if (vg->committed_cft) if (vg->committed_cft)
config_destroy(vg->committed_cft); config_destroy(vg->committed_cft);
if (vg->lv_names)
radix_tree_destroy(vg->lv_names);
if (vg->pv_names)
radix_tree_destroy(vg->pv_names);
dm_pool_destroy(vg->vgmem); dm_pool_destroy(vg->vgmem);
} }
@ -129,6 +137,12 @@ int unlink_lv_from_vg(struct logical_volume *lv)
dm_list_move(&lv->vg->removed_lvs, &lvl->list); dm_list_move(&lv->vg->removed_lvs, &lvl->list);
lv->status |= LV_REMOVED; lv->status |= LV_REMOVED;
/* lv->lv_name stays valid for historical LV usage
* So just remove the name from active lv_names */
if (lv->vg->lv_names &&
!radix_tree_remove(lv->vg->lv_names, lv->name, strlen(lv->name)))
stack;
return 1; return 1;
} }

View File

@ -64,6 +64,9 @@ struct volume_group {
struct profile *profile; struct profile *profile;
uint64_t status; uint64_t status;
struct radix_tree *lv_names; /* maintained tree for LV names within VG */
struct radix_tree *pv_names; /* PV names used for metadata import */
struct id id; struct id id;
const char *name; const char *name;
const char *old_name; /* Set during vgrename and vgcfgrestore */ const char *old_name; /* Set during vgrename and vgcfgrestore */

View File

@ -73,8 +73,7 @@ static int _mirrored_text_import_area_count(const struct dm_config_node *sn, uin
return 1; return 1;
} }
static int _mirrored_text_import(struct lv_segment *seg, const struct dm_config_node *sn, static int _mirrored_text_import(struct lv_segment *seg, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash)
{ {
const struct dm_config_value *cv; const struct dm_config_value *cv;
const char *logname = NULL; const char *logname = NULL;
@ -126,7 +125,7 @@ static int _mirrored_text_import(struct lv_segment *seg, const struct dm_config_
return 0; return 0;
} }
return text_import_areas(seg, sn, cv, pv_hash, MIRROR_IMAGE); return text_import_areas(seg, sn, cv, MIRROR_IMAGE);
} }
static int _mirrored_text_export(const struct lv_segment *seg, struct formatter *f) static int _mirrored_text_export(const struct lv_segment *seg, struct formatter *f)

View File

@ -128,8 +128,7 @@ static int _raid_text_import_areas(struct lv_segment *seg,
} }
static int _raid_text_import(struct lv_segment *seg, static int _raid_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash)
{ {
const struct dm_config_value *cv; const struct dm_config_value *cv;
const struct { const struct {

View File

@ -34,9 +34,7 @@ static const char *_snap_target_name(const struct lv_segment *seg,
return lvseg_name(seg); return lvseg_name(seg);
} }
static int _snap_text_import(struct lv_segment *seg, const struct dm_config_node *sn)
static int _snap_text_import(struct lv_segment *seg, const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
uint32_t chunk_size; uint32_t chunk_size;
struct logical_volume *org, *cow; struct logical_volume *org, *cow;

View File

@ -69,8 +69,7 @@ static int _striped_text_import_area_count(const struct dm_config_node *sn, uint
return 1; return 1;
} }
static int _striped_text_import(struct lv_segment *seg, const struct dm_config_node *sn, static int _striped_text_import(struct lv_segment *seg, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash)
{ {
const struct dm_config_value *cv; const struct dm_config_value *cv;
@ -89,7 +88,7 @@ static int _striped_text_import(struct lv_segment *seg, const struct dm_config_n
seg->area_len /= seg->area_count; seg->area_len /= seg->area_count;
return text_import_areas(seg, sn, cv, pv_hash, 0); return text_import_areas(seg, sn, cv, 0);
} }
static int _striped_text_export(const struct lv_segment *seg, struct formatter *f) static int _striped_text_export(const struct lv_segment *seg, struct formatter *f)

View File

@ -79,8 +79,7 @@ static int _thin_pool_add_message(struct lv_segment *seg,
} }
static int _thin_pool_text_import(struct lv_segment *seg, static int _thin_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
const char *lv_name; const char *lv_name;
struct logical_volume *pool_data_lv, *pool_metadata_lv; struct logical_volume *pool_data_lv, *pool_metadata_lv;
@ -467,8 +466,7 @@ static void _thin_display(const struct lv_segment *seg)
} }
static int _thin_text_import(struct lv_segment *seg, static int _thin_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
const char *lv_name; const char *lv_name;
struct logical_volume *pool_lv, *origin = NULL, *external_lv = NULL, *merge_lv = NULL; struct logical_volume *pool_lv, *origin = NULL, *external_lv = NULL, *merge_lv = NULL;

View File

@ -19,8 +19,7 @@
#include "lib/format_text/text_export.h" #include "lib/format_text/text_export.h"
#include "lib/config/config.h" #include "lib/config/config.h"
static int _unknown_text_import(struct lv_segment *seg, const struct dm_config_node *sn, static int _unknown_text_import(struct lv_segment *seg, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash)
{ {
struct dm_config_node *new, *last = NULL, *head = NULL; struct dm_config_node *new, *last = NULL, *head = NULL;
const struct dm_config_node *current; const struct dm_config_node *current;

View File

@ -74,8 +74,7 @@ static void _vdo_display(const struct lv_segment *seg)
} }
static int _vdo_text_import(struct lv_segment *seg, static int _vdo_text_import(struct lv_segment *seg,
const struct dm_config_node *n, const struct dm_config_node *n)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct logical_volume *vdo_pool_lv; struct logical_volume *vdo_pool_lv;
const char *str; const char *str;
@ -206,8 +205,7 @@ static int _vdo_pool_text_import_area_count(const struct dm_config_node *sn __at
} }
static int _vdo_pool_text_import(struct lv_segment *seg, static int _vdo_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *n, const struct dm_config_node *n)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct dm_vdo_target_params *vtp = &seg->vdo_params; struct dm_vdo_target_params *vtp = &seg->vdo_params;
struct logical_volume *data_lv; struct logical_volume *data_lv;

View File

@ -39,8 +39,7 @@ static void _writecache_display(const struct lv_segment *seg)
} }
static int _writecache_text_import(struct lv_segment *seg, static int _writecache_text_import(struct lv_segment *seg,
const struct dm_config_node *sn, const struct dm_config_node *sn)
struct dm_hash_table *pv_hash __attribute__((unused)))
{ {
struct logical_volume *origin_lv = NULL; struct logical_volume *origin_lv = NULL;
struct logical_volume *fast_lv; struct logical_volume *fast_lv;