summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlasdair G Kergon <agk@redhat.com>2015-03-04 01:16:32 +0000
committerAlasdair G Kergon <agk@redhat.com>2015-03-04 01:16:32 +0000
commitbfbb5d269aa1ed56d9308117b57d4d2da49d53f6 (patch)
treeba2e006489117b63c5ae35d0b7d360306858db61
parent3562b5ab39b32bd27c81f57185e397facb7690f5 (diff)
downloadlvm2-bfbb5d269aa1ed56d9308117b57d4d2da49d53f6.tar.gz
systemid: Add ACCESS_NEEDS_SYSTEM_ID VG flag.
Set ACCESS_NEEDS_SYSTEM_ID VG status flag whenever there is a non-lvm1 system_id set. Prevents concurrent access from older LVM2 versions. Not set on VGs that bear a system_id only due to conversion from lvm1 metadata.
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/format1/format1.c2
-rw-r--r--lib/format1/import-export.c4
-rw-r--r--lib/format_text/flags.c1
-rw-r--r--lib/format_text/import_vsn1.c20
-rw-r--r--lib/metadata/metadata-exported.h3
-rw-r--r--lib/metadata/vg.c3
-rw-r--r--tools/vgchange.c6
8 files changed, 29 insertions, 11 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index ae8bc7008..9beb668b0 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.117 -
====================================
+ Set ACCESS_NEEDS_SYSTEM_ID VG status flag while system_id is set.
Preserve original format type field when processing backup files.
Implement status action for lvm2-monitor initscript to display monitored LVs.
Allow lvchange -p to change kernel state only if metadata state differs.
diff --git a/lib/format1/format1.c b/lib/format1/format1.c
index 19df8aa7a..7f37cf5dc 100644
--- a/lib/format1/format1.c
+++ b/lib/format1/format1.c
@@ -501,6 +501,8 @@ static int _format1_vg_setup(struct format_instance *fid, struct volume_group *v
!generate_lvm1_system_id(vg->cmd, vg->lvm1_system_id, ""))
return_0;
+ vg->status &= ~ACCESS_NEEDS_SYSTEM_ID;
+
return 1;
}
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 9b387e2a1..4846a8b6f 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -69,8 +69,10 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id));
/* Store system_id from first PV if PV belongs to a VG */
- if (vg && !*vg->lvm1_system_id)
+ if (vg && !*vg->lvm1_system_id) {
strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);
+ vg->status &= ~ACCESS_NEEDS_SYSTEM_ID;
+ }
if (vg &&
strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index cf012710a..1a4a5036a 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -36,6 +36,7 @@ static const struct flag _vg_flags[] = {
{LVM_WRITE, "WRITE", STATUS_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
+ {ACCESS_NEEDS_SYSTEM_ID, "ACCESS_NEEDS_SYSTEM_ID", STATUS_FLAG},
{PARTIAL_VG, NULL, 0},
{PRECOMMITTED, NULL, 0},
{ARCHIVED_VG, NULL, 0},
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 64c08a0bd..8ab9363eb 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -733,11 +733,10 @@ static struct volume_group *_read_vg(struct format_instance *fid,
{
const struct dm_config_node *vgn;
const struct dm_config_value *cv;
- const char *str, *format_str;
+ const char *str, *system_id, *format_str;
struct volume_group *vg;
struct dm_hash_table *pv_hash = NULL, *lv_hash = NULL;
unsigned scan_done_once = use_cached_pvs;
- char *system_id;
/* skip any top-level values */
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib)
@@ -751,9 +750,6 @@ static struct volume_group *_read_vg(struct format_instance *fid,
if (!(vg = alloc_vg("read_vg", fid->fmt->cmd, vgn->key)))
return_NULL;
- if (!(system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
- goto_bad;
- vg->system_id = system_id;
/*
* The pv hash memorises the pv section names -> pv
@@ -782,9 +778,6 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
- if (dm_config_get_str(vgn, "system_id", &str))
- strncpy(system_id, str, NAME_LEN);
-
if (!_read_id(&vg->id, vgn, "id")) {
log_error("Couldn't read uuid for volume group %s.", vg->name);
goto bad;
@@ -802,6 +795,17 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
+ if (dm_config_get_str(vgn, "system_id", &system_id)) {
+ if (!(vg->status & ACCESS_NEEDS_SYSTEM_ID)) {
+ if (!(vg->lvm1_system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
+ goto_bad;
+ strncpy(vg->lvm1_system_id, system_id, NAME_LEN);
+ } else if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) {
+ log_error("Failed to allocate memory for system_id in vg_set_system_id.");
+ goto bad;
+ }
+ }
+
if (!_read_int32(vgn, "extent_size", &vg->extent_size)) {
log_error("Couldn't read extent size for volume group %s.",
vg->name);
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 758fa536f..5fbfdefb8 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -60,6 +60,7 @@
#define LVM_WRITE UINT64_C(0x0000000000000200) /* LV, VG */
#define CLUSTERED UINT64_C(0x0000000000000400) /* VG */
+#define ACCESS_NEEDS_SYSTEM_ID UINT64_C(0x0020000000000000) /* VG */
//#define SHARED UINT64_C(0x0000000000000800) /* VG */
/* FIXME Remove when metadata restructuring is completed */
@@ -122,7 +123,7 @@
#define PV_ALLOCATION_PROHIBITED UINT64_C(0x0010000000000000) /* PV - internal use only - allocation prohibited
e.g. to prohibit allocation of a RAID image
on a PV already holing an image of the RAID set */
-/* Next unused flag: UINT64_C(0x0020000000000000) */
+/* Next unused flag: UINT64_C(0x0040000000000000) */
/* Format features flags */
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 404cc6fa6..b23063ec0 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -615,6 +615,7 @@ int vg_set_system_id(struct volume_group *vg, const char *system_id)
{
if (!system_id || !*system_id) {
vg->system_id = NULL;
+ vg->status &= ~ACCESS_NEEDS_SYSTEM_ID;
return 1;
}
@@ -632,6 +633,8 @@ int vg_set_system_id(struct volume_group *vg, const char *system_id)
if (vg->lvm1_system_id)
*vg->lvm1_system_id = '\0';
+ vg->status |= ACCESS_NEEDS_SYSTEM_ID;
+
return 1;
}
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 36b44a9ad..557fe3408 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -575,10 +575,14 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg)
vg->name, vg->system_id, system_id);
vg->system_id = system_id;
-
if (vg->lvm1_system_id)
*vg->lvm1_system_id = '\0';
+ if (vg->system_id && *vg->system_id)
+ vg->status |= ACCESS_NEEDS_SYSTEM_ID;
+ else
+ vg->status &= ~ACCESS_NEEDS_SYSTEM_ID;
+
return 1;
}