Ok so in earlier parts of this series i showed how i migrated two raid partitions of a disk i wanted to use exclusively for data. The original disk topology looked as follows
Disk /dev/sda: 243031 cylinders, 255 heads, 63 sectors/track Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System /dev/sda1 0+ 45689- 45690- 367001600 fd Linux raid autodetect /dev/sda2 * 45689+ 45702- 13- 102400 fd Linux raid autodetect /dev/sda3 45702+ 243031- 197329- 1585042432 83 Linux /dev/sda4 0 - 0 0 0 Empty
/dev/sda1 & /dev/sda2 have now been migrated away and can be reclaimed The problem is i dont want 3 separate partitions i just want one partitions which will include all the space. For the benefit of the reader. The disk is a 1.8 TB disk; the first 2 partitions take up 300GB and the last partitions takes up 1.5TB of data. I want to end up with one partitions that contains 1.8TB and i don’t want to delete any of the data on the data partitions (about 90%) used.
I want to resize an ext2/3/4 partition so i my first port of call is resize2fs. I know that i can change the disk topology and get resize2fs to grow the disk; however i have never had to grow a disk backwards, so off to the man pages. It didn’t take long before you see a pretty big warning
“make sure you create it with the same starting disk cylinder as before! Otherwise, the resize operation will certainly not work, and you may lose your entire filesystem”
Ok so it looks like resize2fs is out unless i can first move the sdc3 partition to the beginning of the disk. hanging around in irc i had a lot of people telling me to give (g)parted a go, although most where sceptical if it was possible at all. I took a look at (g)parted however as far as i can tell all (g)parted is only able to copy a partitions from one location two another. If i had 1.5TB avalible space at the beginning of the disk i would have been able to copy /dev/sdc3, change the last cylinder, resiz2fs and everything would be sorted. however As mentioned we only had 300GB avalible.
The night was getting late and the hacker in me started to consider some more exotic, dangerous and some would say down right stupid solutions. I eventually arrived at dd. I thought perhaps i could just to something like
dd if=/dev/sdc3 of=/dev/sdc bs=1M conv=noerror
In theory this would create on block device /dev/sdc3 containing the file system on /dev/sdc3. The obvious problem here is that dd will start over writing the beginning of /dev/sdc3 before it has finished copying all of the data from /dev/sdc3. Would this work? I figured in theory dd would read the partition table into memory, pick the two start positions and continue the copy process until it reaches the end of /sdv/sdc3. It would neither know or care that we, or more accurately it, was overwriting the beginning of /dev/sdc3
At this point i should but if the a disclaimer
THIS IS VERY DANGEROUS, POSSIBLY STUPID.
DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING
AND YOU DONT MIND LOSING YOUR DATA
Ok that out of the way i gave it a go and to my supprise it seem to have worked. If you are doing this on a remote machine i strongly recommend you use tmux or screen, if the dd is interrupted you have almost certainly lost your data.
[root@server ~]$ df -h | grep sdc /dev/sdc3 1.5T 1.4T 98G 94% /data/disk1 [root@server ~]$ umount /dev/sdc3 [root@server ~]$ dd if=/dev/sdc3 of=/dev/sdc bs=1M conv=noerror [root@server ~]$ mount /dev/sdc /data/disk1 [root@server ~]$ df -h | grep sdc /dev/sdc 1.5T 1.4T 98G 94% /data/disk1 [root@server ~]$ umount /dev/sdc [root@server ~]$ e2fsck -f /dev/sdc [root@server ~]$ resize2fs /dev/sdc [root@server ~]$ mount /dev/sdc /data/disk1 [root@server ~]$ df -h | grep sdc /dev/sdc 1.8T 1.4T 462G 75% /data/disk1
So there we are looks like it wasn’t so insane after all. Comments most welcome
UPDATE: I had a problem mounting the new disk via its UUID. tune2fs -l showed the same UUID which was present in /etc/fstab; However using the mount command didn’t work.
[root@server ~]# tune2fs -l /dev/sdd | grep UUID Filesystem UUID: 67966bfd-92b5-47b8-a545-277a4bea8be5 [root@server ~]# grep 67966bfd-92b5-47b8-a545-277a4bea8be5 /etc/fstab UUID=67966bfd-92b5-47b8-a545-277a4bea8be5 /data/disk2 ext4 noatime,nodiratime,nodelalloc 1 2 [root@server ~]# mount /data/disk2/ mount: special device UUID=67966bfd-92b5-47b8-a545-277a4bea8be5 does not exist
I have fixed this by doing running the following steps, not sure which one fixed it will test on the next system
[root@server ~]# cd /dev/disk/by-uuid/ [root@server ~]# ln -sv ../../sdd 67966bfd-92b5-47b8-a545-277a4bea8be5 [root@server ~]# mount /data/disk2/ [root@server ~]# umount /data/disk2/ [root@server ~]# rm 67966bfd-92b5-47b8-a545-277a4bea8be5 [root@server ~]# blockdev --rereadpt /dev/sdd [root@server ~]# partprobe /dev/sdd [root@server ~]# mount /data/disk2/
Also note that this server hasn’t been rebooted yet. Will update after it has.
Edit: System rebooted without issue, haven’t re-tested the mounting by uuid (or i don’t remember the results :)). however i preformed this procedure a couple of times without issue