Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/rekall/ on line 74

i’ve got a drive geometry for dual-boot xp and debian that (i thought) prevented me from being able to shrink a too-generous linux root partition in favor of giving more space to my shared fat32 ‘data’ partition… like so:

/dev/hda2 ; ext2 ; 16mb –> /boot
/dev/hda1 ; ntfs ; 12gb –> [xp]
/dev/hda3 ; swap ; 2gb –> (linux-swap)
/dev/hda4 –> (extended)
/dev/hda5 ; xfs ; 8gb –> / [linux]
/dev/hda6 ; fat32 ; 52gb –> /data

this worked well but after i’d installed every kde application i wanted, to my surprise, i had a lot of room left over on my linux root. “ok,” i thought, “i’ll shrink it and have even more space for all my stuff.”

so i attached an external disk, and booted the same gparted livecd that i’d used to set things up initially. once there, though, i discovered it was impossible to resize logical partitions within an extended partition. i couldn’t let it go — i can think of lots to do with an extra 4gb, couldn’t you? — so i endeavoured into risky territory.

i selected my primary disk, clicked on my linux root partition, clicked ‘copy,’ selected my secondary disk, created a new partition of the same size and filesystem, clicked ‘paste,’ ‘apply,’ and then waited with baited breath. a good amount of time passed and then, huzzah, “all operations successful.” (i didn’t bother to copy /dev/hda6 - i didn’t have anything there yet.)

i then re-selected my primary disk, deleted the two partitions within the extended partition, and created two new ones.

/dev/hda5 ; xfs ; 4gb –> / [linux]
/dev/hda6 ; fat32 ; 56gb –> /data

“aah, that’s better.” or so i believed. upon trying to reverse the previous operation to copy my linux root partition back onto my primary disk i was faced with an error along the lines of “source and destination partition are different sizes.” well, no duh. i tried again just to be sure. no dice.

“great, i’ve got a perfect backup, and no way to restore it.” large amounts of web searching and trial-and-error ensued all to no avail. i tried cp /dev/sda3 /dev/hda5 but it got stuck dereferencing cyclic symbolic links and filled the disk. just super.

however, using cp still seemed to me the most elegant solution, but with some command line options obviously as of yet unbeknowst to me. i put it to rest and slept on it. upon waking i searched anew and found this heroic blog post by some dude in italy. (seriously, as geeky as it sounds, i truly love the world-shrinking power of the web.)

so, here’s how i was able to get my linux back:

booted the gparted livecd
closed gparted
opened a shell
mkdir /mnt/h5
mount -t xfs /dev/hda5 /mnt/h5
mkdir /mnt/s3
mount -t xfs /dev/sda3 /mnt/s3
cp -a /mnt/s3/* /mnt/h5/

i ejected the disc, turned off my external drive, rebooted, and wouldn’t you know it, linux / was restored.

according to the man page for cp, the -a option provides the same as -dpR… dereference symbolic links (don’t follow them), preserve mode/ownership/timestamps, and copy directories recursively.

how handy that the original programmer had this exact purpose in mind when creating cp. thank you, whoever you are (or were).