What is the best way to clone a Linux partition onto a smaller partition?

6,480

Solution 1

I would:

  1. resize the filesystem in-place with something like resize2fs -p /dev/<device_name_fs_is_on> 20G
    It will undoubtedly refuse to run first time, suggesting that you run fsck first. You can force it to run, but the fsck operation is strongly recommended as trying to resize a filesystem with errors (even minor ones) could lead to disaster. Rerun the resize command once the check is completed
  2. copy it to the other drive with dd if=/dev/<device_name_fs_is_on> of=/path/to/other/location/filesystem.img bs=1048576 count=20480
  3. reformat the disks as needed
  4. copy the filesystem back with dd if=/path/to/other/location/filesystem.img of=/dev/<new_device_name>
  5. resize up to fill the new partition with resize2fs -p /dev/<new_device_name>
  6. mount the newly resized filesystem and edit any relevant config it contains, like /etc/fstab
  7. you will also need to check your grub configuration to make sure it refers to the new root partition name and you may need to rebuild your initrd (though probably not as you are going from RAID to normal not the other way around which causes problems if the initrd is not RAID aware)
  8. cross your fingers and reboot...

As this is your root filesystem, you are going to need to do this from a live CD as you will not be able to resize the filesystem (step 2) while it is mounted.

If you change the 20G passed to resize2fs in step 1, make sure you change the 1048576x20480 passed to dd in step 2 accordingly.

Obviously this is not a risk free operation, so you might want to separately backup important data+configuration on the filesystem by other means before step 3.
For even greater safety: if you have time and a disk to spare, restore the shrunk filesystem to the extra disk, reconfigure appropriately as per steps 6 & 7, and make sure you can boot off that before progressing to step 3. This way you know you have a fully working copy of the filesystem elsewhere before wiping it from the old location, and can easily revert back to the old setup and abort/retry if you discover problems at that stage.

This way you are not going to lose any file/directory/device properties while copying stuff around as you are operating on the filesystem wholesale rather than individual files, dirs and device nodes.

Solution 2

I've never used it but there is a partition imaging program, called partimage which is available on System Rescue CD.

I'm not sure what will happen if you use partimage, but if you use cp (be careful not to try to copy the directory you are copying to when you do your copy it may need cp -ax) you will have to reinstall Grub, as it hard codes physical hard disk locations which will change during the copy.

Share:
6,480

Related videos on Youtube

thecoop
Author by

thecoop

Updated on September 17, 2022

Comments

  • thecoop
    thecoop almost 2 years

    I've currently got an 80 GB RAID 0 (yes, I know, that's why I'm changing it...) ext3 Linux device that's about 80% free, and I want to change it to a 40 GB ext4 partition using one of the previous RAID 0 partitions. I've got enough spare space on another large partition for all the files, and the best method I thought of doing the switch is:

    1. cp -a all files on the filesystem to a directory under a large partition
    2. Repartition
    3. cp -a all files back to a new partition

    The thing is, I'm worried about special file properties (it's a Linux root device); will cp -a keep all the necessary file properties so the new partition is bootable afterwards? Am I missing another way of doing it?

  • Neal
    Neal over 14 years
    Shrink it before taking the image? But then I think it will have to restripe which will take ages, losing the advantage (partimage does not copy empty blocks - 80% of your drive) that partimage has over dd.
  • pbies
    pbies almost 11 years
    Using pv instead of dd can give progress in disk cloning. As with dd user would not see the progress till the end of the process or an error.
  • Verdi Erel Ergün
    Verdi Erel Ergün over 10 years
    @pbies you can see progress with dd. The method is open up a new shell and find the dd pid: pgrep -l '^dd$' then issue a watch and kill to the pid watch -n 10 kill -USR1 8789 This will output dd's progress every 10 seconds.
  • David Spillett
    David Spillett over 10 years
    I usually use pv myself for the progress indicator, but I stick with dd and cat when giving examples publicly as they are found almost everywhere and pv, while increasingly available by default in Linux distributions, is much less common on out-of-the-box installs.