[lvm-devel] [PATCH 1/6] thin: add spare lv support
Zdenek Kabelac
zkabelac at redhat.com
Tue Jun 25 11:56:01 UTC 2013
Add support for SPARE volume.
Signed-off-by: Zdenek Kabelac <zkabelac at redhat.com>
---
lib/format_text/flags.c | 1 +
lib/format_text/import_vsn1.c | 10 ++++++++++
lib/metadata/metadata-exported.h | 3 +++
lib/metadata/metadata.c | 24 ++++++++++++++++--------
lib/metadata/snapshot_manip.c | 3 ++-
lib/metadata/vg.h | 2 ++
6 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index 28a7dc4..6d15d20 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -59,6 +59,7 @@ static const struct flag _lv_flags[] = {
{LV_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
{LV_REBUILD, "REBUILD", STATUS_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
+ {SPARE_LV, "SPARE", STATUS_FLAG},
{RAID, NULL, 0},
{RAID_META, NULL, 0},
{RAID_IMAGE, NULL, 0},
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 852f2c5..d9f05c9 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -605,6 +605,16 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
if (timestamp && !lv_set_creation(lv, hostname, timestamp))
return_0;
+ if (lv_is_spare(lv)) {
+ if (lv->vg->spare) {
+ /* CHECKME: maybe just ignore all others ? */
+ log_error("VG with multiple spare LVs is not supported.");
+ return 0;
+ }
+ log_debug_metadata("Logical volume %s is spare.", lv->name);
+ lv->vg->spare = lv;
+ }
+
return 1;
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 10aea9e..453b98b 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -92,6 +92,8 @@
#define LV_WRITEMOSTLY UINT64_C(0x0000010000000000) /* LV (RAID1) */
+#define SPARE_LV UINT64_C(0x0000020000000000) /* LV internal use */
+
#define LVM_READ UINT64_C(0x00000100) /* LV, VG */
#define LVM_WRITE UINT64_C(0x00000200) /* LV, VG */
@@ -153,6 +155,7 @@
#define lv_is_raid_type(lv) (((lv)->status & (RAID | RAID_IMAGE | RAID_META)) ? 1 : 0)
#define lv_is_virtual(lv) (((lv)->status & VIRTUAL) ? 1 : 0)
+#define lv_is_spare(lv) (((lv)->status & SPARE_LV) ? 1 : 0)
/* Ordered list - see lv_manip.c */
typedef enum {
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 8a98aa6..ecedbdc 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2290,9 +2290,10 @@ int vg_validate(struct volume_group *vg)
struct str_list *sl;
char uuid[64] __attribute__((aligned(8)));
int r = 1;
- uint32_t hidden_lv_count = 0, lv_count = 0, lv_visible_count = 0;
- uint32_t pv_count = 0;
- uint32_t num_snapshots = 0;
+ unsigned hidden_lv_count = 0, lv_count = 0, lv_visible_count = 0;
+ unsigned pv_count = 0;
+ unsigned num_snapshots = 0;
+ unsigned spare_count = 0;
struct validate_hash vhash = { NULL };
if (vg->alloc == ALLOC_CLING_BY_TAGS) {
@@ -2404,6 +2405,12 @@ int vg_validate(struct volume_group *vg)
r = 0;
}
+ if (lv_is_spare(lvl->lv) && ++spare_count > 1) {
+ log_error(INTERNAL_ERROR "LV %s is %d. spare (allowed is one).",
+ lvl->lv->name, spare_count);
+ r = 0;
+ }
+
if (lvl->lv->status & VISIBLE_LV)
continue;
@@ -2429,11 +2436,12 @@ int vg_validate(struct volume_group *vg)
/*
* all volumes = visible LVs + snapshot_cows + invisible LVs
*/
- if (lv_count != lv_visible_count + num_snapshots + hidden_lv_count) {
- log_error(INTERNAL_ERROR "#internal LVs (%u) != #LVs (%"
- PRIu32 ") + #snapshots (%" PRIu32 ") + #internal LVs (%u) in VG %s",
- lv_count, lv_visible_count,
- num_snapshots, hidden_lv_count, vg->name);
+ if (lv_count != lv_visible_count + num_snapshots + hidden_lv_count + spare_count) {
+ log_error(INTERNAL_ERROR "#LVs (%u) != #visible LVs (%u) "
+ "+ #snapshots (%u) + #internal LVs (%u) "
+ "+ #spare LV (%u) in VG %s",
+ lv_count, lv_visible_count, num_snapshots,
+ hidden_lv_count, spare_count, vg->name);
r = 0;
}
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
index e0d2f5b..6da592e 100644
--- a/lib/metadata/snapshot_manip.c
+++ b/lib/metadata/snapshot_manip.c
@@ -75,7 +75,8 @@ int lv_is_cow_covering_origin(const struct logical_volume *lv)
int lv_is_visible(const struct logical_volume *lv)
{
- if (lv->status & SNAPSHOT)
+ /* spare LV is implicitely invisible */
+ if (lv->status & (SNAPSHOT | SPARE_LV))
return 0;
if (lv_is_cow(lv)) {
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 0dc3ba7..dc5bb12 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -20,6 +20,7 @@ struct dm_pool;
struct format_instance;
struct dm_list;
struct id;
+struct logical_volume;
typedef enum {
ALLOC_INVALID,
@@ -120,6 +121,7 @@ struct volume_group {
uint32_t mda_copies; /* target number of mdas for this VG */
struct dm_hash_table *hostnames; /* map of creation hostnames */
+ struct logical_volume *spare; /* pointer for spare LV in this VG */
};
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
--
1.8.2.1
More information about the lvm-devel
mailing list