master - tests: extend harness
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4937df4aed699a...
Commit: 4937df4aed699a5e3bc3c860e897fa0e448cfc6b
Parent: c888c925b8d561158c3cea6d4f5ea4e173848c00
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Jun 8 22:23:39 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:07:51 2013 +0200
tests: extend harness
Add limit for buffer so if the test is running in some loop
and generating lots of output, the output log gets too large
for browser to display (at least Firefox is quite confused
to display 300MB logs).
For now limit max output of one test to 32MB.
If there is need to see full log set LVM_TEST_UNLIMITED to
disable interruption of test.
harness now also prints max memory used during test,
it user and system time and amount of read/write operations.
---
test/Makefile.in | 3 +-
test/lib/harness.c | 163 ++++++++++++++++++++++++++++++++++------------------
2 files changed, 110 insertions(+), 56 deletions(-)
diff --git a/test/Makefile.in b/test/Makefile.in
index b799f83..89092d0 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -63,6 +63,7 @@ help:
@echo " LVM_TEST_NODEBUG Do not debug lvm commands."
@echo " LVM_TEST_PARALLEL May skip agresive wipe of LVMTEST resources."
@echo " LVM_TEST_RESULTS Where to create result files [results]."
+ @echo " LVM_TEST_UNLIMITED Set to get unlimited test log (>32MB)"
@echo " LVM_VERIFY_UDEV Default verify state for lvm.conf."
@echo " S Skip given test (regex)."
@echo " T Run given test (regex)."
@@ -124,7 +125,7 @@ CMDS = lvm $(shell cat $(top_builddir)/tools/.commands)
ln -sf $(abs_top_srcdir)/test/$$f $$f; \
done; \
fi
- $(MKDIR_P) -m a=rwx $(LVM_TEST_RESULTS)
+ @$(MKDIR_P) -m a=rwx $(LVM_TEST_RESULTS)
touch $@
.lib-dir-stamp:
diff --git a/test/lib/harness.c b/test/lib/harness.c
index 2377116..696d011 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2010-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -14,20 +14,24 @@
#define _GNU_SOURCE
#include <fcntl.h>
-#include <string.h>
+#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h> /* rusage */
+#include <sys/select.h>
#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
#include <time.h>
-#include <sys/time.h>
-#include <limits.h>
+#include <unistd.h>
static pid_t pid;
static int fds[2];
#define MAX 1024
+#define MAX_LOG_SIZE (32*1024*1024) /* Default max size of test log */
struct stats {
int nfailed;
@@ -35,6 +39,7 @@ struct stats {
int npassed;
int nknownfail;
int nwarned;
+ int ninterrupted;
int status[MAX];
};
@@ -47,6 +52,7 @@ static int die = 0;
static int verbose = 0; /* >1 with timestamps */
static int interactive = 0; /* disable all redirections */
static const char *results;
+static unsigned fullbuffer = 0;
static FILE *outfile = NULL;
@@ -64,6 +70,7 @@ enum {
FAILED,
WARNED,
KNOWNFAIL,
+ INTERRUPTED,
};
static void handler( int sig ) {
@@ -156,6 +163,12 @@ static int64_t _get_time_us(void)
static void _append_buf(const char *buf, size_t len)
{
if ((readbuf_used + len) >= readbuf_sz) {
+ if ((readbuf_sz >= MAX_LOG_SIZE) &&
+ !getenv("LVM_TEST_UNLIMITED")) {
+ if (fullbuffer++ == 0)
+ kill(pid, SIGINT);
+ return;
+ }
readbuf_sz = readbuf_sz ? 2 * readbuf_sz : 4096;
readbuf = realloc(readbuf, readbuf_sz);
}
@@ -212,9 +225,10 @@ static void drain(void) {
static int outfile_last = -1, outfile_counter = 0;
while ((sz = read(fds[1], buf, sizeof(buf) - 1)) > 0) {
+ if (fullbuffer)
+ continue;
buf[sz] = '\0';
bp = (verbose < 2) ? buf : _append_with_stamp(buf, stamp);
-
if (sz > (bp - buf)) {
_append_buf(bp, sz - (bp - buf));
stamp = -1; /* unfinished line */
@@ -230,28 +244,49 @@ static void drain(void) {
}
}
-static const char *duration(time_t start)
+static const char *duration(time_t start, const struct rusage *usage)
{
- static char buf[16];
+ static char buf[100];
int t = (int)(time(NULL) - start);
- sprintf(buf, "%2d:%02d", t / 60, t % 60);
+ int p = sprintf(buf, "%2d:%02d", t / 60, t % 60);
+
+ if (usage)
+ sprintf(buf + p, " %2ld:%02ld.%03ld/%ld:%02ld.%03ld%5ld%8ld/%ld",
+ usage->ru_utime.tv_sec / 60, usage->ru_utime.tv_sec % 60,
+ usage->ru_utime.tv_usec / 1000,
+ usage->ru_stime.tv_sec / 60, usage->ru_stime.tv_sec % 60,
+ usage->ru_stime.tv_usec / 1000,
+ usage->ru_maxrss / 1024,
+ usage->ru_inblock, usage->ru_oublock);
+
return buf;
}
-static void passed(int i, char *f, time_t t) {
+static void passed(int i, char *f, time_t t, const struct rusage *usage) {
if (readbuf && strstr(readbuf, "TEST EXPECT FAIL")) {
++ s.npassed;
s.status[i] = PASSED;
- printf("passed (UNEXPECTED). %s\n", duration(t));
+ printf("passed (UNEXPECTED). %s\n", duration(t, usage));
} else if (readbuf && strstr(readbuf, "TEST WARNING")) {
++s.nwarned;
s.status[i] = WARNED;
- printf("warnings %s\n", duration(t));
+ printf("warnings %s\n", duration(t, usage));
} else {
++ s.npassed;
s.status[i] = PASSED;
- printf("passed. %s\n", duration(t));
+ printf("passed. %s\n", duration(t, usage));
+ }
+}
+
+static void interrupted(int i, char *f) {
+ ++ s.ninterrupted;
+ s.status[i] = INTERRUPTED;
+ printf("\ninterrupted.\n");
+ if (!verbose && fullbuffer) {
+ printf("-- Interrupted %s ------------------------------------\n", f);
+ dump();
+ printf("\n-- Interrupted %s (end) ------------------------------\n", f);
}
}
@@ -271,12 +306,8 @@ static void failed(int i, char *f, int st) {
++ s.nfailed;
s.status[i] = FAILED;
- if(die == 2) {
- printf("interrupted.\n");
- return;
- }
printf("FAILED.\n");
- if (!verbose) {
+ if (!verbose && readbuf) {
printf("-- FAILED %s ------------------------------------\n", f);
dump();
printf("-- FAILED %s (end) ------------------------------\n", f);
@@ -284,6 +315,7 @@ static void failed(int i, char *f, int st) {
}
static void run(int i, char *f) {
+ struct rusage usage;
char flavour[512], script[512];
pid = fork();
@@ -306,45 +338,64 @@ static void run(int i, char *f) {
} else {
strcpy(script, f);
}
- execlp("bash", "bash", script, NULL);
+ execlp("bash", "bash", "-noprofile", "-norc", script, NULL);
perror("execlp");
fflush(stderr);
_exit(202);
} else {
- int st, w;
+ int st = -1, w;
time_t start = time(NULL);
char buf[128];
char outpath[PATH_MAX];
char *c = outpath + strlen(results) + 1;
+ struct timeval timeout;
+ fd_set master_set, copy_set;
+
snprintf(buf, sizeof(buf), "%s ...", f);
printf("Running %-60s ", buf);
fflush(stdout);
snprintf(outpath, sizeof(outpath), "%s/%s.txt", results, f);
while ((c = strchr(c, '/')))
*c = '_';
- if ((outfile = fopen(outpath, "w"))) {
- while ((w = waitpid(pid, &st, WNOHANG)) == 0) {
- drain();
- usleep(20000);
- }
- if (w != pid) {
- perror("waitpid");
- exit(206);
- }
+ if (!(outfile = fopen(outpath, "w")))
+ perror("fopen");
+
+ FD_ZERO(&master_set);
+ FD_SET(fds[1], &master_set);
+ while ((w = wait4(pid, &st, WNOHANG, &usage)) == 0) {
+ if (fullbuffer && fullbuffer++ == 8000)
+ /* Output doesn't won't to stop... */
+ kill(pid, SIGKILL);
+ memcpy(©_set, &master_set, sizeof(master_set));
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500000;
+ if (select(fds[1] + 1, ©_set, NULL, NULL, &timeout) <= 0)
+ continue;
drain();
- if (WIFEXITED(st)) {
- if (WEXITSTATUS(st) == 0)
- passed(i, f, start);
- else if (WEXITSTATUS(st) == 200)
- skipped(i, f);
- else
- failed(i, f, st);
- } else
+ }
+ if (w != pid) {
+ perror("waitpid");
+ exit(206);
+ }
+ drain();
+ if (fullbuffer || (die == 2))
+ interrupted(i, f);
+ else if (WIFEXITED(st)) {
+ if (WEXITSTATUS(st) == 0)
+ passed(i, f, start, &usage);
+ else if (WEXITSTATUS(st) == 200)
+ skipped(i, f);
+ else
failed(i, f, st);
-
- clear();
+ } else
+ failed(i, f, st);
+ clear();
+ if (outfile)
fclose(outfile);
- }
+ if (fullbuffer)
+ printf("\nTest was interrupted, output has got too large (>%u) (loop:%u)\n"
+ "Set LVM_TEST_UNLIMITED=1 for unlimited log.\n",
+ (unsigned) readbuf_sz, fullbuffer);
}
}
@@ -368,16 +419,15 @@ int main(int argc, char **argv) {
if (be_interactive)
interactive = atoi(be_interactive);
- if (!(results = getenv("LVM_TEST_RESULTS")))
- results = "results";
- snprintf(results_list, sizeof(results_list), "%s/list", results);
+ results = getenv("LVM_TEST_RESULTS") ? : "results";
+ (void) snprintf(results_list, sizeof(results_list), "%s/list", results);
if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds)) {
perror("socketpair");
return 201;
}
- if ( fcntl( fds[1], F_SETFL, O_NONBLOCK ) == -1 ) {
+ if (fcntl(fds[1], F_SETFL, O_NONBLOCK ) == -1) {
perror("fcntl on socket");
return 202;
}
@@ -390,16 +440,15 @@ int main(int argc, char **argv) {
}
/* run the tests */
- for (i = 1; i < argc; ++ i) {
+ for (i = 1; !die && i < argc; ++i)
run(i, argv[i]);
- if (die)
- break;
- }
- printf("\n## %d tests %s : %d OK, %d warnings, %d failures, %d known failures; %d skipped\n",
- s.nwarned + s.npassed + s.nfailed + s.nskipped,
- duration(start),
- s.npassed, s.nwarned, s.nfailed, s.nknownfail, s.nskipped);
+ printf("\n## %d tests %s : %d OK, %d warnings, %d failures, %d known failures; "
+ "%d skipped, %d interrupted\n",
+ s.nwarned + s.npassed + s.nfailed + s.nskipped + s.ninterrupted,
+ duration(start, NULL),
+ s.npassed, s.nwarned, s.nfailed, s.nknownfail,
+ s.nskipped, s.ninterrupted);
/* dump a list to results */
if ((list = fopen(results_list, "w"))) {
@@ -409,6 +458,7 @@ int main(int argc, char **argv) {
case FAILED: result = "failed"; break;
case SKIPPED: result = "skipped"; break;
case WARNED: result = "warnings"; break;
+ case INTERRUPTED: result = "interrupted"; break;
default: result = "unknown"; break;
}
fprintf(list, "%s %s\n", argv[i], result);
@@ -418,7 +468,7 @@ int main(int argc, char **argv) {
perror("fopen result");
/* print out a summary */
- if (s.nfailed || s.nskipped || s.nknownfail) {
+ if (s.nfailed || s.nskipped || s.nknownfail || s.ninterrupted) {
for (i = 1; i < argc; ++ i) {
switch (s.status[i]) {
case FAILED:
@@ -430,11 +480,14 @@ int main(int argc, char **argv) {
case SKIPPED:
printf("skipped: %s\n", argv[i]);
break;
+ case INTERRUPTED:
+ printf("interrupted: %s\n", argv[i]);
+ break;
default: /* do nothing */ ;
}
}
printf("\n");
- return s.nfailed > 0 || die;
+ return (s.nfailed > 0) || (s.ninterrupted > 0) || die;
}
free(readbuf);
10 years, 9 months
master - thin: enable resize for thin pool metadata LV
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c888c925b8d561...
Commit: c888c925b8d561158c3cea6d4f5ea4e173848c00
Parent: 87aca628d6b477ec4f0b6dac7d4895b31253a6e1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 13:11:54 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:07:51 2013 +0200
thin: enable resize for thin pool metadata LV
Support 'clasic' way of resizing of metadata LV.
Normally we disallow to work with internal 'invisible' devices.
But in this case we can make an exception and if user has some
special needs how to extend thin pool metadata LV - support it.
After resize of metadata LV, the pool will be suspended and resumed,
to be notified of this change.
---
tools/lvresize.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 6de3b3b..bb9a535 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -530,7 +530,8 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
- if (!lv_is_visible(lv)) {
+ if (!lv_is_visible(lv) &&
+ !lv_is_thin_pool_metadata(lv)) {
log_error("Can't resize internal logical volume %s", lv->name);
return ECMD_FAILED;
}
10 years, 9 months
master - thin: lvresize supports pool metadata resize
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=87aca628d6b477...
Commit: 87aca628d6b477ec4f0b6dac7d4895b31253a6e1
Parent: 72c3ae253e52b896795cc0769860c4fcd82ef244
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 13:45:49 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:05:20 2013 +0200
thin: lvresize supports pool metadata resize
Add support for lvresize of thin pool metadata device.
lvresize --poolmetadatasize +20 vgname/thinpool_lv
or
lvresize -L +20 vgname/thinpool_lv_tmeta
Where the second one allows all the args for resize (striping...)
and the first option resizes accoding to the last metadata lv segment.
---
WHATS_NEW | 1 +
man/lvcreate.8.in | 4 +-
man/lvresize.8.in | 9 +++
tools/commands.h | 10 +++-
tools/lvresize.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 152 insertions(+), 23 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 084738d..aecf227 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Add lvresize support for online thin pool metadata volume resize.
Add helper functions find_pool_lv() and pool_can_resize_metadata().
Add detection for thin pool metadata resize kernel support.
Report lvs volume type 'e' with higher priority.
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 3d675ae..ac5cf65 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -61,7 +61,7 @@ lvcreate \- create a logical volume in an existing volume group
.RB [ \-\-discards
.RI { ignore | nopassdown | passdown }]
.RB [ \-\-poolmetadatasize
-.IR ThinPoolMetadataSize [ bBsSkKmMgG ]]]
+.IR MetadataVolumeSize [ bBsSkKmMgG ]]]
.RB [ \-\-thinpool
.IR ThinPoolLogicalVolume { Name | Path }
.RB [ \-s | \-\-snapshot
@@ -271,7 +271,7 @@ Sets access permissions to read only (\fIr\fP) or read and write (\fIrw\fP).
.br
Default is read and write.
.TP
-.IR \fB\-\-poolmetadatasize " " ThinPoolMetadataSize [ bBsSkKmMgG ]
+.IR \fB\-\-poolmetadatasize " " MetadataVolumeSize [ bBsSkKmMgG ]
Sets the size of thin pool's metadata logical volume.
Supported values are in range between 2MiB and 16GiB.
Default value is (Pool_LV_size / Pool_LV_chunk_size * 64b).
diff --git a/man/lvresize.8.in b/man/lvresize.8.in
index 7e85993..e04869d 100644
--- a/man/lvresize.8.in
+++ b/man/lvresize.8.in
@@ -11,6 +11,8 @@ lvresize \- resize a logical volume
.RI [ + | \- ] LogicalExtentsNumber [ % { VG | LV | PVS | FREE | ORIGIN "}] |"
.RB [ \-L | \-\-size
.RI [ + | \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]}
+.RB [ \-\-poolmetadatasize
+.RI [ + ] MetadataVolumeSize [ bBsSkKmMgG ]
.RB [ \-f | \-\-force ]
.RB [ \-n | \-\-nofsck ]
.RB [ \-r | \-\-resizefs ]
@@ -73,6 +75,13 @@ Defaults to whatever the last segment of the Logical Volume uses.
Not applicable to LVs using the original metadata LVM format, which must
use a single value throughout.
.TP
+.IR \fB\-\-poolmetadatasize " [" + ] MetadataVolumeSize [ bBsSkKmMgG ]
+Change or set the thin pool metadata logical volume size.
+With the \fI+\fP sign the value is added to the actual size
+of the metadata volume and rounded to the full extent size
+and without it, the value is taken as an absolute one.
+Maximal size is 16GiB. Default unit is megabytes.
+.TP
.BR \-I ", " \-\-stripesize " " \fIStripeSize
Gives the number of kilobytes for the granularity of the stripes.
Defaults to whatever the last segment of the Logical Volume uses.
diff --git a/tools/commands.h b/tools/commands.h
index 64d6d0d..2d99d5a 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -233,7 +233,7 @@ xx(lvcreate,
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents LogicalExtentsNumber[%{VG|FREE|ORIGIN}] |\n"
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
- "\t[--poolmetadatasize Size[bBsSkKmMgG]]\n"
+ "\t[--poolmetadatasize MetadataVolumeSize[bBsSkKmMgG]]\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[--noudevsync]\n"
@@ -308,6 +308,7 @@ xx(lvextend,
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
"\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
+ "\t --poolmetadatasize [+]MetadataVolumeSize[bBsSkKmMgG]}\n"
"\t[-m|--mirrors Mirrors]\n"
"\t[--nosync]\n"
"\t[--use-policies]\n"
@@ -321,7 +322,8 @@ xx(lvextend,
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG,
- nofsck_ARG, nosync_ARG, noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG,
+ nofsck_ARG, nosync_ARG, noudevsync_ARG, poolmetadatasize_ARG,
+ resizefs_ARG, size_ARG, stripes_ARG,
stripesize_ARG, test_ARG, type_ARG, use_policies_ARG)
xx(lvmchange,
@@ -437,6 +439,7 @@ xx(lvresize,
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents [+|-]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n"
"\t -L|--size [+|-]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
+ "\t --poolmetadatasize [+]MetadataVolumeSize[bBsSkKmMgG]}\n"
"\t[-n|--nofsck]\n"
"\t[--noudevsync]\n"
"\t[-r|--resizefs]\n"
@@ -447,7 +450,8 @@ xx(lvresize,
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, nofsck_ARG,
- noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG,
+ noudevsync_ARG, resizefs_ARG, poolmetadatasize_ARG,
+ size_ARG, stripes_ARG, stripesize_ARG,
test_ARG, type_ARG)
xx(lvs,
diff --git a/tools/lvresize.c b/tools/lvresize.c
index f552992..6de3b3b 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.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.
*
@@ -30,7 +30,10 @@ struct lvresize_params {
/* size */
uint32_t extents;
uint64_t size;
+ int sizeargs;
sign_t sign;
+ uint64_t poolmetadatasize;
+ sign_t poolmetadatasign;
percent_type_t percent;
enum {
@@ -192,6 +195,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
int use_policy = arg_count(cmd, use_policies_ARG);
lp->sign = SIGN_NONE;
+ lp->poolmetadatasign = SIGN_NONE;
lp->resize = LV_ANY;
cmd_name = command_name(cmd);
@@ -211,13 +215,14 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
* one or more PVs. Most likely, the intent was "resize this
* LV the best you can with these PVs"
*/
- if ((arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG) == 0) &&
- (argc >= 2)) {
+ lp->sizeargs = arg_count(cmd, extents_ARG) + arg_count(cmd, size_ARG);
+ if ((lp->sizeargs == 0) && (argc >= 2)) {
lp->extents = 100;
lp->percent = PERCENT_PVS;
lp->sign = SIGN_PLUS;
- } else if ((arg_count(cmd, extents_ARG) +
- arg_count(cmd, size_ARG) != 1)) {
+ } else if ((lp->sizeargs != 1) &&
+ ((lp->sizeargs == 2) ||
+ !arg_count(cmd, poolmetadatasize_ARG))) {
log_error("Please specify either size or extents but not "
"both.");
return 0;
@@ -235,6 +240,15 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
lp->sign = arg_sign_value(cmd, size_ARG, SIGN_NONE);
lp->percent = PERCENT_NONE;
}
+
+ if (arg_count(cmd, poolmetadatasize_ARG)) {
+ lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, 0);
+ lp->poolmetadatasign = arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE);
+ if (lp->poolmetadatasign == SIGN_MINUS) {
+ log_error("Can't reduce pool metadata size.");
+ return 0;
+ }
+ }
}
if (lp->resize == LV_EXTEND && lp->sign == SIGN_MINUS) {
@@ -242,7 +256,8 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
return 0;
}
- if (lp->resize == LV_REDUCE && lp->sign == SIGN_PLUS) {
+ if (lp->resize == LV_REDUCE &&
+ ((lp->sign == SIGN_PLUS) || (lp->poolmetadatasign == SIGN_PLUS))) {
log_error("Positive sign not permitted - use lvextend");
return 0;
}
@@ -306,18 +321,23 @@ static int _adjust_policy_params(struct cmd_context *cmd,
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, 1, &percent))
return_0;
- if (percent > policy_threshold) {
- /* FIXME: metadata resize support missing */
- log_error("Resize for %s/%s is not yet supported.",
- lp->vg_name, lp->lv_name);
- return ECMD_FAILED;
+ if ((PERCENT_0 < percent && percent <= PERCENT_100) &&
+ (percent > policy_threshold)) {
+ if (!pool_can_resize_metadata(lv)) {
+ log_error_once("Online metadata resize for %s/%s is not supported.",
+ lp->vg_name, lp->lv_name);
+ return 0;
+ }
+ lp->poolmetadatasize = (first_seg(lv)->metadata_lv->size *
+ policy_amount + 99) / 100;
+ lp->poolmetadatasign = SIGN_PLUS;
}
if (!lv_thin_pool_percent(lv, 0, &percent))
return_0;
if (!(PERCENT_0 < percent && percent <= PERCENT_100) ||
percent <= policy_threshold)
- return 1; /* nothing to do */
+ return 1;
} else {
if (!lv_snapshot_percent(lv, &percent))
return_0;
@@ -326,6 +346,7 @@ static int _adjust_policy_params(struct cmd_context *cmd,
}
lp->extents = policy_amount;
+ lp->sizeargs = (lp->extents) ? 1 : 0;
return 1;
}
@@ -358,6 +379,74 @@ static uint32_t lvseg_get_stripes(struct lv_segment *seg, uint32_t *stripesize)
return 0;
}
+static int _lvresize_poolmetadata(struct cmd_context *cmd, struct volume_group *vg,
+ struct lvresize_params *lp,
+ const struct logical_volume *pool_lv,
+ struct dm_list *pvh,
+ alloc_policy_t alloc)
+{
+ struct logical_volume *lv;
+ struct lv_segment *mseg;
+ uint32_t extents;
+ uint32_t seg_mirrors;
+
+ if (!pool_can_resize_metadata(pool_lv)) {
+ log_error("Support for online metadata resize not detected.");
+ return 0;
+ }
+
+ if (lp->poolmetadatasize % vg->extent_size) {
+ lp->poolmetadatasize += vg->extent_size -
+ (lp->poolmetadatasize % vg->extent_size);
+ log_print_unless_silent("Rounding pool metadata size to boundary between physical extents: %s",
+ display_size(cmd, lp->poolmetadatasize));
+ }
+
+ if (!(extents = extents_from_size(vg->cmd, lp->poolmetadatasize,
+ vg->extent_size)))
+ return_0;
+
+ lv = first_seg(pool_lv)->metadata_lv;
+ if (lp->poolmetadatasign == SIGN_PLUS) {
+ if (extents >= (MAX_EXTENT_COUNT - lv->le_count)) {
+ log_error("Unable to extend %s by %u extents, exceeds limit (%u).",
+ lv->name, lv->le_count, MAX_EXTENT_COUNT);
+ return 0;
+ }
+ extents += lv->le_count;
+ }
+
+ if (extents * vg->extent_size > DM_THIN_MAX_METADATA_SIZE) {
+ log_print_unless_silent("Rounding size to maximum supported size 16GiB "
+ "for metadata volume %s.", lv->name);
+ extents = (DM_THIN_MAX_METADATA_SIZE + vg->extent_size - 1) /
+ vg->extent_size;
+ }
+
+ if (extents == lv->le_count) {
+ log_print_unless_silent("Metadata volume %s has already %s.",
+ lv->name, display_size(cmd, lv->size));
+ return 2;
+ }
+
+ log_print_unless_silent("Extending logical volume %s to %s.",
+ lv->name,
+ display_size(cmd, (uint64_t) extents * vg->extent_size));
+ mseg = last_seg(lv);
+ seg_mirrors = lv_mirror_count(lv);
+ if (!lv_extend(lv,
+ mseg->segtype,
+ mseg->area_count / seg_mirrors,
+ mseg->stripe_size,
+ seg_mirrors,
+ mseg->region_size,
+ extents - lv->le_count, NULL,
+ pvh, alloc))
+ return_0;
+
+ return 1;
+}
+
static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
struct lvresize_params *lp)
{
@@ -485,6 +574,8 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
+ if (lp->sizeargs) { /* TODO: reindent or move to function */
+
switch(lp->percent) {
case PERCENT_VG:
lp->extents = percent_of_extents(lp->extents, vg->extent_count,
@@ -552,6 +643,11 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
}
if (lp->extents == lv->le_count) {
+ /* A bit of hack - but still may resize metadata */
+ if (lp->poolmetadatasize) {
+ lp->sizeargs = 0;
+ goto metadata_resize;
+ }
if (use_policy)
return ECMD_PROCESSED; /* Nothing to do. */
if (!lp->resizefs) {
@@ -778,6 +874,9 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
log_warn("Thin pool volumes do not have filesystem.");
lp->resizefs = 0;
}
+ } else if (lp->poolmetadatasize) {
+ log_error("--poolmetadatasize can be used only with thin pools.");
+ return ECMD_FAILED;
}
if ((lp->resize == LV_REDUCE) && lp->argc)
@@ -832,18 +931,34 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
+ /* If thin metadata, must suspend thin pool */
+ if (lv_is_thin_pool_metadata(lv)) {
+ if (!(lock_lv = find_pool_lv(lv)))
+ return_0;
+ /* If snapshot, must suspend all associated devices */
+ } else if (lv_is_cow(lv))
+ lock_lv = origin_from_cow(lv);
+ else
+ lock_lv = lv;
+
+ } /* lp->sizeargs */
+
+ if (lp->poolmetadatasize) {
+metadata_resize:
+ if (!(status = _lvresize_poolmetadata(cmd, vg, lp, lv, pvh, alloc))) {
+ stack;
+ return ECMD_FAILED;
+ } else if ((status == 2) && !lp->sizeargs)
+ return ECMD_PROCESSED;
+ lock_lv = lv;
+ }
+
/* store vg on disk(s) */
if (!vg_write(vg)) {
stack;
return ECMD_FAILED;
}
- /* If snapshot, must suspend all associated devices */
- if (lv_is_cow(lv))
- lock_lv = origin_from_cow(lv);
- else
- lock_lv = lv;
-
if (!suspend_lv(cmd, lock_lv)) {
log_error("Failed to suspend %s", lock_lv->name);
vg_revert(vg);
10 years, 9 months
master - thin: add helper functions
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=72c3ae253e52b8...
Commit: 72c3ae253e52b896795cc0769860c4fcd82ef244
Parent: 55a3859632c861e8a3bd07a7c848fdb1901e0a05
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 12:32:01 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:03:30 2013 +0200
thin: add helper functions
Add find_pool_lv() and pool_can_resize_metadata().
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 2 ++
lib/metadata/thin_manip.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index f85730c..084738d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Add helper functions find_pool_lv() and pool_can_resize_metadata().
Add detection for thin pool metadata resize kernel support.
Report lvs volume type 'e' with higher priority.
Report lvs volume type 'o' also for external origin volumes.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index cfa5ad8..5fb5b6c 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -578,7 +578,9 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint32_t extent_size);
+struct logical_volume *find_pool_lv(struct logical_volume *lv);
int pool_is_active(const struct logical_volume *pool_lv);
+int pool_can_resize_metadata(const struct logical_volume *pool_lv);
int update_pool_lv(struct logical_volume *lv, int activate);
int update_pool_params(struct cmd_context *cmd, unsigned attr, int passed_args,
uint32_t data_extents, uint32_t extent_size,
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 1239af9..37b5d77 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -309,6 +309,28 @@ int pool_is_active(const struct logical_volume *lv)
return 0;
}
+int pool_can_resize_metadata(const struct logical_volume *lv)
+{
+ static unsigned attr = 0U;
+ struct lv_segment *seg;
+
+ if (!lv_is_thin_pool(lv)) {
+ log_error(INTERNAL_ERROR "LV %s is not thin pool.", lv->name);
+ return 0;
+ }
+
+ seg = first_seg(lv);
+ if ((attr == 0U) && activation() && seg->segtype &&
+ seg->segtype->ops->target_present &&
+ !seg->segtype->ops->target_present(lv->vg->cmd, NULL, &attr)) {
+ log_error("%s: Required device-mapper target(s) not "
+ "detected in your kernel", seg->segtype->name);
+ return 0;
+ }
+
+ return (attr & THIN_FEATURE_METADATA_RESIZE) ? 1 : 0;
+}
+
int pool_below_threshold(const struct lv_segment *pool_seg)
{
percent_t percent;
@@ -352,6 +374,16 @@ struct lv_segment *find_pool_seg(const struct lv_segment *seg)
return pool_seg;
}
+struct logical_volume *find_pool_lv(struct logical_volume *lv)
+{
+ struct lv_segment *seg;
+
+ if (!(seg = find_pool_seg(first_seg(lv))))
+ return_NULL;
+
+ return seg->lv;
+}
+
/*
* Find a free device_id for given thin_pool segment.
*
10 years, 9 months
master - thin: detect online metadata resize support
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=55a3859632c861...
Commit: 55a3859632c861e8a3bd07a7c848fdb1901e0a05
Parent: 01ef97fcbbfe0ed49b3dc61765d166efe8647e8a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 12:31:01 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:03:28 2013 +0200
thin: detect online metadata resize support
---
WHATS_NEW | 1 +
lib/activate/activate.h | 1 +
lib/thin/thin.c | 1 +
3 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index f9f51dc..f85730c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Add detection for thin pool metadata resize kernel support.
Report lvs volume type 'e' with higher priority.
Report lvs volume type 'o' also for external origin volumes.
Report lvs target type 't' only for thin pools and thin volumes.
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 1cbb67f..80733fe 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -51,6 +51,7 @@ enum {
THIN_FEATURE_HELD_ROOT = (1 << 2),
THIN_FEATURE_BLOCK_SIZE = (1 << 3),
THIN_FEATURE_DISCARDS_NON_POWER_2 = (1 << 4),
+ THIN_FEATURE_METADATA_RESIZE = (1 << 5),
};
void set_activation(int activation);
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 4bfae33..d1ffd27 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -562,6 +562,7 @@ static int _thin_target_present(struct cmd_context *cmd,
{ 1, 1, THIN_FEATURE_EXTERNAL_ORIGIN, "external_origin" },
{ 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" },
{ 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" },
+ { 1, 8, THIN_FEATURE_METADATA_RESIZE, "metadata_resize" },
};
static const char _lvmconf[] = "global/thin_disabled_features";
10 years, 9 months
master - thin: report 'e' metadata type with higher priority
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=01ef97fcbbfe0e...
Commit: 01ef97fcbbfe0ed49b3dc61765d166efe8647e8a
Parent: c0290489c33be7d8318e3005dffcebc62a6f3354
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 5 13:46:38 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:03:08 2013 +0200
thin: report 'e' metadata type with higher priority
Giving volume type information about being 'metadata' type of volume
has higher priority then i.e. 'mirror' or 'thin' flag - for those
type we have 'target attr' (7th. field).
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index c94c9e1..f9f51dc 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Report lvs volume type 'e' with higher priority.
Report lvs volume type 'o' also for external origin volumes.
Report lvs target type 't' only for thin pools and thin volumes.
Fix test for active snapshot in cluster before resizing it.
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 9cfc2fe..fb7870d 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -536,6 +536,9 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
/* Origin takes precedence over mirror and thin volume */
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->status & RAID_META))
+ repstr[0] = 'e';
else if (lv->status & RAID)
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
else if (lv->status & MIRRORED)
@@ -548,8 +551,6 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
repstr[0] = 't';
else if (lv_is_thin_pool_data(lv))
repstr[0] = 'T';
- else if (lv_is_thin_pool_metadata(lv) || (lv->status & RAID_META))
- repstr[0] = 'e';
else if (lv->status & MIRROR_IMAGE)
repstr[0] = (_lv_mimage_in_sync(lv)) ? 'i' : 'I';
else if (lv->status & RAID_IMAGE)
10 years, 9 months
master - thin: report o as volume type for external origin
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c0290489c33be7...
Commit: c0290489c33be7d8318e3005dffcebc62a6f3354
Parent: 7151ede767ad168b71f338c48835fcf64a9e3ce7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 5 13:45:31 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 14:02:41 2013 +0200
thin: report o as volume type for external origin
Reuse 'o' attr for lvs report also for external origin.
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 96478e6..c94c9e1 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Report lvs volume type 'o' also for external origin volumes.
Report lvs target type 't' only for thin pools and thin volumes.
Fix test for active snapshot in cluster before resizing it.
Report backtrace from dump filter error path.
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index e53fdf3..9cfc2fe 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -534,7 +534,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
else if (lv->status & CONVERTING)
repstr[0] = 'c';
/* Origin takes precedence over mirror and thin volume */
- else if (lv_is_origin(lv))
+ else if (lv_is_origin(lv) || lv_is_external_origin(lv))
repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
else if (lv->status & RAID)
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
10 years, 9 months
master - thin: report t for thin pool and volume
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7151ede767ad16...
Commit: 7151ede767ad168b71f338c48835fcf64a9e3ce7
Parent: 272f5ae208d20dc56599e61b37e74afac05a1140
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 5 13:44:10 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 13:58:16 2013 +0200
thin: report t for thin pool and volume
Do not mark internal device _tdata and _tmeta as having target type 't'.
They have the target type on their own (i.e. mirror, raid).
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 57aab93..96478e6 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Report lvs target type 't' only for thin pools and thin volumes.
Fix test for active snapshot in cluster before resizing it.
Report backtrace from dump filter error path.
Do not use persistent filter with lvmetad.
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 182eb57..e53fdf3 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -617,7 +617,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
repstr[5] = '-';
}
- if (lv_is_thin_type(lv))
+ if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
repstr[6] = 't';
else if (lv_is_raid_type(lv))
repstr[6] = 'r';
10 years, 9 months
master - snapshots: check for active state
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=272f5ae208d20d...
Commit: 272f5ae208d20dc56599e61b37e74afac05a1140
Parent: 1cdb6ca2b246bf5dc680abde3b0a2ea0192f1aaf
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 13:07:13 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 13:57:18 2013 +0200
snapshots: check for active state
Fix testing if the snapshot could be resized and use lv_is_active()
to get correct answer in cluster.
---
WHATS_NEW | 1 +
tools/lvresize.c | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index fe42b81..57aab93 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Fix test for active snapshot in cluster before resizing it.
Report backtrace from dump filter error path.
Do not use persistent filter with lvmetad.
Composable persistent filter functionality for global filter.
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 558dff0..f552992 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -362,7 +362,6 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
struct lvresize_params *lp)
{
struct logical_volume *lv;
- struct lvinfo info;
uint32_t stripesize_extents;
uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size;
uint32_t seg_mirrors = 0;
@@ -762,7 +761,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
- if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) {
+ if (lv_is_active(lv)) {
log_error("Snapshot origin volumes can be resized "
"only while inactive: try lvchange -an");
return ECMD_FAILED;
10 years, 9 months
master - cleanup: skip test if already tested for SIGN_PLUS
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1cdb6ca2b246bf...
Commit: 1cdb6ca2b246bf5dc680abde3b0a2ea0192f1aaf
Parent: 1dcba13dfcccfb043f49708ca8f44c4d9fa9a260
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jun 11 13:09:11 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Jun 11 13:55:26 2013 +0200
cleanup: skip test if already tested for SIGN_PLUS
---
tools/lvresize.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 7b1bd50..558dff0 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -537,9 +537,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_PROCESSED;
}
}
- }
-
- if (lp->sign == SIGN_MINUS) {
+ } else if (lp->sign == SIGN_MINUS) {
if (lp->extents >= lv->le_count) {
log_error("Unable to reduce %s below 1 extent",
lp->lv_name);
10 years, 9 months