Thursday, February 7, 2008

Converting lvm to a normal partition

I've recently set up a new gentoo-box and first decided to use lvm2 on my root. Well, I ran into some issues with the kernel and initrd which I could figure out and fix. But then I noticed that, because of the lvm, I won't be able to access the disk from Windows with the free ext3-drivers that are available. Linux will even boot faster because I'll have no need for the initrd anymore. That's when I decided to get rid of the lvm.And that's actually easier than you'd think: If you have a spare-partition or -harddisk around that is at least the size of the logical volume that you'd like to convert to a partition, you can easily do this with dd. Imagine that /dev/vg/volume is a logical volume that consists of only one partition, /dev/sday:

sh# dd if=/dev/vg/volume of=/dev/sdbx bs=8M
sh# dd if=/dev/sdbx of=/dev/sday bs=8M

That's it. This will back up the logical, continuous data that's hosted on the lvm to a partition. After the first dd you'll be able to mount /dev/sdbx and see how the content of /dev/vg/volume has been copied. The mounted partition's usable size will be exactly the same as the volume's size, even if the partition itself is much bigger. That's because the filesystem on it will still be the same size it was before. You could (but it wouldn't make much sense because we want to move the data to the other partition anyways) fix this with resize2fs (if you use ext2 or ext3, that is).
The second dd copies the data back to the partition that it was formerly stored on, but without the additional lvm-abstraction. The lvm will be overwritten by the 'flat' filesystem-data. If sdbx happens to be bigger than sday, an error will be printed that dd reached the end of the partition. This is nothing to worry about since the data left on sdbx is not interesting to us anyways.
You can fix the filesystem-size to the actual partition size with resize2fs. Since the lvm itself needs some space, too, it will be slightly (a few bytes) larger now.

13 comments:

  1. Excelent buddy. I was really looking for it.

    I am going to do this for a vmware vm

    1. Create virtual disk (sdb) to hold the LVM enabled disk on the guest
    2. Partiton the disk similar to the LVM layout.
    3. Boot the LVM machine with a live CD.
    4. dd if=/dev/vg/volume|ssh vmguest > /dev/sdbx

    ReplyDelete
  2. > If you have a spare-partition _or_ -harddisk around

    ReplyDelete
  3. Tqvm Daniel.
    this command:
    " dd if=/dev/vg/volume of=/dev/sdbx bs=8M " this will overide all data in /dev/sdbx (possibly your ext harddisk).

    what if we use this command:
    " mount /dev/sdbx /mnt "
    " dd if=/dev/vg/volume of=/mnt/datafile.dd bs=8M "

    my 2 cent

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. What about the conv=noerror,sync? I have seen it used else where but I am not sure if its needed or useful.

    ReplyDelete
    Replies
    1. Don't know - haven't seen or used it before. It worked fine without conv=noerror,sync, though.

      Delete
    2. conv=noerror,sync is for recovering from a drive with dead/unreadable sectors.

      noerror -> keep going on read error/unreadable sector
      sync -> put blank space in the output file where the unreadable sectors would be, don't just truncate them.

      Delete
  6. I tried doing this but got this error--

    writing '/dev/hda1" : No space left on device

    Not sure how to get past this. :/

    ReplyDelete
    Replies
    1. That's because hda1 is smaller than the partition that you would like to convert

      Delete
  7. Very elegant solution to the problem

    ReplyDelete
  8. Ok I understand, I created standard file system like /, /boot, /var & /home. copied the data using dd command and edit grub.cfg. However system is not booting with this newly created disk.

    ReplyDelete
  9. Just my 2 Cents, One thing I LOVE to do to my systems, and a reason I don't use LVM, is I "sanitize" the FSTAB and GRUB. Using GParted I label the partitions, including SWAP, and this is an example FSTAB Entry.

    LABEL="ROOT" / ext4 defaults 1 1
    LABEL="BOOT" /boot ext4 defaults 1 2
    LABEL="SWAP" swap swap defaults 0 0
    LABEL="DATA" /data ext4 defaults 1 3

    and in grub, root=/dev/sda2 vs root=UUID=XYZ

    ReplyDelete