summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW2
-rw-r--r--lib/cache/lvmcache.c30
-rw-r--r--lib/cache/lvmcache.h10
-rw-r--r--lib/format1/disk-rep.c15
-rw-r--r--lib/format1/format1.c2
-rw-r--r--lib/format1/lvm1-label.c8
-rw-r--r--lib/format_pool/disk_rep.c2
-rw-r--r--lib/format_text/format-text.c12
-rw-r--r--lib/format_text/format-text.h3
-rw-r--r--lib/format_text/import-export.h4
-rw-r--r--lib/format_text/import.c4
-rw-r--r--lib/format_text/import_vsn1.c17
-rw-r--r--lib/format_text/text_label.c8
-rw-r--r--lib/label/label.c6
14 files changed, 87 insertions, 36 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 2f67f934..580881f2 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 e47761d7..075a0b76 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 78468041..e58ba416 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 af76b8fa..f62b7897 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 c2c2f3ff..a403eaee 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 dfd81401..9b30c916 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 dcb5a2be..00b52cb1 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 8e21addd..701455f4 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 b8bdb95e..358f32b9 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 df8d3752..bf00c7fc 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 95a8abc9..f2b7cf1a 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 36ac655a..f9af1284 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 d7886332..144fbf98 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 21bee5cc..c74f2294 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;
}