Thinkpad Carbon X1 1st-3d Gen and Ubuntu 18.04

My dear friend Dirk just bought a second-hand Carbon X1 first generation, just like mine (3448 serie). I thought he might need a quick help to get going with Ubuntu 18.04 and this machine. Note that the content of this tutorial works for the 2nd and 3rd generation (20BS serie) as well.

I had 3 complains after installing a brand new Ubuntu 18.04 LTS on an encrypted disk:

  • no hibernate feature
  • no fingerprint scanner feature
  • a too sensitive trackpad

Hopefully all these problems can be solved to provide the OS this laptop deserves.

Hibernate

This chapter is the trickiest part of this tutorial, therefore it comes first. Keep in mind that we are going to change partitions sizes, it’s best to do it right after linux have been installed: when all you can loose is your time, not your data. If your laptop has a running system with sensitive data: please do a backup first.

In order to enable the hibernation, we’ll need to fix the swap partition size, so the RAM content can fit in it when the machine goes to deep sleep. Then we’ll need to setup systemd so it suspends when the lid is closed, and hibernate after a (defined) while if not resumed in the meantime. And to close this chapter, we’ll setup some policies to enable the “hibernate” button in the system menu.

Partitioning

If you didn’t partition the SSD yourself during the installation, high are the chance that your swap partition is smaller than the amount of RAM in your machine. And if you succeeded to install Ubuntu 18.04 with a custom partitioning and and encrypted file-system, than please leave a note in the comment to explain how. I tried many different approach without success: whether the install failed or the machine didn’t boot properly. So let’s start with the assumption that you installed Ubuntu with an encrypted file-system, by letting the installer partition your disk.

You’ll need to boot on the installation disk/usb-drive again, because we shouldn’t change the partition of a running system. Open a Terminal window and decrypt the encrypted partition of your installed system:

ubuntu@ubuntu:~$ sudo cryptsetup luksOpen /dev/sda3 crypt1
Enter passphrase for /dev/sda3

In that example, ensure that /dev/sda3 is your encrypted volume. If you are not sure, check with fdisk -l which is the big partition on your hard-drive, this is most likely the last one. On a NVMe hard-drive the name might be very different.

Once the volume decrypted, scan the LVM volume-groups and active them with the following commands:

root@ubuntu:~# vgscan --mknode
Reading volume groups from cache.
Found volume group "ubuntu-vg" using metadata type lvm2
root@ubuntu:~# vgchange -ay
2 logical volume(s) in volume group "ubuntu-vg" now active

You’ll be then able to check that the volume-group has been activated correctly with:

root@ubuntu:~# pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/crypt1 ubuntu-vg lvm2 a-- 237.25g 48.00m

and list logical-volumes with:

root@ubuntu:~# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root ubuntu-vg -wi-a----- 236.25g
swap_1 ubuntu-vg -wi-a----- 976.00m

It is recommended to scan the file-system prior to modifications:

root@ubuntu:~# e2fsck -f /dev/mapper/ubuntu--vg-root

Now you can resize your root partition to give some room for the swap partition. There is a whole science to calculate how big your swap should be if you want to hibernate, or you can follow the rule of thumb: RAM amount + 4GB. If the swap is exactly the size of your RAM this might work as well, a bit extra is recommended if your machine is actually swapping – rarely on modern machine – but this depend on you usage. If you start docker or virtual box sometime, follow the rule of thumb…

So in my case the volume-group is about 237GB big, I subtracted 12GB for the swap it leaves 225GB for the root (system) partition:

root@ubuntu:~# resize2fs -p /dev/mapper/ubuntu--vg-root 225g
resize2fs 1.44.1 (24-Mar-2018)
Resizing the filesystem on /dev/mapper/ubuntu--vg-root to 58982400 (4k) blocks.
Begin pass 2 (max = 2947)
Relocating blocks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 1880)
Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 24242)
Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/mapper/ubuntu--vg-root is now 58982400 (4k) blocks long.

To be sure, just check the file-system again with:

