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 [[wp>Solid-state_drive|Solid State Drive (SSD)]]. You will also see gains if you go from a [[wp>SATA]] SSD to an [[wp>M.2|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 [[wp>GUID_Partition_Table|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 [[wp>Master_boot_record|MBR]] partition type I've used for years. Using [fdisk](https://wiki.gentoo.org/wiki/Handbook:AMD64/Blocks/Disks#Alternative:_Using_fdisk_to_partition_the_disk) 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 [[wp>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 [[wp>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](https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Base#Chrooting) 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 [[wp>Universally_unique_identifier|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](https://bugs.gentoo.org/671650) and reverting to `dev-libs/elfutils-0.173` solved the [problem](https://forums.gentoo.org/viewtopic-p-8284118.html#8284118).
====== Links ======
* [Partition - Gentoo Wiki](https://wiki.gentoo.org/wiki/Partition)
* [Handbook:AMD64/Blocks/Disks - Gentoo Wiki](https://wiki.gentoo.org/wiki/Handbook:AMD64/Blocks/Disks)