(There’s a french version of this article and I’m sorry if there’s grammar or syntax errors. English isn’t my native language)

I’m going to describe here what I did to upgrade the internal hard drive of my laptop. But first, here’s a description of the situation of my computer:

It’s a laptop (not a desktop)

Its OS is Debian Linux

Its hard drive has two partitions A small boot up partition An encrypted partition



I wanted to have the same data on the new hard drive but without having to reinstall the operating system. I’ll go through the details of this transfer later on.

If you have a similar situation, you could be inspired by the steps taken in this document. But before doing anything, I would strongly recommend that you do a full backup. You could use, for example, a tool like Clonezilla to do that.

I cannot be held responsible for any data loss or other harmful situation since your situation is probably different to mine. It is very important that you understand each and every step that you want to do.

TL;DR:

Booting from a Debian live CD, I created the required partitions (encrypted or not) and installed LVM volumes inside the encrypted partition I used rsync to copy all the files from the old hard drive to the new one I modified a few configuration files (/etc/fstab, /etc/ crypttab) I chroot ed in the new hard drive I ran update-initramfs and update-grub2 inside the chroot environment I rebooted the computer

Initial conditions

So, my laptop came with a internal 120 GB hard drive and I wanted to upgrade it to a 1 TB hard drive. In the original operating system installation of this computer, I’ve used the option of installing it in a encrypted LVM volume using all the hard drive capacity. For this hard drive upgrade, I had a few goals :

I wanted to upgrade the hard drive without rebooting

I wanted to change the new disk partition configuration

I wanted to keep the old hard drive intact so that I could revert if necessary (even though I’ve made a backup)

Two web documents already existed about this but weren’t exactly what I needed:

A 2007 document about a Grub (Legacy) system

A 2000 document about a Lilo installation

But my situation was different. Grub 2 was installed which is very different from Grub or Lilo. Besides, new tools streamlines the steps described in those procedures.

Retrieving the needed tools

First of all, I needed to be able to access both the hard drives to transfer the data from the old one to the new one. Unlike a desktop, I couldn’t easily connect two internal hard drive in a laptop unless you use a hard drive enclosure. It allowed me to access one of the internal hard drive as a USB external one.

Then, I’ve downloaded a Debian live CD image. It allows a computer to boot without touching any files on the internal hard drive. If I booted the computer from the hard drive, some open files could be modified by the system while being copied on the new hard drive which is something we don’t want.

I’ve chosen the amd64 architecture standard Live CD version for my situation. I’ve burned it on a empty CD.

Planning the new hard drive’s layout

Identifing the old hard drive’s layout

The old (120 GB) hard drive’s layout is:

A small 228 MB ext2 partition mounted as /boot

The rest of hard drive is a encrypted partition containing a LVM volume group : A 106 GB root partition mounted as / A 4 GB swap partition



Information about local partitions can be retrieved using df -h . For example, on my laptop:

$ df -h Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur /dev/mapper/labod-root 106G 81G 20G 81% / udev 10M 0 10M 0% /dev tmpfs 401M 6,6M 394M 2% /run tmpfs 1001M 92K 1001M 1% /dev/shm tmpfs 1001M 0 1001M 0% /sys/fs/cgroup tmpfs 5,0M 4,0K 5,0M 1% /run/lock tmpfs 100M 12K 100M 1% /run/user /dev/sda1 228M 31M 186M 15% /boot

The information is found on the second and last lines, on the second and last column.

By the way, since I use my computer in Canadian French, you may see some command output in French. But the commands to type in should still be the same.

To retrieve the swap partition’s size, I could have used the swapon -s command. For example, on my laptop:

$ sudo swapon -s Filename Type Size Used Priority /dev/mapper/labod-swap_1 partition 4005884 0 -1

It’s on the « Size » column. In my case, it’s about 4 Gb.

Deciding the new hard drive’s layout

I’ve decided that the new hard drive’s layout will be:

A small ext4 200 MB partition mounted as /boot

The rest of hard drive is a encrypted partition containing a LVM volume group : A 15 GB root partition mounted as / A 4 GB swap partition A 1 GB partition mounted as /tmp A 50 GB partition mounted as /var The rest of the available capacity will be a partition mounted as /home



A few notes about my choices:

I’ve kept the /usr directory in the root partition because with systemd as an OS init system, it seems that there’s still some trouble if you try to put it in a separate partition (see http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken/)

