From bfbb5d269aa1ed56d9308117b57d4d2da49d53f6 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 4 Mar 2015 01:16:32 +0000 Subject: [PATCH] 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. --- WHATS_NEW | 1 + lib/format1/format1.c | 2 ++ lib/format1/import-export.c | 4 +++- lib/format_text/flags.c | 1 + lib/format_text/import_vsn1.c | 20 ++++++++++++-------- lib/metadata/metadata-exported.h | 3 ++- lib/metadata/vg.c | 3 +++ tools/vgchange.c | 6 +++++- 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; } -- 2.43.5