[lvm-devel] Don't allow resizing of internal logical volumes
Mike Snitzer
snitzer at redhat.com
Fri Mar 19 23:44:18 UTC 2010
On Fri, Mar 19 2010 at 6:27pm -0400,
Mikulas Patocka <mpatocka at redhat.com> wrote:
>
>
> On Fri, 19 Mar 2010, Mike Snitzer wrote:
>
> > On Thu, Mar 18 2010 at 7:53pm -0400,
> > Mikulas Patocka <mpatocka at redhat.com> wrote:
> > > Don't allow resizing of internal logical volumes.
> > >
> > > This patch prevents lvresize from being able to resize internal LVs: mirror
> > > legs (*_mimage_*), mirror log (*_mlog), snapshot placeholder LVs (snapshot*)
> > > and others. Resizing these would leads to unexpected metadata and sometimes
> > > crashes (in case of growing snapshot*).
> > >
> > > Note that test for VISIBLE_LV is not sufficient because snapshot0 volumes
> > > have the VISIBLE_LV flag set. So we test the name instead of the flags.
> >
> > OK, but snapshotX volumes are part of the LVM2 snapshot "fiction". They
> > never get exposed to the end user (even with lvs -a). Only the user
> > facing snapshot LV name gets exposed:
> > # lvs test/snapshot0
> > One or more specified logical volume(s) not found.
> > # lvs test/testlv1_snap
> > LV VG Attr LSize Origin Snap% Move Log Copy% Convert
> > testlv1_snap test swi-a- 4.00g testlv1
> >
> > As such we shouldn't have to worry about the user attempting to resize
> > the hidden snapshotX volume. Am I still missing something?
>
> If you do lvresize vgs/snapshot0, it allows it. If you extend it, it
> crashes. Try it. snapshotX isn't visible enen with "a", but for lvresize
> it exists.
I didn't realize that, OK.
> > diff --git a/tools/lvresize.c b/tools/lvresize.c
> > index 849fd2e..f08be60 100644
> > --- a/tools/lvresize.c
> > +++ b/tools/lvresize.c
> > @@ -323,6 +323,11 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
> >
> > lv = lvl->lv;
> >
> > + if (!lv_is_visible(lv) && !lv_is_accessible_hidden(lv)) {
> > + log_error("Can't resize internal logical volume %s", lv->name);
> > + return ECMD_FAILED;
> > + }
> > +
> > if (lv->status & LOCKED) {
> > log_error("Can't resize locked LV %s", lv->name);
> > return ECMD_FAILED;
> >
>
> OK. It is cleaner than my patch that checks the name, so commit it (except
> !lv_is_accessible_hidden(lv), because that has to wait until we commit
> shared snapshots).
>
> I tested it and it refuses "snapshotX" volumes.
But as you said above: "snapshot0 volumes have the VISIBLE_LV flag set."
That said, I do see that in practice the existing lvm2 code does reject
resizing "snapshot" type snapshot0 using !lv_is_visible(lv). I'll have
a closer look to understand that.
But when I tried it with the "multisnapshot" type snapshot0 (w/
multisnap enabled LVM2 2.02.63 from my people page + the above patch)
lvresize allowed it and then crashed in _setup_alloced_segment():
# lvresize -L 5.0G test/snapshot0
Extending logical volume snapshot0 to 5.00 GiB
Segmentation fault (core dumped)
(gdb) bt
#0 0x00000000004520ea in _setup_alloced_segment (region_size=<value optimized out>, aa=<value optimized out>, segtype=<value optimized out>,
stripe_size=<value optimized out>, area_count=<value optimized out>, status=<value optimized out>, lv=<value optimized out>) at metadata/lv_manip.c:690
#1 _setup_alloced_segments (region_size=<value optimized out>, aa=<value optimized out>, segtype=<value optimized out>, stripe_size=<value optimized out>,
area_count=<value optimized out>, status=<value optimized out>, lv=<value optimized out>) at metadata/lv_manip.c:727
#2 lv_add_segment (region_size=<value optimized out>, aa=<value optimized out>, segtype=<value optimized out>, stripe_size=<value optimized out>,
area_count=<value optimized out>, status=<value optimized out>, lv=<value optimized out>) at metadata/lv_manip.c:1387
#3 0x000000000045498a in lv_extend (lv=0xe66878, segtype=0xe40770, stripes=<value optimized out>, stripe_size=<value optimized out>, mirrors=0, extents=256,
mirrored_pv=<value optimized out>, mirrored_pe=<value optimized out>, status=<value optimized out>, allocatable_pvs=<value optimized out>,
alloc=<value optimized out>) at metadata/lv_manip.c:1638
#4 0x000000000041d9ea in _lvresize (lp=<value optimized out>, vg=<value optimized out>, cmd=<value optimized out>) at lvresize.c:629
#5 lvresize (lp=<value optimized out>, vg=<value optimized out>, cmd=<value optimized out>) at lvresize.c:702
#6 0x0000000000418550 in lvm_run_command (cmd=0xdd5fe0, argc=1, argv=0x7fff3bc2c1a8) at lvmcmdline.c:1071
#7 0x000000000041ab20 in lvm2_main (argc=4, argv=0x7fff3bc2c190) at lvmcmdline.c:1423
#8 0x000000335341eb1d in __libc_start_main () from /lib64/libc.so.6
#9 0x000000000040f089 in _start ()
(gdb) l
685 uint32_t s, extents, area_multiple;
686 struct lv_segment *seg;
687
688 area_multiple = calc_area_multiple(segtype, area_count);
689
690 if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
691 lv->le_count,
692 aa[0].len * area_multiple,
693 status, stripe_size, NULL,
694 area_count,
Mike
More information about the lvm-devel
mailing list