as an OS init system, it seems that there’s still some trouble if you try to put it in a separate partition (see http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken/) I’ve put a lot of space for the /var partition because I’m going to use lxc on this computer and it stores its containers (which can grow very much) in /var/lib/lxc. This is a personal decision

Preparing the new hard drive

First of all, I have connected the new hard drive inside my laptop and put aside the old one. Doing that now saves us an unnecessary reboot later on. I’ve made sure that I was connected to the Internet with an Ethernet cable since I was going to download some files later on (even though I guess this could work with Wi-Fi)

Booting with the CD

I’ve booted my laptop with the CD burned with Debian Live image downloaded earlier. I had configured the BIOS to let me do this.

I’ve come across the Debian Live CD starting menu. Typically, I would have chosen the « Live (amd64) » option but for some reason I cannot. If I do, I end up with a black screen at the end of the booting up sequence. So I have to use the « Live (amd64 failsafe) » option.

After many information lines have scrolled across the screen, I end up at a bash shell prompt:

[…] Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u1 x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. user@debian:~$

I become a superuser:

user@debian:~$ sudo -i root@debian:~#

Installing needed software

This is the reason why we needed to be connected to the Internet. I have to install two needed software:

cryptsetup to deal with LUKS encrypted partitions

to deal with LUKS encrypted partitions lvm2 to deal with LVM volumes

We have to also install kbd-compat to avoid cryptsetup software dependency problems.

To install these two software commands :

root@debian:~# aptitude install cryptsetup lvm2 kbd-compat The following NEW packages will be installed: cryptsetup cryptsetup-bin{a} kbd-compat libcryptsetup4{a} libdevmapper-event1.02.1{a} lvm2 0 packages upgraded, 6 newly installed, 0 to remove and 0 not upgraded. Need to get 1,038 kB of archives. After unpacking 2,330 kB will be used. Do you want to continue [Y/n/?]

I choose « Y ». My laptop start to fetch the required packages and installs them in memory (and not on the hard drive). It takes some times.

Partitionning the new hard drive

I’m locating the device file name of the new hard drive (even though I’m pretty sure what it should be):

root@debian:~# ls /dev/sd* /dev/sda

The hard drive’s name is « /dev/sda ». I use fdisk to partition this drive. Here’s the commands used inside fdisk (followed with an comment explaining what’s going on):

root@debian:~# fdisk /dev/sda n # Create new partition p # Primary partition 1 # Partition number desired 2048 # First sector location +200M # Last sector location (200 MB farther) n # Create new partition p # Primary partition 2 # Partition number desired [return] # Default first sector location [return] # Default last sector location (End of hardrive) a # Toogle booting flag 1 # Partition number concerned p # Display list of partitions (optional) w # Write new partition table root@debian:~#

With the « p » command I can see (because of the sizes) that the partitions are:

/dev/sda1 for the /boot partition

/dev/sda2 for the encrypted partition

Encrypting a partition

I start the partition encryption process on /dev/sda2:

root@debian:~# cryptsetup luksFormat /dev/sda2 WARNING ======= This will overwrite data on /dev/sda2 irrevocably. Are you sure ? (Type uppercase yes):

I type « YES »

Are you sure ? (Type uppercase yes): YES Enter LUKS passphrase:

I type in the encrypted partition passphrase. It will be used to unlock the encrypted partition at booting time. It can be the same as the one on the old hard drive or something else. Nothing is echoed while I type the password. I have to type the password two times to ensure that no errors are inserted.

Enter LUKS passphrase: Verify passphrase: root@debian:~#

I unlock the newly created encrypted partition:

root@debian:~# cryptsetup luksOpen /dev/sda2 labod2014_crypt Enter passphrase for /dev/sda2: root@debian:~#

I type in the passphrase chosen in the preceding step.

Installing LVM volumes

Now, we use LVM. I create a physical volume in the encrypted partition reachable at /dev/mapper/labod2014_crypt:

root@debian:~# pvcreate /dev/mapper/labod2014_crypt Writing physical volume data to disk "/dev/mapper/labod2014_crypt" Physical volume "/dev/mapper/labod2014_crypt" successfully created root@debian:~#

I have to create a LVM volume group. As it’s mentionned in the 2007 reference how to I have to use a different group volume name than what is used in my old hard drive.