root@ubuntu:~# e2fsck -f /dev/mapper/ubuntu--vg-root
e2fsck 1.44.1 (24-Mar-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/ubuntu--vg-root: 177123/14745600 files (0.1% non-contiguous), 2426029/58982400 blocks

you can now safely reduce the size of the logical-volume with:

root@ubuntu:~# lvreduce -L 225G -r /dev/ubuntu-vg/root 
fsck from util-linux 2.31.1
/dev/mapper/ubuntu--vg-root: clean, 177123/14745600 files, 2426029/58982400 blocks
resize2fs 1.44.1 (24-Mar-2018)
The filesystem is already 58982400 (4k) blocks long. Nothing to do!
Size of logical volume ubuntu-vg/root changed from 236.25 GiB (60481 extents) to 225.00 GiB (57600 extents).
Logical volume ubuntu-vg/root successfully resized.

You can remove the old swap volume:

root@ubuntu:~# lvremove /dev/ubuntu-vg/swap_1 
Do you really want to remove and DISCARD active logical volume ubuntu-vg/swap_1? [y/n]: y
Logical volume "swap_1" successfully removed

…and create a new bigger one. This following command says “use the remaining space”, and note that volume names are kept the same.

root@ubuntu:~# lvcreate -l 100%FREE -n swap_1 ubuntu-vg 
Logical volume "swap_1" created.

Check what’s just been done, the list of logical-volumes:

root@ubuntu:~# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root ubuntu-vg -wi-a----- 225.00g
swap_1 ubuntu-vg -wi-a----- 12.25g

Create the swap file-system:

root@ubuntu:~# mkswap -L swap_1 /dev/ubuntu-vg/swap_1 
Setting up swapspace version 1, size = 12.3 GiB (13157527552 bytes)
LABEL=swap_1, UUID=4a10e0f5-44d7-4f57-ae23-de172958e7f1

And adapt the fstab if required. If you gave it the same logical-volume name than it already was, you can skip this step. Ubuntu 18.04 uses LV names instead of UUID.

root@ubuntu:~# mount /dev/ubuntu-vg/root /mnt/
root@ubuntu:~# vi /mnt/etc/fstab
root@ubuntu:~# umount /mnt

Write last changes to the disk:

root@ubuntu:~# pvchange -x n /dev/mapper/crypt1
Physical volume "/dev/mapper/crypt1" changed
1 physical volume changed / 0 physical volumes not changed

…and deactivate open volume-groups:

root@ubuntu:~# vgchange -an
0 logical volume(s) in volume group "ubuntu-vg" now active
root@ubuntu:~# cryptsetup luksClose crypt1

You can now restart your machine and boot your installed operating system. You will be prompted for the password at boot to decrypt the LUKS volume. Everything should work as before, but this time with a bigger swap partition.

Lastly, you’ll have to change a line in /etc/default/grub to tell your kernel that there possibly is the content of your RAM in your swap when booting. If so, it should “resume” from hibernation.

GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=4a10e0f5-44d7-4f57-ae23-de172958e7f1"

Where the value of UUID is the string returned when running mkswap to make the swap. If you don’t find it back in your terminal, just run:

lsblk -o NAME,UUID

Once GRUB defaults updated you will need to update the actual GRUB config files with the command

sudo update-grub

Reboot your machine, test the hibernation. If this works as it should, tap your own shoulder: Congratulation, the hardest work is done.

Configure hardware events and enable “hibernate” in the system actions (top right menu)

I wanted my laptop to suspend when I close the lid and hibernate after a defined time if the suspend isn’t resumed (namely: the lid kept closed)

To enable that, edit as system-logind configuration file:

sudo vim /etc/systemd/logind.conf

You’ll be prompted for the root password. If you don’t know how to use vim just grow up and learn.
Vi won’t be be removed from major distribution anytime soon.

Well, uncomment and edit the HandleHibernateKey and HandleLidSwitch variables:

[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#HandlePowerKey=poweroff
#HandleSuspendKey=suspend
HandleHibernateKey=hibernate
HandleLidSwitch=suspend-then-hibernate
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=
#LidSwitchIgnoreInhibited=yes
#HoldoffTimeoutSec=30
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192
#UserTasksMax=33%

The timeout to switch from suspend to hibernate can be set in /etc/systemd/sleep.conf. The file might not yet exists.

sudo vim /etc/systemd/sleep.conf
[sleep]
HibernateDelaySec=900

I found 15 minutes a good delay for an old 1th generation with a battery holding about 2h. For a 3rd generation with a much better battery (and economic architecture), I switched it to one hour.

When you are done, restart systemd-logind service with the following command:

sudo systemctl restart systemd-logind.service

If you need to debug the service, and possibly find a mistake in your config file, just check the logs:

sudo journalctl -u systemd-logind.service

Next, to enable the “hibernate” button in the system menu edit the /etc/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla file.

sudo vim /etc/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla

with the following content

[Re-enable hibernate by default in upower]
Identity=unix-user:* Action=org.freedesktop.upower.hibernate ResultActive=yes

[Re-enable hibernate by default in logind]
Identity=unix-user:* Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions;org.freedesktop.login1.hibernate-ignore-inhibit ResultActive=yes

When your computer is in hibernation and you push the power button, you’ll be asked for a password, just like a normal boot. That’s right, the content of your RAM has been saved to the hard-drive and the machine completely turned off. To resume it, the volume need to be decrypted again, and for that your password is asked.

That’s it for the hibernation.

Trackpad

Install the synaptic driver

xserver-xorg-input-synaptics-hwe-18.04

and copy the following content in /etc/X11/Xsession.d/56_synaptic_fix :

 export `xinput list | grep -i touchpad | awk '{ print $6 }'`
xinput --set-prop "$id" "Synaptics Noise Cancellation" 20 20
xinput --set-prop "$id" "Synaptics Finger" 35 45 250
xinput --set-prop "$id" "Synaptics Scrolling Distance" 180 180
true

Ensure that the owner of the file is root and permissions 644. Restart your session and you’ll have a usable trackpad.

Fingerprint scanner

Just install the pam package to enable fingerprint authentication on Ubuntu:

sudo apt install libpam-fprint

Then run the following command to teach your system to use the fingerprint as an authentication system:

sudo pam-auth-update

…and select the fingerprint option

You’ll find a new “Fingerprint login” option in users settings to register one finger.

Keep in mind that the finger-print authentication is not the safest thing ever. Your finger isn’t a password, it’s an image and the computer will try to “guess” if this is you, with potential mistakes. You will be able to log in with this technique, but not to unlock your password-keychain. For the latter you’ll always need a real password.

References

http://ubuntuhandbook.org/index.php/2018/05/add-hibernate-option-ubuntu-18-04/

https://help.ubuntu.com/community/PowerManagement/Hibernat

https://help.ubuntu.com/community/ResizeEncryptedPartition

https://askubuntu.com/questions/1049526/fingerprint-activation-on-ubuntu-18-04

https://ubuntu-mate.community/t/hibernate-resume-from-hibernation-ubuntu-mate-18-04/16924

https://help.ubuntu.com/community/EnableHibernateWithEncryptedSwap

https://askubuntu.com/questions/1072504/lid-closed-suspend-then-hibernate

https://wiki.archlinux.org/index.php/Dm-crypt/Swap_encryption