Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
I am trying to clone my whole Ubuntu 20.04 LTS operating system from a bigger (500 GB) HDD to a smaller (120 GB) SSD. I know that there is a huge difference between 120 and 500 GB, but I am only using ~50 GB.
I've sucessfully shrunk my partitions to be able to clone them. I have 4 partitions:
30 GB system partition (/) (8 GB used)
70 GB partition for datas (/home) (12 GB used)
8 GB swap partition
300 MB EFI partition
(this is a GPT disk)
Total: ~110 GB. It means that their max size can't reach my SSD's 120 GB limit. I've tested my system after resizing partitions and it's working properly.
However, I could not clone my HDD's content to my smaller SSD. I've tried Clonezilla (booted from DVD) with -icds parameter. It didn't work. So I decided to give it a try to disable/enable "Resize partition table proportionally" option. It failed again.
After that, I tried dd. According to this site, dd can be used as cloning tool, and it is suitable for cloning bigger disks to smaller disks. So I followed the instructions.
Use fdisk to explore my disks:
Disk model: ST500LT012-1DG14
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 8C2B2A2F-1B20-47AA-81E5-B3C18447B27D
Device Start End Sectors Size Type
/dev/sdc1 2048 58652671 58650624 28G Linux filesystem
/dev/sdc2 99999744 116000767 16001024 7,6G Linux swap
/dev/sdc3 116000768 116586495 585728 286M EFI System
/dev/sdc4 116586496 252962815 136376320 65G Linux filesystem
(this is my source disk)
My target disk is /dev/sdb. After calculate some values, I "created" my command which is suitable for my disk:
This procedure took about 50-60 mins. After it finished, I was very surprised because my SSD was full empty (like before dd procedure). So I had to realized that this way was wrong (again).
How can I clone my whole OS (and each partition) from my HDD to my SSD properly?
I believe in new install & restore from your normal backup. Then you know when you drive fails, your backup works & is complete. If backup missing anything, you still have larger drive to go back an get missing data. After install rsync /home from backup. Use your exported list of installed apps to reinstall apps. if data partition(s), you can rsync those also. Gpt drives have unique GUID in primary partition table, partition & backup partition table that must be at end of drive. So only dd from same size to same size works with gpt.
The dd method should have worked though there should have been no need for those parameters. Since you have pv it can also be simplified as:
# pv /dev/sdc > /dev/sdb
No need for dd, though dd should have worked. This needs done as root because of the IO redirection. If you want to do it with sudo you'll need to do it in a shell:
$ sudo sh -c 'pv /dev/sdc > /dev/sdb'
or indeed use dd after all:
$ sudo pv /dev/sdc | sudo dd of=/dev/sdb
If you do that and you think it hasn't worked, please show us the partition table of sdb afterwards.
$ sudo fdisk -l /dev/sdb
And please do have backups! One error and all data is gone…
If the total partitions size and location fits into the smaller disk than Clonezilla can be used.
The trick is to exit to shell after booting from clonezilla and create the partition table using sgdisk. best thing is to take it from the source HDD (sda in this example)
sgdisk --backup=table /dev/sda # To save from source HDD
sgdisk --load-backup=table /dev/sdb # To load into target SDD
sgdisk -R /dev/sdb /dev/sda # If on same system
sgdisk -G /dev/sdb # Cange UUID
Run clonezilla. use Expert mode. make sure that -icds is selected
and than choose -k (Do NOT create partition table on boot sector on target machine)
Forget dd it is copying the whole this use rsync with the directories mounted on the new ssd connected. Firstly let us make certain you setup the new drive with the partitions in the proper order the 1 is supposed to be the efi system partition. An example of gdisk doing this.
root@zeus-H370M-DS3H:~# dd if=/dev/zero of=/dev/sdb bs=512 count=34
34+0 records in
34+0 records out
17408 bytes (17 kB, 17 KiB) copied, 0.00286715 s, 6.1 MB/s
root@zeus-H370M-DS3H:~# dd if=/dev/zero of=/dev/sdb bs=512 count=34 seek=$((`blockdev --getsz /dev/sde` - 34))
34+0 records in
34+0 records out
17408 bytes (17 kB, 17 KiB) copied, 0.00584954 s, 3.0 MB/s
root@zeus-H370M-DS3H:~# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.5
Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present
Creating new GPT entries in memory.
Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-234441614, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-234441614, default = 234441614) or {+-}size{KMGTP}: +256M
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI system partition'
Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-234441614, default = 526336) or {+-}size{KMGTP}:
Last sector (526336-234441614, default = 234441614) or {+-}size{KMGTP}:
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sde.
The operation has completed successfully.
You just continue with the proper sizes for the 3 and 4 partitions you need, with 30G used for the second size, 70G the third and just take the rest left over for the swap, it is type 8200 to be chosen. Of course formatting. The first sector is not important it will default to the correct one, just use the sizes in the second and it will do it properly for you.
root@zeus-H370M-DS3H:~# mount /dev/sdb1 /tmp/ssdboot
root@zeus-H370M-DS3H:~# mount /dev/sda3 /tmp/oldssdboot
root@zeus-H370M-DS3H:~# mount /dev/sdb2 /tmp/ssdroot
root@zeus-H370M-DS3H:~# mount /dev/sdb3 /tmp/ssdhome
Nano used for at the very least editing the fstab to the make entries with the proper partition ids. My drive and file below in my Pi as an example of it.
root@buster-raspi:~# blkid
/dev/sda1: SEC_TYPE="msdos" UUID="3651-174E" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="9fad4e77-177d-4a3c-929a-3897e6bc1810"
/dev/sda2: UUID="4a349c2c-0df5-4fdb-a99f-906423554de9" TYPE="ext4" PARTUUID="59097f66-f9fb-4a50-a491-8a71becaa2bd"
root@buster-raspi:~# cat /etc/fstab
# The root file system has fs_passno=1 as per fstab(5) for automatic fsck.
#LABEL=RASPIROOT / ext4 rw 0 1
PARTUUID=59097f66-f9fb-4a50-a491-8a71becaa2bd / ext4 rw 0 1
# All other file systems have fs_passno=2 as per fstab(5) for automatic fsck.
#LABEL=RASPIFIRM /boot/firmware vfat rw 0 2
PARTUUID=9fad4e77-177d-4a3c-929a-3897e6bc1810 /boot/firmware vfat rw 0 2
# the /proc filesystem
proc /proc proc defaults 0 0
root@zeus-H370M-DS3H:~# nano /tmp/ssdroot/etc/fstab
I do not think I have missed anything with the UUIDs in them, my Kubuntu machine you see most of the posting from is MBR setup so I cannot mount an efi partition to check there the Pi boots via named files it finds hardwired into the firmware in the first fat partition on a drive. If necessary to re-install grub perhaps this page will help.
Edit: And now it comes to me with the below you can make the PARTUUID identical to your old drive and it should just boot. Plus if needing to get extra space back he explains this too with the partition table manually to get all of it.
All this best done with both drives offline with a booted usb linux stick or dvd.
Edit2: Had time on my hand so looked around some more on the /boot partition there is the file EFI/ubuntu/grub.cfg it has a UUID that needs to be changed to the / one. As well as the /etc/fstab on the new drive / partition. This link below worked perfectly for me to install the grub to my EFI partition on my system that until few hours ago was booting as MBR now as EFI. You may want to give it a try booted from an installer in EFI mode.
root@zeus-H370M-DS3H:/home/zeus# ll /sys/firmware/efi/
config_table esrt/ fw_vendor runtime-map/ vars/
efivars/ fw_platform_size runtime systab
root@zeus-H370M-DS3H:/home/zeus# mount |grep sda
/dev/sda3 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /boot/efi type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
I don't think rsync is a good tool for this use case because as your answer illustrates: 1) you'll have to replicate the partition table yourself; 2) you'll have to make all the filesystems yourself; but what you didn't also mention is 3) rsync will not copy ACLs, extended attributes, SELinux labels and unless you're careful not even sparse files. It can be hard or impossible to get this right with rsync; it's more doable with tar but even then you need complex options to get all the extended attributes. If it's appropriate, a binary copy of the device is simpler.
Well, it's factual that rsync doesn't copy file attributes, it's also factual that you didn't handle sparse files, so I don't see that as merely opinion. I am sure prospective users can make their own mind up whether they want to create partitions with same UUIDs and other metadata, handle the bootloaders etc. I don't know why you are so hostile to having these things pointed out, but okay, it isn't for us to decide.
I'm not going to engage with the accusations, but in answer to your request for an example, here is just one: touch ~/foo; sudo chattr +i ~/foo; lsattr ~/foo; sudo rsync -ahPHAXx ~/foo ~/bar; lsattr ~/bar. As you will see, rsync (using the same options you proposed) lost the immutable attribute. Depending upon filesystems used there can be many things that rsync misses. If determined to use rsync then -S for sparse files should definitely be used also.