I know what is my old hard drive’s group volume name but if I didn’t I could connect the old hard drive (inside the enclosure) to my computer. Messages would be shown since the kernel would detect the new USB device. Somewhere in these messages, you should see a hint as to what the name of the device file should be named. For example, I could see something like : […] [25523.636218] sd 5:0:0:0: [sdb] Write Protect is off […] In this case « sdb » would be what we are looking for. So the device file would be /dev/sdb. I could see which partition on this disk is the encrypted one with this command: root@debian:~# cfdisk /dev/sdb And look for the partition whose type is « crypto_LUKS ». In my case, I could see that it matches the sdb5 partition. I could then exit cfdisk . I could then unlock this partition with: root@debian:~# cryptsetup luksOpen /dev/sdb5 labod_crypt Enter passphrase for /dev/sdb5: And finally, to know the LVM volume group name I could use: root@debian:~# vgs VG #PV #LV #SN Attr Vsize Vfree labod 1 2 0 wz--n- 111.55g 0 root@debian:~# In my case, it would be « labod ». But I already knew that. To make sure, I wouldn’t do anything foolish before I really need to use my old disk drive, I would lock the encrypted partition: root@debian:~# cryptsetup luksClose labod_crypt root@debian:~# I could then turn off (and even unplug) the old hard drive.

I will use the volume group name « labod_2014 » for the new hard drive. To create a new volume group:

root@debian:~# vgcreate labod_2014 /dev/mapper/labod2014_crypt Volume group "labod_2014" successfully created root@debian:~#

I activate the volume group:

root@debian:~# vgchange -a y labod_2014 0 logical volume(s) in volume group "labod_2014" now active root@debian:~#

I can create logical volumes in this volume group. I chose names (in French, but you should be able to follow) linked to their use. Based on the sizes decided earlier:

root@debian:~# lvcreate --size 15G --name racine --zero n labod_2014 WARNING: "racine" not zeroed Logical volume "racine" created root@debian:~# lvcreate --size 4G --name echange --zero n labod_2014 WARNING: "echange" not zeroed Logical volume "echange" created root@debian:~# lvcreate --size 1G --name temporaire --zero n labod_2014 WARNING: "temporaire" not zeroed Logical volume "temporaire" created root@debian:~# lvcreate --size 50G --name variable --zero n labod_2014 WARNING: "variable" not zeroed Logical volume "variable" created

To know how much space I have left in the volume group (so that I know how much to allocate to the home partition):

root@debian:~# vgdisplay --- Volume group --- VG Name labod_2014 System ID Format lvm2 […] Total PE 238419 Alloc PE / Size 17920 / 70.00 GiB Free PE / Size 220499 / 861.31 GiB […] root@debian:~#

I take note of what is shown on the « Free PE / Size » line and use it in the next command:

root@debian:~# lvcreate --size 861.31G --name maison --zero n labod_2014 Rounding up size to full physical extent 861.31 GiB WARNING: "maison" not zeroed Logical volume "maison" created

I want to point out that I’ve used the option « --zero n » because I had an error message if I didn’t. See https://bbs.archlinux.org/viewtopic.php?pid=981109#p981109 for more details

Creating the partitions’ filesystems

I create a filesystem in each of the partitions. It’s going to take a lot of time:

root@debian:~# mkfs.ext4 -c /dev/sda1 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux […] Writing superblocks and filesystem accounting information: done root@debian:~# mkfs.ext4 -c /dev/mapper/labod_2014-racine mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux […] Writing superblocks and filesystem accounting information: done root@debian:~# mkfs.ext4 -c /dev/mapper/labod_2014-temporaire mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux […] Writing superblocks and filesystem accounting information: done root@debian:~# mkfs.ext4 -c /dev/mapper/labod_2014-variable mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux […] Writing superblocks and filesystem accounting information: done root@debian:~# mkfs.ext4 -c /dev/mapper/labod_2014-maison mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux […] Writing superblocks and filesystem accounting information: done

I create a swap partition:

root@debian:~# mkswap /dev/mapper/labod_2014-echange mkswap: /dev/mapper/labod_2014-echange: warning: don't erase bootbits sectors on whole disk. Use -f to force. Setting up swapspace version 1, size 4197300 KiB no label, UUID=[…] root@debian:~#

Copying the data

I create directories (still in memory) to mount different partitions. It could be anywhere but I will create them in the current directory:

root@debian:~# mkdir nouveau ancien root@debian:~#

Preparing the new hard drive’s access

I mount the new hard drive’s root directory in the « nouveau » (new in French) directory:

root@debian:~# mount /dev/mapper/labod_2014-racine nouveau [66763.630330] EXT4-fs (dm-1): mounted filesystem with ordered data mode. Opts: (null) root@debian:~#

I create the directory on the new hard drive and there, I mount the partitions created before:

