lvm2 package update
Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>master
parent
bcc54a4f58
commit
f30b2134bb
|
@ -0,0 +1,38 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
tools/lvcreate.c | 5 ++++-
|
||||||
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 5260321..1147dad 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.131 -
|
||||||
|
=====================================
|
||||||
|
+ Disallow usage of --stripe and --stripesize when creating cache pool.
|
||||||
|
Swapping of LV identifiers handles more complex LVs.
|
||||||
|
Fix VG metadata comparison failure while scanning the VG for lvmetad.
|
||||||
|
Ignore persistent cache if configuration changed. (2.02.127)
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index 364a16a..7bba761 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -770,7 +770,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
CACHE_POOL_ARGS,
|
||||||
|
LVCREATE_ARGS,
|
||||||
|
POOL_ARGS,
|
||||||
|
- SIZE_ARGS,
|
||||||
|
+ extents_ARG,
|
||||||
|
+ size_ARG,
|
||||||
|
cache_ARG,
|
||||||
|
chunksize_ARG,
|
||||||
|
-1))
|
||||||
|
@@ -1096,6 +1097,8 @@ static int _determine_cache_argument(struct volume_group *vg,
|
||||||
|
}
|
||||||
|
/* FIXME How to handle skip flag? */
|
||||||
|
if (arg_from_list_is_set(cmd, "is unsupported with cache conversion",
|
||||||
|
+ stripes_ARG,
|
||||||
|
+ stripesize_ARG,
|
||||||
|
setactivationskip_ARG,
|
||||||
|
ignoreactivationskip_ARG,
|
||||||
|
-1))
|
|
@ -0,0 +1,521 @@
|
||||||
|
libdm/libdm-stats.c | 223 ++++++++++++++++++++++++++++++----------------------
|
||||||
|
tools/dmsetup.c | 1 +
|
||||||
|
2 files changed, 131 insertions(+), 93 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
|
||||||
|
index 93c7760..ee62fe6 100644
|
||||||
|
--- a/libdm/libdm-stats.c
|
||||||
|
+++ b/libdm/libdm-stats.c
|
||||||
|
@@ -144,17 +144,24 @@ struct dm_stats *dm_stats_create(const char *program_id)
|
||||||
|
return_NULL;
|
||||||
|
|
||||||
|
/* FIXME: better hint. */
|
||||||
|
- if (!(dms->mem = dm_pool_create("stats_pool", 4096)))
|
||||||
|
- goto_bad;
|
||||||
|
+ if (!(dms->mem = dm_pool_create("stats_pool", 4096))) {
|
||||||
|
+ dm_free(dms);
|
||||||
|
+ return_NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!(dms->hist_mem = dm_pool_create("histogram_pool", hist_hint)))
|
||||||
|
- return_0;
|
||||||
|
+ goto_bad;
|
||||||
|
|
||||||
|
if (!program_id || !strlen(program_id))
|
||||||
|
dms->program_id = _program_id_from_proc();
|
||||||
|
else
|
||||||
|
dms->program_id = dm_strdup(program_id);
|
||||||
|
|
||||||
|
+ if (!dms->program_id) {
|
||||||
|
+ dm_pool_destroy(dms->hist_mem);
|
||||||
|
+ goto_bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
dms->major = -1;
|
||||||
|
dms->minor = -1;
|
||||||
|
dms->name = NULL;
|
||||||
|
@@ -171,6 +178,7 @@ struct dm_stats *dm_stats_create(const char *program_id)
|
||||||
|
return dms;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
+ dm_pool_destroy(dms->mem);
|
||||||
|
dm_free(dms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -186,15 +194,15 @@ static int _stats_region_present(const struct dm_stats_region *region)
|
||||||
|
static void _stats_histograms_destroy(struct dm_pool *mem,
|
||||||
|
struct dm_stats_region *region)
|
||||||
|
{
|
||||||
|
- uint64_t n;
|
||||||
|
-
|
||||||
|
/* Unpopulated handle. */
|
||||||
|
if (!region->counters)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- for (n = _nr_areas_region(region) - 1; n; n--)
|
||||||
|
- if (region->counters[n].histogram)
|
||||||
|
- dm_pool_free(mem, region->counters[n].histogram);
|
||||||
|
+ /*
|
||||||
|
+ * Only the first histogram needs to be freed explicitly.
|
||||||
|
+ */
|
||||||
|
+ if (region->counters[0].histogram)
|
||||||
|
+ dm_pool_free(mem, region->counters[0].histogram);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _stats_region_destroy(struct dm_stats_region *region)
|
||||||
|
@@ -316,11 +324,54 @@ int dm_stats_driver_supports_histogram(void)
|
||||||
|
return _stats_check_precise_timestamps(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int _fill_hist_arg(char *hist_arg, size_t hist_len, uint64_t scale,
|
||||||
|
+ struct dm_histogram *bounds)
|
||||||
|
+{
|
||||||
|
+ int i, l, len = 0, nr_bins;
|
||||||
|
+ char *arg = hist_arg;
|
||||||
|
+ uint64_t value;
|
||||||
|
+
|
||||||
|
+ nr_bins = bounds->nr_bins;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < nr_bins; i++) {
|
||||||
|
+ value = bounds->bins[i].upper / scale;
|
||||||
|
+ if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
|
||||||
|
+ (i == (nr_bins - 1)) ? "" : ",")) < 0)
|
||||||
|
+ return_0;
|
||||||
|
+ len += l;
|
||||||
|
+ arg += l;
|
||||||
|
+ }
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *_get_hist_arg(struct dm_histogram *bounds, uint64_t scale,
|
||||||
|
+ size_t *len)
|
||||||
|
+{
|
||||||
|
+ struct dm_histogram_bin *entry, *bins;
|
||||||
|
+ size_t hist_len = 1; /* terminating '\0' */
|
||||||
|
+ double value;
|
||||||
|
+
|
||||||
|
+ entry = bins = bounds->bins;
|
||||||
|
+
|
||||||
|
+ entry += bounds->nr_bins - 1;
|
||||||
|
+ while(entry >= bins) {
|
||||||
|
+ value = (double) (entry--)->upper;
|
||||||
|
+ /* Use lround to avoid size_t -> double cast warning. */
|
||||||
|
+ hist_len += 1 + (size_t) lround(log10(value / scale));
|
||||||
|
+ if (entry != bins)
|
||||||
|
+ hist_len++; /* ',' */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *len = hist_len;
|
||||||
|
+
|
||||||
|
+ return dm_zalloc(hist_len);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
|
||||||
|
{
|
||||||
|
struct dm_histogram_bin *entry, *bins;
|
||||||
|
- size_t hist_len = 1, len = 0;
|
||||||
|
- char *hist_arg, *arg = NULL;
|
||||||
|
+ size_t hist_len;
|
||||||
|
+ char *hist_arg;
|
||||||
|
uint64_t scale;
|
||||||
|
|
||||||
|
entry = bins = bounds->bins;
|
||||||
|
@@ -331,53 +382,37 @@ static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Validate entries and set *precise if precision < 1ms. */
|
||||||
|
entry += bounds->nr_bins - 1;
|
||||||
|
- while(entry >= bins) {
|
||||||
|
- double value;
|
||||||
|
+ while (entry >= bins) {
|
||||||
|
if (entry != bins) {
|
||||||
|
if (entry->upper < (entry - 1)->upper) {
|
||||||
|
log_error("Histogram boundaries must be in "
|
||||||
|
"order of increasing magnitude.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- hist_len++; /* ',' */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only enable precise_timestamps automatically if any
|
||||||
|
* value in the histogram bounds uses precision < 1ms.
|
||||||
|
*/
|
||||||
|
- if (!*precise && (entry->upper % NSEC_PER_MSEC))
|
||||||
|
+ if (((entry--)->upper % NSEC_PER_MSEC) && !*precise)
|
||||||
|
*precise = 1;
|
||||||
|
-
|
||||||
|
- value = (double) (entry--)->upper;
|
||||||
|
- /* Use lround to avoid size_t -> double cast warning. */
|
||||||
|
- hist_len += 1 + (size_t) lround(log10(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!(hist_arg = dm_zalloc(hist_len))) {
|
||||||
|
+ scale = (*precise) ? 1 : NSEC_PER_MSEC;
|
||||||
|
+
|
||||||
|
+ /* Calculate hist_len and allocate a character buffer. */
|
||||||
|
+ if (!(hist_arg = _get_hist_arg(bounds, scale, &hist_len))) {
|
||||||
|
log_error("Could not allocate memory for histogram argument.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- arg = hist_arg;
|
||||||
|
-
|
||||||
|
- if (*precise)
|
||||||
|
- scale = 1;
|
||||||
|
- else
|
||||||
|
- scale = (*precise) ? 1 : NSEC_PER_MSEC;
|
||||||
|
+ /* Fill hist_arg with boundary strings. */
|
||||||
|
+ if (!_fill_hist_arg(hist_arg, hist_len, scale, bounds))
|
||||||
|
+ goto_bad;
|
||||||
|
|
||||||
|
- for (entry = bins; entry < (bins + bounds->nr_bins); entry++) {
|
||||||
|
- uint64_t value;
|
||||||
|
- ssize_t l = 0;
|
||||||
|
- int last = !(entry < (bins + bounds->nr_bins - 1));
|
||||||
|
- value = entry->upper / scale;
|
||||||
|
- if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
|
||||||
|
- (last) ? "" : ",")) < 0)
|
||||||
|
- goto_bad;
|
||||||
|
- len += (size_t) l;
|
||||||
|
- arg += (size_t) l;
|
||||||
|
- }
|
||||||
|
return hist_arg;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
@@ -419,13 +454,13 @@ static int _stats_parse_histogram_spec(struct dm_stats *dms,
|
||||||
|
const char *histogram)
|
||||||
|
{
|
||||||
|
static const char *_valid_chars = "0123456789,";
|
||||||
|
- uint64_t scale = region->timescale;
|
||||||
|
+ uint64_t scale = region->timescale, this_val = 0;
|
||||||
|
struct dm_pool *mem = dms->hist_mem;
|
||||||
|
struct dm_histogram_bin cur;
|
||||||
|
struct dm_histogram hist;
|
||||||
|
int nr_bins = 1;
|
||||||
|
- const char *c, *v;
|
||||||
|
- char *p;
|
||||||
|
+ const char *c, *v, *val_start;
|
||||||
|
+ char *p, *endptr = NULL;
|
||||||
|
|
||||||
|
/* Advance past "histogram:". */
|
||||||
|
histogram = strchr(histogram, ':');
|
||||||
|
@@ -466,9 +501,8 @@ static int _stats_parse_histogram_spec(struct dm_stats *dms,
|
||||||
|
histogram);
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
- const char *val_start = c;
|
||||||
|
- char *endptr = NULL;
|
||||||
|
- uint64_t this_val = 0;
|
||||||
|
+ val_start = c;
|
||||||
|
+ endptr = NULL;
|
||||||
|
|
||||||
|
this_val = strtoull(val_start, &endptr, 10);
|
||||||
|
if (!endptr) {
|
||||||
|
@@ -592,11 +626,11 @@ static int _stats_parse_list_region(struct dm_stats *dms,
|
||||||
|
|
||||||
|
static int _stats_parse_list(struct dm_stats *dms, const char *resp)
|
||||||
|
{
|
||||||
|
- struct dm_pool *mem = dms->mem;
|
||||||
|
- struct dm_stats_region cur;
|
||||||
|
uint64_t max_region = 0, nr_regions = 0;
|
||||||
|
+ struct dm_stats_region cur, fill;
|
||||||
|
+ struct dm_pool *mem = dms->mem;
|
||||||
|
FILE *list_rows;
|
||||||
|
- /* FIXME: determine correct maximum line length based on kernel format */
|
||||||
|
+ /* FIXME: use correct maximum line length for kernel format */
|
||||||
|
char line[256];
|
||||||
|
|
||||||
|
if (!resp) {
|
||||||
|
@@ -631,7 +665,6 @@ static int _stats_parse_list(struct dm_stats *dms, const char *resp)
|
||||||
|
|
||||||
|
/* handle holes in the list of region_ids */
|
||||||
|
if (cur.region_id > max_region) {
|
||||||
|
- struct dm_stats_region fill;
|
||||||
|
memset(&fill, 0, sizeof(fill));
|
||||||
|
fill.region_id = DM_STATS_REGION_NOT_PRESENT;
|
||||||
|
do {
|
||||||
|
@@ -707,54 +740,51 @@ static int _stats_parse_histogram(struct dm_pool *mem, char *hist_str,
|
||||||
|
struct dm_histogram **histogram,
|
||||||
|
struct dm_stats_region *region)
|
||||||
|
{
|
||||||
|
+ struct dm_histogram hist, *bounds = region->bounds;
|
||||||
|
static const char *_valid_chars = "0123456789:";
|
||||||
|
int nr_bins = region->bounds->nr_bins;
|
||||||
|
- struct dm_histogram hist, *bounds = region->bounds;
|
||||||
|
+ const char *c, *v, *val_start;
|
||||||
|
struct dm_histogram_bin cur;
|
||||||
|
- uint64_t sum = 0;
|
||||||
|
- const char *c, *v;
|
||||||
|
+ uint64_t sum = 0, this_val;
|
||||||
|
+ char *endptr = NULL;
|
||||||
|
int bin = 0;
|
||||||
|
|
||||||
|
c = hist_str;
|
||||||
|
|
||||||
|
- dm_pool_begin_object(mem, sizeof(cur));
|
||||||
|
+ if (!dm_pool_begin_object(mem, sizeof(cur)))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
hist.nr_bins = nr_bins;
|
||||||
|
|
||||||
|
- dm_pool_grow_object(mem, &hist, sizeof(hist));
|
||||||
|
+ if (!dm_pool_grow_object(mem, &hist, sizeof(hist)))
|
||||||
|
+ goto_bad;
|
||||||
|
|
||||||
|
do {
|
||||||
|
memset(&cur, 0, sizeof(cur));
|
||||||
|
for (v = _valid_chars; *v; v++)
|
||||||
|
if (*c == *v)
|
||||||
|
break;
|
||||||
|
- if (!*v) {
|
||||||
|
- stack;
|
||||||
|
+ if (!*v)
|
||||||
|
goto badchar;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (*c == ',') {
|
||||||
|
- log_error("Invalid histogram: %s", hist_str);
|
||||||
|
- return 0;
|
||||||
|
- } else {
|
||||||
|
- const char *val_start = c;
|
||||||
|
- char *endptr = NULL;
|
||||||
|
- uint64_t this_val = 0;
|
||||||
|
+ if (*c == ',')
|
||||||
|
+ goto badchar;
|
||||||
|
+ else {
|
||||||
|
+ val_start = c;
|
||||||
|
+ endptr = NULL;
|
||||||
|
|
||||||
|
this_val = strtoull(val_start, &endptr, 10);
|
||||||
|
if (!endptr) {
|
||||||
|
log_error("Could not parse histogram value.");
|
||||||
|
- return 0;
|
||||||
|
+ goto bad;
|
||||||
|
}
|
||||||
|
c = endptr; /* Advance to colon, or end. */
|
||||||
|
|
||||||
|
if (*c == ':')
|
||||||
|
c++;
|
||||||
|
- else if (*c & (*c != '\n')) {
|
||||||
|
+ else if (*c & (*c != '\n'))
|
||||||
|
/* Expected ':', '\n', or NULL. */
|
||||||
|
- stack;
|
||||||
|
goto badchar;
|
||||||
|
- }
|
||||||
|
|
||||||
|
if (*c == ':')
|
||||||
|
c++;
|
||||||
|
@@ -763,7 +793,8 @@ static int _stats_parse_histogram(struct dm_pool *mem, char *hist_str,
|
||||||
|
cur.count = this_val;
|
||||||
|
sum += this_val;
|
||||||
|
|
||||||
|
- dm_pool_grow_object(mem, &cur, sizeof(cur));
|
||||||
|
+ if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
|
||||||
|
+ goto_bad;
|
||||||
|
|
||||||
|
bin++;
|
||||||
|
}
|
||||||
|
@@ -778,6 +809,8 @@ static int _stats_parse_histogram(struct dm_pool *mem, char *hist_str,
|
||||||
|
|
||||||
|
badchar:
|
||||||
|
log_error("Invalid character in histogram data: '%c' (0x%x)", *c, *c);
|
||||||
|
+bad:
|
||||||
|
+ dm_pool_abandon_object(mem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -786,8 +819,8 @@ static int _stats_parse_region(struct dm_stats *dms, const char *resp,
|
||||||
|
uint64_t timescale)
|
||||||
|
{
|
||||||
|
struct dm_histogram *hist = NULL;
|
||||||
|
- struct dm_stats_counters cur;
|
||||||
|
struct dm_pool *mem = dms->mem;
|
||||||
|
+ struct dm_stats_counters cur;
|
||||||
|
FILE *stats_rows = NULL;
|
||||||
|
uint64_t start, len;
|
||||||
|
char row[256];
|
||||||
|
@@ -1040,12 +1073,12 @@ static int _stats_create_region(struct dm_stats *dms, uint64_t *region_id,
|
||||||
|
int precise, const char *hist_arg,
|
||||||
|
const char *program_id, const char *aux_data)
|
||||||
|
{
|
||||||
|
- struct dm_task *dmt = NULL;
|
||||||
|
- char msg[1024], range[64];
|
||||||
|
const char *err_fmt = "Could not prepare @stats_create %s.";
|
||||||
|
const char *precise_str = PRECISE_ARG;
|
||||||
|
const char *resp, *opt_args = NULL;
|
||||||
|
- int r = 0, nr_opt = 0; /* number of optional args. */
|
||||||
|
+ char msg[1024], range[64], *endptr = NULL;
|
||||||
|
+ struct dm_task *dmt = NULL;
|
||||||
|
+ int r = 0, nr_opt = 0;
|
||||||
|
|
||||||
|
if (!_stats_bound(dms))
|
||||||
|
return_0;
|
||||||
|
@@ -1105,7 +1138,6 @@ static int _stats_create_region(struct dm_stats *dms, uint64_t *region_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (region_id) {
|
||||||
|
- char *endptr = NULL;
|
||||||
|
*region_id = strtoull(resp, &endptr, 10);
|
||||||
|
if (resp == endptr)
|
||||||
|
goto_out;
|
||||||
|
@@ -1195,11 +1227,11 @@ static struct dm_task *_stats_print_region(struct dm_stats *dms,
|
||||||
|
uint64_t region_id, unsigned start_line,
|
||||||
|
unsigned num_lines, unsigned clear)
|
||||||
|
{
|
||||||
|
- struct dm_task *dmt = NULL;
|
||||||
|
/* @stats_print[_clear] <region_id> [<start_line> <num_lines>] */
|
||||||
|
const char *clear_str = "_clear", *lines_fmt = "%u %u";
|
||||||
|
const char *msg_fmt = "@stats_print%s " FMTu64 " %s";
|
||||||
|
const char *err_fmt = "Could not prepare @stats_print %s.";
|
||||||
|
+ struct dm_task *dmt = NULL;
|
||||||
|
char msg[1024], lines[64];
|
||||||
|
|
||||||
|
if (start_line || num_lines)
|
||||||
|
@@ -1292,6 +1324,8 @@ int dm_stats_populate(struct dm_stats *dms, const char *program_id,
|
||||||
|
uint64_t region_id)
|
||||||
|
{
|
||||||
|
int all_regions = (region_id == DM_STATS_REGIONS_ALL);
|
||||||
|
+ struct dm_task *dmt = NULL; /* @stats_print task */
|
||||||
|
+ const char *resp;
|
||||||
|
|
||||||
|
if (!_stats_bound(dms))
|
||||||
|
return_0;
|
||||||
|
@@ -1311,9 +1345,6 @@ int dm_stats_populate(struct dm_stats *dms, const char *program_id,
|
||||||
|
|
||||||
|
dm_stats_walk_start(dms);
|
||||||
|
do {
|
||||||
|
- struct dm_task *dmt = NULL; /* @stats_print task */
|
||||||
|
- const char *resp;
|
||||||
|
-
|
||||||
|
region_id = (all_regions)
|
||||||
|
? dm_stats_get_current_region(dms) : region_id;
|
||||||
|
|
||||||
|
@@ -1967,10 +1998,12 @@ static struct dm_histogram *_alloc_dm_histogram(int nr_bins)
|
||||||
|
struct dm_histogram *dm_histogram_bounds_from_string(const char *bounds_str)
|
||||||
|
{
|
||||||
|
static const char *_valid_chars = "0123456789,muns";
|
||||||
|
- struct dm_histogram *dmh;
|
||||||
|
+ uint64_t this_val = 0, mult = 1;
|
||||||
|
+ const char *c, *v, *val_start;
|
||||||
|
struct dm_histogram_bin *cur;
|
||||||
|
- const char *c, *v;
|
||||||
|
+ struct dm_histogram *dmh;
|
||||||
|
int nr_entries = 1;
|
||||||
|
+ char *endptr;
|
||||||
|
|
||||||
|
c = bounds_str;
|
||||||
|
|
||||||
|
@@ -2003,9 +2036,8 @@ struct dm_histogram *dm_histogram_bounds_from_string(const char *bounds_str)
|
||||||
|
bounds_str);
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
- const char *val_start = c;
|
||||||
|
- char *endptr = NULL;
|
||||||
|
- uint64_t this_val = 0, mult = 1;
|
||||||
|
+ val_start = c;
|
||||||
|
+ endptr = NULL;
|
||||||
|
|
||||||
|
this_val = strtoull(val_start, &endptr, 10);
|
||||||
|
if (!endptr) {
|
||||||
|
@@ -2058,10 +2090,10 @@ bad:
|
||||||
|
|
||||||
|
struct dm_histogram *dm_histogram_bounds_from_uint64(const uint64_t *bounds)
|
||||||
|
{
|
||||||
|
- struct dm_histogram *dmh;
|
||||||
|
+ const uint64_t *entry = bounds;
|
||||||
|
struct dm_histogram_bin *cur;
|
||||||
|
+ struct dm_histogram *dmh;
|
||||||
|
int nr_entries = 1;
|
||||||
|
- const uint64_t *entry = bounds;
|
||||||
|
|
||||||
|
if (!bounds || !bounds[0]) {
|
||||||
|
log_error("Could not parse empty histogram bounds array");
|
||||||
|
@@ -2113,6 +2145,7 @@ void dm_histogram_bounds_destroy(struct dm_histogram *bounds)
|
||||||
|
*/
|
||||||
|
static void _scale_bound_value_to_suffix(uint64_t *bound, const char **suffix)
|
||||||
|
{
|
||||||
|
+ *suffix = "ns";
|
||||||
|
if (!(*bound % NSEC_PER_SEC)) {
|
||||||
|
*bound /= NSEC_PER_SEC;
|
||||||
|
*suffix = "s";
|
||||||
|
@@ -2191,12 +2224,14 @@ const char *dm_histogram_to_string(const struct dm_histogram *dmh, int bin,
|
||||||
|
int width, int flags)
|
||||||
|
{
|
||||||
|
int minwidth, bounds, values, start, last;
|
||||||
|
- uint64_t lower, upper; /* bounds of the current bin. */
|
||||||
|
+ uint64_t lower, upper, val_u64; /* bounds of the current bin. */
|
||||||
|
/* Use the histogram pool for string building. */
|
||||||
|
struct dm_pool *mem = dmh->dms->hist_mem;
|
||||||
|
char buf[64], bounds_buf[64];
|
||||||
|
const char *sep = "";
|
||||||
|
+ int bounds_width;
|
||||||
|
ssize_t len = 0;
|
||||||
|
+ float val_flt;
|
||||||
|
|
||||||
|
bounds = flags & DM_HISTOGRAM_BOUNDS_MASK;
|
||||||
|
values = flags & DM_HISTOGRAM_VALUES;
|
||||||
|
@@ -2222,12 +2257,11 @@ const char *dm_histogram_to_string(const struct dm_histogram *dmh, int bin,
|
||||||
|
/* Set bounds string to the empty string. */
|
||||||
|
bounds_buf[0] = '\0';
|
||||||
|
|
||||||
|
- dm_pool_begin_object(mem, 64);
|
||||||
|
+ if (!dm_pool_begin_object(mem, 64))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
for (bin = start; bin <= last; bin++) {
|
||||||
|
if (bounds) {
|
||||||
|
- int bounds_width;
|
||||||
|
-
|
||||||
|
/* Default bounds width depends on time suffixes. */
|
||||||
|
bounds_width = (!(flags & DM_HISTOGRAM_SUFFIX))
|
||||||
|
? BOUND_WIDTH_NOSUFFIX
|
||||||
|
@@ -2260,15 +2294,14 @@ const char *dm_histogram_to_string(const struct dm_histogram *dmh, int bin,
|
||||||
|
|
||||||
|
if (flags & DM_HISTOGRAM_PERCENT) {
|
||||||
|
dm_percent_t pr;
|
||||||
|
- float value;
|
||||||
|
pr = dm_histogram_get_bin_percent(dmh, bin);
|
||||||
|
- value = dm_percent_to_float(pr);
|
||||||
|
+ val_flt = dm_percent_to_float(pr);
|
||||||
|
len = dm_snprintf(buf, sizeof(buf), "%s%*.2f%%%s",
|
||||||
|
- bounds_buf, width, value, sep);
|
||||||
|
+ bounds_buf, width, val_flt, sep);
|
||||||
|
} else if (values) {
|
||||||
|
- uint64_t value = dmh->bins[bin].count;
|
||||||
|
+ val_u64 = dmh->bins[bin].count;
|
||||||
|
len = dm_snprintf(buf, sizeof(buf), "%s%*"PRIu64"%s",
|
||||||
|
- bounds_buf, width, value, sep);
|
||||||
|
+ bounds_buf, width, val_u64, sep);
|
||||||
|
} else if (bounds)
|
||||||
|
len = dm_snprintf(buf, sizeof(buf), "%s%s", bounds_buf,
|
||||||
|
sep);
|
||||||
|
@@ -2277,9 +2310,13 @@ const char *dm_histogram_to_string(const struct dm_histogram *dmh, int bin,
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
width = minwidth; /* re-set histogram column width. */
|
||||||
|
- dm_pool_grow_object(mem, buf, (size_t) len);
|
||||||
|
+ if (!dm_pool_grow_object(mem, buf, (size_t) len))
|
||||||
|
+ goto_bad;
|
||||||
|
}
|
||||||
|
- dm_pool_grow_object(mem, "\0", 1);
|
||||||
|
+
|
||||||
|
+ if (!dm_pool_grow_object(mem, "\0", 1))
|
||||||
|
+ goto_bad;
|
||||||
|
+
|
||||||
|
return (const char *) dm_pool_end_object(mem);
|
||||||
|
|
||||||
|
bad:
|
||||||
|
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
|
||||||
|
index 61ad5a9..8b7ad74 100644
|
||||||
|
--- a/tools/dmsetup.c
|
||||||
|
+++ b/tools/dmsetup.c
|
||||||
|
@@ -4674,6 +4674,7 @@ static int _do_stats_create_regions(struct dm_stats *dms,
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) {
|
||||||
|
+ dm_histogram_bounds_destroy(bounds);
|
||||||
|
dm_stats_destroy(dms);
|
||||||
|
return_0;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
WHATS_NEW_DM | 4 ++++
|
||||||
|
libdm/libdm-deptree.c | 2 +-
|
||||||
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||||
|
index b509d68..9e30786 100644
|
||||||
|
--- a/WHATS_NEW_DM
|
||||||
|
+++ b/WHATS_NEW_DM
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 1.02.108 -
|
||||||
|
+=====================================
|
||||||
|
+ Do not check for full thin pool when activating without messages (1.02.107).
|
||||||
|
+
|
||||||
|
Version 1.02.107 - 5th September 2015
|
||||||
|
=====================================
|
||||||
|
Parse thin-pool status with one single routine internally.
|
||||||
|
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
|
||||||
|
index d40362d..7b7ca5b 100644
|
||||||
|
--- a/libdm/libdm-deptree.c
|
||||||
|
+++ b/libdm/libdm-deptree.c
|
||||||
|
@@ -1633,7 +1633,7 @@ static int _node_send_messages(struct dm_tree_node *dnode,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!send)
|
||||||
|
+ if (!have_messages || !send)
|
||||||
|
return 1; /* transaction_id is matching */
|
||||||
|
|
||||||
|
dm_list_iterate_items(tmsg, &seg->thin_messages) {
|
|
@ -0,0 +1,28 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
lib/cache/lvmetad.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 5de648c..9ddecbc 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.131 -
|
||||||
|
=====================================
|
||||||
|
+ Fix VG metadata comparison failure while scanning the VG for lvmetad.
|
||||||
|
Ignore persistent cache if configuration changed. (2.02.127)
|
||||||
|
|
||||||
|
Version 2.02.130 - 5th September 2015
|
||||||
|
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
|
||||||
|
index b2e2f55..0fff65a 100644
|
||||||
|
--- a/lib/cache/lvmetad.c
|
||||||
|
+++ b/lib/cache/lvmetad.c
|
||||||
|
@@ -1174,7 +1174,7 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
|
||||||
|
if (!vgmeta_ret) {
|
||||||
|
vgmeta_ret = vgmeta;
|
||||||
|
} else {
|
||||||
|
- if (!compare_config(vgmeta_ret->root, vgmeta->root)) {
|
||||||
|
+ if (compare_config(vgmeta_ret->root, vgmeta->root)) {
|
||||||
|
log_error("VG metadata comparison failed");
|
||||||
|
dm_config_destroy(vgmeta);
|
||||||
|
dm_config_destroy(vgmeta_ret);
|
|
@ -0,0 +1,37 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
scripts/vgimportclone.sh | 4 ++--
|
||||||
|
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index f41475c..1718c29 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.131 -
|
||||||
|
=====================================
|
||||||
|
+ Fix vgimportclone cache_dir path name (2.02.115).
|
||||||
|
Disallow usage of --stripe and --stripesize when creating cache pool.
|
||||||
|
Swapping of LV identifiers handles more complex LVs.
|
||||||
|
Fix VG metadata comparison failure while scanning the VG for lvmetad.
|
||||||
|
diff --git a/scripts/vgimportclone.sh b/scripts/vgimportclone.sh
|
||||||
|
index 388d14c..af8cf5c 100755
|
||||||
|
--- a/scripts/vgimportclone.sh
|
||||||
|
+++ b/scripts/vgimportclone.sh
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2009 Chris Procter All rights reserved.
|
||||||
|
-# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
|
||||||
|
+# Copyright (C) 2009-2015 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is part of LVM2.
|
||||||
|
#
|
||||||
|
@@ -239,7 +239,7 @@ LVMCONF=${TMP_LVM_SYSTEM_DIR}/lvm.conf
|
||||||
|
|
||||||
|
CMD_CONFIG_LINE="devices { \
|
||||||
|
scan = [ \"${TMP_LVM_SYSTEM_DIR}\" ] \
|
||||||
|
- cache_dir = \"$TMP_LVM_SYSTEM_DIR}/cache\"
|
||||||
|
+ cache_dir = \"${TMP_LVM_SYSTEM_DIR}/cache\"
|
||||||
|
global_filter = [ \"a|.*|\" ] \
|
||||||
|
${FILTER}
|
||||||
|
} \
|
|
@ -0,0 +1,49 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
tools/lvmcmdline.c | 8 +++++++-
|
||||||
|
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index e74fd55..5de648c 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.131 -
|
||||||
|
+=====================================
|
||||||
|
+ Ignore persistent cache if configuration changed. (2.02.127)
|
||||||
|
+
|
||||||
|
Version 2.02.130 - 5th September 2015
|
||||||
|
=====================================
|
||||||
|
Fix use of uninitialized device status if reading outdated .cache record.
|
||||||
|
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||||
|
index b7809c7..d3bace7 100644
|
||||||
|
--- a/tools/lvmcmdline.c
|
||||||
|
+++ b/tools/lvmcmdline.c
|
||||||
|
@@ -1478,6 +1478,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
char *arg_new, *arg;
|
||||||
|
int i;
|
||||||
|
int skip_hyphens;
|
||||||
|
+ int refresh_done = 0;
|
||||||
|
|
||||||
|
init_error_message_produced(0);
|
||||||
|
|
||||||
|
@@ -1554,6 +1555,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
log_error("Updated config file invalid. Aborting.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
+ refresh_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_prepare_profiles(cmd))
|
||||||
|
@@ -1562,7 +1564,11 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
if (!cmd->initialized.connections && !_cmd_no_meta_proc(cmd) && !init_connections(cmd))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
- if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, 1))
|
||||||
|
+ /* Note: Load persistent cache only if we haven't refreshed toolcontext!
|
||||||
|
+ * If toolcontext has been refreshed, it means config has changed
|
||||||
|
+ * and we can't rely on persistent cache anymore.
|
||||||
|
+ */
|
||||||
|
+ if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, !refresh_done))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (arg_count(cmd, readonly_ARG))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
tools/lvconvert.c | 4 ++--
|
||||||
|
tools/lvconvert_poll.c | 13 +++++++++----
|
||||||
|
3 files changed, 12 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 9ddecbc..5260321 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.131 -
|
||||||
|
=====================================
|
||||||
|
+ Swapping of LV identifiers handles more complex LVs.
|
||||||
|
Fix VG metadata comparison failure while scanning the VG for lvmetad.
|
||||||
|
Ignore persistent cache if configuration changed. (2.02.127)
|
||||||
|
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 2bffb07..919537a 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -2489,14 +2489,14 @@ deactivate_pmslv:
|
||||||
|
if (!detach_pool_metadata_lv(first_seg(pool_lv), &mlv))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ /* Swap _pmspare and _tmeta name */
|
||||||
|
if (!swap_lv_identifiers(cmd, mlv, pmslv))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
- /* Used _pmspare will become _tmeta */
|
||||||
|
if (!attach_pool_metadata_lv(first_seg(pool_lv), pmslv))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
- /* Used _tmeta will become visible _meta%d */
|
||||||
|
+ /* Used _tmeta (now _pmspare) becomes _meta%d */
|
||||||
|
if (!lv_rename_update(cmd, mlv, pms_path, 0))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
diff --git a/tools/lvconvert_poll.c b/tools/lvconvert_poll.c
|
||||||
|
index e3a3709..1b230bc 100644
|
||||||
|
--- a/tools/lvconvert_poll.c
|
||||||
|
+++ b/tools/lvconvert_poll.c
|
||||||
|
@@ -44,15 +44,20 @@ int swap_lv_identifiers(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *a, struct logical_volume *b)
|
||||||
|
{
|
||||||
|
union lvid lvid;
|
||||||
|
- const char *name;
|
||||||
|
+ const char *aname = a->name, *bname = b->name;
|
||||||
|
|
||||||
|
lvid = a->lvid;
|
||||||
|
a->lvid = b->lvid;
|
||||||
|
b->lvid = lvid;
|
||||||
|
|
||||||
|
- name = a->name;
|
||||||
|
- a->name = b->name;
|
||||||
|
- if (!lv_rename_update(cmd, b, name, 0))
|
||||||
|
+ /* rename temporarily to 'unused' name */
|
||||||
|
+ if (!lv_rename_update(cmd, a, "pmove_tmeta", 0))
|
||||||
|
+ return_0;
|
||||||
|
+ /* name rename 'b' to unused name of 'a' */
|
||||||
|
+ if (!lv_rename_update(cmd, b, aname, 0))
|
||||||
|
+ return_0;
|
||||||
|
+ /* finish name swapping */
|
||||||
|
+ if (!lv_rename_update(cmd, a, bname, 0))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
return 1;
|
|
@ -0,0 +1,51 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
lib/metadata/lv_manip.c | 23 ++++++++++++++++++-----
|
||||||
|
2 files changed, 22 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 1718c29..0fa6bb6 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.133 -
|
||||||
|
+======================================
|
||||||
|
+ Check for enough space in thin-pool in command before creating new thin.
|
||||||
|
+
|
||||||
|
Version 2.02.131 -
|
||||||
|
=====================================
|
||||||
|
Fix vgimportclone cache_dir path name (2.02.115).
|
||||||
|
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||||
|
index 88c516b..32aa666 100644
|
||||||
|
--- a/lib/metadata/lv_manip.c
|
||||||
|
+++ b/lib/metadata/lv_manip.c
|
||||||
|
@@ -7038,12 +7038,25 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (seg_is_thin_volume(lp) &&
|
||||||
|
- lv_is_new_thin_pool(pool_lv)) {
|
||||||
|
+ if (seg_is_thin_volume(lp)) {
|
||||||
|
thin_pool_was_active = lv_is_active(pool_lv);
|
||||||
|
- if (!check_new_thin_pool(pool_lv))
|
||||||
|
- return_NULL;
|
||||||
|
- /* New pool is now inactive */
|
||||||
|
+ if (lv_is_new_thin_pool(pool_lv)) {
|
||||||
|
+ if (!check_new_thin_pool(pool_lv))
|
||||||
|
+ return_NULL;
|
||||||
|
+ /* New pool is now inactive */
|
||||||
|
+ } else {
|
||||||
|
+ if (!activate_lv_excl_local(cmd, pool_lv)) {
|
||||||
|
+ log_error("Aborting. Failed to locally activate thin pool %s.",
|
||||||
|
+ display_lvname(pool_lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (!pool_below_threshold(first_seg(pool_lv))) {
|
||||||
|
+ log_error("Cannot create new thin volume, free space in "
|
||||||
|
+ "thin pool %s reached threshold.",
|
||||||
|
+ display_lvname(pool_lv));
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seg_is_cache(lp) &&
|
|
@ -0,0 +1,30 @@
|
||||||
|
WHATS_NEW_DM | 4 ++++
|
||||||
|
libdm/libdm-deptree.c | 3 ++-
|
||||||
|
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||||
|
index 9e30786..71b25ba 100644
|
||||||
|
--- a/WHATS_NEW_DM
|
||||||
|
+++ b/WHATS_NEW_DM
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 1.02.110 -
|
||||||
|
+======================================
|
||||||
|
+ Enforce writethrough mode for cleaner policy.
|
||||||
|
+
|
||||||
|
Version 1.02.108 -
|
||||||
|
=====================================
|
||||||
|
Do not check for full thin pool when activating without messages (1.02.107).
|
||||||
|
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
|
||||||
|
index 7b7ca5b..fc79e33 100644
|
||||||
|
--- a/libdm/libdm-deptree.c
|
||||||
|
+++ b/libdm/libdm-deptree.c
|
||||||
|
@@ -3456,7 +3456,8 @@ int dm_tree_node_add_cache_target(struct dm_tree_node *node,
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
seg->data_block_size = data_block_size;
|
||||||
|
- seg->flags = feature_flags;
|
||||||
|
+ /* Enforce WriteThough mode for cleaner policy */
|
||||||
|
+ seg->flags = (strcmp(policy_name, "cleaner") == 0) ? DM_CACHE_FEATURE_WRITETHROUGH : feature_flags;
|
||||||
|
seg->policy_name = policy_name;
|
||||||
|
|
||||||
|
/* FIXME: better validation missing */
|
|
@ -0,0 +1,204 @@
|
||||||
|
commit 8aa13d867d8c707450bb1de1479e18a3bbbc324a
|
||||||
|
Author: Peter Rajnoha <prajnoha@redhat.com>
|
||||||
|
Date: Tue Dec 1 13:10:31 2015 +0100
|
||||||
|
|
||||||
|
bz1274676
|
||||||
|
---
|
||||||
|
lib/activate/dev_manager.c | 11 ++++--
|
||||||
|
libdm/.exported_symbols.Base | 1 -
|
||||||
|
libdm/.exported_symbols.DM_1_02_107 | 1 +
|
||||||
|
libdm/libdevmapper.h | 5 +++
|
||||||
|
libdm/libdm-deptree.c | 25 ++++++++++++--
|
||||||
|
test/shell/lvextend-thin-bz1274676.sh | 63 +++++++++++++++++++++++++++++++++++
|
||||||
|
6 files changed, 100 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
||||||
|
index c8e9589..e1f547f 100644
|
||||||
|
--- a/lib/activate/dev_manager.c
|
||||||
|
+++ b/lib/activate/dev_manager.c
|
||||||
|
@@ -3277,7 +3277,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
break;
|
||||||
|
case SUSPEND:
|
||||||
|
dm_tree_skip_lockfs(root);
|
||||||
|
- if (!dm->flush_required && lv_is_mirror(lv) && !lv_is_pvmove(lv))
|
||||||
|
+ if (!dm->flush_required && !lv_is_pvmove(lv))
|
||||||
|
dm_tree_use_no_flush_suspend(root);
|
||||||
|
/* Fall through */
|
||||||
|
case SUSPEND_WITH_LOCKFS:
|
||||||
|
@@ -3296,7 +3296,14 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
if (!dm_tree_preload_children(root, dlid, DLID_SIZE))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
- if (dm_tree_node_size_changed(root))
|
||||||
|
+ if ((dm_tree_node_size_changed(root) < 0))
|
||||||
|
+ dm->flush_required = 1;
|
||||||
|
+
|
||||||
|
+ /* Currently keep the code require flush for any
|
||||||
|
+ * non 'thin pool/volume, mirror' or with any size change */
|
||||||
|
+ if (!lv_is_thin_volume(lv) &&
|
||||||
|
+ !lv_is_thin_pool(lv) &&
|
||||||
|
+ (!lv_is_mirror(lv) || dm_tree_node_size_changed(root)))
|
||||||
|
dm->flush_required = 1;
|
||||||
|
|
||||||
|
if (action == ACTIVATE) {
|
||||||
|
diff --git a/libdm/.exported_symbols.Base b/libdm/.exported_symbols.Base
|
||||||
|
index f9c3cb1..27fef53 100644
|
||||||
|
--- a/libdm/.exported_symbols.Base
|
||||||
|
+++ b/libdm/.exported_symbols.Base
|
||||||
|
@@ -262,7 +262,6 @@ dm_tree_node_set_thin_external_origin
|
||||||
|
dm_tree_node_set_thin_pool_discard
|
||||||
|
dm_tree_node_set_thin_pool_error_if_no_space
|
||||||
|
dm_tree_node_set_udev_flags
|
||||||
|
-dm_tree_node_size_changed
|
||||||
|
dm_tree_preload_children
|
||||||
|
dm_tree_retry_remove
|
||||||
|
dm_tree_set_cookie
|
||||||
|
diff --git a/libdm/.exported_symbols.DM_1_02_107 b/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
index 89d3464..0c7b7af 100644
|
||||||
|
--- a/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
+++ b/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
@@ -13,3 +13,4 @@ dm_stats_create_region
|
||||||
|
dm_stats_driver_supports_histogram
|
||||||
|
dm_stats_get_histogram
|
||||||
|
dm_stats_get_region_nr_histogram_bins
|
||||||
|
+dm_tree_node_size_changed
|
||||||
|
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
|
||||||
|
index 098fa85..8d4b096 100644
|
||||||
|
--- a/libdm/libdevmapper.h
|
||||||
|
+++ b/libdm/libdevmapper.h
|
||||||
|
@@ -1252,6 +1252,11 @@ const char *dm_tree_node_get_name(const struct dm_tree_node *node);
|
||||||
|
const char *dm_tree_node_get_uuid(const struct dm_tree_node *node);
|
||||||
|
const struct dm_info *dm_tree_node_get_info(const struct dm_tree_node *node);
|
||||||
|
void *dm_tree_node_get_context(const struct dm_tree_node *node);
|
||||||
|
+/*
|
||||||
|
+ * Returns 0 when node size and its children is unchanged.
|
||||||
|
+ * Returns 1 when node or any of its children has increased size.
|
||||||
|
+ * Rerurns -1 when node or any of its children has reduced size.
|
||||||
|
+ */
|
||||||
|
int dm_tree_node_size_changed(const struct dm_tree_node *dnode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
|
||||||
|
index fc79e33..0584079 100644
|
||||||
|
--- a/libdm/libdm-deptree.c
|
||||||
|
+++ b/libdm/libdm-deptree.c
|
||||||
|
@@ -220,7 +220,7 @@ struct load_properties {
|
||||||
|
uint32_t read_ahead_flags;
|
||||||
|
|
||||||
|
unsigned segment_count;
|
||||||
|
- unsigned size_changed;
|
||||||
|
+ int size_changed;
|
||||||
|
struct dm_list segs;
|
||||||
|
|
||||||
|
const char *new_name;
|
||||||
|
@@ -2768,7 +2768,8 @@ static int _load_node(struct dm_tree_node *dnode)
|
||||||
|
|
||||||
|
existing_table_size = dm_task_get_existing_table_size(dmt);
|
||||||
|
if ((dnode->props.size_changed =
|
||||||
|
- (existing_table_size == seg_start) ? 0 : 1)) {
|
||||||
|
+ (existing_table_size == seg_start) ? 0 :
|
||||||
|
+ (existing_table_size > seg_start) ? -1 : 1)) {
|
||||||
|
/*
|
||||||
|
* Kernel usually skips size validation on zero-length devices
|
||||||
|
* now so no need to preload them.
|
||||||
|
@@ -2864,8 +2865,10 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Propagate device size change change */
|
||||||
|
- if (child->props.size_changed)
|
||||||
|
+ if (child->props.size_changed > 0 && !dnode->props.size_changed)
|
||||||
|
dnode->props.size_changed = 1;
|
||||||
|
+ else if (child->props.size_changed < 0)
|
||||||
|
+ dnode->props.size_changed = -1;
|
||||||
|
|
||||||
|
/* Resume device immediately if it has parents and its size changed */
|
||||||
|
if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed)
|
||||||
|
@@ -4190,3 +4193,19 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
|
||||||
|
dnode->callback = cb;
|
||||||
|
dnode->callback_data = data;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Backward compatible dm_tree_node_size_changed() implementations.
|
||||||
|
+ *
|
||||||
|
+ * Keep these at the end of the file to avoid adding clutter around the
|
||||||
|
+ * current dm_tree_node_size_changed() version.
|
||||||
|
+ */
|
||||||
|
+#if defined(__GNUC__)
|
||||||
|
+int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode);
|
||||||
|
+DM_EXPORT_SYMBOL_BASE(dm_tree_node_size_changed);
|
||||||
|
+int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode)
|
||||||
|
+{
|
||||||
|
+ /* Base does not make difference between smaller and bigger */
|
||||||
|
+ return dm_tree_node_size_changed(dnode) ? 1 : 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff --git a/test/shell/lvextend-thin-bz1274676.sh b/test/shell/lvextend-thin-bz1274676.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..facace0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/shell/lvextend-thin-bz1274676.sh
|
||||||
|
@@ -0,0 +1,63 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
+
|
||||||
|
+# ensure there is no data loss during thin-pool resize
|
||||||
|
+
|
||||||
|
+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
|
||||||
|
+
|
||||||
|
+. lib/inittest
|
||||||
|
+
|
||||||
|
+test -e LOCAL_LVMPOLLD && skip
|
||||||
|
+
|
||||||
|
+which md5sum || skip
|
||||||
|
+
|
||||||
|
+aux have_thin 1 0 0 || skip
|
||||||
|
+
|
||||||
|
+aux prepare_pvs 2 20
|
||||||
|
+
|
||||||
|
+vgcreate -s 512K $vg $(< DEVICES)
|
||||||
|
+
|
||||||
|
+lvcreate -L1M -V2M -n $lv1 -T $vg/pool
|
||||||
|
+
|
||||||
|
+# just ensure we check what we need to check
|
||||||
|
+check lv_field $vg/pool size "1.00m"
|
||||||
|
+check lv_field $vg/$lv1 size "2.00m"
|
||||||
|
+
|
||||||
|
+# prepare 2097152 file content
|
||||||
|
+seq 0 315465 > 2M
|
||||||
|
+md5sum 2M | cut -f 1 -d ' ' | tee MD5
|
||||||
|
+dd if=2M of="$DM_DEV_DIR/mapper/$vg-$lv1" bs=512K conv=fdatasync 2>&1 >log &
|
||||||
|
+#dd if=2M of="$DM_DEV_DIR/mapper/$vg-$lv1" bs=2M oflag=direct &
|
||||||
|
+
|
||||||
|
+# give it some time to fill thin-volume
|
||||||
|
+# eventually loop to wait for 100% full pool...
|
||||||
|
+sleep .1
|
||||||
|
+lvs -a $vg
|
||||||
|
+
|
||||||
|
+# this must not 'block & wait' on suspending flush
|
||||||
|
+# if it waits on thin-pool's target timeout
|
||||||
|
+# it will harm queued data
|
||||||
|
+lvextend -L+512k $vg/pool
|
||||||
|
+lvextend -L+512k $vg/pool
|
||||||
|
+
|
||||||
|
+# collect 'dd' result
|
||||||
|
+wait
|
||||||
|
+cat log
|
||||||
|
+
|
||||||
|
+lvs -a $vg
|
||||||
|
+
|
||||||
|
+dd if="$DM_DEV_DIR/mapper/$vg-$lv1" of=2M-2 iflag=direct
|
||||||
|
+md5sum 2M-2 | cut -f 1 -d ' ' | tee MD5-2
|
||||||
|
+
|
||||||
|
+# these 2 are supposed to match
|
||||||
|
+diff MD5 MD5-2
|
||||||
|
+
|
||||||
|
+vgremove -f $vg
|
|
@ -0,0 +1,74 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
tools/pvscan.c | 9 +++++++++
|
||||||
|
tools/tools.h | 2 ++
|
||||||
|
tools/vgchange.c | 4 ++--
|
||||||
|
4 files changed, 17 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 945b282..8c87a92 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -2,6 +2,10 @@ Version 2.02.142 -
|
||||||
|
====================================
|
||||||
|
Do not check for suspended devices if scanning for lvmetad update.
|
||||||
|
|
||||||
|
+Version 2.02.140 -
|
||||||
|
+===================================
|
||||||
|
+ Restore background polling processing during auto-activation (2.02.119).
|
||||||
|
+
|
||||||
|
Version 2.02.133 -
|
||||||
|
======================================
|
||||||
|
Check for enough space in thin-pool in command before creating new thin.
|
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
||||||
|
index 3adb91c..b3b5911 100644
|
||||||
|
--- a/tools/pvscan.c
|
||||||
|
+++ b/tools/pvscan.c
|
||||||
|
@@ -154,6 +154,15 @@ static int _auto_activation_handler(struct cmd_context *cmd,
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * After sucessfull activation we need to initialise polling
|
||||||
|
+ * for all activated LVs in a VG. Possible enhancement would
|
||||||
|
+ * be adding --poll y|n cmdline option for pvscan and call
|
||||||
|
+ * init_background_polling routine in autoactivation handler.
|
||||||
|
+ */
|
||||||
|
+ if (!(vgchange_background_polling(vg->cmd, vg)))
|
||||||
|
+ goto_out;
|
||||||
|
+
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
diff --git a/tools/tools.h b/tools/tools.h
|
||||||
|
index 4ed893f..634b101 100644
|
||||||
|
--- a/tools/tools.h
|
||||||
|
+++ b/tools/tools.h
|
||||||
|
@@ -183,4 +183,6 @@ int mirror_remove_missing(struct cmd_context *cmd,
|
||||||
|
int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
activation_change_t activate);
|
||||||
|
|
||||||
|
+int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg);
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
||||||
|
index 1d3c64a..d572220 100644
|
||||||
|
--- a/tools/vgchange.c
|
||||||
|
+++ b/tools/vgchange.c
|
||||||
|
@@ -174,7 +174,7 @@ static int _vgchange_monitoring(struct cmd_context *cmd, struct volume_group *vg
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int _vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg)
|
||||||
|
+int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg)
|
||||||
|
{
|
||||||
|
int polled;
|
||||||
|
|
||||||
|
@@ -999,7 +999,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||||
|
|
||||||
|
if (!arg_count(cmd, refresh_ARG) &&
|
||||||
|
background_polling())
|
||||||
|
- if (!_vgchange_background_polling(cmd, vg))
|
||||||
|
+ if (!vgchange_background_polling(cmd, vg))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (arg_is_set(cmd, lockstart_ARG)) {
|
|
@ -0,0 +1,37 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
lib/filters/filter-usable.c | 9 +--------
|
||||||
|
2 files changed, 5 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 0fa6bb6..945b282 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.142 -
|
||||||
|
+====================================
|
||||||
|
+ Do not check for suspended devices if scanning for lvmetad update.
|
||||||
|
+
|
||||||
|
Version 2.02.133 -
|
||||||
|
======================================
|
||||||
|
Check for enough space in thin-pool in command before creating new thin.
|
||||||
|
diff --git a/lib/filters/filter-usable.c b/lib/filters/filter-usable.c
|
||||||
|
index 9377661..b24a30c 100644
|
||||||
|
--- a/lib/filters/filter-usable.c
|
||||||
|
+++ b/lib/filters/filter-usable.c
|
||||||
|
@@ -126,15 +126,8 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
|
||||||
|
break;
|
||||||
|
case FILTER_MODE_PRE_LVMETAD:
|
||||||
|
ucp.check_empty = 1;
|
||||||
|
- /*
|
||||||
|
- * If we're scanning for lvmetad update,
|
||||||
|
- * we don't want to hang on blocked/suspended devices.
|
||||||
|
- * When the device is unblocked/resumed, surely,
|
||||||
|
- * there's going to be a CHANGE event so the device
|
||||||
|
- * gets scanned via udev rule anyway after resume.
|
||||||
|
- */
|
||||||
|
ucp.check_blocked = 1;
|
||||||
|
- ucp.check_suspended = 1;
|
||||||
|
+ ucp.check_suspended = 0;
|
||||||
|
ucp.check_error_target = 1;
|
||||||
|
ucp.check_reserved = 1;
|
||||||
|
break;
|
|
@ -0,0 +1,77 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
lib/activate/activate.c | 10 ++++++++++
|
||||||
|
lib/activate/dev_manager.c | 13 +++++++------
|
||||||
|
3 files changed, 21 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 8c87a92..6441cc1 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.155 -
|
||||||
|
+====================================
|
||||||
|
+ Fix flushing for mirror target.
|
||||||
|
+
|
||||||
|
Version 2.02.142 -
|
||||||
|
====================================
|
||||||
|
Do not check for suspended devices if scanning for lvmetad update.
|
||||||
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
|
||||||
|
index 7d2adf1..8b0fcb3 100644
|
||||||
|
--- a/lib/activate/activate.c
|
||||||
|
+++ b/lib/activate/activate.c
|
||||||
|
@@ -1900,6 +1900,16 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Flush is ATM required for the tested cases
|
||||||
|
+ * NOTE: Mirror repair requires noflush for proper repair!
|
||||||
|
+ * TODO: Relax this limiting condition further */
|
||||||
|
+ if (!flush_required &&
|
||||||
|
+ (lv_is_pvmove(ondisk_lv) ||
|
||||||
|
+ (!lv_is_mirror(ondisk_lv) && !lv_is_thin_pool(ondisk_lv) && !lv_is_thin_volume(ondisk_lv)))) {
|
||||||
|
+ log_debug("Requiring flush for LV %s.", display_lvname(ondisk_lv));
|
||||||
|
+ flush_required = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!monitor_dev_for_events(cmd, ondisk_lv, laopts, 0))
|
||||||
|
/* FIXME Consider aborting here */
|
||||||
|
stack;
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
|
||||||
|
index e1f547f..c95dfbe 100644
|
||||||
|
--- a/lib/activate/dev_manager.c
|
||||||
|
+++ b/lib/activate/dev_manager.c
|
||||||
|
@@ -3277,7 +3277,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
break;
|
||||||
|
case SUSPEND:
|
||||||
|
dm_tree_skip_lockfs(root);
|
||||||
|
- if (!dm->flush_required && !lv_is_pvmove(lv))
|
||||||
|
+ if (!dm->flush_required)
|
||||||
|
dm_tree_use_no_flush_suspend(root);
|
||||||
|
/* Fall through */
|
||||||
|
case SUSPEND_WITH_LOCKFS:
|
||||||
|
@@ -3298,12 +3298,11 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
|
||||||
|
if ((dm_tree_node_size_changed(root) < 0))
|
||||||
|
dm->flush_required = 1;
|
||||||
|
-
|
||||||
|
/* Currently keep the code require flush for any
|
||||||
|
- * non 'thin pool/volume, mirror' or with any size change */
|
||||||
|
- if (!lv_is_thin_volume(lv) &&
|
||||||
|
- !lv_is_thin_pool(lv) &&
|
||||||
|
- (!lv_is_mirror(lv) || dm_tree_node_size_changed(root)))
|
||||||
|
+ * non 'thin pool/volume' and size increase */
|
||||||
|
+ else if (!lv_is_thin_volume(lv) &&
|
||||||
|
+ !lv_is_thin_pool(lv) &&
|
||||||
|
+ dm_tree_node_size_changed(root))
|
||||||
|
dm->flush_required = 1;
|
||||||
|
|
||||||
|
if (action == ACTIVATE) {
|
||||||
|
@@ -3347,6 +3346,8 @@ int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv
|
||||||
|
int dev_manager_preload(struct dev_manager *dm, const struct logical_volume *lv,
|
||||||
|
struct lv_activate_opts *laopts, int *flush_required)
|
||||||
|
{
|
||||||
|
+ dm->flush_required = *flush_required;
|
||||||
|
+
|
||||||
|
if (!_tree_action(dm, lv, laopts, PRELOAD))
|
||||||
|
return_0;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
lib/metadata/raid_manip.c | 5 +++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 977e578..5cbf4ec 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.167 -
|
||||||
|
+======================================
|
||||||
|
+ Disable lvconvert of thin pool to raid while active.
|
||||||
|
+
|
||||||
|
Version 2.02.166 - 26th September 2016
|
||||||
|
======================================
|
||||||
|
Fix lvm2-activation-generator to read all LVM2 config sources. (2.02.155)
|
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
|
||||||
|
index e5fdf4f..5fc520e 100644
|
||||||
|
--- a/lib/metadata/raid_manip.c
|
||||||
|
+++ b/lib/metadata/raid_manip.c
|
||||||
|
@@ -776,6 +776,11 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (lv_is_active(lv_lock_holder(lv)) && (old_count == 1) && (lv_is_thin_pool_data(lv) || lv_is_thin_pool_metadata(lv))) {
|
||||||
|
+ log_error("Can't add image to active thin pool LV %s yet. Deactivate first.", display_lvname(lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!archive(lv->vg))
|
||||||
|
return_0;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
@@ -, +, @@
|
||||||
|
convert internal LV"
|
||||||
|
---
|
||||||
|
tools/lvconvert.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ a/tools/lvconvert.c
|
||||||
|
@@ -243,6 +243,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
|
||||||
|
!strstr(lp->lv_name, "_tmeta") &&
|
||||||
|
!strstr(lp->lv_name, "_cdata") &&
|
||||||
|
!strstr(lp->lv_name, "_cmeta") &&
|
||||||
|
+ !strstr(lp->lv_name, "_corig") &&
|
||||||
|
!apply_lvname_restrictions(lp->lv_name))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
@@ -4440,7 +4441,8 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
|
!lv_is_thin_pool_metadata(lv) &&
|
||||||
|
!lv_is_thin_pool_data(lv) &&
|
||||||
|
!lv_is_used_cache_pool(lv) &&
|
||||||
|
- !lv_is_raid_image(lv)) {
|
||||||
|
+ !lv_is_raid_image(lv) &&
|
||||||
|
+ !(lv_is_raid(lv) && strstr(lv->name, "_corig"))) {
|
||||||
|
log_error("Cannot convert internal LV %s.", display_lvname(lv));
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
--
|
||||||
|
|
|
@ -0,0 +1,532 @@
|
||||||
|
WHATS_NEW | 2 +
|
||||||
|
lib/metadata/raid_manip.c | 277 +++++++++++++++++++++++++++++++---
|
||||||
|
test/shell/lvconvert-raid-takeover.sh | 53 ++++++-
|
||||||
|
tools/lvconvert.c | 24 +--
|
||||||
|
4 files changed, 314 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 5cbf4ec..6a0c311 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,7 @@
|
||||||
|
Version 2.02.167 -
|
||||||
|
======================================
|
||||||
|
+ Add direct striped -> raid4 conversion
|
||||||
|
+ Fix raid4 parity image pair position on conversions from striped/raid0*
|
||||||
|
Disable lvconvert of thin pool to raid while active.
|
||||||
|
|
||||||
|
Version 2.02.166 - 26th September 2016
|
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
|
||||||
|
index 5fc520e..e5fd195 100644
|
||||||
|
--- a/lib/metadata/raid_manip.c
|
||||||
|
+++ b/lib/metadata/raid_manip.c
|
||||||
|
@@ -2459,7 +2459,7 @@ static struct lv_segment *_convert_striped_to_raid0(struct logical_volume *lv,
|
||||||
|
0 /* chunk_size */,
|
||||||
|
0 /* seg->region_size */, 0u /* extents_copied */ ,
|
||||||
|
NULL /* pvmove_source_seg */))) {
|
||||||
|
- log_error("Failed to allocate new raid0 segement for LV %s.", display_lvname(lv));
|
||||||
|
+ log_error("Failed to allocate new raid0 segment for LV %s.", display_lvname(lv));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2519,42 +2519,51 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
|
||||||
|
{ .current_types = SEG_STRIPED_TARGET, /* linear, i.e. seg->area_count = 1 */
|
||||||
|
.possible_types = SEG_RAID1,
|
||||||
|
.current_areas = 1,
|
||||||
|
- .options = ALLOW_NONE },
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
{ .current_types = SEG_STRIPED_TARGET, /* linear, i.e. seg->area_count = 1 */
|
||||||
|
.possible_types = SEG_RAID0|SEG_RAID0_META,
|
||||||
|
.current_areas = 1,
|
||||||
|
.options = ALLOW_STRIPE_SIZE },
|
||||||
|
- { .current_types = SEG_STRIPED_TARGET, /* striped, i.e. seg->area_count > 1 */
|
||||||
|
+ { .current_types = SEG_STRIPED_TARGET, /* striped -> raid0*, i.e. seg->area_count > 1 */
|
||||||
|
.possible_types = SEG_RAID0|SEG_RAID0_META,
|
||||||
|
.current_areas = ~0U,
|
||||||
|
.options = ALLOW_NONE },
|
||||||
|
+ { .current_types = SEG_STRIPED_TARGET, /* striped -> raid4 , i.e. seg->area_count > 1 */
|
||||||
|
+ .possible_types = SEG_RAID4,
|
||||||
|
+ .current_areas = ~0U,
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
/* raid0* -> */
|
||||||
|
{ .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count = 1 */
|
||||||
|
.possible_types = SEG_RAID1,
|
||||||
|
.current_areas = 1,
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
+ { .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> striped, i.e. seg->area_count > 1 */
|
||||||
|
+ .possible_types = SEG_STRIPED_TARGET,
|
||||||
|
+ .current_areas = ~0U,
|
||||||
|
.options = ALLOW_NONE },
|
||||||
|
- { .current_types = SEG_RAID0|SEG_RAID0_META, /* seg->area_count > 1 */
|
||||||
|
- .possible_types = SEG_RAID4,
|
||||||
|
+ { .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> raid0*, i.e. seg->area_count > 1 */
|
||||||
|
+ .possible_types = SEG_RAID0_META|SEG_RAID0,
|
||||||
|
.current_areas = ~0U,
|
||||||
|
.options = ALLOW_NONE },
|
||||||
|
- { .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0 striped, i.e. seg->area_count > 0 */
|
||||||
|
+ { .current_types = SEG_RAID0|SEG_RAID0_META, /* raid0* -> raid4, i.e. seg->area_count > 1 */
|
||||||
|
+ .possible_types = SEG_RAID4,
|
||||||
|
+ .current_areas = ~0U,
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
+ /* raid4 -> -> */
|
||||||
|
+ { .current_types = SEG_RAID4, /* raid4 ->striped/raid0*, i.e. seg->area_count > 1 */
|
||||||
|
.possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
|
||||||
|
.current_areas = ~0U,
|
||||||
|
.options = ALLOW_NONE },
|
||||||
|
- /* raid1 -> */
|
||||||
|
+ /* raid1 -> mirror */
|
||||||
|
{ .current_types = SEG_RAID1,
|
||||||
|
- .possible_types = SEG_RAID1|SEG_MIRROR,
|
||||||
|
+ .possible_types = SEG_MIRROR,
|
||||||
|
.current_areas = ~0U,
|
||||||
|
- .options = ALLOW_NONE },
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
/* mirror -> raid1 with arbitrary number of legs */
|
||||||
|
{ .current_types = SEG_MIRROR,
|
||||||
|
- .possible_types = SEG_MIRROR|SEG_RAID1,
|
||||||
|
- .current_areas = ~0U,
|
||||||
|
- .options = ALLOW_NONE },
|
||||||
|
- { .current_types = SEG_RAID4,
|
||||||
|
- .possible_types = SEG_STRIPED_TARGET|SEG_RAID0|SEG_RAID0_META,
|
||||||
|
+ .possible_types = SEG_RAID1,
|
||||||
|
.current_areas = ~0U,
|
||||||
|
- .options = ALLOW_NONE },
|
||||||
|
+ .options = ALLOW_NONE }, /* FIXME: ALLOW_REGION_SIZE */
|
||||||
|
|
||||||
|
/* END */
|
||||||
|
{ .current_types = 0 }
|
||||||
|
@@ -2861,9 +2870,176 @@ static int _raid1_to_mirrored_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
allocate_pvs, 1, &removal_lvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * HM Helper: (raid0_meta -> raid4)
|
||||||
|
+ *
|
||||||
|
+ * To convert raid0_meta to raid4, which involves shifting the
|
||||||
|
+ * parity device to lv segment area 0 and thus changing MD
|
||||||
|
+ * array roles, detach the MetaLVs and reload as raid0 in
|
||||||
|
+ * order to wipe them then reattach and set back to raid0_meta.
|
||||||
|
+ */
|
||||||
|
+static int _clear_meta_lvs(struct logical_volume *lv)
|
||||||
|
+{
|
||||||
|
+ uint32_t s;
|
||||||
|
+ struct lv_segment *seg = first_seg(lv);
|
||||||
|
+ struct lv_segment_area *tmp_areas;
|
||||||
|
+ const struct segment_type *tmp_segtype;
|
||||||
|
+ struct dm_list meta_lvs;
|
||||||
|
+ struct lv_list *lvl_array, *lvl;
|
||||||
|
+
|
||||||
|
+ /* Reject non-raid0_meta segment types cautiously */
|
||||||
|
+ if (!seg_is_raid0_meta(seg) ||
|
||||||
|
+ !seg->meta_areas)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (!(lvl_array = dm_pool_alloc(lv->vg->vgmem, seg->area_count * sizeof(*lvl_array))))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ dm_list_init(&meta_lvs);
|
||||||
|
+ tmp_areas = seg->meta_areas;
|
||||||
|
+
|
||||||
|
+ /* Extract all MetaLVs listing them on @meta_lvs */
|
||||||
|
+ log_debug_metadata("Extracting all MetaLVs of %s to activate as raid0",
|
||||||
|
+ display_lvname(lv));
|
||||||
|
+ if (!_extract_image_component_sublist(seg, RAID_META, 0, seg->area_count, &meta_lvs, 0))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ /* Memorize meta areas and segtype to set again after initializing. */
|
||||||
|
+ seg->meta_areas = NULL;
|
||||||
|
+ tmp_segtype = seg->segtype;
|
||||||
|
+
|
||||||
|
+ if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0)) ||
|
||||||
|
+ !lv_update_and_reload(lv))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Now deactivate the MetaLVs before clearing, so
|
||||||
|
+ * that _clear_lvs() will activate them visible.
|
||||||
|
+ */
|
||||||
|
+ log_debug_metadata("Deactivating pulled out MetaLVs of %s before initializing.",
|
||||||
|
+ display_lvname(lv));
|
||||||
|
+ dm_list_iterate_items(lvl, &meta_lvs)
|
||||||
|
+ if (!deactivate_lv(lv->vg->cmd, lvl->lv))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ log_debug_metadata("Clearing allocated raid0_meta metadata LVs for conversion to raid4");
|
||||||
|
+ if (!_clear_lvs(&meta_lvs)) {
|
||||||
|
+ log_error("Failed to initialize metadata LVs");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Set memorized meta areas and raid0_meta segtype */
|
||||||
|
+ seg->meta_areas = tmp_areas;
|
||||||
|
+ seg->segtype = tmp_segtype;
|
||||||
|
+
|
||||||
|
+ log_debug_metadata("Adding metadata LVs back into %s", display_lvname(lv));
|
||||||
|
+ s = 0;
|
||||||
|
+ dm_list_iterate_items(lvl, &meta_lvs) {
|
||||||
|
+ lv_set_hidden(lvl->lv);
|
||||||
|
+ if (!set_lv_segment_area_lv(seg, s++, lvl->lv, 0, RAID_META))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * HM Helper: (raid0* <-> raid4)
|
||||||
|
+ *
|
||||||
|
+ * Rename SubLVs (pairs) allowing to shift names w/o collisions with active ones.
|
||||||
|
+ */
|
||||||
|
+#define SLV_COUNT 2
|
||||||
|
+static int _rename_area_lvs(struct logical_volume *lv, const char *suffix)
|
||||||
|
+{
|
||||||
|
+ uint32_t s;
|
||||||
|
+ size_t sz = strlen("rimage") + (suffix ? strlen(suffix) : 0) + 1;
|
||||||
|
+ char *sfx[SLV_COUNT] = { NULL, NULL };
|
||||||
|
+ struct lv_segment *seg = first_seg(lv);
|
||||||
|
+
|
||||||
|
+ /* Create _generate_raid_name() suffixes w/ or w/o passed in @suffix */
|
||||||
|
+ for (s = 0; s < SLV_COUNT; s++)
|
||||||
|
+ if (!(sfx[s] = dm_pool_alloc(lv->vg->cmd->mem, sz)) ||
|
||||||
|
+ dm_snprintf(sfx[s], sz, suffix ? "%s%s" : "%s", s ? "rmeta" : "rimage", suffix) < 0)
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ /* Change names (temporarily) to be able to shift numerical name suffixes */
|
||||||
|
+ for (s = 0; s < seg->area_count; s++) {
|
||||||
|
+ if (!(seg_lv(seg, s)->name = _generate_raid_name(lv, sfx[0], s)))
|
||||||
|
+ return_0;
|
||||||
|
+ if (seg->meta_areas &&
|
||||||
|
+ !(seg_metalv(seg, s)->name = _generate_raid_name(lv, sfx[1], s)))
|
||||||
|
+ return_0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (s = 0; s < SLV_COUNT; s++)
|
||||||
|
+ dm_pool_free(lv->vg->cmd->mem, sfx[s]);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * HM Helper: (raid0* <-> raid4)
|
||||||
|
+ *
|
||||||
|
+ * Switch area LVs in lv segment @seg indexed by @s1 and @s2
|
||||||
|
+ */
|
||||||
|
+static void _switch_area_lvs(struct lv_segment *seg, uint32_t s1, uint32_t s2)
|
||||||
|
+{
|
||||||
|
+ struct logical_volume *lvt;
|
||||||
|
+
|
||||||
|
+ lvt = seg_lv(seg, s1);
|
||||||
|
+ seg_lv(seg, s1) = seg_lv(seg, s2);
|
||||||
|
+ seg_lv(seg, s2) = lvt;
|
||||||
|
+
|
||||||
|
+ /* Be cautious */
|
||||||
|
+ if (seg->meta_areas) {
|
||||||
|
+ lvt = seg_metalv(seg, s1);
|
||||||
|
+ seg_metalv(seg, s1) = seg_metalv(seg, s2);
|
||||||
|
+ seg_metalv(seg, s2) = lvt;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * HM Helper:
|
||||||
|
+ *
|
||||||
|
+ * shift range of area LVs in @seg in range [ @s1, @s2 ] up if @s1 < @s2,
|
||||||
|
+ * else down bubbling the parity SubLVs up/down whilst shifting.
|
||||||
|
+ */
|
||||||
|
+static void _shift_area_lvs(struct lv_segment *seg, uint32_t s1, uint32_t s2)
|
||||||
|
+{
|
||||||
|
+ uint32_t s;
|
||||||
|
+
|
||||||
|
+ if (s1 < s2)
|
||||||
|
+ /* Forward shift n+1 -> n */
|
||||||
|
+ for (s = s1; s < s2; s++)
|
||||||
|
+ _switch_area_lvs(seg, s, s + 1);
|
||||||
|
+ else
|
||||||
|
+ /* Reverse shift n-1 -> n */
|
||||||
|
+ for (s = s1; s > s2; s--)
|
||||||
|
+ _switch_area_lvs(seg, s, s - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Switch position of first and last area lv within
|
||||||
|
+ * @lv to move parity SubLVs from end to end.
|
||||||
|
+ *
|
||||||
|
+ * Direction depends on segment type raid4 / raid0_meta.
|
||||||
|
+ */
|
||||||
|
+static int _shift_parity_dev(struct lv_segment *seg)
|
||||||
|
+{
|
||||||
|
+ if (seg_is_raid0_meta(seg))
|
||||||
|
+ _shift_area_lvs(seg, seg->area_count - 1, 0);
|
||||||
|
+ else if (seg_is_raid4(seg))
|
||||||
|
+ _shift_area_lvs(seg, 0, seg->area_count - 1);
|
||||||
|
+ else
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* raid45 -> raid0* / striped */
|
||||||
|
static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
{
|
||||||
|
+ int rename_sublvs = 0;
|
||||||
|
struct lv_segment *seg = first_seg(lv);
|
||||||
|
struct dm_list removal_lvs;
|
||||||
|
|
||||||
|
@@ -2879,10 +3055,39 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
if (!_raid_in_sync(lv))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ if (!yes && yes_no_prompt("Are you sure you want to convert \"%s\" LV %s to \"%s\" "
|
||||||
|
+ "type using all resilience? [y/n]: ",
|
||||||
|
+ lvseg_name(seg), display_lvname(lv), new_segtype->name) == 'n') {
|
||||||
|
+ log_error("Logical volume %s NOT converted to \"%s\"",
|
||||||
|
+ display_lvname(lv), new_segtype->name);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (sigint_caught())
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
/* Archive metadata */
|
||||||
|
if (!archive(lv->vg))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * raid4 (which actually gets mapped to raid5/dedicated first parity disk)
|
||||||
|
+ * needs shifting of SubLVs to move the parity SubLV pair in the first area
|
||||||
|
+ * to the last one before conversion to raid0[_meta]/striped to allow for
|
||||||
|
+ * SubLV removal from the end of the areas arrays.
|
||||||
|
+ */
|
||||||
|
+ if (seg_is_raid4(seg)) {
|
||||||
|
+ /* Shift parity SubLV pair "PDD..." -> "DD...P" to be able to remove it off the end */
|
||||||
|
+ if (!_shift_parity_dev(seg))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (segtype_is_any_raid0(new_segtype) &&
|
||||||
|
+ !(rename_sublvs = _rename_area_lvs(lv, "_"))) {
|
||||||
|
+ log_error("Failed to rename %s LV %s MetaLVs", lvseg_name(seg), display_lvname(lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Remove meta and data LVs requested */
|
||||||
|
if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs, 0, 0))
|
||||||
|
return 0;
|
||||||
|
@@ -2902,7 +3107,19 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
|
||||||
|
seg->region_size = 0;
|
||||||
|
|
||||||
|
- return _lv_update_reload_fns_reset_eliminate_lvs(lv, &removal_lvs);
|
||||||
|
+ if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, &removal_lvs))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (rename_sublvs) {
|
||||||
|
+ if (!_rename_area_lvs(lv, NULL)) {
|
||||||
|
+ log_error("Failed to rename %s LV %s MetaLVs", lvseg_name(seg), display_lvname(lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (!lv_update_and_reload(lv))
|
||||||
|
+ return_0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _striped_to_raid0_wrapper(struct logical_volume *lv,
|
||||||
|
@@ -2930,6 +3147,9 @@ static int _striped_to_raid0_wrapper(struct logical_volume *lv,
|
||||||
|
static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
{
|
||||||
|
struct lv_segment *seg = first_seg(lv);
|
||||||
|
+ struct dm_list removal_lvs;
|
||||||
|
+
|
||||||
|
+ dm_list_init(&removal_lvs);
|
||||||
|
|
||||||
|
if (seg_is_raid10(seg))
|
||||||
|
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
|
||||||
|
@@ -2944,6 +3164,13 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* FIXME: restricted to raid4 for the time being... */
|
||||||
|
+ if (!segtype_is_raid4(new_segtype)) {
|
||||||
|
+ /* Can't convert striped/raid0* to e.g. raid10_offset */
|
||||||
|
+ log_error("Can't convert %s to %s", display_lvname(lv), new_segtype->name);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Archive metadata */
|
||||||
|
if (!archive(lv->vg))
|
||||||
|
return_0;
|
||||||
|
@@ -2961,7 +3188,10 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
log_debug_metadata("Adding metadata LVs to %s", display_lvname(lv));
|
||||||
|
if (!_raid0_add_or_remove_metadata_lvs(lv, 1 /* update_and_reload */, allocate_pvs, NULL))
|
||||||
|
return 0;
|
||||||
|
- }
|
||||||
|
+ /* raid0_meta -> raid4 needs clearing of MetaLVs in order to avoid raid disk role cahnge issues in the kernel */
|
||||||
|
+ } else if (segtype_is_raid4(new_segtype) &&
|
||||||
|
+ !_clear_meta_lvs(lv))
|
||||||
|
+ return 0;
|
||||||
|
|
||||||
|
/* Add the additional component LV pairs */
|
||||||
|
log_debug_metadata("Adding %" PRIu32 " component LV pair(s) to %s", new_image_count - lv_raid_image_count(lv),
|
||||||
|
@@ -2969,8 +3199,9 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, NULL, 0, 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!segtype_is_raid4(new_segtype)) {
|
||||||
|
- /* Can't convert striped/raid0* to e.g. raid10_offset */
|
||||||
|
+ if (segtype_is_raid4(new_segtype) &&
|
||||||
|
+ (!_shift_parity_dev(seg) ||
|
||||||
|
+ !_rename_area_lvs(lv, "_"))) {
|
||||||
|
log_error("Can't convert %s to %s", display_lvname(lv), new_segtype->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2987,6 +3218,14 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
|
||||||
|
if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, NULL))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
+ if (segtype_is_raid4(new_segtype)) {
|
||||||
|
+ /* We had to rename SubLVs because of collision free sgifting, rename back... */
|
||||||
|
+ if (!_rename_area_lvs(lv, NULL))
|
||||||
|
+ return 0;
|
||||||
|
+ if (!lv_update_and_reload(lv))
|
||||||
|
+ return_0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/test/shell/lvconvert-raid-takeover.sh b/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
index 19a65d3..0140e22 100644
|
||||||
|
--- a/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
+++ b/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
@@ -78,22 +78,58 @@ aux wait_for_sync $vg $lv1
|
||||||
|
# Clean up
|
||||||
|
lvremove --yes $vg/$lv1
|
||||||
|
|
||||||
|
-# Create 3-way raid0
|
||||||
|
-lvcreate -y -aey --type raid0 -i 3 -L 64M -n $lv1 $vg
|
||||||
|
-check lv_field $vg/$lv1 segtype "raid0"
|
||||||
|
+# Create 3-way striped
|
||||||
|
+lvcreate -y -aey --type striped -i 3 -L 64M -n $lv1 $vg
|
||||||
|
+check lv_field $vg/$lv1 segtype "striped"
|
||||||
|
check lv_field $vg/$lv1 stripes 3
|
||||||
|
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv1
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
|
||||||
|
-# Convert raid0 -> raid4
|
||||||
|
+# Create 3-way raid0
|
||||||
|
+lvcreate -y -aey --type raid0 -i 3 -L 64M -n $lv2 $vg
|
||||||
|
+check lv_field $vg/$lv2 segtype "raid0"
|
||||||
|
+check lv_field $vg/$lv2 stripes 3
|
||||||
|
+echo y | mkfs -t ext4 /dev/mapper/$vg-$lv2
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv2
|
||||||
|
+
|
||||||
|
+# Create 3-way raid0_meta
|
||||||
|
+lvcreate -y -aey --type raid0_meta -i 3 -L 64M -n $lv3 $vg
|
||||||
|
+check lv_field $vg/$lv3 segtype "raid0_meta"
|
||||||
|
+check lv_field $vg/$lv3 stripes 3
|
||||||
|
+echo y | mkfs -t ext4 /dev/mapper/$vg-$lv3
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv3
|
||||||
|
+
|
||||||
|
+# Create 3-way raid4
|
||||||
|
+lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
|
||||||
|
+check lv_field $vg/$lv4 segtype "raid4"
|
||||||
|
+check lv_field $vg/$lv4 stripes 4
|
||||||
|
+echo y | mkfs -t ext4 /dev/mapper/$vg-$lv4
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv4
|
||||||
|
+aux wait_for_sync $vg $lv4
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv4
|
||||||
|
+
|
||||||
|
+# Convert raid4 -> striped (correct raid4 mapping test!)
|
||||||
|
+lvconvert -y --ty striped $vg/$lv4
|
||||||
|
+check lv_field $vg/$lv4 segtype "striped"
|
||||||
|
+check lv_field $vg/$lv4 stripes 3
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv4
|
||||||
|
+
|
||||||
|
+# Convert striped -> raid4
|
||||||
|
lvconvert -y --ty raid4 $vg/$lv1
|
||||||
|
-lvchange --refresh $vg/$lv1
|
||||||
|
check lv_field $vg/$lv1 segtype "raid4"
|
||||||
|
check lv_field $vg/$lv1 stripes 4
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
aux wait_for_sync $vg $lv1
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
|
||||||
|
+# Convert raid0 -> raid4
|
||||||
|
+lvconvert -y --ty raid4 $vg/$lv2
|
||||||
|
+check lv_field $vg/$lv2 segtype "raid4"
|
||||||
|
+check lv_field $vg/$lv2 stripes 4
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv2
|
||||||
|
+aux wait_for_sync $vg $lv2
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv2
|
||||||
|
+
|
||||||
|
# Convert raid4 -> raid0_meta
|
||||||
|
lvconvert -y --ty raid0_meta $vg/$lv1
|
||||||
|
check lv_field $vg/$lv1 segtype "raid0_meta"
|
||||||
|
@@ -116,11 +152,16 @@ fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
|
||||||
|
# Convert raid0 -> raid4
|
||||||
|
lvconvert -y --ty raid4 $vg/$lv1
|
||||||
|
-lvchange --refresh $vg/$lv1
|
||||||
|
check lv_field $vg/$lv1 segtype "raid4"
|
||||||
|
check lv_field $vg/$lv1 stripes 4
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
aux wait_for_sync $vg $lv1
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
|
||||||
|
+# Convert raid4 -> striped
|
||||||
|
+lvconvert -y --ty striped $vg/$lv1
|
||||||
|
+check lv_field $vg/$lv1 segtype "striped"
|
||||||
|
+check lv_field $vg/$lv1 stripes 3
|
||||||
|
+fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
+
|
||||||
|
vgremove -ff $vg
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 0d2a4d1..541df72 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -1931,7 +1931,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
goto try_new_takeover_or_reshape;
|
||||||
|
- } else if (!lp->repair && !lp->replace && (!*lp->type_str || seg->segtype == lp->segtype)) {
|
||||||
|
+ } else if (!lp->repair && !lp->replace && !*lp->type_str) {
|
||||||
|
log_error("Conversion operation not yet supported.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2017,28 +2017,18 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
try_new_takeover_or_reshape:
|
||||||
|
-
|
||||||
|
/* FIXME This needs changing globally. */
|
||||||
|
if (!arg_is_set(cmd, stripes_long_ARG))
|
||||||
|
lp->stripes = 0;
|
||||||
|
|
||||||
|
- /* Only let raid4 through for now. */
|
||||||
|
- if (lp->type_str && lp->type_str[0] && lp->segtype != seg->segtype &&
|
||||||
|
- ((seg_is_raid4(seg) && seg_is_striped(lp) && lp->stripes > 1) ||
|
||||||
|
- (seg_is_striped(seg) && seg->area_count > 1 && seg_is_raid4(lp)))) {
|
||||||
|
- if (!lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, lp->stripes, lp->stripe_size_supplied, lp->stripe_size,
|
||||||
|
- lp->region_size, lp->pvh))
|
||||||
|
- return_0;
|
||||||
|
-
|
||||||
|
- log_print_unless_silent("Logical volume %s successfully converted.",
|
||||||
|
- display_lvname(lv));
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
+ if (!lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, lp->stripes, lp->stripe_size_supplied, lp->stripe_size,
|
||||||
|
+ lp->region_size, lp->pvh))
|
||||||
|
+ return_0;
|
||||||
|
|
||||||
|
- log_error("Conversion operation not yet supported.");
|
||||||
|
- return 0;
|
||||||
|
+ log_print_unless_silent("Logical volume %s successfully converted.",
|
||||||
|
+ display_lvname(lv));
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volume *cow,
|
|
@ -0,0 +1,303 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
lib/activate/activate.c | 25 +++++++++++++++++++++++++
|
||||||
|
lib/activate/activate.h | 3 ++-
|
||||||
|
lib/metadata/lv.c | 16 +++++++++++++++-
|
||||||
|
lib/metadata/segtype.h | 3 ++-
|
||||||
|
lib/raid/raid.c | 10 ++++++++--
|
||||||
|
test/shell/lvconvert-raid-takeover.sh | 13 +++++++++++++
|
||||||
|
tools/lvconvert.c | 26 ++++++++++++++++++++++++++
|
||||||
|
tools/lvcreate.c | 6 ++++++
|
||||||
|
9 files changed, 98 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 6a0c311..519bbc9 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.167 -
|
||||||
|
======================================
|
||||||
|
+ Prevent raid4 creation/conversion on non-supporting kernels
|
||||||
|
Add direct striped -> raid4 conversion
|
||||||
|
Fix raid4 parity image pair position on conversions from striped/raid0*
|
||||||
|
Disable lvconvert of thin pool to raid while active.
|
||||||
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
|
||||||
|
index 5550955..571f2b2 100644
|
||||||
|
--- a/lib/activate/activate.c
|
||||||
|
+++ b/lib/activate/activate.c
|
||||||
|
@@ -370,6 +370,11 @@ void activation_exit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
+int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype)
|
||||||
|
+{
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int lv_is_active(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
@@ -1489,6 +1494,26 @@ out:
|
||||||
|
return r || l;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Check if "raid4" @segtype is supported by kernel.
|
||||||
|
+ *
|
||||||
|
+ * if segment type is not raid4, return 1.
|
||||||
|
+ */
|
||||||
|
+int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype)
|
||||||
|
+{
|
||||||
|
+ unsigned attrs;
|
||||||
|
+
|
||||||
|
+ if (segtype_is_raid4(segtype) &&
|
||||||
|
+ (!segtype->ops->target_present ||
|
||||||
|
+ !segtype->ops->target_present(cmd, NULL, &attrs) ||
|
||||||
|
+ !(attrs & RAID_FEATURE_RAID4))) {
|
||||||
|
+ log_error("RAID module does not support RAID4.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int lv_is_active(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return _lv_is_active(lv, NULL, NULL, NULL);
|
||||||
|
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
|
||||||
|
index 1e8d7a8..3922d78 100644
|
||||||
|
--- a/lib/activate/activate.h
|
||||||
|
+++ b/lib/activate/activate.h
|
||||||
|
@@ -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-2016 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -99,6 +99,7 @@ int target_present(struct cmd_context *cmd, const char *target_name,
|
||||||
|
int use_modprobe);
|
||||||
|
int target_version(const char *target_name, uint32_t *maj,
|
||||||
|
uint32_t *min, uint32_t *patchlevel);
|
||||||
|
+int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype);
|
||||||
|
int lvm_dm_prefix_check(int major, int minor, const char *prefix);
|
||||||
|
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||||
|
struct dm_list *modules);
|
||||||
|
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
|
||||||
|
index 53a1044..0f1b6e7 100644
|
||||||
|
--- a/lib/metadata/lv.c
|
||||||
|
+++ b/lib/metadata/lv.c
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
- * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -1425,6 +1425,7 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
|
enum activation_change activate, int needs_exclusive)
|
||||||
|
{
|
||||||
|
const char *ay_with_mode = NULL;
|
||||||
|
+ struct lv_segment *seg = first_seg(lv);
|
||||||
|
|
||||||
|
if (activate == CHANGE_ASY)
|
||||||
|
ay_with_mode = "sh";
|
||||||
|
@@ -1461,6 +1462,9 @@ deactivate:
|
||||||
|
break;
|
||||||
|
case CHANGE_ALY:
|
||||||
|
case CHANGE_AAY:
|
||||||
|
+ if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
+ goto no_raid4;
|
||||||
|
+
|
||||||
|
if (needs_exclusive || _lv_is_exclusive(lv)) {
|
||||||
|
log_verbose("Activating logical volume %s exclusively locally.",
|
||||||
|
display_lvname(lv));
|
||||||
|
@@ -1475,6 +1479,9 @@ deactivate:
|
||||||
|
break;
|
||||||
|
case CHANGE_AEY:
|
||||||
|
exclusive:
|
||||||
|
+ if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
+ goto no_raid4;
|
||||||
|
+
|
||||||
|
log_verbose("Activating logical volume %s exclusively.",
|
||||||
|
display_lvname(lv));
|
||||||
|
if (!activate_lv_excl(cmd, lv))
|
||||||
|
@@ -1483,6 +1490,9 @@ exclusive:
|
||||||
|
case CHANGE_ASY:
|
||||||
|
case CHANGE_AY:
|
||||||
|
default:
|
||||||
|
+ if (!raid4_is_supported(cmd, seg->segtype))
|
||||||
|
+ goto no_raid4;
|
||||||
|
+
|
||||||
|
if (needs_exclusive || _lv_is_exclusive(lv))
|
||||||
|
goto exclusive;
|
||||||
|
log_verbose("Activating logical volume %s.", display_lvname(lv));
|
||||||
|
@@ -1495,6 +1505,10 @@ exclusive:
|
||||||
|
log_error("Failed to unlock logical volume %s.", display_lvname(lv));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
+
|
||||||
|
+no_raid4:
|
||||||
|
+ log_error("Failed to activate %s LV %s", lvseg_name(seg), display_lvname(lv));
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
|
||||||
|
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
|
||||||
|
index 9ca740d..292b8b6 100644
|
||||||
|
--- a/lib/metadata/segtype.h
|
||||||
|
+++ b/lib/metadata/segtype.h
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
|
- * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -268,6 +268,7 @@ struct segment_type *init_unknown_segtype(struct cmd_context *cmd,
|
||||||
|
#define RAID_FEATURE_RAID10 (1U << 0) /* version 1.3 */
|
||||||
|
#define RAID_FEATURE_RAID0 (1U << 1) /* version 1.7 */
|
||||||
|
#define RAID_FEATURE_RESHAPING (1U << 2) /* version 1.8 */
|
||||||
|
+#define RAID_FEATURE_RAID4 (1U << 3) /* ! version 1.8 or 1.9.0 */
|
||||||
|
|
||||||
|
#ifdef RAID_INTERNAL
|
||||||
|
int init_raid_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||||
|
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
|
||||||
|
index 3bc3c75..92a96a3 100644
|
||||||
|
--- a/lib/raid/raid.c
|
||||||
|
+++ b/lib/raid/raid.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2011-2016 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -366,7 +366,7 @@ static int _raid_target_present(struct cmd_context *cmd,
|
||||||
|
|
||||||
|
static int _raid_checked = 0;
|
||||||
|
static int _raid_present = 0;
|
||||||
|
- static int _raid_attrs = 0;
|
||||||
|
+ static unsigned _raid_attrs = 0;
|
||||||
|
uint32_t maj, min, patchlevel;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
@@ -389,6 +389,12 @@ static int _raid_target_present(struct cmd_context *cmd,
|
||||||
|
else
|
||||||
|
log_very_verbose("Target raid does not support %s.",
|
||||||
|
_features[i].feature);
|
||||||
|
+
|
||||||
|
+ if (!(maj == 1 && (min == 8 || (min == 9 && patchlevel == 0))))
|
||||||
|
+ _raid_attrs |= RAID_FEATURE_RAID4;
|
||||||
|
+ else
|
||||||
|
+ log_very_verbose("Target raid does not support %s.",
|
||||||
|
+ SEG_TYPE_NAME_RAID4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes)
|
||||||
|
diff --git a/test/shell/lvconvert-raid-takeover.sh b/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
index 0140e22..332786d 100644
|
||||||
|
--- a/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
+++ b/test/shell/lvconvert-raid-takeover.sh
|
||||||
|
@@ -16,6 +16,8 @@ SKIP_WITH_LVMPOLLD=1
|
||||||
|
|
||||||
|
aux have_raid 1 9 0 || skip
|
||||||
|
|
||||||
|
+[ `aux have_raid 1.9.1` ] && correct_raid4_layout=1
|
||||||
|
+
|
||||||
|
aux prepare_vg 9 288
|
||||||
|
|
||||||
|
# Delay 1st leg so that rebuilding status characters
|
||||||
|
@@ -99,6 +101,9 @@ check lv_field $vg/$lv3 stripes 3
|
||||||
|
echo y | mkfs -t ext4 /dev/mapper/$vg-$lv3
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv3
|
||||||
|
|
||||||
|
+if [ $correct_raid4_layout -eq 1 ]
|
||||||
|
+then
|
||||||
|
+
|
||||||
|
# Create 3-way raid4
|
||||||
|
lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
|
||||||
|
check lv_field $vg/$lv4 segtype "raid4"
|
||||||
|
@@ -164,4 +169,12 @@ check lv_field $vg/$lv1 segtype "striped"
|
||||||
|
check lv_field $vg/$lv1 stripes 3
|
||||||
|
fsck -fn /dev/mapper/$vg-$lv1
|
||||||
|
|
||||||
|
+else
|
||||||
|
+
|
||||||
|
+not lvcreate -y -aey --type raid4 -i 3 -L 64M -n $lv4 $vg
|
||||||
|
+not lvconvert -y --ty raid4 $vg/$lv1
|
||||||
|
+not lvconvert -y --ty raid4 $vg/$lv2
|
||||||
|
+
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
vgremove -ff $vg
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 541df72..7a4215a 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -1821,6 +1821,25 @@ static void _lvconvert_raid_repair_ask(struct cmd_context *cmd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Check for dm-raid target supporting raid4 conversion properly. */
|
||||||
|
+static int _raid4_conversion_supported(struct logical_volume *lv, struct lvconvert_params *lp)
|
||||||
|
+{
|
||||||
|
+ int ret = 1;
|
||||||
|
+ struct lv_segment *seg = first_seg(lv);
|
||||||
|
+
|
||||||
|
+ if (seg_is_raid4(seg))
|
||||||
|
+ ret = raid4_is_supported(lv->vg->cmd, seg->segtype);
|
||||||
|
+ else if (segtype_is_raid4(lp->segtype))
|
||||||
|
+ ret = raid4_is_supported(lv->vg->cmd, lp->segtype);
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ log_error("Cannot convert %s LV %s to %s.",
|
||||||
|
+ lvseg_name(seg), display_lvname(lv), lp->segtype->name);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp)
|
||||||
|
{
|
||||||
|
int replace = 0, image_count = 0;
|
||||||
|
@@ -1945,6 +1964,9 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!_raid4_conversion_supported(lv, lp))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
if (!arg_is_set(cmd, stripes_long_ARG))
|
||||||
|
lp->stripes = 0;
|
||||||
|
|
||||||
|
@@ -2018,6 +2040,10 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
}
|
||||||
|
|
||||||
|
try_new_takeover_or_reshape:
|
||||||
|
+
|
||||||
|
+ if (!_raid4_conversion_supported(lv, lp))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
/* FIXME This needs changing globally. */
|
||||||
|
if (!arg_is_set(cmd, stripes_long_ARG))
|
||||||
|
lp->stripes = 0;
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index 387c8d4..dbc0708 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -1054,6 +1054,12 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (segtype_is_raid4(lp->segtype) &&
|
||||||
|
+ !(lp->target_attr & RAID_FEATURE_RAID4)) {
|
||||||
|
+ log_error("RAID module does not support RAID4.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (segtype_is_raid10(lp->segtype) && !(lp->target_attr & RAID_FEATURE_RAID10)) {
|
||||||
|
log_error("RAID module does not support RAID10.");
|
||||||
|
return 0;
|
|
@ -0,0 +1,49 @@
|
||||||
|
From dae4f53acb269219e876c229c8f034fcdaf3ff5a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Sat, 4 Feb 2017 14:47:27 +0100
|
||||||
|
Subject: [PATCH] clvmd: add mutex protection for cpg_ call
|
||||||
|
|
||||||
|
The library for corosync multicasting is not supporting multithread
|
||||||
|
usage - add local mutex to avoid parallel call of cpg_mcast_joined().
|
||||||
|
---
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
daemons/clvmd/clvmd-corosync.c | 4 ++++
|
||||||
|
2 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 8ae2df8..0b571ae 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.169 -
|
||||||
|
=====================================
|
||||||
|
+ Avoid parallel usage of cpg_mcast_joined() in clvmd with corosync.
|
||||||
|
Fix segfault in lvmetad from missing NULL in daemon_reply_simple.
|
||||||
|
|
||||||
|
Version 2.02.167 -
|
||||||
|
diff --git a/daemons/clvmd/clvmd-corosync.c b/daemons/clvmd/clvmd-corosync.c
|
||||||
|
index 05c9882..2227cbf 100644
|
||||||
|
--- a/daemons/clvmd/clvmd-corosync.c
|
||||||
|
+++ b/daemons/clvmd/clvmd-corosync.c
|
||||||
|
@@ -532,6 +532,7 @@ static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
|
||||||
|
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
|
||||||
|
const char *errtext)
|
||||||
|
{
|
||||||
|
+ static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
struct iovec iov[2];
|
||||||
|
cs_error_t err;
|
||||||
|
int target_node;
|
||||||
|
@@ -546,7 +547,10 @@ static int _cluster_send_message(const void *buf, int msglen, const char *csid,
|
||||||
|
iov[1].iov_base = (char *)buf;
|
||||||
|
iov[1].iov_len = msglen;
|
||||||
|
|
||||||
|
+ pthread_mutex_lock(&_mutex);
|
||||||
|
err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
|
||||||
|
+ pthread_mutex_unlock(&_mutex);
|
||||||
|
+
|
||||||
|
return cs_to_errno(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
WHATS_NEW | 4 ++++
|
||||||
|
daemons/lvmetad/lvmetad-core.c | 9 ++++++---
|
||||||
|
2 files changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 519bbc9..8ae2df8 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+Version 2.02.169 -
|
||||||
|
+=====================================
|
||||||
|
+ Fix segfault in lvmetad from missing NULL in daemon_reply_simple.
|
||||||
|
+
|
||||||
|
Version 2.02.167 -
|
||||||
|
======================================
|
||||||
|
Prevent raid4 creation/conversion on non-supporting kernels
|
||||||
|
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
|
||||||
|
index 36a5cec..c46c7ac 100644
|
||||||
|
--- a/daemons/lvmetad/lvmetad-core.c
|
||||||
|
+++ b/daemons/lvmetad/lvmetad-core.c
|
||||||
|
@@ -2745,7 +2745,8 @@ static response handler(daemon_state s, client_handle h, request r)
|
||||||
|
"expected = %s", state->token,
|
||||||
|
"received = %s", token,
|
||||||
|
"update_pid = " FMTd64, (int64_t)state->update_pid,
|
||||||
|
- "reason = %s", "another command has populated the cache");
|
||||||
|
+ "reason = %s", "another command has populated the cache",
|
||||||
|
+ NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGLOG(state, "token_update end len %d pid %d new token %s",
|
||||||
|
@@ -2778,7 +2779,8 @@ static response handler(daemon_state s, client_handle h, request r)
|
||||||
|
"expected = %s", state->token,
|
||||||
|
"received = %s", token,
|
||||||
|
"update_pid = " FMTd64, (int64_t)state->update_pid,
|
||||||
|
- "reason = %s", "another command has populated the cache");
|
||||||
|
+ "reason = %s", "another command has populated the cache",
|
||||||
|
+ NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a pid doing update was cancelled, ignore its update messages. */
|
||||||
|
@@ -2793,7 +2795,8 @@ static response handler(daemon_state s, client_handle h, request r)
|
||||||
|
"expected = %s", state->token,
|
||||||
|
"received = %s", token,
|
||||||
|
"update_pid = " FMTd64, (int64_t)state->update_pid,
|
||||||
|
- "reason = %s", "another command has populated the lvmetad cache");
|
||||||
|
+ "reason = %s", "another command has populated the lvmetad cache",
|
||||||
|
+ NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&state->token_lock);
|
|
@ -0,0 +1,34 @@
|
||||||
|
WHATS_NEW | 1 +
|
||||||
|
tools/lvcreate.c | 4 +++-
|
||||||
|
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 0b571ae..26aa5b0 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
Version 2.02.169 -
|
||||||
|
=====================================
|
||||||
|
+ Fix limit of stripes in lvcreate.
|
||||||
|
Avoid parallel usage of cpg_mcast_joined() in clvmd with corosync.
|
||||||
|
Fix segfault in lvmetad from missing NULL in daemon_reply_simple.
|
||||||
|
|
||||||
|
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
|
||||||
|
index dbc0708..dae9da6 100644
|
||||||
|
--- a/tools/lvcreate.c
|
||||||
|
+++ b/tools/lvcreate.c
|
||||||
|
@@ -559,8 +559,10 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
|
||||||
|
else if (seg_is_any_raid6(lp))
|
||||||
|
max_images -= 2;
|
||||||
|
}
|
||||||
|
- } else
|
||||||
|
+ } else if (seg_is_mirrored(lp))
|
||||||
|
max_images = DEFAULT_MIRROR_MAX_IMAGES;
|
||||||
|
+ else
|
||||||
|
+ max_images = MAX_STRIPES;
|
||||||
|
|
||||||
|
/* Common mirror and raid params */
|
||||||
|
if (arg_is_set(cmd, mirrors_ARG)) {
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
conf/example.conf.in | 2 +-
|
||||||
|
lib/config/defaults.h | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/conf/example.conf.in b/conf/example.conf.in
|
||||||
|
index b1a2a9c..8e68165 100644
|
||||||
|
--- a/conf/example.conf.in
|
||||||
|
+++ b/conf/example.conf.in
|
||||||
|
@@ -311,7 +311,7 @@ devices {
|
||||||
|
# or activating LVs in it while a PV appears on multiple devices.
|
||||||
|
# Enabling this setting allows the VG to be used as usual even with
|
||||||
|
# uncertain devices.
|
||||||
|
- allow_changes_with_duplicate_pvs = 0
|
||||||
|
+ allow_changes_with_duplicate_pvs = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuration section allocation.
|
||||||
|
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
|
||||||
|
index d988779..985c832 100644
|
||||||
|
--- a/lib/config/defaults.h
|
||||||
|
+++ b/lib/config/defaults.h
|
||||||
|
@@ -45,7 +45,7 @@
|
||||||
|
#define DEFAULT_DATA_ALIGNMENT_DETECTION 1
|
||||||
|
#define DEFAULT_ISSUE_DISCARDS 0
|
||||||
|
#define DEFAULT_PV_MIN_SIZE_KB 2048
|
||||||
|
-#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 0
|
||||||
|
+#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 1
|
||||||
|
|
||||||
|
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
|
||||||
|
#define DEFAULT_ERROR_WHEN_FULL 0
|
|
@ -0,0 +1,104 @@
|
||||||
|
configure | 20 ++++++++++----------
|
||||||
|
configure.in | 4 ++--
|
||||||
|
lib/device/dev-type.c | 3 +--
|
||||||
|
3 files changed, 13 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 8253bfc..587b978 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -11951,12 +11951,12 @@ if test -n "$BLKID_CFLAGS"; then
|
||||||
|
pkg_cv_BLKID_CFLAGS="$BLKID_CFLAGS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
|
||||||
|
- ($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
|
||||||
|
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.23\""; } >&5
|
||||||
|
+ ($PKG_CONFIG --exists --print-errors "blkid >= 2.23") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
- pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.24" 2>/dev/null`
|
||||||
|
+ pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.23" 2>/dev/null`
|
||||||
|
test "x$?" != "x0" && pkg_failed=yes
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
@@ -11968,12 +11968,12 @@ if test -n "$BLKID_LIBS"; then
|
||||||
|
pkg_cv_BLKID_LIBS="$BLKID_LIBS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
|
||||||
|
- ($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
|
||||||
|
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.23\""; } >&5
|
||||||
|
+ ($PKG_CONFIG --exists --print-errors "blkid >= 2.23") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
- pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.24" 2>/dev/null`
|
||||||
|
+ pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.23" 2>/dev/null`
|
||||||
|
test "x$?" != "x0" && pkg_failed=yes
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
@@ -11994,9 +11994,9 @@ else
|
||||||
|
_pkg_short_errors_supported=no
|
||||||
|
fi
|
||||||
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
|
- BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
|
||||||
|
+ BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.23" 2>&1`
|
||||||
|
else
|
||||||
|
- BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
|
||||||
|
+ BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.23" 2>&1`
|
||||||
|
fi
|
||||||
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
echo "$BLKID_PKG_ERRORS" >&5
|
||||||
|
@@ -12004,7 +12004,7 @@ fi
|
||||||
|
if test "$BLKID_WIPING" = maybe; then
|
||||||
|
BLKID_WIPING=no
|
||||||
|
else
|
||||||
|
- as_fn_error $? "bailing out... blkid library >= 2.24 is required" "$LINENO" 5
|
||||||
|
+ as_fn_error $? "bailing out... blkid library >= 2.23 is required" "$LINENO" 5
|
||||||
|
fi
|
||||||
|
elif test $pkg_failed = untried; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
@@ -12012,7 +12012,7 @@ $as_echo "no" >&6; }
|
||||||
|
if test "$BLKID_WIPING" = maybe; then
|
||||||
|
BLKID_WIPING=no
|
||||||
|
else
|
||||||
|
- as_fn_error $? "bailing out... blkid library >= 2.24 is required" "$LINENO" 5
|
||||||
|
+ as_fn_error $? "bailing out... blkid library >= 2.23 is required" "$LINENO" 5
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
BLKID_CFLAGS=$pkg_cv_BLKID_CFLAGS
|
||||||
|
diff --git a/configure.in b/configure.in
|
||||||
|
index 33b5c76..9ed6226 100644
|
||||||
|
--- a/configure.in
|
||||||
|
+++ b/configure.in
|
||||||
|
@@ -1302,12 +1302,12 @@ AC_MSG_RESULT($BLKID_WIPING)
|
||||||
|
|
||||||
|
if test "$BLKID_WIPING" != no; then
|
||||||
|
pkg_config_init
|
||||||
|
- PKG_CHECK_MODULES(BLKID, blkid >= 2.24,
|
||||||
|
+ PKG_CHECK_MODULES(BLKID, blkid >= 2.23,
|
||||||
|
[test "$BLKID_WIPING" = maybe && BLKID_WIPING=yes],
|
||||||
|
[if test "$BLKID_WIPING" = maybe; then
|
||||||
|
BLKID_WIPING=no
|
||||||
|
else
|
||||||
|
- AC_MSG_ERROR([bailing out... blkid library >= 2.24 is required])
|
||||||
|
+ AC_MSG_ERROR([bailing out... blkid library >= 2.23 is required])
|
||||||
|
fi])
|
||||||
|
if test "$BLKID_WIPING" = yes; then
|
||||||
|
BLKID_PC="blkid"
|
||||||
|
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
|
||||||
|
index 0246c09..bae984a 100644
|
||||||
|
--- a/lib/device/dev-type.c
|
||||||
|
+++ b/lib/device/dev-type.c
|
||||||
|
@@ -703,8 +703,7 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
|
||||||
|
BLKID_SUBLKS_TYPE |
|
||||||
|
BLKID_SUBLKS_USAGE |
|
||||||
|
BLKID_SUBLKS_VERSION |
|
||||||
|
- BLKID_SUBLKS_MAGIC |
|
||||||
|
- BLKID_SUBLKS_BADCSUM);
|
||||||
|
+ BLKID_SUBLKS_MAGIC);
|
||||||
|
|
||||||
|
while (!blkid_do_probe(probe)) {
|
||||||
|
if ((r_wipe = _blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force)) == 1) {
|
|
@ -0,0 +1,21 @@
|
||||||
|
libdm/.exported_symbols.DM_1_02_107 | 1 +
|
||||||
|
libdm/.exported_symbols.DM_1_02_110 | 1 -
|
||||||
|
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libdm/.exported_symbols.DM_1_02_107 b/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
index 89d3464..0c7b7af 100644
|
||||||
|
--- a/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
+++ b/libdm/.exported_symbols.DM_1_02_107
|
||||||
|
@@ -13,3 +13,4 @@ dm_stats_create_region
|
||||||
|
dm_stats_driver_supports_histogram
|
||||||
|
dm_stats_get_histogram
|
||||||
|
dm_stats_get_region_nr_histogram_bins
|
||||||
|
+dm_tree_node_size_changed
|
||||||
|
diff --git a/libdm/.exported_symbols.DM_1_02_110 b/libdm/.exported_symbols.DM_1_02_110
|
||||||
|
index eba5625..da742ee 100644
|
||||||
|
--- a/libdm/.exported_symbols.DM_1_02_110
|
||||||
|
+++ b/libdm/.exported_symbols.DM_1_02_110
|
||||||
|
@@ -1,3 +1,2 @@
|
||||||
|
dm_report_compact_given_fields
|
||||||
|
dm_hold_control_dev
|
||||||
|
-dm_tree_node_size_changed
|
|
@ -0,0 +1,27 @@
|
||||||
|
commit dc1c96b8bebbd6bfe9b774fdb13f904f976f29bd
|
||||||
|
Author: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu Jul 2 13:45:38 2015 -0500
|
||||||
|
|
||||||
|
lvmlockd: tech preview notice
|
||||||
|
---
|
||||||
|
tools/toollib.c | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||||
|
index 6b8ce22..b8edaea 100644
|
||||||
|
--- a/tools/toollib.c
|
||||||
|
+++ b/tools/toollib.c
|
||||||
|
@@ -981,6 +981,13 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
|
||||||
|
vp_new->clustered = 0;
|
||||||
|
|
||||||
|
log_debug("Setting lock_type to %s", vp_new->lock_type);
|
||||||
|
+
|
||||||
|
+ if (is_lockd_type(vp_new->lock_type)) {
|
||||||
|
+ log_print("WARNING: shared lock type \"%s\" and lvmlockd are Technology Preview.", vp_new->lock_type);
|
||||||
|
+ log_print("For more information on Technology Preview features, visit:");
|
||||||
|
+ log_print("https://access.redhat.com/support/offerings/techpreview/");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
udev/10-dm.rules.in | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
|
||||||
|
index 2755530..8d7a8ca 100644
|
||||||
|
--- a/udev/10-dm.rules.in
|
||||||
|
+++ b/udev/10-dm.rules.in
|
||||||
|
@@ -120,10 +120,6 @@ ENV{DM_UDEV_RULES_VSN}="2"
|
||||||
|
|
||||||
|
ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}"
|
||||||
|
|
||||||
|
-# We have to ignore further rule application for inappropriate events
|
||||||
|
-# and devices. But still send the notification if cookie exists.
|
||||||
|
-ENV{DM_UUID}=="mpath-?*", ENV{DM_ACTION}=="PATH_FAILED", GOTO="dm_disable"
|
||||||
|
-
|
||||||
|
# Avoid processing and scanning a DM device in the other (foreign)
|
||||||
|
# rules if it is in suspended state. However, we still keep 'disk'
|
||||||
|
# and 'DM subsystem' related rules enabled in this case.
|
|
@ -0,0 +1,323 @@
|
||||||
|
WHATS_NEW | 1 -
|
||||||
|
daemons/dmeventd/plugins/raid/dmeventd_raid.c | 42 +++--------
|
||||||
|
lib/metadata/lv.c | 7 ++
|
||||||
|
lib/metadata/raid_manip.c | 2 +-
|
||||||
|
test/shell/lvconvert-repair-raid.sh | 104 ++------------------------
|
||||||
|
tools/lvconvert.c | 19 +++++
|
||||||
|
6 files changed, 41 insertions(+), 134 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||||
|
index 25f6742..977e578 100644
|
||||||
|
--- a/WHATS_NEW
|
||||||
|
+++ b/WHATS_NEW
|
||||||
|
@@ -3,7 +3,6 @@ Version 2.02.166 - 26th September 2016
|
||||||
|
Fix lvm2-activation-generator to read all LVM2 config sources. (2.02.155)
|
||||||
|
Fix lvchange-rebuild-raid.sh to cope with older target versions.
|
||||||
|
Use dm_config_parse_without_dup_node_check() to speedup metadata reading.
|
||||||
|
- Fix lvconvert --repair regression
|
||||||
|
Fix reported origin lv field for cache volumes. (2.02.133)
|
||||||
|
Always specify snapshot cow LV for monitoring not internal LV. (2.02.165)
|
||||||
|
Fix lvchange --discard|--zero for active thin-pool.
|
||||||
|
diff --git a/daemons/dmeventd/plugins/raid/dmeventd_raid.c b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||||
|
index bec594a..770fbc6 100644
|
||||||
|
--- a/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||||
|
+++ b/daemons/dmeventd/plugins/raid/dmeventd_raid.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/*
|
||||||
|
- * Copyright (C) 2005-2016 Red Hat, Inc. All rights reserved.
|
||||||
|
+ * Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of LVM2.
|
||||||
|
*
|
||||||
|
@@ -13,20 +13,14 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
-#include "defaults.h"
|
||||||
|
#include "dmeventd_lvm.h"
|
||||||
|
#include "libdevmapper-event.h"
|
||||||
|
|
||||||
|
-/* Hold enough elements for the mximum number of RAID images */
|
||||||
|
-#define RAID_DEVS_ELEMS ((DEFAULT_RAID_MAX_IMAGES + 63) / 64)
|
||||||
|
-
|
||||||
|
struct dso_state {
|
||||||
|
struct dm_pool *mem;
|
||||||
|
char cmd_lvscan[512];
|
||||||
|
char cmd_lvconvert[512];
|
||||||
|
- uint64_t raid_devs[RAID_DEVS_ELEMS];
|
||||||
|
int failed;
|
||||||
|
- int warned;
|
||||||
|
};
|
||||||
|
|
||||||
|
DM_EVENT_LOG_FN("raid")
|
||||||
|
@@ -37,39 +31,20 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||||
|
{
|
||||||
|
struct dm_status_raid *status;
|
||||||
|
const char *d;
|
||||||
|
- int dead = 0, r = 1;
|
||||||
|
|
||||||
|
if (!dm_get_status_raid(state->mem, params, &status)) {
|
||||||
|
log_error("Failed to process status line for %s.", device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- d = status->dev_health;
|
||||||
|
- while ((d = strchr(d, 'D'))) {
|
||||||
|
- uint32_t dev = (uint32_t)(d - status->dev_health);
|
||||||
|
-
|
||||||
|
- if (!(state->raid_devs[dev / 64] & (1 << (dev % 64))))
|
||||||
|
- log_error("Device #%u of %s array, %s, has failed.",
|
||||||
|
- dev, status->raid_type, device);
|
||||||
|
-
|
||||||
|
- state->raid_devs[dev / 64] |= (1 << (dev % 64));
|
||||||
|
- d++;
|
||||||
|
- dead = 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (dead) {
|
||||||
|
- if (status->insync_regions < status->total_regions) {
|
||||||
|
- if (!state->warned)
|
||||||
|
- log_warn("WARNING: waiting for resynchronization to finish "
|
||||||
|
- "before initiating repair on RAID device %s", device);
|
||||||
|
-
|
||||||
|
- state->warned = 1;
|
||||||
|
- goto out; /* Not yet done syncing with accessible devices */
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ if ((d = strchr(status->dev_health, 'D'))) {
|
||||||
|
if (state->failed)
|
||||||
|
goto out; /* already reported */
|
||||||
|
|
||||||
|
+ log_error("Device #%d of %s array, %s, has failed.",
|
||||||
|
+ (int)(d - status->dev_health),
|
||||||
|
+ status->raid_type, device);
|
||||||
|
+
|
||||||
|
state->failed = 1;
|
||||||
|
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvscan))
|
||||||
|
log_warn("WARNING: Re-scan of RAID device %s failed.", device);
|
||||||
|
@@ -77,7 +52,8 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||||
|
/* if repair goes OK, report success even if lvscan has failed */
|
||||||
|
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
|
||||||
|
log_info("Repair of RAID device %s failed.", device);
|
||||||
|
- r = 0;
|
||||||
|
+ dm_pool_free(state->mem, status);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state->failed = 0;
|
||||||
|
@@ -88,7 +64,7 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||||
|
out:
|
||||||
|
dm_pool_free(state->mem, status);
|
||||||
|
|
||||||
|
- return r;
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_event(struct dm_task *dmt,
|
||||||
|
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
|
||||||
|
index 70036f9..53a1044 100644
|
||||||
|
--- a/lib/metadata/lv.c
|
||||||
|
+++ b/lib/metadata/lv.c
|
||||||
|
@@ -988,6 +988,7 @@ int lv_mirror_image_in_sync(const struct logical_volume *lv)
|
||||||
|
int lv_raid_image_in_sync(const struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
unsigned s;
|
||||||
|
+ dm_percent_t percent;
|
||||||
|
char *raid_health;
|
||||||
|
struct lv_segment *seg, *raid_seg = NULL;
|
||||||
|
|
||||||
|
@@ -1017,6 +1018,12 @@ int lv_raid_image_in_sync(const struct logical_volume *lv)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!lv_raid_percent(raid_seg->lv, &percent))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (percent == DM_PERCENT_100)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
/* Find out which sub-LV this is. */
|
||||||
|
for (s = 0; s < raid_seg->area_count; s++)
|
||||||
|
if (seg_lv(raid_seg, s) == lv)
|
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
|
||||||
|
index deb88a2..e5fdf4f 100644
|
||||||
|
--- a/lib/metadata/raid_manip.c
|
||||||
|
+++ b/lib/metadata/raid_manip.c
|
||||||
|
@@ -3658,7 +3658,7 @@ static int _lv_raid_rebuild_or_replace(struct logical_volume *lv,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!_raid_in_sync(lv)) {
|
||||||
|
+ if (!mirror_in_sync() && !_raid_in_sync(lv)) {
|
||||||
|
log_error("Unable to replace devices in %s/%s while it is"
|
||||||
|
" not in-sync.", lv->vg->name, lv->name);
|
||||||
|
return 0;
|
||||||
|
diff --git a/test/shell/lvconvert-repair-raid.sh b/test/shell/lvconvert-repair-raid.sh
|
||||||
|
index b51d8fe..1ef91c4 100644
|
||||||
|
--- a/test/shell/lvconvert-repair-raid.sh
|
||||||
|
+++ b/test/shell/lvconvert-repair-raid.sh
|
||||||
|
@@ -22,52 +22,11 @@ aux lvmconf 'allocation/maximise_cling = 0' \
|
||||||
|
|
||||||
|
aux prepare_vg 8
|
||||||
|
|
||||||
|
-function delay
|
||||||
|
-{
|
||||||
|
- for d in $(< DEVICES)
|
||||||
|
- do
|
||||||
|
- aux delay_dev "$d" 0 $1 $(get first_extent_sector "$d")
|
||||||
|
- done
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
# It's possible small raid arrays do have problems with reporting in-sync.
|
||||||
|
# So try bigger size
|
||||||
|
-RAID_SIZE=32
|
||||||
|
-
|
||||||
|
-# Fast sync and repair afterwards
|
||||||
|
-delay 0
|
||||||
|
-
|
||||||
|
-# RAID1 dual-leg single replace after initial sync
|
||||||
|
-lvcreate --type raid1 -m 1 -L $RAID_SIZE -n $lv1 $vg "$dev1" "$dev2"
|
||||||
|
-aux wait_for_sync $vg $lv1
|
||||||
|
-aux disable_dev "$dev2"
|
||||||
|
-lvconvert -y --repair $vg/$lv1
|
||||||
|
-vgreduce --removemissing $vg
|
||||||
|
-aux enable_dev "$dev2"
|
||||||
|
-vgextend $vg "$dev2"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
-# Delayed sync to allow for repair during rebuild
|
||||||
|
-delay 50
|
||||||
|
-
|
||||||
|
-# RAID1 triple-leg single replace during initial sync
|
||||||
|
-lvcreate --type raid1 -m 2 -L $RAID_SIZE -n $lv1 $vg "$dev1" "$dev2" "$dev3"
|
||||||
|
-aux disable_dev "$dev2" "$dev3"
|
||||||
|
-not lvconvert -y --repair $vg/$lv1
|
||||||
|
-aux wait_for_sync $vg $lv1
|
||||||
|
-lvconvert -y --repair $vg/$lv1
|
||||||
|
-vgreduce --removemissing $vg
|
||||||
|
-aux enable_dev "$dev2" "$dev3"
|
||||||
|
-vgextend $vg "$dev2" "$dev3"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-# Larger RAID size possible for striped RAID
|
||||||
|
RAID_SIZE=64
|
||||||
|
|
||||||
|
-# Fast sync and repair afterwards
|
||||||
|
-delay 0
|
||||||
|
-# RAID5 single replace after initial sync
|
||||||
|
+# RAID5 single replace
|
||||||
|
lvcreate --type raid5 -i 2 -L $RAID_SIZE -n $lv1 $vg "$dev1" "$dev2" "$dev3"
|
||||||
|
aux wait_for_sync $vg $lv1
|
||||||
|
aux disable_dev "$dev3"
|
||||||
|
@@ -75,69 +34,16 @@ lvconvert -y --repair $vg/$lv1
|
||||||
|
vgreduce --removemissing $vg
|
||||||
|
aux enable_dev "$dev3"
|
||||||
|
vgextend $vg "$dev3"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
+lvremove -ff $vg
|
||||||
|
|
||||||
|
-# Delayed sync to allow for repair during rebuild
|
||||||
|
-delay 50
|
||||||
|
-
|
||||||
|
-# RAID5 single replace during initial sync
|
||||||
|
-lvcreate --type raid5 -i 2 -L $RAID_SIZE -n $lv1 $vg "$dev1" "$dev2" "$dev3"
|
||||||
|
-aux disable_dev "$dev3"
|
||||||
|
-not lvconvert -y --repair $vg/$lv1
|
||||||
|
-aux wait_for_sync $vg $lv1
|
||||||
|
-lvconvert -y --repair $vg/$lv1
|
||||||
|
-vgreduce --removemissing $vg
|
||||||
|
-aux enable_dev "$dev3"
|
||||||
|
-vgextend $vg "$dev3"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
-# Fast sync and repair afterwards
|
||||||
|
-delay 0
|
||||||
|
-
|
||||||
|
-# RAID6 double replace after initial sync
|
||||||
|
+# RAID6 double replace
|
||||||
|
lvcreate --type raid6 -i 3 -L $RAID_SIZE -n $lv1 $vg \
|
||||||
|
"$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
|
||||||
|
aux wait_for_sync $vg $lv1
|
||||||
|
aux disable_dev "$dev4" "$dev5"
|
||||||
|
lvconvert -y --repair $vg/$lv1
|
||||||
|
vgreduce --removemissing $vg
|
||||||
|
-aux enable_dev "$dev4" "$dev5"
|
||||||
|
-vgextend $vg "$dev4" "$dev5"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
-# Delayed sync to allow for repair during rebuild
|
||||||
|
-delay 50
|
||||||
|
-
|
||||||
|
-# RAID6 single replace after initial sync
|
||||||
|
-lvcreate --type raid6 -i 3 -L $RAID_SIZE -n $lv1 $vg \
|
||||||
|
- "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
|
||||||
|
-aux disable_dev "$dev4"
|
||||||
|
-not lvconvert -y --repair $vg/$lv1
|
||||||
|
-delay 0 # Fast sync and repair afterwards
|
||||||
|
-aux disable_dev "$dev4" # Need to disable again after changing delay
|
||||||
|
-aux wait_for_sync $vg $lv1
|
||||||
|
-lvconvert -y --repair $vg/$lv1
|
||||||
|
-vgreduce --removemissing $vg
|
||||||
|
aux enable_dev "$dev4"
|
||||||
|
-vgextend $vg "$dev4"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
-# Delayed sync to allow for repair during rebuild
|
||||||
|
-delay 50
|
||||||
|
-
|
||||||
|
-# RAID10 single replace after initial sync
|
||||||
|
-lvcreate --type raid10 -m 1 -i 2 -L $RAID_SIZE -n $lv1 $vg \
|
||||||
|
- "$dev1" "$dev2" "$dev3" "$dev4"
|
||||||
|
-aux disable_dev "$dev4"
|
||||||
|
-not lvconvert -y --repair $vg/$lv1
|
||||||
|
-delay 0 # Fast sync and repair afterwards
|
||||||
|
-aux disable_dev "$dev4" # Need to disable again after changing delay
|
||||||
|
-aux disable_dev "$dev1"
|
||||||
|
-aux wait_for_sync $vg $lv1
|
||||||
|
-lvconvert -y --repair $vg/$lv1
|
||||||
|
-vgreduce --removemissing $vg
|
||||||
|
-aux enable_dev "$dev4"
|
||||||
|
-vgextend $vg "$dev4"
|
||||||
|
-lvremove -ff $vg/$lv1
|
||||||
|
-
|
||||||
|
+aux enable_dev "$dev5"
|
||||||
|
+vgextend $vg "$dev4" "$dev5"
|
||||||
|
vgremove -ff $vg
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||||
|
index 3607247..d1d21b6 100644
|
||||||
|
--- a/tools/lvconvert.c
|
||||||
|
+++ b/tools/lvconvert.c
|
||||||
|
@@ -1826,6 +1826,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
struct dm_list *failed_pvs;
|
||||||
|
struct cmd_context *cmd = lv->vg->cmd;
|
||||||
|
struct lv_segment *seg = first_seg(lv);
|
||||||
|
+ dm_percent_t sync_percent;
|
||||||
|
|
||||||
|
if (_linear_type_requested(lp->type_str)) {
|
||||||
|
if (arg_is_set(cmd, mirrors_ARG) && (arg_uint_value(cmd, mirrors_ARG, 0) != 0)) {
|
||||||
|
@@ -1973,6 +1974,24 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!lv_raid_percent(lv, &sync_percent)) {
|
||||||
|
+ log_error("Unable to determine sync status of %s.",
|
||||||
|
+ display_lvname(lv));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (sync_percent != DM_PERCENT_100) {
|
||||||
|
+ log_warn("WARNING: %s is not in-sync.", display_lvname(lv));
|
||||||
|
+ log_warn("WARNING: Portions of the array may be unrecoverable.");
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * The kernel will not allow a device to be replaced
|
||||||
|
+ * in an array that is not in-sync unless we override
|
||||||
|
+ * by forcing the array to be considered "in-sync".
|
||||||
|
+ */
|
||||||
|
+ init_mirror_in_sync(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_lvconvert_raid_repair_ask(cmd, lp, &replace);
|
||||||
|
|
||||||
|
if (replace) {
|
|
@ -0,0 +1,18 @@
|
||||||
|
VERSION | 2 +-
|
||||||
|
VERSION_DM | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/VERSION b/VERSION
|
||||||
|
index dd4e60e..39d6c15 100644
|
||||||
|
--- a/VERSION
|
||||||
|
+++ b/VERSION
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-2.02.166(2) (2016-09-26)
|
||||||
|
+2.02.166(2)-RHEL7 (2016-11-16)
|
||||||
|
diff --git a/VERSION_DM b/VERSION_DM
|
||||||
|
index d53f47a..005fbd4 100644
|
||||||
|
--- a/VERSION_DM
|
||||||
|
+++ b/VERSION_DM
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-1.02.135 (2016-09-26)
|
||||||
|
+1.02.135-RHEL7 (2016-11-16)
|
|
@ -0,0 +1,30 @@
|
||||||
|
conf/example.conf.in | 2 +-
|
||||||
|
lib/config/config_settings.h | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/conf/example.conf.in b/conf/example.conf.in
|
||||||
|
index c0afcb7..ec12918 100644
|
||||||
|
--- a/conf/example.conf.in
|
||||||
|
+++ b/conf/example.conf.in
|
||||||
|
@@ -106,7 +106,7 @@ devices {
|
||||||
|
# Example
|
||||||
|
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
|
||||||
|
#
|
||||||
|
- # This configuration option does not have a default value defined.
|
||||||
|
+ preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
|
||||||
|
|
||||||
|
# Configuration option devices/filter.
|
||||||
|
# Limit the block devices that are used by LVM commands.
|
||||||
|
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
|
||||||
|
index 9017043..c06b6f0 100644
|
||||||
|
--- a/lib/config/config_settings.h
|
||||||
|
+++ b/lib/config/config_settings.h
|
||||||
|
@@ -205,7 +205,7 @@ cfg(devices_external_device_info_source_CFG, "external_device_info_source", devi
|
||||||
|
" compiled with udev support.\n"
|
||||||
|
"#\n")
|
||||||
|
|
||||||
|
-cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED , CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL, 0, NULL,
|
||||||
|
+cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#S^/dev/mpath/#S^/dev/mapper/mpath#S^/dev/[hs]d", vsn(1, 2, 19), NULL, 0, NULL,
|
||||||
|
"Select which path name to display for a block device.\n"
|
||||||
|
"If multiple path names exist for a block device, and LVM needs to\n"
|
||||||
|
"display a name for the device, the path names are matched against\n"
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue