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

If two or more VGs are found with the same name, use one that is not exported.

This commit is contained in:
Alasdair Kergon 2006-04-12 17:54:11 +00:00
parent 5dbc1f263a
commit e8db70239e
7 changed files with 105 additions and 19 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.03 -
===================================
If two or more VGs are found with the same name, use one that is not exported.
Whenever vgname is captured, also capture vgid and whether exported.
Remove an incorrect unlock_vg() from process_each_lv().
Update extent size information in vgchange and vgcreate man pages.

93
lib/cache/lvmcache.c vendored
View File

@ -86,7 +86,8 @@ int vgs_locked(void)
return _vgs_locked;
}
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
/* If vgid supplied, require a match. */
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
{
struct lvmcache_vginfo *vginfo;
@ -96,6 +97,12 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
return NULL;
if (vgid)
do
if (!strncmp(vgid, vginfo->vgid, sizeof(vginfo->vgid)))
return vginfo;
while ((vginfo = vginfo->next));
return vginfo;
}
@ -107,8 +114,9 @@ const struct format_type *fmt_from_vgname(const char *vgname)
struct list *devh, *tmp;
struct list devs;
struct device_list *devl;
char vgid[ID_LEN + 1];
if (!(vginfo = vginfo_from_vgname(vgname)))
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
return NULL;
/* This function is normally called before reading metadata so
@ -120,6 +128,8 @@ const struct format_type *fmt_from_vgname(const char *vgname)
list_add(&devs, &devl->list);
}
memcpy(vgid, vginfo->vgid, sizeof(vgid));
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
label_read(devl->dev, &label);
@ -127,6 +137,11 @@ const struct format_type *fmt_from_vgname(const char *vgname)
dm_free(devl);
}
/* If vginfo changed, caller needs to rescan */
if (!(vginfo = vginfo_from_vgname(vgname, NULL)) ||
strncmp(vginfo->vgid, vgid, sizeof(vgid)))
return NULL;
return vginfo->fmt;
}
@ -297,7 +312,7 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
static void _drop_vginfo(struct lvmcache_info *info)
static int _drop_vginfo(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
@ -306,6 +321,14 @@ static void _drop_vginfo(struct lvmcache_info *info)
if (info->vginfo && list_empty(&info->vginfo->infos)) {
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
if (info->vginfo->next) {
if (!dm_hash_insert(_vgname_hash, info->vginfo->vgname, info->vginfo->next)) {
log_error("vg hash re-insertion failed: %s",
info->vginfo->vgname);
return 0;
}
}
if (info->vginfo->vgname)
dm_free(info->vginfo->vgname);
if (*info->vginfo->vgid)
@ -315,6 +338,8 @@ static void _drop_vginfo(struct lvmcache_info *info)
}
info->vginfo = NULL;
return 1;
}
/* Unused
@ -375,10 +400,46 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
return 1;
}
static int _lvmcache_update_vgname(struct lvmcache_info *info,
const char *vgname)
static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
struct lvmcache_vginfo *primary_vginfo)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_vginfo *last_vginfo = primary_vginfo;
/* Pre-existing VG takes precedence. Unexported VG takes precedence. */
if (primary_vginfo) {
if (!(primary_vginfo->status & EXPORTED_VG) ||
(new_vginfo->status & EXPORTED_VG)) {
while (last_vginfo->next)
last_vginfo = last_vginfo->next;
last_vginfo->next = new_vginfo;
log_debug("VG %s: %s takes precedence over %s",
new_vginfo->vgname, primary_vginfo->vgid,
vgid);
return 1;
} else
log_debug("VG %s: %s takes precedence over exported %s",
new_vginfo->vgname, vgid,
primary_vginfo->vgid);
dm_hash_remove(_vgname_hash, primary_vginfo->vgname);
}
if (!dm_hash_insert(_vgname_hash, new_vginfo->vgname, new_vginfo)) {
log_error("cache_update: vg hash insertion failed: %s",
new_vginfo->vgname);
return 0;
}
if (primary_vginfo)
new_vginfo->next = primary_vginfo;
return 1;
}
static int _lvmcache_update_vgname(struct lvmcache_info *info,
const char *vgname, const char *vgid)
{
struct lvmcache_vginfo *vginfo, *primary_vginfo;
/* If vgname is NULL and we don't already have a vgname,
* assume ORPHAN - we want every entry to have a vginfo
@ -394,7 +455,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
_drop_vginfo(info);
/* Get existing vginfo or create new one */
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = vginfo_from_vgname(vgname, vgid))) {
if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
log_error("lvmcache_update_vgname: list alloc failed");
return 0;
@ -406,9 +467,8 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
return 0;
}
list_init(&vginfo->infos);
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
log_error("cache_update: vg hash insertion failed: %s",
vginfo->vgname);
primary_vginfo = vginfo_from_vgname(vgname, NULL);
if (!_insert_vginfo(vginfo, vgid, primary_vginfo)) {
dm_free(vginfo->vgname);
dm_free(vginfo);
return 0;
@ -454,7 +514,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus)
{
if (!_lvmcache_update_vgname(info, vgname) ||
if (!_lvmcache_update_vgname(info, vgname, vgid) ||
!_lvmcache_update_vgid(info, vgid) ||
!_lvmcache_update_vgstatus(info, vgstatus))
return_0;
@ -606,9 +666,14 @@ static void _lvmcache_destroy_entry(struct lvmcache_info *info)
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
{
if (vginfo->vgname)
dm_free(vginfo->vgname);
dm_free(vginfo);
struct lvmcache_vginfo *next;
do {
next = vginfo->next;
if (vginfo->vgname)
dm_free(vginfo->vgname);
dm_free(vginfo);
} while ((vginfo = next));
}
static void _lvmcache_destroy_lockname(int present)

View File

@ -42,6 +42,7 @@ struct lvmcache_vginfo {
uint32_t status;
char vgid[ID_LEN + 1];
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
};
/* One per device */
@ -82,7 +83,8 @@ void lvmcache_unlock_vgname(const char *vgname);
/* Queries */
const struct format_type *fmt_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);

View File

@ -470,7 +470,7 @@ int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
struct lvmcache_info *info;
/* Fast path if we already saw this VG and cached the list of PVs */
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
if (vg_name && (vginfo = vginfo_from_vgname(vg_name, NULL)) &&
vginfo->infos.n) {
list_iterate_items(info, &vginfo->infos) {
dev = info->dev;

View File

@ -314,7 +314,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
/*
* If the cache scanning doesn't work, this will never work
*/
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
if (vg_name && (vginfo = vginfo_from_vgname(vg_name, NULL)) &&
vginfo->infos.n) {
if (_read_vg_pds(fmt, mem, vginfo, pdhead, &totaldevs)) {

View File

@ -879,6 +879,8 @@ const char *vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah;
uint32_t wrap = 0;
const char *vgname = NULL;
unsigned int len = 0;
char buf[NAME_LEN + 1];
if (!dev_open(dev_area->dev)) {
stack;
@ -891,6 +893,22 @@ const char *vgname_from_mda(const struct format_type *fmt,
/* FIXME Cope with returning a list */
rlocn = mdah->raw_locns;
/* Do quick check for a vgname */
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
NAME_LEN, buf))
goto_out;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
len++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf))
goto_out;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
@ -1543,7 +1561,7 @@ static struct format_instance *_create_text_instance(const struct format_type
/* Scan PVs in VG for any further MDAs */
lvmcache_label_scan(fmt->cmd, 0);
if (!(vginfo = vginfo_from_vgname(vgname))) {
if (!(vginfo = vginfo_from_vgname(vgname, NULL))) {
stack;
goto out;
}

View File

@ -862,7 +862,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
struct volume_group *vg;
struct physical_volume *pv;
if (!(vginfo = vginfo_from_vgname(ORPHAN))) {
if (!(vginfo = vginfo_from_vgname(ORPHAN, NULL))) {
stack;
return NULL;
}