Browse Source

lvm2 package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
f30b2134bb
  1. 38
      SOURCES/lvm2-2_02_131-disallow-usage-of-stripe-and-stripesize-when-creating-cache-pool.patch
  2. 521
      SOURCES/lvm2-2_02_131-dmstats-fixups.patch
  3. 29
      SOURCES/lvm2-2_02_131-do-not-check-for-full-thin-pool-when-activating-without-messages.patch
  4. 28
      SOURCES/lvm2-2_02_131-fix-vg-metadata-comparison-failure-while-scanning-the-vg-for-lvmetad.patch
  5. 37
      SOURCES/lvm2-2_02_131-fix-vgimportclone-cache_dir-path-name.patch
  6. 49
      SOURCES/lvm2-2_02_131-ignore-persistent-cache-if-configuration-changed.patch
  7. 2169
      SOURCES/lvm2-2_02_131-standardise-error-paths.patch
  8. 66
      SOURCES/lvm2-2_02_131-swapping-of-lv-identifiers-handles-more-complex-lvs.patch
  9. 51
      SOURCES/lvm2-2_02_133-check-for-space-in-thin-pool-before-creating-new-thin.patch
  10. 30
      SOURCES/lvm2-2_02_133-enforce-writethrough-mode-for-cleaner-policy.patch
  11. 204
      SOURCES/lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch
  12. 74
      SOURCES/lvm2-2_02_140-restore-background-polling-processing-during-auto-activation.patch
  13. 37
      SOURCES/lvm2-2_02_142-do-not-check-for-suspended-devices-if-scanning-for-lvmetad-update.patch
  14. 77
      SOURCES/lvm2-2_02_155-fix-flushing-for-mirror-target.patch
  15. 32
      SOURCES/lvm2-2_02_167-disable-lvconvert-of-thin-pool-to-raid-while-active.patch
  16. 27
      SOURCES/lvm2-2_02_167-fix-inability-of-lvconvert-repair-for-cache-raid-volumes.patch
  17. 532
      SOURCES/lvm2-2_02_167-fix-raid4-coversion-from-striped.patch
  18. 303
      SOURCES/lvm2-2_02_167-prevent-raid4-creation-and-conversion-on-non-supporting-kernels.patch
  19. 49
      SOURCES/lvm2-2_02_169-clvmd-add-mutex-protection-for-cpg_-call.patch
  20. 50
      SOURCES/lvm2-2_02_169-fix-segfault-in-lvmetad-from-missing-null-in-daemon_reply_simple.patch
  21. 34
      SOURCES/lvm2-2_02_169-lvcreate-fix-striped-limit.patch
  22. 30
      SOURCES/lvm2-default-allow-changes-with-duplicate-pvs.patch
  23. 104
      SOURCES/lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch
  24. 21
      SOURCES/lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch
  25. 27
      SOURCES/lvm2-lvmlockd-tech-preview-warning.patch
  26. 18
      SOURCES/lvm2-remove-mpath-device-handling-from-udev-rules.patch
  27. 323
      SOURCES/lvm2-revert-fix-for-lvconvert-repair-for-raid-lvs.patch
  28. 18
      SOURCES/lvm2-rhel7.patch
  29. 30
      SOURCES/lvm2-set-default-preferred_names.patch
  30. 3989
      SPECS/lvm2.spec

38
SOURCES/lvm2-2_02_131-disallow-usage-of-stripe-and-stripesize-when-creating-cache-pool.patch

@ -0,0 +1,38 @@ @@ -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))

521
SOURCES/lvm2-2_02_131-dmstats-fixups.patch

@ -0,0 +1,521 @@ @@ -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;
}

29
SOURCES/lvm2-2_02_131-do-not-check-for-full-thin-pool-when-activating-without-messages.patch

@ -0,0 +1,29 @@ @@ -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) {

28
SOURCES/lvm2-2_02_131-fix-vg-metadata-comparison-failure-while-scanning-the-vg-for-lvmetad.patch

@ -0,0 +1,28 @@ @@ -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);

