* [PATCH 1/6] thin: add spare lv support
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 2/6] thin: report spare as 'e' volume type Zdenek Kabelac
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
Add support for SPARE volume.
Signed-off-by: Zdenek Kabelac <zkabelac@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
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/6] thin: report spare as 'e' volume type
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 1/6] thin: add spare lv support Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 3/6] thin: removal of spare disables recovery Zdenek Kabelac
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
Reuse m'e'tadata volume type as spar'e'
since essentially they are related and there is no big reason
to introduce new flag - but of course we may use some other letters.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/lv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 6215e1a..b95d0a3 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -547,6 +547,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
else if (lv_is_origin(lv) || lv_is_external_origin(lv))
repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
else if (lv_is_thin_pool_metadata(lv) ||
+ lv_is_spare(lv) ||
(lv->status & RAID_META))
repstr[0] = 'e';
else if (lv->status & RAID)
--
1.8.2.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/6] thin: removal of spare disables recovery
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 1/6] thin: add spare lv support Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 2/6] thin: report spare as 'e' volume type Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 4/6] thin: lvchange spare lv manipulation Zdenek Kabelac
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
Warn user when removing spare LV.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/lv_manip.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 8acca49..f0fad05 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -3623,6 +3623,7 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
{
percent_t snap_percent;
struct dm_list *snh, *snht;
+ struct lv_list *lvl;
struct lvinfo info;
if (lv_is_cow(lv)) {
@@ -3681,6 +3682,24 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
!_lv_remove_segs_using_this_lv(cmd, lv, force, level, "pool"))
return_0;
+ if (lv_is_thin_pool(lv) && lv->vg->spare) {
+ dm_list_iterate_items(lvl, &lv->vg->lvs)
+ if (lv_is_thin_pool(lvl->lv) && lvl->lv != lv)
+ break;
+
+ if ((!lv_is_thin_pool(lvl->lv) || lvl->lv == lv) &&
+ !lv_remove_with_dependencies(cmd, lv->vg->spare, force, level + 1))
+ return_0;
+ }
+
+ if (lv_is_spare(lv) &&
+ (force == PROMPT) &&
+ (yes_no_prompt("Removal of spare logical volume \"%s\" disables thin pool recovery. "
+ "Proceed? [y/n]: ", lv->name) == 'n')) {
+ log_error("Logical volume \"%s\" not removed.", lv->name);
+ return 0;
+ }
+
return lv_remove_single(cmd, lv, force);
}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/6] thin: lvchange spare lv manipulation
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
` (2 preceding siblings ...)
2013-06-25 11:56 ` [PATCH 3/6] thin: removal of spare disables recovery Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 5/6] thin: add spare lvcreate support Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 6/6] thin: unfinished lvconvert Zdenek Kabelac
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
Allow lvchange of spare flag for an LV.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/args.h | 1 +
tools/commands.h | 5 ++--
tools/lvchange.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index 2fed97e..b8d0ad6 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -76,6 +76,7 @@ arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0)
arg(discards_ARG, '\0', "discards", discards_arg, 0)
arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE)
+arg(spare_ARG, '\0', "spare", yes_no_arg, 0)
arg(stripes_long_ARG, '\0', "stripes", int_arg, 0)
arg(sysinit_ARG, '\0', "sysinit", NULL, 0)
arg(thinpool_ARG, '\0', "thinpool", string_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 2d99d5a..ca29b81 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -92,6 +92,7 @@ xx(lvchange,
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
"\t[--refresh]\n"
"\t[--resync]\n"
+ "\t[--spare {y|n}]\n"
"\t[--syncaction {check|repair}\n"
"\t[--sysinit]\n"
"\t[-t|--test]\n"
@@ -106,8 +107,8 @@ xx(lvchange,
alloc_ARG, autobackup_ARG, activate_ARG, available_ARG, contiguous_ARG,
discards_ARG, force_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG,
major_ARG, minor_ARG, monitor_ARG, minrecoveryrate_ARG, maxrecoveryrate_ARG,
- noudevsync_ARG, partial_ARG,
- permission_ARG, persistent_ARG, poll_ARG, readahead_ARG, resync_ARG,
+ noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG,
+ poll_ARG, readahead_ARG, resync_ARG, spare_ARG,
refresh_ARG, addtag_ARG, deltag_ARG, syncaction_ARG, sysinit_ARG, test_ARG,
writebehind_ARG, writemostly_ARG, zero_ARG)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index c88d8ef..f7fcf44 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -101,6 +101,77 @@ out:
return r;
}
+static int lvchange_spare(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ struct lv_list *lvl;
+ uint64_t max_size = 0;
+ unsigned spare = arg_uint_value(cmd, spare_ARG, 0);
+
+ if (lv_is_active(lv)) {
+ log_error("Cannot change spare for active logical volume \"%s\".",
+ lv->name);
+ return 0;
+ }
+
+ if (spare) {
+ if (lv_is_spare(lv)) {
+ log_error("Logical volume \"%s\" is already spare volume.",
+ lv->name);
+ return 0;
+ }
+
+ if (!(lv->status & LVM_WRITE)) {
+ log_error("Cannot use read-only logical volume \"%s\" for spare.",
+ lv->name);
+ return 0;
+ }
+
+ if (!lv_is_visible(lv)) {
+ log_error("Cannot use invisible logical volume \"%s\" for spare.",
+ lv->name);
+ return 0;
+ }
+
+ /* FIXME: validate size */
+ dm_list_iterate_items(lvl, &lv->vg->lvs)
+ if (lv_is_thin_pool_metadata(lvl->lv) &&
+ (max_size < lvl->lv->size))
+ max_size = lvl->lv->size;
+
+ if (lv->size < max_size) {
+ log_error("Logical volume \"%s\" must have@least %s for spare.",
+ lv->name, display_size(lv->vg->cmd, max_size));
+ return 0;
+ }
+
+ if (lv->vg->spare) {
+ log_print_unless_silent("Replacing spare logical volume \"%s\".",
+ lv->vg->spare->name);
+ lv->vg->spare->status &= ~SPARE_LV;
+ }
+
+ lv->vg->spare = lv;
+ lv->status |= SPARE_LV;
+ } else {
+ if (!lv_is_spare(lv)) {
+ log_error("Logical volume \"%s\" is not a spare volume.",
+ lv->name);
+ return 0;
+ }
+
+ lv->vg->spare = NULL;
+ lv->status &= ~SPARE_LV;
+ }
+
+ log_very_verbose("Updating spare logical volume \"%s\" on disk(s).", lv->name);
+ if (!vg_write(lv->vg) || !vg_commit(lv->vg))
+ return_0;
+
+ backup(lv->vg);
+ return 1;
+}
+
static int lvchange_pool_update(struct cmd_context *cmd,
struct logical_volume *lv)
{
@@ -930,7 +1001,9 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
lv_is_virtual_origin(origin = origin_from_cow(lv)))
lv = origin;
- if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
+ if (!lv_is_visible(lv) &&
+ !lv_is_spare(lv) &&
+ !lv_is_virtual_origin(lv)) {
log_error("Unable to change internal LV %s directly",
lv->name);
return ECMD_FAILED;
@@ -997,6 +1070,16 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
+ if (arg_count(cmd, spare_ARG)) {
+ if (!archived && !archive(lv->vg)) {
+ stack;
+ return ECMD_FAILED;
+ }
+ archived = 1;
+ doit += lvchange_spare(cmd, lv);
+ docmds++;
+ }
+
if (arg_count(cmd, discards_ARG) ||
arg_count(cmd, zero_ARG)) {
if (!archived && !archive(lv->vg)) {
@@ -1120,6 +1203,7 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, contiguous_ARG) ||
arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) ||
+ arg_count(cmd, spare_ARG) ||
arg_count(cmd, persistent_ARG) ||
arg_count(cmd, addtag_ARG) ||
arg_count(cmd, deltag_ARG);
--
1.8.2.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/6] thin: add spare lvcreate support
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
` (3 preceding siblings ...)
2013-06-25 11:56 ` [PATCH 4/6] thin: lvchange spare lv manipulation Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
2013-06-25 11:56 ` [PATCH 6/6] thin: unfinished lvconvert Zdenek Kabelac
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
Add --spare option and create and hanle spare lv
when thin pool is created.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/metadata-exported.h | 1 +
tools/commands.h | 10 +++--
tools/lvcreate.c | 83 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 453b98b..a368dca 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -615,6 +615,7 @@ struct lvcreate_params {
int minor; /* all */
int log_count; /* mirror */
int nosync; /* mirror */
+ int spare; /* thin pool */
activation_change_t activate; /* non-snapshot, non-mirror */
thin_discards_t discards; /* thin */
diff --git a/tools/commands.h b/tools/commands.h
index ca29b81..d1cef36 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -208,6 +208,7 @@ xx(lvcreate,
"\t[-T|--thin [-c|--chunksize ChunkSize]\n"
"\t [--discards {ignore|nopassdown|passdown}]\n"
"\t [--poolmetadatasize MetadataSize[bBsSkKmMgG]]]\n"
+ "\t [--spare {y|n}]\n"
"\t[--thinpool ThinPoolLogicalVolume{Name|Path}]\n"
"\t[-t|--test]\n"
"\t[--type VolumeType]\n"
@@ -251,10 +252,11 @@ xx(lvcreate,
chunksize_ARG, contiguous_ARG, corelog_ARG, discards_ARG, extents_ARG,
ignoremonitoring_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
monitor_ARG, minrecoveryrate_ARG, maxrecoveryrate_ARG, name_ARG, nosync_ARG,
- noudevsync_ARG, permission_ARG,
- persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, snapshot_ARG,
- stripes_ARG, stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG, type_ARG,
- virtualoriginsize_ARG, poolmetadatasize_ARG, virtualsize_ARG, zero_ARG)
+ noudevsync_ARG, permission_ARG, persistent_ARG, poolmetadatasize_ARG,
+ readahead_ARG, regionsize_ARG,
+ size_ARG, snapshot_ARG, spare_ARG, stripes_ARG, stripesize_ARG,
+ test_ARG, thin_ARG, thinpool_ARG, type_ARG,
+ virtualoriginsize_ARG,virtualsize_ARG, zero_ARG)
xx(lvdisplay,
"Display information about a logical volume",
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 80ca1bc..a149c64 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -887,6 +887,12 @@ static int _lvcreate_params(struct lvcreate_params *lp,
return 0;
}
+ if (lp->create_thin_pool) {
+ lp->spare = arg_uint_value(cmd, spare_ARG, 1); /* TODO: lvm.conf default */
+ } else if (arg_count(cmd, spare_ARG)) {
+ log_error("--spare is only available with thin pool creation.");
+ return 0;
+ }
/*
* Allocation parameters
*/
@@ -945,6 +951,7 @@ static int _check_thin_parameters(struct volume_group *vg, struct lvcreate_param
contiguous_ARG,
discards_ARG,
poolmetadatasize_ARG,
+ spare_ARG,
stripes_ARG,
stripesize_ARG,
zero_ARG
@@ -1043,6 +1050,71 @@ static int _validate_internal_thin_processing(const struct lvcreate_params *lp)
return r;
}
+/* Create spare LV */
+static int _handle_spare(struct volume_group *vg, uint32_t extents,
+ struct dm_list *pvh)
+{
+ struct logical_volume *lv = vg->spare;
+ uint32_t seg_mirrors;
+ struct lv_segment *seg;
+ struct lvcreate_params lp = {
+ .activate = CHANGE_ALY,
+ .alloc = ALLOC_INHERIT,
+ .extents = extents,
+ .lv_name = "spare_%d",
+ .major = -1,
+ .minor = -1,
+ .permission = LVM_READ | LVM_WRITE,
+ .pvh = pvh ? : &vg->pvs,
+ .read_ahead = DM_READ_AHEAD_AUTO,
+ .stripes = 1,
+ .vg_name = vg->name,
+ .zero = 1,
+ };
+
+ dm_list_init(&lp.tags);
+
+ if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
+ return_0;
+
+ /* vg_write & vg_commit with pool creation */
+ /* FIXME: resolve archive */
+ if (lv) {
+ seg = last_seg(lv);
+ seg_mirrors = lv_mirror_count(lv);
+
+ /* Check spare is big enough and preserve segtype */
+ if ((lv->le_count < extents) && seg &&
+ !lv_extend(lv,
+ seg->segtype,
+ seg->area_count / seg_mirrors,
+ seg->stripe_size,
+ seg_mirrors,
+ seg->region_size,
+ extents - lv->le_count, NULL,
+ pvh, lv->alloc))
+ return_0;
+
+ return 1;
+ }
+
+ /* FIXME: Maybe using silent mode ? */
+ if (!(lv = lv_create_single(vg, &lp)))
+ return_0;
+
+ /* no need to keep active */
+ if (!deactivate_lv(vg->cmd, lv)) {
+ log_error("Unable to deactivate spare LV. "
+ "Manual intervention required.");
+ return 0;
+ }
+
+ lv->status |= SPARE_LV;
+ vg->spare = lv;
+
+ return 1;
+}
+
int lvcreate(struct cmd_context *cmd, int argc, char **argv)
{
int r = ECMD_PROCESSED;
@@ -1090,9 +1162,16 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
goto_out;
}
- if (lp.create_thin_pool)
+ if (lp.create_thin_pool) {
+ if (!lp.spare)
+ log_warn("WARNING: recovery without spare LV for "
+ "pool %s is not automated.", lp.pool);
+ else if (!_handle_spare(vg, lp.poolmetadataextents, lp.pvh))
+ return_0;
+
log_verbose("Making thin pool %s in VG %s using segtype %s",
lp.pool ? : "with generated name", lp.vg_name, lp.segtype->name);
+ }
if (lp.thin)
log_verbose("Making thin LV %s in pool %s in VG %s%s%s using segtype %s",
--
1.8.2.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 6/6] thin: unfinished lvconvert
2013-06-25 11:56 [PATCH 0/6] spare LV support Zdenek Kabelac
` (4 preceding siblings ...)
2013-06-25 11:56 ` [PATCH 5/6] thin: add spare lvcreate support Zdenek Kabelac
@ 2013-06-25 11:56 ` Zdenek Kabelac
5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-06-25 11:56 UTC (permalink / raw)
To: lvm-devel
begining of lvconvert support for spare LV.
will match what can be made in lvcreate.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/commands.h | 3 ++-
tools/lvconvert.c | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/commands.h b/tools/commands.h
index d1cef36..b1e5544 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -166,6 +166,7 @@ xx(lvconvert,
"\t[--poolmetadata ThinMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
"\t [-r|--readahead ReadAheadSectors|auto|none]\n"
+ "\t [--spare {y|n}]\n"
"\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n"
"\t[-T|--thin ExternalLogicalVolume[Path]\n"
"\t [--originname NewExternalOriginVolumeName]]\n"
@@ -177,7 +178,7 @@ xx(lvconvert,
readahead_ARG, regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG,
trackchanges_ARG, type_ARG, stripes_long_ARG, stripesize_ARG, test_ARG,
chunksize_ARG, discards_ARG, poolmetadata_ARG, poolmetadatasize_ARG,
- originname_ARG, thin_ARG, thinpool_ARG,
+ originname_ARG, spare_ARG, thin_ARG, thinpool_ARG,
use_policies_ARG, force_ARG, zero_ARG)
xx(lvcreate,
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index be6b55f..7ee3d4b 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -22,6 +22,7 @@ struct lvconvert_params {
int snapshot;
int merge;
int merge_mirror;
+ int spare;
int thin;
int yes;
int zero;
@@ -495,6 +496,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return_0;
}
+ lp->spare = arg_uint_value(cmd, spare_ARG, 0);
lp->force = arg_count(cmd, force_ARG);
lp->yes = arg_count(cmd, yes_ARG);
--
1.8.2.1
^ permalink raw reply related [flat|nested] 7+ messages in thread