From f084e627cc5847aa1f08e25b654b6f9512a5b39d Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Tue, 11 Apr 2006 17:42:15 +0000 Subject: [PATCH] When scanning, also record whether or not VG is exported. --- WHATS_NEW | 2 +- lib/cache/lvmcache.c | 30 +++++++++++++++++++++++++----- lib/cache/lvmcache.h | 10 ++++++++-- lib/format1/disk-rep.c | 15 +++++++++------ lib/format1/format1.c | 2 +- lib/format1/lvm1-label.c | 8 ++++++-- lib/format_pool/disk_rep.c | 2 +- lib/format_text/format-text.c | 12 +++++++----- lib/format_text/format-text.h | 3 ++- lib/format_text/import-export.h | 4 ++-- lib/format_text/import.c | 4 ++-- lib/format_text/import_vsn1.c | 17 +++++++++++++++-- lib/format_text/text_label.c | 8 +++++--- lib/label/label.c | 6 +++--- 14 files changed, 87 insertions(+), 36 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 2f67f934e..580881f22 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,6 +1,6 @@ Version 2.02.03 - =================================== - Whenever vgname is captured, also capture vgid. + 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. Introduce origin_from_cow() and lv_is_visible(). diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index e47761d76..075a0b764 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -435,10 +435,28 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info, return 1; } -int lvmcache_update_vgname_and_id(struct lvmcache_info *info, const char *vgname, const char *vgid) +static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus) +{ + if (!info || !info->vginfo) + return 1; + + if ((info->vginfo->status & EXPORTED_VG) != (vgstatus & EXPORTED_VG)) + log_debug("lvmcache: %s: VG %s exported", + dev_name(info->dev), + vgstatus & EXPORTED_VG ? "now" : "no longer"); + + info->vginfo->status = vgstatus; + + return 1; +} + +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) || - !_lvmcache_update_vgid(info, vgid)) + !_lvmcache_update_vgid(info, vgid) || + !_lvmcache_update_vgstatus(info, vgstatus)) return_0; return 1; @@ -457,7 +475,8 @@ int lvmcache_update_vg(struct volume_group *vg) /* FIXME Could pvl->pv->dev->pvid ever be different? */ if ((info = info_from_pvid(pvid_s)) && !lvmcache_update_vgname_and_id(info, vg->name, - (char *) &vg->id)) + (char *) &vg->id, + vg->status)) return_0; } @@ -466,7 +485,8 @@ int lvmcache_update_vg(struct volume_group *vg) struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, struct device *dev, - const char *vgname, const char *vgid) + const char *vgname, const char *vgid, + uint32_t vgstatus) { struct label *label; struct lvmcache_info *existing, *info; @@ -562,7 +582,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, return NULL; } - if (!lvmcache_update_vgname_and_id(info, vgname, vgid)) { + if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus)) { if (!existing) { dm_hash_remove(_pvid_hash, pvid_s); strcpy(info->dev->pvid, ""); diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index 78468041e..e58ba4168 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -33,15 +33,18 @@ struct cmd_context; struct format_type; struct volume_group; +/* One per VG */ struct lvmcache_vginfo { struct list list; /* Join these vginfos together */ struct list infos; /* List head for lvmcache_infos */ const struct format_type *fmt; char *vgname; /* "" == orphan */ + uint32_t status; char vgid[ID_LEN + 1]; char _padding[7]; }; +/* One per device */ struct lvmcache_info { struct list list; /* Join VG members together */ struct list mdas; /* list head for metadata areas */ @@ -64,11 +67,14 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan); /* Add/delete a device */ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, struct device *dev, - const char *vgname, const char *vgid); + const char *vgname, const char *vgid, + uint32_t vgstatus); void lvmcache_del(struct lvmcache_info *info); /* Update things */ -int lvmcache_update_vgname_and_id(struct lvmcache_info *info, const char *vgname, const char *vgid); +int lvmcache_update_vgname_and_id(struct lvmcache_info *info, + const char *vgname, const char *vgid, + uint32_t vgstatus); int lvmcache_update_vg(struct volume_group *vg); void lvmcache_lock_vgname(const char *vgname, int read_only); diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c index af76b8faf..f62b7897e 100644 --- a/lib/format1/disk-rep.c +++ b/lib/format1/disk-rep.c @@ -321,12 +321,14 @@ static int _read_extents(struct disk_list *data) static void __update_lvmcache(const struct format_type *fmt, struct disk_list *dl, - struct device *dev, const char *vgid) + struct device *dev, const char *vgid, + int exported) { struct lvmcache_info *info; if (!(info = lvmcache_add(fmt->labeller, dl->pvd.pv_uuid, dev, - dl->pvd.vg_name, vgid))) { + dl->pvd.vg_name, vgid, + exported ? EXPORTED_VG : 0))) { stack; return; } @@ -364,24 +366,25 @@ static struct disk_list *__read_disk(const struct format_type *fmt, if (!*dl->pvd.vg_name) { log_very_verbose("%s is not a member of any format1 VG", name); - __update_lvmcache(fmt, dl, dev, NULL); + __update_lvmcache(fmt, dl, dev, NULL, 0); return (vg_name) ? NULL : dl; } if (!read_vgd(dl->dev, &dl->vgd, &dl->pvd)) { log_error("Failed to read VG data from PV (%s)", name); - __update_lvmcache(fmt, dl, dev, NULL); + __update_lvmcache(fmt, dl, dev, NULL, 0); goto bad; } if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) { log_very_verbose("%s is not a member of the VG %s", name, vg_name); - __update_lvmcache(fmt, dl, dev, NULL); + __update_lvmcache(fmt, dl, dev, NULL, 0); goto bad; } - __update_lvmcache(fmt, dl, dev, dl->vgd.vg_uuid); + __update_lvmcache(fmt, dl, dev, dl->vgd.vg_uuid, + dl->vgd.vg_status & VG_EXPORTED); if (!_read_uuids(dl)) { log_error("Failed to read PV uuid list from %s", name); diff --git a/lib/format1/format1.c b/lib/format1/format1.c index c2c2f3fff..a403eaeed 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -396,7 +396,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv, struct lvmcache_info *info; if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev, - pv->vg_name, NULL))) { + pv->vg_name, NULL, 0))) { stack; return 0; } diff --git a/lib/format1/lvm1-label.c b/lib/format1/lvm1-label.c index dfd814012..9b30c916f 100644 --- a/lib/format1/lvm1-label.c +++ b/lib/format1/lvm1-label.c @@ -61,13 +61,17 @@ static int _read(struct labeller *l, struct device *dev, char *buf, struct vg_disk vgd; struct lvmcache_info *info; const char *vgid = NULL; + int exported = 0; munge_pvd(dev, pvd); - if (*pvd->vg_name && read_vgd(dev, &vgd, pvd)) + if (*pvd->vg_name && read_vgd(dev, &vgd, pvd)) { vgid = vgd.vg_uuid; + exported = pvd->pv_status & VG_EXPORTED; + } - if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, vgid))) { + if (!(info = lvmcache_add(l, pvd->pv_uuid, dev, pvd->vg_name, vgid, + exported))) { stack; return 0; } diff --git a/lib/format_pool/disk_rep.c b/lib/format_pool/disk_rep.c index dcb5a2be8..00b52cb1e 100644 --- a/lib/format_pool/disk_rep.c +++ b/lib/format_pool/disk_rep.c @@ -98,7 +98,7 @@ int read_pool_label(struct pool_list *pl, struct labeller *l, log_debug("Calculated uuid %s for %s", uuid, pd->pl_pool_name); if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name, - (char *) &vgid))) { + (char *) &vgid, 0))) { stack; return 0; } diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index 8e21addd0..701455f45 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -219,7 +219,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area, error: if ((info = info_from_pvid(dev_area->dev->pvid))) - lvmcache_update_vgname_and_id(info, ORPHAN, NULL); + lvmcache_update_vgname_and_id(info, ORPHAN, NULL, 0); return NULL; } @@ -872,7 +872,8 @@ static int _scan_file(const struct format_type *fmt) } const char *vgname_from_mda(const struct format_type *fmt, - struct device_area *dev_area, struct id *vgid) + struct device_area *dev_area, struct id *vgid, + uint32_t *vgstatus) { struct raw_locn *rlocn; struct mda_header *mdah; @@ -907,7 +908,7 @@ const char *vgname_from_mda(const struct format_type *fmt, (off_t) (dev_area->start + MDA_HEADER_SIZE), wrap, calc_crc, rlocn->checksum, - vgid))) + vgid, vgstatus))) goto_out; /* Ignore this entry if the characters aren't permissible */ @@ -937,6 +938,7 @@ static int _scan_raw(const struct format_type *fmt) struct volume_group *vg; struct format_instance fid; struct id vgid; + uint32_t vgstatus; raw_list = &((struct mda_lists *) fmt->private)->raws; @@ -945,7 +947,7 @@ static int _scan_raw(const struct format_type *fmt) list_iterate_items(rl, raw_list) { /* FIXME We're reading mdah twice here... */ - if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid))) { + if ((vgname = vgname_from_mda(fmt, &rl->dev_area, &vgid, &vgstatus))) { if ((vg = _vg_read_raw_area(&fid, vgname, &rl->dev_area, 0))) lvmcache_update_vg(vg); @@ -1115,7 +1117,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv, /* FIXME Test mode don't update cache? */ if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev, - ORPHAN, NULL))) { + ORPHAN, NULL, 0))) { stack; return 0; } diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h index b8bdb95ee..358f32b98 100644 --- a/lib/format_text/format-text.h +++ b/lib/format_text/format-text.h @@ -55,6 +55,7 @@ int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mda void del_mdas(struct list *mdas); const char *vgname_from_mda(const struct format_type *fmt, - struct device_area *dev_area, struct id *vgid); + struct device_area *dev_area, struct id *vgid, + uint32_t *vgstatus); #endif diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h index df8d37526..bf00c7fc3 100644 --- a/lib/format_text/import-export.h +++ b/lib/format_text/import-export.h @@ -49,7 +49,7 @@ struct text_vg_version_ops { time_t *when, char **desc); const char *(*read_vgname) (const struct format_type *fmt, struct config_tree *cft, - struct id *vgid); + struct id *vgid, uint32_t *vgstatus); }; struct text_vg_version_ops *text_vg_vsn1_init(void); @@ -78,6 +78,6 @@ const char *text_vgname_import(const struct format_type *fmt, off_t offset, uint32_t size, off_t offset2, uint32_t size2, checksum_fn_t checksum_fn, uint32_t checksum, - struct id *vgid); + struct id *vgid, uint32_t *vgstatus); #endif diff --git a/lib/format_text/import.c b/lib/format_text/import.c index 95a8abc9d..f2b7cf1a8 100644 --- a/lib/format_text/import.c +++ b/lib/format_text/import.c @@ -28,7 +28,7 @@ const char *text_vgname_import(const struct format_type *fmt, off_t offset, uint32_t size, off_t offset2, uint32_t size2, checksum_fn_t checksum_fn, uint32_t checksum, - struct id *vgid) + struct id *vgid, uint32_t *vgstatus) { struct config_tree *cft; struct text_vg_version_ops **vsn; @@ -57,7 +57,7 @@ const char *text_vgname_import(const struct format_type *fmt, if (!(*vsn)->check_version(cft)) continue; - if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid))) + if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid, vgstatus))) goto_out; break; diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c index 36ac655a1..f9af12844 100644 --- a/lib/format_text/import_vsn1.c +++ b/lib/format_text/import_vsn1.c @@ -799,9 +799,10 @@ static void _read_desc(struct dm_pool *mem, } static const char *_read_vgname(const struct format_type *fmt, - struct config_tree *cft, struct id *vgid) + struct config_tree *cft, struct id *vgid, + uint32_t *vgstatus) { - struct config_node *vgn; + struct config_node *vgn, *cn; struct dm_pool *mem = fmt->cmd->mem; char *vgname; @@ -823,6 +824,18 @@ static const char *_read_vgname(const struct format_type *fmt, return 0; } + if (!(cn = find_config_node(vgn, "status"))) { + log_error("Couldn't find status flags for volume group %s.", + vgname); + return 0; + } + + if (!(read_flags(vgstatus, VG_FLAGS, cn->v))) { + log_error("Couldn't read status flags for volume group %s.", + vgname); + return 0; + } + return vgname; } diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c index d78863323..144fbf987 100644 --- a/lib/format_text/text_label.c +++ b/lib/format_text/text_label.c @@ -198,10 +198,11 @@ static int _read(struct labeller *l, struct device *dev, char *buf, struct id vgid; struct mda_context *mdac; const char *vgname; + uint32_t vgstatus; pvhdr = (struct pv_header *) ((void *) buf + xlate32(lh->offset_xl)); - if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL))) + if (!(info = lvmcache_add(l, pvhdr->pv_uuid, dev, NULL, NULL, 0))) return_0; *label = info->label; @@ -234,8 +235,9 @@ 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 = vgname_from_mda(info->fmt, &mdac->area, - &vgid)) && - !lvmcache_update_vgname_and_id(info, vgname, (char *) &vgid)) + &vgid, &vgstatus)) && + !lvmcache_update_vgname_and_id(info, vgname, + (char *) &vgid, vgstatus)) return_0; } diff --git a/lib/label/label.c b/lib/label/label.c index 21bee5ccc..c74f22942 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -175,7 +175,7 @@ static struct labeller *_find_labeller(struct device *dev, char *buf, out: if (!found) { if ((info = info_from_pvid(dev->pvid))) - lvmcache_update_vgname_and_id(info, ORPHAN, NULL); + lvmcache_update_vgname_and_id(info, ORPHAN, NULL, 0); log_very_verbose("%s: No label detected", dev_name(dev)); } @@ -267,7 +267,7 @@ int label_read(struct device *dev, struct label **result) stack; if ((info = info_from_pvid(dev->pvid))) - lvmcache_update_vgname_and_id(info, ORPHAN, NULL); + lvmcache_update_vgname_and_id(info, ORPHAN, NULL, 0); goto out; } @@ -348,7 +348,7 @@ int label_verify(struct device *dev) stack; if ((info = info_from_pvid(dev->pvid))) - lvmcache_update_vgname_and_id(info, ORPHAN, NULL); + lvmcache_update_vgname_and_id(info, ORPHAN, NULL, 0); goto out; }