Single disk to raid1 with LVM on Debian stretch
Recently, I remembered that I have a second disk on my server and missed to use it when installing the system… So I decided to migrate to raid 1 on a single LVM volume group.
The best guide I found was, like often, on the ArchLinux wiki. Here’s my guide for Debian stretch.
First create a partition on the second disk using fdisk
and make it bootable:
% fdisk /dev/sdb
Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xcb9034eb.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (1-4, default 1):
First sector (2048-586072367, default 2048): 2048
Last sector, +sectors or +size{K,M,G,T,P} (2048-586072367, default 586072367):
Created a new partition 1 of type 'Linux' and of size 279.5G GiB.
Command (m for help): a
Selected partition 1
The bootable flag on partition 1 is enabled now.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Create a degraded raid 1 array on /dev/sdb1
, dump the mdadm config into
/etc/mdadm/mdadm.conf
and re-generate the initramfs (otherwise the raid
device will be named /dev/md127 instead of /dev/md0, which is probably a
bug…):
% mdadm --create /dev/md0 --level=1 --raid-devices=2 missing /dev/sdb1
mdadm: Note: this array has metadata at the start and
may not be suitable as a boot device. If you plan to
store '/boot' on this device please ensure that
your boot-loader understands md/v1.x metadata, or use
--metadata=0.90
Continue creating array? y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
% mdadm --detail --scan >> /etc/mdadm/mdadm.conf
% update-initramfs -u
Create a LVM physical volume on /dev/md0
, a volume group and a new volume for
our root filesystem and create a ext4 filesystem on it:
% pvcreate /dev/md0
Physical volume "/dev/md0" successfully created.
% vgcreate vg0 /dev/md0
Volume group "vg0" successfully created
% lvcreate -L 20G -n root vg0
Logical volume "root" created.
% mkfs.ext4 /dev/mapper/vg0-root
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 2359296 4k blocks and 589824 inodes
Filesystem UUID: bb31a512-9d4a-4501-98a8-f4755ebdb5d3
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
Copy the content of your current root content to the newly created root filesystem using rsync
:
% mkdir /mnt/root
% mount /dev/mapper/vg0-root /mnt/root
% rsync -avxHAX --numeric-ids --progress / /mnt/root
If you used a separate /boot
partition, also rsync
it to /mnt/root/boot
.
Then edit /mnt/root/etc/fstab
to mount the root partition from vg0/root
, the simpler way to do this is to rely on disks uuid
:
% blkid /dev/mapper/vg0-root
/dev/mapper/vg0-root: UUID="bb31a512-9d4a-4501-98a8-f4755ebdb5d3" TYPE="ext4"
The corresponding fstab line should be:
UUID=bb31a512-9d4a-4501-98a8-f4755ebdb5d3 / ext4 errors=remount-ro 0 1
Then chroot
to your new root and install and update grub configuration:
% mount --bind /sys /mnt/root/sys
% mount --bind /proc /mnt/root/proc
% mount --bind /dev /mnt/root/dev
% chroot /mnt/root /bin/bash
% grub-install /dev/sdb
% update-grub
You may encounter some warnings like WARNING: Failed to connect to lvmetad. Falling back to device scanning.
or /usr/sbin/grub-probe: warning: Couldn't find physical volume `(null)'. Some modules may be missing from core image..
,
they where not relevant for me.
Then exit the chroot umount the new root:
% exit
% umount /mnt/root/dev
% umount /mnt/root/proc
% umount /mnt/root/sys
% umount /mnt/root
At this point if you tell your bios to boot on the second disk it should work
and use vg0/root
as root filesystem.
Unfortunately I was doing this on a remote server with no way to configure the
bios and not access to the console. In this case you want to configure grub
from the first disk to boot on the second disk (you will need to have
os-prober
installed):
% update-grub
(it should output a line like "Found Debian GNU/Linux 9 (stretch) on /dev/mapper/vg0-root")
Then we want to select boot on second disk by default in grub, edit
/boot/grub/grub.cfg
and check for menuentry
line, then try to figure
out what would looks like the grub screen, you can change the default boot by
setting GRUB_DEFAULT
in /etc/default/grub
.
For me it was:
0 Debian GNU/Linux, with Linux 4.9.0-9-amd64
1 Debian GNU/Linux, with Linux 4.9.0-9-amd64 (recovery mode)
2 Debian GNU/Linux 9 (stretch) (on /dev/mapper/vg0-root)
[...]
So I wrote GRUB_DEFAULT=2
in /etc/default/grub
and ran update-grub
again.
Reboot, cross your fingers and hopefully you will boot on your new root.
Then ensure you don’t use anything from /dev/sda
(or copy it to your LVM on
vg0), then apply the partitioning scheme from /dev/sdb
to /dev/sda
using
sfdisk
(assuming the two disk are identical).
% sfdisk -d /dev/sdb | sfdisk /dev/sda
Finally add /dev/sda1
to the raid array:
% mdadm /dev/md0 -a /dev/sda1
Wait for the raid synchronization to finish by looking at /proc/mdstat
.
Then re-install grub on /dev/sda
and regenerate initramfs and grub configs::
% grub-install /dev/sda
% update-grub
Reboot and you should boot on your raid array, yay !