[lvm-devel] [PATCH 5/6] thin: add spare lvcreate support
Zdenek Kabelac
zkabelac at redhat.com
Tue Jun 25 11:56:05 UTC 2013
Add --spare option and create and hanle spare lv
when thin pool is created.
Signed-off-by: Zdenek Kabelac <zkabelac at 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
More information about the lvm-devel
mailing list