root@debian:~# cd nouveau root@debian:~/nouveau# mkdir home root@debian:~/nouveau# mount /dev/mapper/labod_2014-maison home [83927.434854] EXT4-fs (dm-5): mounted filesystem with ordered data mode. Opts: (null) root@debian:~/nouveau# mkdir tmp root@debian:~/nouveau# mount /dev/mapper/labod_2014-temporaire tmp [84076.138633] EXT4-fs (dm-3): mounted filesystem with ordered data mode. Opts: (null) root@debian:~/nouveau# mkdir var root@debian:~/nouveau# mount /dev/mapper/labod_2014-variable var [84152.952032] EXT4-fs (dm-4): mounted filesystem with ordered data mode. Opts: (null) root@debian:~/nouveau# mkdir boot root@debian:~/nouveau# mount /dev/sda1 boot [84312.046264] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null) root@debian:~/nouveau# cd .. root@debian:~#

Preparing the old hard drive’s access

I connect and turn on the old hard drive (inside the enclosure USB). Linux Kernel messages are shown and I get the hint of the file device linked to the hard drive. For example, I see :

root@debian:~# […] [84725.976045] sdb: sdb1 sdb2 < sdb5 > […]

So the old hard drive’s partitions are:

/dev/sdb1 is linked to the /boot directory

/dev/sdb5 is the encrypted partition

If I didn’t know whose partition is linked to what I could type this command: root@debian:~# cfdisk /dev/sdb I could then find which device file has a « crypto_LUKS » filesystem type. In my case, I would have seen that the partition is sdb5. The other one is associated to the /boot directory. I would then exit the program.

I unlock the encrypted partition:

root@debian:~# cryptsetup luksOpen /dev/sdb5 labod_crypt Enter passphrase for /dev/sdb5: root@debian:~#

I have to activate the old hard drive’s LVM volume group. I can get its name from :

root@debian:~# vgs VG #PV #LV #SN Attr Vsize Vfree labod 1 2 0 wz--n- 111.55g 0 labod_2014 1 5 0 wz--n- 931.31g 0 root@debian:~#

Since « labod_2014 » is the volume group’s name I’ve created earlier, « labod » is what I was looking for. I activate it:

root@debian:~# vgchange -a y labod 2 logical volume(2) in volume group "labod" now active root@debian:~#

Likewise, to get the logical volume’s name inside the encrypted partition:

root@debian:~# lvs LV VG Attr LSize Pool Origin Data% Move Log Copy% Con vert root labod -wi-a--- 107.73g swap_1 labod -wi-a--- 3.82g echange labod_2014 -wi-a--- 4.00g maison labod_2014 -wi-a--- 861.31g […] root@debian:~#

The name I was looking for is « root ».

I mount the old hard drive partition in the « ancien » (old in French) directory. I mount it read-only to ensure I won’t write over these files:

root@debian:~# mount -o ro /dev/mapper/labod-root ancien [88156.314315] kjournald starting. commit interval 5 seconds [88156.314471] EXT3-fs (dm-7): mounted filesystem with ordered data mode. root@debian:~# mount -o ro /dev/sdb1 ancien/boot root@debian:~#

Transferring data from the old hard drive to the new one

Here’s the situation, right now:

Directory « nouveau » holds all of the new hard drive’s directory tree

Directory « ancien » holds all of the old hard drive’s directory tree

I want now to copy all the content of the old hard drive to the new hard drive. I use rsync that is included on the live CD:

root@debian:~# rsync --archive --verbose --hard-links --acls --xattrs ancien/ nouveau

A lot is displayed onscreen and it takes a lot of time to finish.

Updating configuration files on the new hard drive

Editing /etc/fstab

I have to edit the fstab file on the new hard drive because its content describes the old hard drive’s devices. Beforehand I need the universally unique identifier (UUID) of /dev/sda1 (which will be mounted as /boot in the future). I will use it while editing this file:

root@debian:~# blkid /dev/sda1 /dev/sda1: UUID="c17e031c-c3ed-4758-9cc8-8e7fde858077" TYPE="ext4" root@debian:~# nano nouveau/etc/fstab

Before editing fstab, it contained:

# /etc/fstab: static file system information # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/mapper/labod-root / ext3 errrors=remount-ro 0 1 # /boot was on /dev/sda1 during installation UUID=777f6f67-6b00-4741-9f63-80d5 /boot ext2 defaults 0 2 /dev/mapper/labod-swap_1 none swap sw 0 0 /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0

After editing this file, it looks like this:

