How to Resize Data in Linux Using DD Command

Hey, did you know that you can use a 2nd copy of dd to resize your data in Linux?

Let’s say you need some sort of dd operation to skip over a first part, let’s say you want to skip the MBR (512 bytes) but you don’t want to transmit entirely with 512 for every block. So you resize it for lets say 1024k:

dd if=/dev/sda bs=512 skip=1 | dd bs=1024k | dd of=/dev/sdb bs=512 seek=1

Of course I don’t know if you will get much speed improvements going from drive to drive as in the example above.

Also I do not know if the above command is useful because the MBR does contain partitioning information; however if you are going to copy the whole drive to a new location I don’t see why you wouldn’t take the partition table with you. Now if you were copying just the partitions, then that would be a different story, but in this case we are taking the whole drive (sda).

I still firmly believe that if you are going to copy a whole drive, then you need take the MBR (which contains your partition info) as well. If you are going to take only a partition at a time (i.e. not the whole drive) then that is a different story. And like I stated before I would then use parted or fdisk or resize2fs or partition magic to resize the destination to get the larger drive size.

Here’s an example of how I find dd resizing useful:

I have a 650MB ISO image on one box that I need to transfer to another. For some reason my 2nd box keeps loosing network connectivity after a while – what a bummer :-( I tried 5 or 6 times using the following command, each time it would die out before transferring the entire image:

tar -czvf – disc1.iso | ssh “(cd /var/ftp/pub && tar -xzvf – )”

I decided to start transferring where I left off rather than keep trying to transfer the entire image. The amount I currently had transferred (around 500MB) was not easily divisible by 1024k or 2048k, but the value was divisible by 512. So I did something like the following to pick up the rest:

dd if=disc1.iso bs=512 skip=107654 | dd bs=1024k | ssh “(cd /var/ftp/pub && cat – >> disc1.iso)”

Of course verify afterwards with an md5sum to verify that the end result is good :-)

I noticed that the 512 by itself (without the resizing for 1024k) was giving about 1 to 2 MB per minute transfer over the network. After resizing the dd transfer to 1024k before going on the network I starting getting about 1 to 4 MB per every few seconds (a great improvent over the 2MB/minute).

Maybe I should have blocked my original tar over the network??? Like this:

tar -czvf – disc1.iso | dd bs=1024k | ssh “(cd /var/ftp/pub && tar -xzvf – )”

Here’s an example to see how this works when trying to skip over the first portion of a destion:

Check out the following tests to show how this works:
yes "1" | tr '\n' ' ' | dd of=one bs=512 count=1
yes "2" | tr '\n' ' ' | dd of=two bs=512 count=1
yes "3" | tr '\n' ' ' | dd of=dest_mbr bs=512 count=1
cat one two > source
cat dest_mbr > dest
dd if=source bs=512 skip=1 | dd bs=1024k | dd of=dest bs=512 seek=1

So with the above information in mind, I could have rewritten my original “resend” without having to worry with 512 bytes on the destination, like so:
Let’s say my entire image size is 700MB.
Let’s say I already transferred 671547392 bytes so far and I need to transfer the rest.
I want to use 1024K block sizes
So lets calculate the block size in bytes:
expr 1024 \* 1024
Now let’s see what the remainder is
expr 671547392 % 1048576
So with the non-zero result we know that this partial amount is not aligned with a 1024K boundary — ignore this answer as we don’t need to use it
Let’s find out how many times our destination is divisible by 1024K
expr 671547392 / 1048576
Now all we have to do is to set the block size to 1024K and then skip the first 640 blocks, and then skip the first 640 blocks when writing:
dd if=disc1.iso bs=1024K skip=640 | ssh “(cd /var/ftp/pub && dd of=disc1.iso bs=1024K seek=640)”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Exit mobile version