First stage was to clone the old disk using dd:
dd if=/dev/sdb of=/dev/sda
Where /dev/sdb is my old hard disk (the input file) and /dev/sda (the output file) is the new hard disk. This took a few hours on a 120GB disk but is reported to be faster if you specify the block size in the dd options. However, the clone operation worked fine.
Having rebooted, I didn't initially realise that the Grub bootloader configuration would now be out of date and that the machine would continue to boot from the old hard disk. It is not possible to reassign the root partition in Yast, but there are some useful instructions on this site on how to do a fresh install of Grub onto a new disk.
Following these instructions, I first created a directory where the cloned root partition on the new disk could be mounted:
mkdir /mnt/new
Next I mounted the cloned root partition:
/mount /dev/sda6 /mnt/new
Next, to bind /dev to the cloned partition:
mount --bind /dev /mnt/new/dev
and then chroot into the new partition:
chroot /mnt/new
Now for a fresh install of Grub onto the cloned disk:
grub-install.unsupported /dev/sda
The grub-install.unsupported command has to be used (rather than just grub-install) because Suse prefers you to use Yast for bootloader configuration. However, when I tried this, neither yast2 (the graphical interface) or yast (the character-based interface) worked within the chroot jail.
A reboot still gave the original result (i.e. the machine booted from the old disk) so the next stage was to edit the Grub bootloader configuration files.
First (and working within the chroot jail on the cloned partition), the new disk has to be entered into the /boot/grub/device.map file. Since I had two old IDE disks in the PC, there were two existing lines in the device.map file:
(hd0) /dev/disk/by-id/ata-[device_ID of first hard disk]
(hd1) /dev/disk/by-id/ata-[device_ID of second hard disk]
I added a third line for the next hard disk starting (hd2). If you don't know the disk ID, you can check it in the Yast2 bootloader configuration to copy the disk ID from there.
A reboot confirmed that Grub was happy with the new disk in the device.map file, so I created a new menu entry in the /boot/grub/menu.lst file. My original menu.lst file looked like this:
# Modified by YaST2. Last modification on Tue Mar 1 15:19:29\
# GMT 2011
# GMT 2011
# THIS FILE WILL BE PARTIALLY OVERWRITTEN by perl-Bootloader
# Configure custom boot parameters for updated kernels in
# /etc/sysconfig/bootloader
# /etc/sysconfig/bootloader
default 0
timeout 8
##YaST - generic_mbr
gfxmenu (hd0,5)/boot/message
##YaST - activate
###Don't change this comment - YaST2 identifier: Original
###name: linux
###name: linux
title Desktop -- openSUSE 11.3 - 2.6.34.7-0.7
root (hd0,5)
kernel /boot/vmlinuz-2.6.34.7-0.7-desktop \
root=/dev/disk/by-id/ata-[old disk_ID]-part[partition no.]\
resume=/dev/disk/by-id/ata-[old disk_ID-part[partition no.]\
splash=silent quiet showopts vga=0x31a
root=/dev/disk/by-id/ata-[old disk_ID]-part[partition no.]\
resume=/dev/disk/by-id/ata-[old disk_ID-part[partition no.]\
splash=silent quiet showopts vga=0x31a
initrd /boot/initrd-2.6.34.7-0.7-desktop
###Don't change this comment - YaST2 identifier: Original
###name: failsafe
###name: failsafe
title Failsafe -- openSUSE 11.3 - 2.6.34.7-0.7
root (hd0,5)
kernel /boot/vmlinuz-2.6.34.7-0.7-desktop \
root=/dev/disk/by-id/ata-[old disk_ID]-part[partition no.]\ showopts apm=off noresume nosmp maxcpus=0 edd=off \
powersaved=off nohz=off highres=off \
processor.max_cstate=1 nomodeset x11failsafe vga=0x31a
root=/dev/disk/by-id/ata-[old disk_ID]-part[partition no.]\ showopts apm=off noresume nosmp maxcpus=0 edd=off \
powersaved=off nohz=off highres=off \
processor.max_cstate=1 nomodeset x11failsafe vga=0x31a
initrd /boot/initrd-2.6.34.7-0.7-desktop
Using the first menu option as a model, I created a new menu option to boot from the new hard disk:
###New menu option###
title Suse linux 11.3
root (hd2,5)
# Note: hd1 was still the 2nd old hard disk at this stage
# Note: hd1 was still the 2nd old hard disk at this stage
kernel /boot/vmlinuz-2.6.34.7-0.7-desktop \
root=/dev/disk/by-id/ata-[new disk_ID]-part[partition no.]\ resume=/dev/disk/by-id/ata-[new disk_ID]_ID-part\
[partition no.]splash=silent quiet showopts vga=0x31a
root=/dev/disk/by-id/ata-[new disk_ID]-part[partition no.]\ resume=/dev/disk/by-id/ata-[new disk_ID]_ID-part\
[partition no.]splash=silent quiet showopts vga=0x31a
initrd /boot/initrd-2.6.34.7-0.7-desktop
A reboot confirmed that this new option worked fine.
Th final stage was to comment out the lines in the /boot/grub/device.map file for the old disks, and assign(hd 0) to the new hard disk. Next, I edited the /boot/menu.lst file, commenting out the menu options for the old hard disk and retaining the menu option for the new hard disk, ensuring that the line beginning root now pointed to (hd0,5) since this hd0 was now the hard disk number for the new disk in device.map.
I disconnected the old disks, rebooted and then selected the new menu option, but for some reason/etc/fstab now had a line for a root partition on one of the old drives (the drive which didn't actually have a root partition...) so the reboot failed. Changing /etc/fstab fixed this.