From 359ee54f0dec9b4ffd581f9a73ccf1e979889a54 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 11 May 2006 18:54:04 +0000 Subject: [PATCH] Add --corelog to lvcreate and lvconvert. --- WHATS_NEW | 1 + lib/metadata/lv_manip.c | 2 +- tools/args.h | 1 + tools/commands.h | 13 +++++----- tools/lvconvert.c | 56 ++++++++++++++++++++++++++++++++++++----- tools/lvcreate.c | 14 ++++++++--- 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index cf5f8c9cc..d88faed93 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.06 - ================================= + Add --corelog to lvcreate and lvconvert. Create a log header for replacement in-sync mirror log. Use set_lv() and dev_set() to wipe sections of devices. Add mirror_in_sync() flag to avoid unnecessary resync on activation. diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 41f6a6fd1..cf333b211 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -1102,7 +1102,7 @@ int lv_add_mirror_segment(struct alloc_handle *ah, struct lv_segment *seg; uint32_t m; - if (list_empty(&log_lv->segments)) { + if (log_lv && list_empty(&log_lv->segments)) { log_error("Log LV %s is empty.", log_lv->name); return 0; } diff --git a/tools/args.h b/tools/args.h index 5967c446d..0254ed27b 100644 --- a/tools/args.h +++ b/tools/args.h @@ -46,6 +46,7 @@ arg(alloc_ARG, '\0', "alloc", alloc_arg) arg(separator_ARG, '\0', "separator", string_arg) arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL) arg(nosync_ARG, '\0', "nosync", NULL) +arg(corelog_ARG, '\0', "corelog", NULL) /* Allow some variations */ arg(resizable_ARG, '\0', "resizable", yes_no_arg) diff --git a/tools/commands.h b/tools/commands.h index b450e2fe6..f2724c51c 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -81,7 +81,7 @@ xx(lvchange, xx(lvconvert, "Change logical volume layout", "lvconvert " - "[-m|--mirrors Mirrors]\n" + "[-m|--mirrors Mirrors [--corelog]]\n" "\t[--alloc AllocationPolicy]\n" "\t[-d|--debug]\n" "\t[-h|-?|--help]\n" @@ -99,7 +99,8 @@ xx(lvconvert, "\t[--version]" "\n" "\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n", - alloc_ARG, chunksize_ARG, mirrors_ARG, snapshot_ARG, test_ARG, zero_ARG) + alloc_ARG, chunksize_ARG, mirrors_ARG, corelog_ARG, + snapshot_ARG, test_ARG, zero_ARG) xx(lvcreate, "Create a logical volume", @@ -114,7 +115,7 @@ xx(lvcreate, "\t{-l|--extents LogicalExtentsNumber |\n" "\t -L|--size LogicalVolumeSize[kKmMgGtT]}\n" "\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n" - "\t[-m|--mirrors Mirrors]\n" + "\t[-m|--mirrors Mirrors [--corelog]]\n" "\t[-n|--name LogicalVolumeName]\n" "\t[-p|--permission {r|rw}]\n" "\t[-r|--readahead ReadAheadSectors]\n" @@ -147,9 +148,9 @@ xx(lvcreate, "\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n", addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG, contiguous_ARG, - extents_ARG, major_ARG, minor_ARG, mirrors_ARG, name_ARG, permission_ARG, - persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, snapshot_ARG, - stripes_ARG, stripesize_ARG, test_ARG, type_ARG, zero_ARG) + corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrors_ARG, name_ARG, + permission_ARG, persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, + snapshot_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG, zero_ARG) xx(lvdisplay, "Display information about a logical volume", diff --git a/tools/lvconvert.c b/tools/lvconvert.c index b4f10921d..1e2db1bc0 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -235,6 +235,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l struct alloc_handle *ah = NULL; struct logical_volume *log_lv; struct list *parallel_areas; + struct segment_type *segtype; /* FIXME: could I just use lp->segtype */ seg = first_seg(lv); existing_mirrors = seg->area_count; @@ -277,10 +278,50 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l return 0; } if (lp->mirrors == existing_mirrors) { - log_error("Logical volume %s already has %" - PRIu32 " mirror(s).", lv->name, - lp->mirrors - 1); - return 1; + if (!seg->log_lv && !arg_count(cmd, corelog_ARG)) { + /* No disk log present, add one. */ + /* FIXME: Why doesn't this work? Without + it, we will probably put the log on the + same device as a mirror leg. + if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv))) { + stack; + return 0; + } + */ + parallel_areas = NULL; + + segtype = get_segtype_from_string(cmd, "striped"); + + if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1, + 0, 1, 0, + NULL, 0, 0, lp->pvh, + lp->alloc, + parallel_areas))) { + stack; + return 0; + } + + if (!(log_lv = create_mirror_log(cmd, lv->vg, ah, + lp->alloc, lv->name, 0))) { + log_error("Failed to create mirror log."); + return 0; + } + seg->log_lv = log_lv; + log_lv->status |= MIRROR_LOG; + first_seg(log_lv)->mirror_seg = seg; + } else if (seg->log_lv && arg_count(cmd, corelog_ARG)) { + /* Had disk log, switch to core. */ + if (!remove_mirror_images(seg, lp->mirrors, + lp->pv_count ? + lp->pvh : NULL, 1)) + return_0; + } else { + /* No change */ + log_error("Logical volume %s already has %" + PRIu32 " mirror(s).", lv->name, + lp->mirrors - 1); + return 1; + } } if (lp->mirrors > existing_mirrors) { /* FIXME Unless anywhere, remove PV of log_lv @@ -314,7 +355,8 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l return_0; if (!(ah = allocate_extents(lv->vg, NULL, lp->segtype, - 1, lp->mirrors - 1, 1, + 1, lp->mirrors - 1, + arg_count(cmd, corelog_ARG) ? 0 : 1, lv->le_count * (lp->mirrors - 1), NULL, 0, 0, lp->pvh, lp->alloc, @@ -325,7 +367,9 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l lv->le_count, lp->region_size); - if (!(log_lv = create_mirror_log(cmd, lv->vg, ah, + log_lv = NULL; + if (!arg_count(cmd, corelog_ARG) && + !(log_lv = create_mirror_log(cmd, lv->vg, ah, lp->alloc, lv->name, 0))) { log_error("Failed to create mirror log."); diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 14752cdcf..fdc74bc22 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -24,6 +24,7 @@ struct lvcreate_params { int zero; int major; int minor; + int corelog; char *origin; const char *vg_name; @@ -291,6 +292,8 @@ static int _read_mirror_params(struct lvcreate_params *lp, return 0; } + lp->corelog = arg_count(cmd, corelog_ARG) ? 1 : 0; + return 1; } @@ -377,6 +380,11 @@ static int _lvcreate_params(struct lvcreate_params *lp, struct cmd_context *cmd, stack; return 0; } + } else { + if (arg_count(cmd, corelog_ARG)) { + log_error("--corelog is only available with mirrors"); + return 0; + } } if (activation() && lp->segtype->ops->target_present && @@ -634,9 +642,9 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) /* FIXME Calculate how many extents needed for the log */ if (!(ah = allocate_extents(vg, NULL, lp->segtype, lp->stripes, - lp->mirrors, 1, lp->extents, - NULL, 0, 0, pvh, lp->alloc, - NULL))) { + lp->mirrors, lp->corelog ? 0 : 1, + lp->extents, NULL, 0, 0, + pvh, lp->alloc, NULL))) { stack; return 0; }