# /etc/fstab: static file system information # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/mapper/labod_2014-racine / ext4 errrors=remount-ro 0 1 # /boot was on /dev/sda1 during (re)installation UUID=c17e031c-c3ed-4758-9cc8-8e7fde858077 /boot ext4 defaults 0 2 /dev/mapper/labod_2014-maison /home ext4 defaults 0 2 /dev/mapper/labod_2014-temporaire /tmp ext4 defaults 0 2 /dev/mapper/labod_2014-variable /var ext4 defaults 0 2 /dev/mapper/labod_2014-echange none swap sw 0 0 /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0

All I did is matching device files, mount points and filesystems in their new configurations while maintaining the root partition options. I had to add some new mount points for the additional partitions.

Editing /etc/crypttab

I will edit crypttab on the new hard drive so that the new volume group will be used at boot time. Beforehand I have to retrieve the UUID of /dev/sda2, the encrypted partition, because will we use it in that file:

root@debian:~# blkid /dev/sda2 /dev/sda2: UUID="873a88f6-dc3a-4aec-8b1b-9ac8b18b8e36" TYPE="crypto_LUKS" root@debian:~# nano nouveau/etc/crypttab

This file had this content before editing it:

labod_crypt UUID=51f64c18-e931-4b51-bbb5-d0ef3314b304 none luks

After editing, it has this content:

labod2014_crypt UUID=873a88f6-dc3a-4aec-8b1b-9ac8b18b8e36 none luks

Updating the new hard drive booting process

I will need to update initramfs and grub2 configuration. I’m going to use chroot on the new hard drive. Beforehand, I unmount the old hard drive’s directories since I don’t need it anymore:

root@debian:~# umount ancien/boot root@debian:~# umount ancien

I disable the old hard drive volume group and lock its encrypted partition:

root@debian:~# vgchange -a n labod 0 logical volume(s) in volume group "labod" now active root@debian:~# cryptsetup luksClose labod_crypt root@debian:~#

I can now turn off and disconnect the old hard drive. The Linux kernel will show some message saying that it detected that disconnection like:

[…] [188297.935821] usb 4-2: USB disconnect, device number 4 […]

Before doing a chroot , we will need to connect some special directories inside « nouveau » directory to the ones setup by the live CD OS:

root@debian:~# mount --bind /dev nouveau/dev root@debian:~# mount --bind /proc nouveau/proc root@debian:~# mount --bind /sys nouveau/sys root@debian:~# chroot nouveau root@debian:/#

I’ll use update-initramfs to update that part of the boot sequence. But beforehand, since the locale used on my computer is French Canada and live CD’s US English, I have to change a environment variable to avoid some error messages later on. This step would have been obviously optional if my locale was English US :

root@debian:/# export LANG=fr_CA.utf8 root@debian:/# update-initramfs -u update-initramfs: Generating /boot/initrd.img-3.16-2-amd64

I use update-grub2 to update Grub 2’s booting information :

root@debian:/# update-grub2 Création du fichier de configuration GRUB… Found background image: .background_cache.png Image Linux trouvée : /boot/vmlinuz-3.16-2-amd64 Image mémoire initiale trouvée : /boot/initrd.img-3.16-2-amd64 Image Linux trouvée : /boot/vmlinuz-3.14-2-amd64 Image mémoire initiale trouvée : /boot/initrd.img-3.14-2-amd64 fait root@debian:/#

I use grub-install to install Grub 2 in the master boot record (MBR) of the new hard drive:

root@debian:/# grub-install /dev/sda Installing for i386-pc platform Installation terminée sans erreur. root@debian:/#

Rebooting with the new hard drive

I exit the chroot environment and unmount all the mount points to the new hard drive:

root@debian:/# exit exit root@debian:~# umount nouveau/dev root@debian:~# umount nouveau/proc root@debian:~# umount nouveau/sys root@debian:~# umount nouveau/home root@debian:~# umount nouveau/tmp root@debian:~# umount nouveau/var root@debian:~# umount nouveau/boot root@debian:~# umount nouveau root@debian:~#

And now the moment of truth, I reboot the computer:

root@debian:~# reboot

At the end of the turn off part of the reboot, I get this message:

[…] Please remove the disc, close the tray(if any) and press ENTER to continue:

I do it. The computer restart. In his booting sequence, I get asked to enter the passphrase of the encrypted partition. I type it in. After many more lines are shown onscreen, I get to my usual login screen.

If you have any question, put them in the comments below. I will try to answer them the best way I can.