17

I'm rearranging a bunch of disks on my server at home and I find myself in the position of wanting to move a bunch of LVM logical volumes to another volume group. Is there a simple way to do this? I saw mention of a cplv command but this seems to be either old or not something that was ever available for Linux.

3 Answers 3

22

If you can arrange for the logical volume to be on a separate subset of physical volumes from the rest of the source volume group (lvconvert sourcevg/sourcelv /dev/pv1 ... may help), you can use vgsplit to split off the lv into a new vg and vgmerge to merge the new vg into the target vg.

Although LVM has a mirroring feature, you can't (sanely) use it to make a copy between volume groups, because both legs of the mirror must live on the same vg and the association can't be broken.

You can copy an LVM volume to another the way you'd copy any volume to another: create a target lv of the appropriate size, then copy the contents with dd if=/dev/sourcevg/sourcelv of=/dev/targetvg/targetlv bs=4M. If the source volume is active, you can leverage LVM to make a consistent copy: first take a snapshot of the source lv with lvcreate -s, then copy the snapshot.

3
  • 2
    Brilliant Gilles....vgsplit / vgmerge will probably be just fine: I can use pvmove after that to move the physical extents to the new disk and then remove the old volume from the VG.
    – jkp
    Dec 2, 2010 at 9:36
  • Shame, this didn't work for me in the end due to differing extent sizes. If thats not an issue for you though I suggest this method would be easiest.
    – jkp
    Dec 2, 2010 at 14:37
  • 1
    After dd (if you don't hurry to throw off old volumes), don't forget to change UUID of new filesystems: tune2fs -U random /dev/targetvg/targetlv
    – midenok
    Oct 20, 2014 at 15:55
4

As of the LVM in Debian stretch (9.0), namely 2.02.168-2, it's possible to do a copy of a logical volume across volume groups using a combination of vgmerge, lvconvert, and vgsplit. Since a move is a combination of a copy and a delete, this will also work for a move.

Alternatively, you can use pvmove to move the physical extents instead. To quote U&L: Purpose of Physical Extents:

A single physical extent is the smallest unit of disk space that can be individually managed by LVM.

A complete self-contained example session using loop devices and lvconvert follows.

Summary: we create volume group vg1 with logical volume lv1, and vg2 with lv2, and make a copy of lv1 in vg2.

Create files.

truncate pv1 --size 100MB
truncate pv2 --size 100MB

Set up loop devices on files.

losetup /dev/loop1 pv1
losetup /dev/loop2 pv2

Create physical volumes on loop devices (initialize loop devices for use by LVM).

pvcreate /dev/loop1 /dev/loop2

Create volume groups vg1 and vg2 on /dev/loop1 and /dev/loop2 respectively.

vgcreate vg1 /dev/loop1
vgcreate vg2 /dev/loop2

Create logical volumes lv1 and lv2 on vg1 and vg2 respectively.

lvcreate -L 10M -n lv1 vg1
lvcreate -L 10M -n lv2 vg2

Create ext4 filesystems on lv1 and lv2.

mkfs.ext4 -j /dev/vg1/lv1
mkfs.ext4 -j /dev/vg2/lv2

Optionally, write something on lv1 so you can later check the copy was correctly created. Make vg1 inactive.

vgchange -a n vg1

Run merge command in test mode. This merges vg1 into vg2.

vgmerge -A y -l -t -v <<destination-vg>> <<source-vg>>
vgmerge -A y -l -t -v vg2 vg1

And then for real.

vgmerge -A y -l -v vg2 vg1

Then create a RAID 1 mirror pair from lv1 using lvconvert. The dest-pv argument tells lvconvert to make the mirror copy on /dev/loop2.

lvconvert --type raid1 --mirrors 1 <<source-lv>> <<dest-pv>>
lvconvert --type raid1 --mirrors 1 /dev/vg2/lv1 /dev/loop2

Then split the mirror. The new LV is now lv1_copy.

lvconvert --splitmirrors 1 --name <<source-lv-copy>> <<source-lv>>
lvconvert --splitmirrors 1 --name lv1_copy /dev/vg2/lv1

Make vg2/lv1 inactive.

lvchange -a n /dev/vg2/lv1

Then (testing mode)

vgsplit -t -v <<source-vg>> <<destination-vg>> <<moved-to-pv>>
vgsplit -t -v /dev/vg2 /dev/vg1 /dev/loop1

For real

vgsplit -v /dev/vg2 /dev/vg1 /dev/loop1

Resulting output:

lvs
[...]
lv1        vg1       -wi-a-----  12.00m
lv1_copy   vg2       -wi-a-----  12.00m
lv2        vg2       -wi-a-----  12.00m

NOTES:

  1. Most of these commands will need to be run as root.

  2. If there is any duplication of the names of the logical volumes in the two volume groups, vgmerge will refuse to proceed.

  3. On merge, logical volumes in vg1 must be inactive. And on split, logical volumes in vg2 belonging to vg1 must be inactive. In our case, this is lv1.

1
  • I have essentially the same answer on U&L. But the U&L version had received more corrections. It's hard to keep multiple copies of the same answer in sync. Maybe I should just have pointed to the U&L answer. Feb 13, 2022 at 19:44
3
pvmove -n lvol1 /dev/sdb1 /dev/sdc1

pvmove can move data between physical volumes: LVM Administrator's Guide

3
  • 11
    But not between volume groups.
    – MattBianco
    Sep 19, 2013 at 14:50
  • I repeat: this doesn't work for two separate volume groups
    – kissgyorgy
    Oct 5, 2017 at 17:34
  • 1
    First vgextend vg1 with a new pv, then pvmove your lv to the new pv, vgsplit a temporary vg that you vgmerge in vg2. Then pvmove again the lv to vg2 original pv, vgreduce vg2 to get read of the intermediate pv. Or to avoid the intermediate copy, you can simply first merge vg1 in vg2, pvmove lv1, and vgsplit again vg1 from vg2. This should answer objections of @ MattBianco and @kissgyorgy and is equivalent to the solution of @Gilles but replacing the snapshot and lowlevel dd by a pvmove
    – marcz
    Jan 21, 2019 at 14:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .