Move partition data with dd to the right

I need some help to get a dd command line that is moving my partition blockwise to the right.

I stumbled upon an error when using tools to image some pcs and now I need to repartiition those machines without losing any data. This works pretty well with gparted 0.18.0. There I move my second partition to the right with an offset of 79MB. Then I grow my first partition 79MB. Everything is working flawlessly. But since there are about 35 machines I wanted to build a script that does that.

The resizing and everything is pretty easy. What I don't get in my head is the moving of the partition to the right. Basically I need a dd command line that does that. My thinking is that I need to start at the back and work my way the front. So I thought:

  • if and of are the same partition (remember is already grown to fit the offset data) /dev/sda2
  • the bs may be 16MiB since that is what gparted benchmarked
  • what would be the parameters that achive the copying from right to left so that the data doesn't get overwritten

I talked to the maintainer of gparted and he said dd is used to achieve this. But I can't figure out how.


  • what would be the parameters that archive the copying from right to left so that the data doesn't get overwritten

Not exists, there is no in one command dd solution

Also I warn you from using dd for moving partition, because if something fails you have no chances to restore data, without backup, which you did before that operation. But if you have backup then operation is trivial. So that was disclaimer.

Now the fun way(I find your question interesting). I did not, moving of partitions in that way, but it may work, so proof of concept on test file:

perl -e 'foreach $i (0..1023) { printf "%0.7i\n", $i; }' >test.dat

just making test file, for experiments

We need also pv command , which able act like buffer for our data in form : pv -B buffer_size_in_bytes

dd if=test.dat | pv -B 1024 | dd of=test.dat seek=2

default dd block size is 512 bytes - we shift data by 2 dd blocks, so buffer in 1024 bytes is enough.

dd if=/div/sda bs=512*device block size* skip=111111*much blocks until sda2 begins*
| pv -B 90000000 *have_to_fit_shift size+*
| dd of=/div/sda seek=(blocks until sda2 begins + amount of blocks we shift that for)

after that, if everything went ok, needs to fix partition table.

but probably more common way - would be move data with dd chunk by chunk

dd if=/div/sda bs=1M count=100 skip=PosToRead seek=PosToWrite
PosToRead -= dd_count
PosToWrite -= dd_count
repeat if not done

also there dd moving in opposite direction, interesting in handling dd command and determining offsets


dd_rescue has option -r for reversing the direction.

Usage example:

partition=/dev/vdc1
disk=/dev/vdc
sector_size=512
new_start_sector=4096
# opos is right after the new partition and given in bytes
opos=$(($new_start_sector * $sector_size + `blockdev --getsize64 $partition`))
dd_rescue -v -r -S $opos $partition $disk

Afterwards don't forget to update the partition table. Don't update it before!