37
SOURCES/lvm2-2_02_131-fix-vgimportclone-cache_dir-path-name.patch

@ -0,0 +1,37 @@ @@ -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}
} \

49
SOURCES/lvm2-2_02_131-ignore-persistent-cache-if-configuration-changed.patch

@ -0,0 +1,49 @@ @@ -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))

2169
SOURCES/lvm2-2_02_131-standardise-error-paths.patch

File diff suppressed because it is too large Load Diff

66
SOURCES/lvm2-2_02_131-swapping-of-lv-identifiers-handles-more-complex-lvs.patch

@ -0,0 +1,66 @@ @@ -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;

51
SOURCES/lvm2-2_02_133-check-for-space-in-thin-pool-before-creating-new-thin.patch

@ -0,0 +1,51 @@ @@ -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) &&

30
SOURCES/lvm2-2_02_133-enforce-writethrough-mode-for-cleaner-policy.patch

@ -0,0 +1,30 @@ @@ -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 */

204
SOURCES/lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch

@ -0,0 +1,204 @@ @@ -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

74
SOURCES/lvm2-2_02_140-restore-background-polling-processing-during-auto-activation.patch

@ -0,0 +1,74 @@ @@ -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)) {

37
SOURCES/lvm2-2_02_142-do-not-check-for-suspended-devices-if-scanning-for-lvmetad-update.patch

@ -0,0 +1,37 @@ @@ -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;

77
SOURCES/lvm2-2_02_155-fix-flushing-for-mirror-target.patch

@ -0,0 +1,77 @@ @@ -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;

32
SOURCES/lvm2-2_02_167-disable-lvconvert-of-thin-pool-to-raid-while-active.patch

@ -0,0 +1,32 @@ @@ -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;

27
SOURCES/lvm2-2_02_167-fix-inability-of-lvconvert-repair-for-cache-raid-volumes.patch

@ -0,0 +1,27 @@ @@ -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;
--

532
SOURCES/lvm2-2_02_167-fix-raid4-coversion-from-striped.patch

@ -0,0 +1,532 @@ @@ -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,

303
SOURCES/lvm2-2_02_167-prevent-raid4-creation-and-conversion-on-non-supporting-kernels.patch

@ -0,0 +1,303 @@ @@ -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;

49
SOURCES/lvm2-2_02_169-clvmd-add-mutex-protection-for-cpg_-call.patch

@ -0,0 +1,49 @@ @@ -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

50
SOURCES/lvm2-2_02_169-fix-segfault-in-lvmetad-from-missing-null-in-daemon_reply_simple.patch

@ -0,0 +1,50 @@ @@ -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);

34
SOURCES/lvm2-2_02_169-lvcreate-fix-striped-limit.patch

@ -0,0 +1,34 @@ @@ -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

30
SOURCES/lvm2-default-allow-changes-with-duplicate-pvs.patch

@ -0,0 +1,30 @@ @@ -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

104
SOURCES/lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch

@ -0,0 +1,104 @@ @@ -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) {

21
SOURCES/lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch

@ -0,0 +1,21 @@ @@ -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

27
SOURCES/lvm2-lvmlockd-tech-preview-warning.patch

@ -0,0 +1,27 @@ @@ -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;
}

18
SOURCES/lvm2-remove-mpath-device-handling-from-udev-rules.patch

@ -0,0 +1,18 @@ @@ -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.

323
SOURCES/lvm2-revert-fix-for-lvconvert-repair-for-raid-lvs.patch

@ -0,0 +1,323 @@ @@ -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) {

18
SOURCES/lvm2-rhel7.patch

@ -0,0 +1,18 @@ @@ -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)

30
SOURCES/lvm2-set-default-preferred_names.patch

@ -0,0 +1,30 @@ @@ -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"

3989
SPECS/lvm2.spec

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save