Table of Contents
Often getting a new hard-drive can help speed up your system, particularly if you are still using traditional platter Hard Disk Drives (HDD) and upgrade to a Solid State Drive (SSD). You will also see gains if you go from a SATA SSD to an M.2 SSD which is a newer, and faster, connection type.
Partition the new drive
After installing the new drive on to the motherboard and rebooting you should be able to find the new device. Mine was located at /dev/nvme0n1
. Initially I tried the native Linux GPT partition table, but found that when writing the kernel image and initramfs I was told they could not be embedded, and rather than spend time going down another rabbit I hole I opted to switch to the more traditional MBR partition type I've used for years. Using fdisk I set the partition type to dos
fdisk /dev/nvme01n1 Command (m for help): o # Creates dos partition Command (m for help): w # Writes to disk
I then used cfdisk
to create three partitions, making the boot sector bootable.
# fdisk -l /dev/nvme0n1 Disk /dev/nvme0n1: 232.9 GiB, 250059350016 bytes, 488397168 sectors Disk model: Samsung SSD 970 EVO 250GB Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xd4db420e Device Boot Start End Sectors Size Id Type /dev/nvme0n1p1 2048 167774207 167772160 80G 83 Linux /dev/nvme0n1p2 * 167774208 168183807 409600 200M 83 Linux /dev/nvme0n1p3 168183808 488397167 320213360 152.7G 83 Linux
Make file systems for each, I opted to stick with Ext4…
mkfs.ext4 -b 1024 /dev/nvme0n1p1 mkfs.ext4 -b 1024 /dev/nvme0n1p2 mkfs.ext4 -b 1024 /dev/nvme0n1p3
Copy Files
Mount the partitions…
mkdir -p /mnt/new-ssd/boot mkdir /mnt/new-ssd/home mount /dev/nvme0n1p1 /mnt/new-ssd/ mount /dev/nvme0n1p2 /mnt/new-ssd/boot mount /dev/nvme0n1p3 /mnt/new-ssd/home
…and copy the relevant partitions over using rsync which will preserve symbolic links…
rsync -av /boot/* /mnt/new-ssd/boot/. rsync -av /home/* /mnt/new-ssd/home/.
For the root partition I opted to exclude a number of directories using an exclude file (a simple text file that lists directory and file paths to exclude). My exclusions were in the file /root/tmp/root_fs_copy.exclude
/usr/portage /var/tmp/portage /mnt/usb* /mnt/work/* /mnt/music/* /mnt/video/* /mnt/pics/* /mnt/data/* /mnt/scans/* /boot /proc/kcore /run/* /lost+found /sys/* /home /export/* /mnt/personal/* /tmp/* /var/spool/clientmqueue/* /var/nullmailerl/* /var/lib/docker/devicemapper
To use an exclude file simply refer to it with the --exclude-from
flag…
rsync -av / /mnt/new-ssd --exclude-from '/root/tmp/root_fs_copy.exclude'
Install GRUB
Now chroot into the new environment you've just copied over. First mount /proc
, /sys
and /dev
in the new environment.
mount --types proc /proc /mnt/new-ssd/proc mount --rbind /sys /mnt/new-ssd/sys mount --make-rslave /mnt/new-ssd/sys mount --rbind /dev /mnt/new-ssd/dev mount --make-rslave /mnt/new-ssd/dev
Then chroot
into it…
chroot /mnt/gentoo /bin/bash source /etc/profile export PS1="(chroot) ${PS1}"
Finally you can install GRUB to the MBR using…
grub2-mkconfig -o /boot/grub/grub.cfg grub2-install --boot-directory=/boot /dev/nvme0n1
Update /etc/fstab
to reflect the new partitions
#LABEL=root / ext4 noatime 0 1 #LABEL=boot /boot ext4 noatime,rw,users 1 2 #LABEL=home /home ext4 noatime,users,exec 0 4 /dev/nvme0n1p1 / ext4 noatime 0 1 /dev/nvme0n1p2 /boot ext4 noatime,rw,users 1 2 /dev/nvme0n1p3 /home ext4 noatime,users,exec 0 4
Exit the chroot
environment, unmount all drives and reboot
exit umount /mnt/new-ssd/proc /mnt/new-ssd/sys /mnt/new-ssd/dev umount /mnt/new-ssd/boot /mnt/new-ssd/home umount /mnt/new-ssd reboot
Boot from the SSD
On rebooting hit F2
or Del
to enter your computers BIOS and select the new drive as the primary/first boot device. Save and exit and you should now boot into your system from the new drive.
Finalising
I use UUID or LABEL
to mount partitions so needed to relabel my partitions and update my /etc/fstab
. Before I had my device booting and running from partitions on /dev/sda
that had the following partitions and labels
# fdisk -l /dev/sda Disk /dev/sda: 232.9 GiB, 250059350016 bytes, 488397168 sectors Disk model: Samsung SSD 840 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x75ae4ae9 Device Boot Start End Sectors Size Id Type LABEL /dev/sda1 63 80003699 80003637 38.2G 83 Linux root /dev/sda2 80003700 96004439 16000740 7.6G 82 Linux swap / Solaris /dev/sda3 * 96004440 96197219 192780 94.1M 83 Linux boot /dev/sda4 96197220 488397167 392199948 187G 5 Extended /dev/sda5 96197283 116198144 20000862 9.6G 83 Linux portage /dev/sda6 116198208 488397167 372198960 177.5G 83 Linux home
These were mounted using entries under /etc/fstab
…
LABEL=root / ext4 noatime 0 1 LABEL=boot /boot ext4 noatime,rw,users 1 2 LABEL=home /home ext4 noatime,users,exec 0 4
To make it clear what these are I pre-fixed each label with sda-
using e2label
e2label /dev/sda1 'sda-root' e2label /dev/sda3 'sda-boot' e2label /dev/sda5 'sda-portage' e2label /dev/sda6 'sda-home' mkdir -p /mnt/sda/root /mnt/sda/boot /mnt/sda/home
I then labelled the new partitions on /dev/nvme0n1
e2label /dev/nvme0n1p1 'root' e2label /dev/nvme0n1p2 'boot' e2label /dev/nvme0n1p3 'home'
…and updated /etc/fstab
to reflect these new labels…
LABEL=sda-root /mnt/sda/root ext4 noatime 0 1 LABEL=sda-boot /boot ext4 noatime,rw,users 1 2 LABEL=sda-home /mnt/sda/home ext4 noatime,users,exec 0 4 #/dev/nvme0n1p1 / ext4 noatime 0 1 #/dev/nvme0n1p2 /boot ext4 noatime,rw,users 1 2 #/dev/nvme0n1p3 /home ext4 noatime,users,exec 0 4 LABEL=root / ext4 noatime 0 1 LABEL=boot /boot ext4 noatime,rw,users 1 2 LABEL=home /home ext4 noatime,users,exec 0 4 UUID=3e54d3ee-ac61-4bce-ae90-1da94ec8bd78 none swap sw 0 0 LABEL=sda-portage /usr/portage ext4 noatime,users 0 3
Troubleshooting
I found on trying to build and compile a new kernel I was getting error messages from objdump
along the lines of…
cd /usr/src/linux make oldconfig make -j9 ... objdump: arch/x86/kernel/acpi/.tmp_sleep.o: unable to initialize decompress status for section .debug_info objdump: arch/x86/kernel/acpi/.tmp_sleep.o: unable to initialize decompress status for section .debug_info objdump: arch/x86/kernel/acpi/.tmp_sleep.o: file format not recognized
This turned out to be because of an issue with a recent update to dev-libs/elfutils-0.175 and reverting to dev-libs/elfutils-0.173
solved the problem.