mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Whenever vgname is captured, also capture vgid.
This commit is contained in:
parent
a14aa9d8c3
commit
cced28dac3
@ -1,6 +1,7 @@
|
||||
Version 2.02.03 -
|
||||
===================================
|
||||
Capture vgid in more places.
|
||||
Whenever vgname is captured, also capture vgid.
|
||||
Remove an incorrect unlock_vg() from process_each_lv().
|
||||
Update extent size information in vgchange and vgcreate man pages.
|
||||
Introduce origin_from_cow() and lv_is_visible().
|
||||
pvremove without -f now fails if there's no PV label.
|
||||
|
17
lib/cache/lvmcache.c
vendored
17
lib/cache/lvmcache.c
vendored
@ -348,7 +348,7 @@ static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
int lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
{
|
||||
if (!vgid || !info->vginfo || !strncmp(info->vginfo->vgid, vgid,
|
||||
sizeof(info->vginfo->vgid)))
|
||||
@ -369,8 +369,8 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("lvmcache: %s: setting VGID to %s", dev_name(info->dev),
|
||||
info->vginfo->vgid);
|
||||
log_debug("lvmcache: %s: setting %s VGID to %s", dev_name(info->dev),
|
||||
info->vginfo->vgname, info->vginfo->vgid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -425,8 +425,11 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
|
||||
/* FIXME Check consistency of list! */
|
||||
vginfo->fmt = info->fmt;
|
||||
|
||||
log_debug("lvmcache: %s now %s%s", dev_name(info->dev),
|
||||
*vgname ? "in VG " : "orphaned", vgname);
|
||||
log_debug("lvmcache: %s: now %s%s%s%s%s", dev_name(info->dev),
|
||||
*vgname ? "in VG " : "orphaned", vgname,
|
||||
vginfo->vgid[0] ? " (" : "",
|
||||
vginfo->vgid[0] ? vginfo->vgid : "",
|
||||
vginfo->vgid[0] ? ")" : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -446,7 +449,7 @@ int lvmcache_update_vg(struct volume_group *vg)
|
||||
if ((info = info_from_pvid(pvid_s))) {
|
||||
lvmcache_update_vgname(info, vg->name);
|
||||
if (!vgid_updated) {
|
||||
_lvmcache_update_vgid(info, (char *) &vg->id);
|
||||
lvmcache_update_vgid(info, (char *) &vg->id);
|
||||
vgid_updated = 1;
|
||||
}
|
||||
}
|
||||
@ -563,7 +566,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_lvmcache_update_vgid(info, vgid))
|
||||
if (!lvmcache_update_vgid(info, vgid))
|
||||
/* Non-critical */
|
||||
stack;
|
||||
|
||||
|
1
lib/cache/lvmcache.h
vendored
1
lib/cache/lvmcache.h
vendored
@ -69,6 +69,7 @@ void lvmcache_del(struct lvmcache_info *info);
|
||||
|
||||
/* Update things */
|
||||
int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname);
|
||||
int lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid);
|
||||
int lvmcache_update_vg(struct volume_group *vg);
|
||||
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only);
|
||||
|
@ -871,65 +871,72 @@ static int _scan_file(const struct format_type *fmt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
|
||||
char *buf, uint32_t size)
|
||||
const char *vgname_from_mda(const struct format_type *fmt,
|
||||
struct device_area *dev_area, struct id *vgid)
|
||||
{
|
||||
struct raw_locn *rlocn;
|
||||
struct mda_header *mdah;
|
||||
unsigned int len;
|
||||
int r = 0;
|
||||
uint32_t wrap = 0;
|
||||
const char *vgname = NULL;
|
||||
|
||||
if (!dev_open(dev_area->dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mdah = _raw_read_mda_header(fmt, dev_area))) {
|
||||
stack;
|
||||
if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
|
||||
goto_out;
|
||||
|
||||
/* FIXME Cope with returning a list */
|
||||
rlocn = mdah->raw_locns;
|
||||
|
||||
if (rlocn->offset + rlocn->size > mdah->size)
|
||||
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
|
||||
|
||||
if (wrap > rlocn->offset) {
|
||||
log_error("%s: metadata too large for circular buffer",
|
||||
dev_name(dev_area->dev));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rlocn = mdah->raw_locns;
|
||||
/* FIXME 64-bit */
|
||||
if (!(vgname = text_vgname_import(fmt, dev_area->dev,
|
||||
(off_t) (dev_area->start +
|
||||
rlocn->offset),
|
||||
(uint32_t) (rlocn->size - wrap),
|
||||
(off_t) (dev_area->start +
|
||||
MDA_HEADER_SIZE),
|
||||
wrap, calc_crc, rlocn->checksum,
|
||||
vgid)))
|
||||
goto_out;
|
||||
|
||||
while (rlocn->offset) {
|
||||
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
|
||||
size, buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
len = 0;
|
||||
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
|
||||
len < (size - 1))
|
||||
len++;
|
||||
buf[len] = '\0';
|
||||
|
||||
/* Ignore this entry if the characters aren't permissible */
|
||||
if (!validate_name(buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
break;
|
||||
|
||||
/* FIXME Cope with returning a list */
|
||||
rlocn++;
|
||||
/* Ignore this entry if the characters aren't permissible */
|
||||
if (!validate_name(vgname)) {
|
||||
stack;
|
||||
vgname = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64
|
||||
" for %s (%s)",
|
||||
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
|
||||
rlocn->size, vgname, vgid->uuid);
|
||||
|
||||
out:
|
||||
if (!dev_close(dev_area->dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
return vgname;
|
||||
}
|
||||
|
||||
static int _scan_raw(const struct format_type *fmt)
|
||||
{
|
||||
struct raw_list *rl;
|
||||
struct list *raw_list;
|
||||
char vgnamebuf[NAME_LEN + 2];
|
||||
const char *vgname;
|
||||
struct volume_group *vg;
|
||||
struct format_instance fid;
|
||||
struct id vgid;
|
||||
|
||||
raw_list = &((struct mda_lists *) fmt->private)->raws;
|
||||
|
||||
@ -938,9 +945,8 @@ static int _scan_raw(const struct format_type *fmt)
|
||||
|
||||
list_iterate_items(rl, raw_list) {
|
||||
/* FIXME We're reading mdah twice here... */
|
||||
if (vgname_from_mda(fmt, &rl->dev_area, vgnamebuf,
|
||||
sizeof(vgnamebuf))) {
|
||||
if ((vg = _vg_read_raw_area(&fid, vgnamebuf,
|
||||
if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid))) {
|
||||
if ((vg = _vg_read_raw_area(&fid, vgname,
|
||||
&rl->dev_area, 0)))
|
||||
lvmcache_update_vg(vg);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mda
|
||||
struct device *dev, uint64_t start, uint64_t size);
|
||||
void del_mdas(struct list *mdas);
|
||||
|
||||
int vgname_from_mda(const struct format_type *fmt, struct device_area *dev_area,
|
||||
char *buf, uint32_t size);
|
||||
const char *vgname_from_mda(const struct format_type *fmt,
|
||||
struct device_area *dev_area, struct id *vgid);
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,9 @@ struct text_vg_version_ops {
|
||||
struct config_tree * cf);
|
||||
void (*read_desc) (struct dm_pool * mem, struct config_tree * cf,
|
||||
time_t *when, char **desc);
|
||||
const char *(*read_vgname) (const struct format_type *fmt,
|
||||
struct config_tree *cft,
|
||||
struct id *vgid);
|
||||
};
|
||||
|
||||
struct text_vg_version_ops *text_vg_vsn1_init(void);
|
||||
@ -70,5 +73,11 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
|
||||
checksum_fn_t checksum_fn,
|
||||
uint32_t checksum,
|
||||
time_t *when, char **desc);
|
||||
const char *text_vgname_import(const struct format_type *fmt,
|
||||
struct device *dev,
|
||||
off_t offset, uint32_t size,
|
||||
off_t offset2, uint32_t size2,
|
||||
checksum_fn_t checksum_fn, uint32_t checksum,
|
||||
struct id *vgid);
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,51 @@
|
||||
/* FIXME Use tidier inclusion method */
|
||||
static struct text_vg_version_ops *(_text_vsn_list[2]);
|
||||
|
||||
const char *text_vgname_import(const struct format_type *fmt,
|
||||
struct device *dev,
|
||||
off_t offset, uint32_t size,
|
||||
off_t offset2, uint32_t size2,
|
||||
checksum_fn_t checksum_fn, uint32_t checksum,
|
||||
struct id *vgid)
|
||||
{
|
||||
struct config_tree *cft;
|
||||
struct text_vg_version_ops **vsn;
|
||||
const char *vgname;
|
||||
|
||||
static int _initialised = 0;
|
||||
|
||||
if (!_initialised) {
|
||||
_text_vsn_list[0] = text_vg_vsn1_init();
|
||||
_text_vsn_list[1] = NULL;
|
||||
_initialised = 1;
|
||||
}
|
||||
|
||||
if (!(cft = create_config_tree(NULL)))
|
||||
goto_out;
|
||||
|
||||
if ((!dev && !read_config_file(cft)) ||
|
||||
(dev && !read_config_fd(cft, dev, offset, size,
|
||||
offset2, size2, checksum_fn, checksum)))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* Find a set of version functions that can read this file
|
||||
*/
|
||||
for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
|
||||
if (!(*vsn)->check_version(cft))
|
||||
continue;
|
||||
|
||||
if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid)))
|
||||
goto_out;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
destroy_config_tree(cft);
|
||||
return vgname;
|
||||
}
|
||||
|
||||
struct volume_group *text_vg_import_fd(struct format_instance *fid,
|
||||
const char *file,
|
||||
struct device *dev,
|
||||
|
@ -798,10 +798,39 @@ static void _read_desc(struct dm_pool *mem,
|
||||
*when = u;
|
||||
}
|
||||
|
||||
static const char *_read_vgname(const struct format_type *fmt,
|
||||
struct config_tree *cft, struct id *vgid)
|
||||
{
|
||||
struct config_node *vgn;
|
||||
struct dm_pool *mem = fmt->cmd->mem;
|
||||
char *vgname;
|
||||
|
||||
/* skip any top-level values */
|
||||
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
|
||||
|
||||
if (!vgn) {
|
||||
log_error("Couldn't find volume group in file.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vgname = dm_pool_strdup(mem, vgn->key)))
|
||||
return_0;
|
||||
|
||||
vgn = vgn->child;
|
||||
|
||||
if (!_read_id(vgid, vgn, "id")) {
|
||||
log_error("Couldn't read uuid for volume group %s.", vgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vgname;
|
||||
}
|
||||
|
||||
static struct text_vg_version_ops _vsn1_ops = {
|
||||
check_version:_check_version,
|
||||
read_vg:_read_vg,
|
||||
read_desc:_read_desc
|
||||
read_desc:_read_desc,
|
||||
read_vgname:_read_vgname
|
||||
};
|
||||
|
||||
struct text_vg_version_ops *text_vg_vsn1_init(void)
|
||||
|
@ -195,13 +195,14 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
|
||||
struct disk_locn *dlocn_xl;
|
||||
uint64_t offset;
|
||||
struct metadata_area *mda;
|
||||
char vgnamebuf[NAME_LEN + 2];
|
||||
struct id vgid;
|
||||
struct mda_context *mdac;
|
||||
const char *vgname;
|
||||
|
||||
pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl));
|
||||
|
||||
if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL)))
|
||||
return 0;
|
||||
return_0;
|
||||
*label = info->label;
|
||||
|
||||
info->device_size = xlate64(pvhdr->device_size_xl);
|
||||
@ -232,10 +233,10 @@ static int _read(struct labeller *l, struct device *dev, char *buf,
|
||||
|
||||
list_iterate_items(mda, &info->mdas) {
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
if (vgname_from_mda(info->fmt, &mdac->area, vgnamebuf,
|
||||
sizeof(vgnamebuf))) {
|
||||
lvmcache_update_vgname(info, vgnamebuf);
|
||||
/* FIXME Also store vgid */
|
||||
if ((vgname = vgname_from_mda(info->fmt, &mdac->area,
|
||||
&vgid))) {
|
||||
lvmcache_update_vgname(info, vgname);
|
||||
lvmcache_update_vgid(info, (char *) &vgid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,15 +117,6 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
|
||||
int found = 0;
|
||||
char readbuf[LABEL_SCAN_SIZE];
|
||||
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
|
||||
if ((info = info_from_pvid(dev->pvid)))
|
||||
lvmcache_update_vgname(info, ORPHAN);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
|
||||
log_debug("%s: Failed to read label area", dev_name(dev));
|
||||
goto out;
|
||||
@ -188,9 +179,6 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
|
||||
log_very_verbose("%s: No label detected", dev_name(dev));
|
||||
}
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -272,16 +260,28 @@ int label_read(struct device *dev, struct label **result)
|
||||
char buf[LABEL_SIZE];
|
||||
struct labeller *l;
|
||||
uint64_t sector;
|
||||
int r;
|
||||
struct lvmcache_info *info;
|
||||
int r = 0;
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or))) {
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
|
||||
if ((info = info_from_pvid(dev->pvid)))
|
||||
lvmcache_update_vgname(info, ORPHAN);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or)))
|
||||
goto_out;
|
||||
|
||||
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
|
||||
(*result)->sector = sector;
|
||||
|
||||
out:
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -335,18 +335,34 @@ int label_write(struct device *dev, struct label *label)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Unused */
|
||||
int label_verify(struct device *dev)
|
||||
{
|
||||
struct labeller *l;
|
||||
char buf[LABEL_SIZE];
|
||||
uint64_t sector;
|
||||
struct lvmcache_info *info;
|
||||
int r = 0;
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or))) {
|
||||
if (!dev_open(dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
|
||||
if ((info = info_from_pvid(dev->pvid)))
|
||||
lvmcache_update_vgname(info, ORPHAN);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
return ((l->ops->verify) ? l->ops->verify(l, buf, sector) : 1);
|
||||
if (!(l = _find_labeller(dev, buf, §or)))
|
||||
goto_out;
|
||||
|
||||
r = l->ops->verify ? l->ops->verify(l, buf, sector) : 1;
|
||||
|
||||
out:
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void label_destroy(struct label *label)
|
||||
|
Loading…
Reference in New Issue
Block a user