diff --git a/WHATS_NEW b/WHATS_NEW index 17516000b..b6f2936d6 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,8 +1,8 @@ Version 2.00.23 - ==================================== + Test for incompatible format/segtype combinations in lv_extend. Fix lvchange example on man page. - Version 2.00.22 - 3rd September 2004 ==================================== Fix /dev/vgname perms. diff --git a/lib/format1/format1.c b/lib/format1/format1.c index cd47b56ce..b1db3e81f 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -24,6 +24,7 @@ #include "lvmcache.h" #include "lvm1-label.h" #include "format1.h" +#include "segtypes.h" #define FMT_LVM1_NAME "lvm1" @@ -492,6 +493,17 @@ static int _vg_setup(struct format_instance *fid, struct volume_group *vg) return 1; } +static int _segtype_supported (struct format_instance *fid, + struct segment_type *segtype) +{ + if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) { + stack; + return 0; + } + + return 1; +} + static struct metadata_area_ops _metadata_format1_ops = { vg_read:_vg_read, vg_write:_vg_write, @@ -542,6 +554,7 @@ static struct format_handler _format1_ops = { pv_write:_pv_write, lv_setup:_lv_setup, vg_setup:_vg_setup, + segtype_supported:_segtype_supported, create_instance:_create_instance, destroy_instance:_destroy_instance, destroy:_destroy, diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 3fc3d985d..8d649b5fd 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -623,6 +623,16 @@ int lv_extend(struct format_instance *fid, lv->le_count += extents; lv->size += (uint64_t) extents *lv->vg->extent_size; + if (fid->fmt->ops->segtype_supported && + !fid->fmt->ops->segtype_supported(fid, segtype)) { + log_error("Metadata format (%s) does not support required " + "LV segment type (%s).", fid->fmt->name, + segtype->name); + log_error("Consider changing the metadata format by running " + "vgconvert."); + return 0; + } + if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count, alloc, segtype, stripes, stripe_size, mirrors, mirrored_pv, mirrored_pe, status)) { diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 2022130b8..c30952dd4 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -341,6 +341,12 @@ struct format_handler { */ int (*vg_setup) (struct format_instance * fi, struct volume_group * vg); + /* + * Check whether particular segment type is supported. + */ + int (*segtype_supported) (struct format_instance *fid, + struct segment_type *segtype); + /* * Create format instance with a particular metadata area */ diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index 7664c7eb3..cf76dea0b 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -149,8 +149,8 @@ int insert_pvmove_mirrors(struct cmd_context *cmd, seg->area[s].u.pv.pe, PVMOVE, allocatable_pvs, lv->alloc)) { - log_error("Allocation for temporary " - "pvmove LV failed"); + log_error("Unable to allocate " + "temporary LV for pvmove."); return 0; } seg->area[s].type = AREA_LV;