summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-03-02 15:45:55 -0600
committerDavid Teigland <teigland@redhat.com>2015-03-03 15:21:31 -0600
commitb6779541fd708ae79d7c62b9d724158556dc7f85 (patch)
treeaf4c492b3f5c85b673079a4b90d7146e28f73b66
parent8df4b3a2527d171a4b94d2b090c822bc04fb4bc0 (diff)
downloadlvm2-dev-dct-lvmlockd-X2.tar.gz
lvmlockd: special status for lockd VGs and LVsdev-dct-lvmlockd-X2
Previous versions of lvm don't recognize lock_type in lockd VGs, so they would allow a lockd VG to be used as a local VG without restriction. To prevent this, the WRITE flag is removed from lockd VGs and replaced with the WRITE_LOCKD flag. This causes old versions of lvm to think the VG is not writable. The same is done for LV flags. WRITE_LOCKD is put on the flags line of the metadata instead of the status line. If it was put on the status line, old versions of lvm would ignore the VG because of the unrecognized flag, and the PVs in the VG would appear unused. In memory, lvm continues to just use the WRITE flag with vg->status and lv->status. WRITE is swapped with WRITE_LOCKD when a lockd VG is read/written to/from disk. The hidden/internal lvmlock LV is given the special LV flag like other special lvs. This does not go to disk.
-rw-r--r--lib/format1/disk-rep.h3
-rw-r--r--lib/format1/import-export.c23
-rw-r--r--lib/format_text/export.c31
-rw-r--r--lib/format_text/flags.c4
-rw-r--r--lib/format_text/import_vsn1.c23
-rw-r--r--lib/locking/lvmlockd.c3
-rw-r--r--lib/metadata/lv_manip.c4
-rw-r--r--lib/metadata/metadata-exported.h6
-rw-r--r--lib/metadata/vg.c3
-rw-r--r--lib/misc/lvm-string.c3
-rw-r--r--tools/vgchange.c1
11 files changed, 83 insertions, 21 deletions
diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h
index 94d27894f..8da77f635 100644
--- a/lib/format1/disk-rep.h
+++ b/lib/format1/disk-rep.h
@@ -41,7 +41,7 @@
#define VG_WRITE 0x02 /* " */
#define VG_CLUSTERED 0x04 /* " */
#define VG_SHARED 0x08 /* " */
-#define VG_LOCK_TYPE 0x10 /* " */
+#define VG_WRITE_LOCKD 0x10 /* " */
/* logical volume */
#define LV_ACTIVE 0x01 /* lv_status */
@@ -52,6 +52,7 @@
#define LV_WRITE 0x02 /* " */
#define LV_SNAPSHOT 0x04 /* " */
#define LV_SNAPSHOT_ORG 0x08 /* " */
+#define LV_WRITE_LOCKD 0x10 /* " */
#define LV_BADBLOCK_ON 0x01 /* lv_badblock */
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 855c04273..ae48571f6 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -25,6 +25,7 @@
#include "pv_alloc.h"
#include "display.h"
#include "metadata.h"
+#include "lvmlockd.h"
#include <time.h>
@@ -240,12 +241,12 @@ int import_vg(struct dm_pool *mem,
if (vgd->vg_access & VG_WRITE)
vg->status |= LVM_WRITE;
+ if (vgd->vg_access & VG_WRITE_LOCKD)
+ vg->status |= LVM_WRITE;
+
if (vgd->vg_access & VG_CLUSTERED)
vg->status |= CLUSTERED;
- if (vgd->vg_access & VG_LOCK_TYPE)
- vg->status |= LOCK_TYPE;
-
if (vgd->vg_access & VG_SHARED)
vg->status |= SHARED;
@@ -267,15 +268,15 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
if (vg->status & LVM_READ)
vgd->vg_access |= VG_READ;
- if (vg->status & LVM_WRITE)
+ if ((vg->status & LVM_WRITE) && !is_lockd_type(vg->lock_type))
vgd->vg_access |= VG_WRITE;
+ if ((vg->status & LVM_WRITE) && is_lockd_type(vg->lock_type))
+ vgd->vg_access |= VG_WRITE_LOCKD;
+
if (vg_is_clustered(vg))
vgd->vg_access |= VG_CLUSTERED;
- if (vg->status & LOCK_TYPE)
- vgd->vg_access |= VG_LOCK_TYPE;
-
if (vg->status & SHARED)
vgd->vg_access |= VG_SHARED;
@@ -324,6 +325,9 @@ int import_lv(struct cmd_context *cmd, struct dm_pool *mem,
if (lvd->lv_access & LV_WRITE)
lv->status |= LVM_WRITE;
+ if (lvd->lv_access & LV_WRITE_LOCKD)
+ lv->status |= LVM_WRITE;
+
if (lvd->lv_badblock)
lv->status |= BADBLOCK_ON;
@@ -356,9 +360,12 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & LVM_READ)
lvd->lv_access |= LV_READ;
- if (lv->status & LVM_WRITE)
+ if ((lv->status & LVM_WRITE) && !is_lockd_type(vg->lock_type))
lvd->lv_access |= LV_WRITE;
+ if ((lv->status & LVM_WRITE) && is_lockd_type(vg->lock_type))
+ lvd->lv_access |= LV_WRITE_LOCKD;
+
if (lv->status & SPINDOWN_LV)
lvd->lv_status |= LV_SPINDOWN;
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 3439f9218..ca704b54b 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -22,6 +22,7 @@
#include "text_export.h"
#include "lvm-version.h"
#include "toolcontext.h"
+#include "lvmlockd.h"
#include <stdarg.h>
#include <time.h>
@@ -404,9 +405,24 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
if (vg->fid && vg->fid->fmt)
outfc(f, "# informational", "format = \"%s\"", vg->fid->fmt->name);
+ /*
+ * When lockd VGs and LVs are written to disk, WRITE is replaced with
+ * WRITE_LOCKD so old versions of lvm will not be able to write them.
+ * When imported, WRITE_LOCKD is replaced with WRITE.
+ */
+ if ((vg->status & LVM_WRITE) && is_lockd_type(vg->lock_type)) {
+ vg->status &= ~LVM_WRITE;
+ vg->status |= LVM_WRITE_LOCKD;
+ }
+
if (!_print_flag_config(f, vg->status, VG_FLAGS))
return_0;
+ if (vg->status & LVM_WRITE_LOCKD) {
+ vg->status |= LVM_WRITE;
+ vg->status &= ~LVM_WRITE_LOCKD;
+ }
+
if (!_out_tags(f, &vg->tags))
return_0;
@@ -614,9 +630,24 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
outf(f, "id = \"%s\"", buffer);
+ /*
+ * When lockd VGs and LVs are written to disk, WRITE is replaced with
+ * WRITE_LOCKD so old versions of lvm will not be able to write them.
+ * When imported, WRITE_LOCKD is replaced with WRITE.
+ */
+ if ((lv->status & LVM_WRITE) && is_lockd_type(lv->vg->lock_type)) {
+ lv->status &= ~LVM_WRITE;
+ lv->status |= LVM_WRITE_LOCKD;
+ }
+
if (!_print_flag_config(f, lv->status, LV_FLAGS))
return_0;
+ if (lv->status & LVM_WRITE_LOCKD) {
+ lv->status |= LVM_WRITE;
+ lv->status &= ~LVM_WRITE_LOCKD;
+ }
+
if (!_out_tags(f, &lv->tags))
return_0;
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index a933013cf..dbef2839b 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -34,8 +34,8 @@ static const struct flag _vg_flags[] = {
{PVMOVE, "PVMOVE", STATUS_FLAG},
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
+ {LVM_WRITE_LOCKD, "WRITE_LOCKD", COMPATIBLE_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
- {LOCK_TYPE, "LOCK_TYPE", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{PARTIAL_VG, NULL, 0},
{PRECOMMITTED, NULL, 0},
@@ -54,6 +54,7 @@ static const struct flag _pv_flags[] = {
static const struct flag _lv_flags[] = {
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
+ {LVM_WRITE_LOCKD, "WRITE_LOCKD", COMPATIBLE_FLAG},
{FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
{VISIBLE_LV, "VISIBLE", STATUS_FLAG},
{PVMOVE, "PVMOVE", STATUS_FLAG},
@@ -91,6 +92,7 @@ static const struct flag _lv_flags[] = {
{CACHE_POOL_DATA, NULL, 0},
{CACHE_POOL_METADATA, NULL, 0},
{LV_PENDING_DELETE, NULL, 0}, /* FIXME Display like COMPATIBLE_FLAG */
+ {LVMLOCK, NULL, 0},
{0, NULL, 0}
};
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 7fb4a5590..4d3e2b3d7 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -550,6 +550,16 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
return 0;
}
+ /*
+ * When lockd VGs and LVs are written to disk, WRITE is replaced with
+ * WRITE_LOCKD so old versions of lvm will not be able to write them.
+ * When imported, WRITE_LOCKD is replaced with WRITE.
+ */
+ if (lv->status & LVM_WRITE_LOCKD) {
+ lv->status &= ~LVM_WRITE_LOCKD;
+ lv->status |= LVM_WRITE;
+ }
+
if (dm_config_has_node(lvn, "creation_time")) {
if (!_read_uint64(lvn, "creation_time", &timestamp)) {
log_error("Invalid creation_time for logical volume %s.",
@@ -642,6 +652,9 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
vg->pool_metadata_spare_lv = lv;
}
+ if (!lv_is_visible(lv) && !strcmp(lv->name, "lvmlock"))
+ lv->status |= LVMLOCK;
+
return 1;
}
@@ -815,6 +828,16 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
+ /*
+ * When lockd VGs and LVs are written to disk, WRITE is replaced with
+ * WRITE_LOCKD so old versions of lvm will not be able to write them.
+ * When imported, WRITE_LOCKD is replaced with WRITE.
+ */
+ if (vg->status & LVM_WRITE_LOCKD) {
+ vg->status &= ~LVM_WRITE_LOCKD;
+ vg->status |= LVM_WRITE;
+ }
+
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/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index d11725575..15af3a796 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -371,7 +371,8 @@ static int _create_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
return 0;
}
- lv_set_hidden(lv);
+ lv_set_hidden(lv); /* FIXME: should this be done before vg is written? */
+ lv->status |= LVMLOCK; /* flag not written to metadata */
return 1;
}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 485c55d92..9eeed68d7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4442,9 +4442,7 @@ static int _lvresize_check_lv(struct cmd_context *cmd, struct logical_volume *lv
return 0;
}
- /* FIXME: use a status flag instead of the name "lvmlock". */
-
- if (!lv_is_visible(lv) && !lv_is_thin_pool_metadata(lv) && strcmp(lv->name, "lvmlock")) {
+ if (!lv_is_visible(lv) && !lv_is_thin_pool_metadata(lv) && !lv_is_lvmlock(lv)) {
log_error("Can't resize internal logical volume %s", lv->name);
return 0;
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d544ed8bc..26fcec246 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -61,7 +61,6 @@
#define CLUSTERED UINT64_C(0x0000000000000400) /* VG */
//#define SHARED UINT64_C(0x0000000000000800) /* VG */
-#define LOCK_TYPE UINT64_C(0x0000000000001000) /* VG */
/* FIXME Remove when metadata restructuring is completed */
#define SNAPSHOT UINT64_C(0x0000000000001000) /* LV - internal use only */
@@ -123,7 +122,9 @@
#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) */
+#define LVMLOCK UINT64_C(0x0020000000000000) /* LV - Internal use only */
+#define LVM_WRITE_LOCKD UINT64_C(0x0040000000000000) /* LV, VG */
+/* Next unused flag: UINT64_C(0x0080000000000000) */
/* Format features flags */
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
@@ -219,6 +220,7 @@
#define lv_is_pool_data(lv) (((lv)->status & (CACHE_POOL_DATA | THIN_POOL_DATA)) ? 1 : 0)
#define lv_is_pool_metadata(lv) (((lv)->status & (CACHE_POOL_METADATA | THIN_POOL_METADATA)) ? 1 : 0)
#define lv_is_pool_metadata_spare(lv) (((lv)->status & POOL_METADATA_SPARE) ? 1 : 0)
+#define lv_is_lvmlock(lv) (((lv)->status & LVMLOCK) ? 1 : 0)
#define lv_is_rlog(lv) (((lv)->status & REPLICATOR_LOG) ? 1 : 0)
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index d50a88ebc..f6e504d04 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -635,9 +635,6 @@ int vg_set_lock_type(struct volume_group *vg, const char *lock_type)
return 0;
}
- if (is_lockd_type(lock_type))
- vg->status |= LOCK_TYPE;
-
return 1;
}
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
index 5d6385817..163fb67e5 100644
--- a/lib/misc/lvm-string.c
+++ b/lib/misc/lvm-string.c
@@ -162,7 +162,8 @@ static const char *_lvname_has_reserved_string(const char *lvname)
"_rmeta",
"_tdata",
"_tmeta",
- "_vorigin"
+ "_vorigin",
+ "lvmlock"
};
unsigned i;
diff --git a/tools/vgchange.c b/tools/vgchange.c
index a35c32ea0..3228ec4e5 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -538,7 +538,6 @@ static int _vgchange_locktype(struct cmd_context *cmd,
}
vg->status &= ~CLUSTERED;
- vg->status &= ~LOCK_TYPE;
vg->lock_type = "none";
vg->lock_args = NULL;