Although at first the proposed "challenge" may seem difficult, not feasible or sound naive as some have commented, it isn't. The main idea behind using dd to migrate from a bigger to a smaller disk is perfectly fine and have benefits for migrating the data. Of course, having enough free space so that the occupied data fits in the destination disk is a necessary requirement.
The idea is to think in dd'ing each partition individually and not the entire disk at once as initially proposed. Even more can be accomplished: The partition(s) that would be truncated can also be safely migrated with a little help of filesystem re-sizing tools. Indeed, such kind of migration is interesting in order to preserve filesystem matadata and extended file attributes that cannot be easily copied with tools like cp, rsync, pax, ... which operate in the filesystem layer and not block device layer. Using dd elliminates the need of re-installing the OS or having to relabel the FS in order to avoid issues with SELinux.
Below is what I usually do to accomplish similar tasks:
1) First you have reduce the filesystem(s) within the affected partitions that would be truncated. For this, use the resize2fs tool (assuming we are talking about an ext2/ext3/ext4 fs - other modern FSs also have resizing tools for the same purpose). Note that although -- for obvious reasons -- a filesystem cannot be bigger than the partition it resides within, it can safely be smaller. The safety trick here is to reduce "more than needed". For example: imagine you have a filesystem of 1TB that you want to migrate to a 500 Gig drive. In this case, I suggest reducing the fs to, let's say, 450 Gig (you have to have enough free space for this, of course, i.e., the currently occupied space in this filesystem cannot exceed 450 Gig). The apparent wasted 50 Gig of space will be fixed after the data migration.
2) Partition the destination disk with the appropriate geometry considering its space constraints;
3) dd the data using the partition device(s) and not the disk device (i.e., use dd if=/dev/sda# of=/dev/sdb#
for each partition instead of using if=/dev/sda of=/dev/sdb
). NOTE: sda and sdb here are just examples;
IMPORTANT NOTE: When dd'ing from a bigger to a smaller partition device, dd will complain about attempting to write post to the end of the block device, that's ok since the filesystem data would have been entirely copied before reaching that point. To avoid such error message you can specify the size of the copy using bs=
and count=
parameters to match the shrunk filesystem size, but this will require some (simple) calculation, but if done wrongly can risk your data.
4) After dd'ing the data, resize the respective filesystem(s) within the destination partition(s) again using resize2fs. This time do not specify the new filesystem size. When ran without a size specification, resize2fs grows the filesystem so that it occupies the maximum allowed size, so, in this case, the 450 Gig filesystem will grow again to occupy the entire 500 Gig partition and no byte will be wasted. (The "reduce more than needed" approach avoids you to accidentally specify sizes wrongly and risk your data. Note that GB vs GiB units can be tricky).
Note for more complex operations: If you have a boot manager that you intend to copy along, which is very likely to be the case, you can dd the first few KBs of the disk using the disk device instead of the partition devices (like dd if=/dev/sda of=/dev/sdb bs=4096 count=5
), and then reconfigure the geometry in /dev/sdb (which will temporarily contain an invalid geometry for the new drive but an intact and valid boot manager). Finally proceed using the partition devices as described above for dd'ing a partition at a time. I did operations like this many times. Quite recently, I successfully performed a complex migration when upgrading from a HDD containing a mix of MacOSX & Linux installations to a smaller SDD in my MacMini6,2. In this case, I had to boot Linux from an external drive, dd'ed the bootmanager, ran gdisk to fix the GPT in the new disk and finally dd'ed each partition containing the just shrunk filesystes. (Note that the GPT partition scheme keeps two copies of the partition table, one in the beginning and another in the end of the disk. gdisk complains a lot because it cannot find the second copy of the PT and because the partitions exceed the disk size, but it correctly fixes the PT copy issue after you redefine the disk geometry). This was a much more complex case, but worth mentioning because illustrates that this kind of operation is also perfectly feasible.
Good luck! ...and most importantly remember to backup all important data before such kind of operation. A mistake and you can surely damage your data irrecoverably.
And just in case I didn't emphasize enough: back up your data before the migration! :)
dd
calculating the optimal block size is useful – Wilf Dec 30 '17 at 22:24