How to boot Ubuntu 18.04 into emergency and rescue mode

Objective

Learning about systemd emergency and rescue targets and how to boot the system into them

Requirements

  • No special requirements

Difficulty

EASY

Conventions

  • # – requires given linux commands to be executed with root privileges either
    directly as a root user or by use of sudo command
  • $ – requires given linux commands to be executed as a regular non-privileged user

Introduction

Systemd has nowadays become the de facto standard init system for all the major Linux distributions.

Superseding SysV and upstart, it also replaced the classical way of defining system runlevels, using system targets, a special type of unit.

In this tutorial we will see how to boot an Ubuntu 18.04 system into the emergency and rescue systemd targets, and what kind of environment they provide to the users.

Systemd targets vs classic runlevels

Systemd has introduced the concept of targets which replaced the classic system runlevels.

As an example, what was know as runlevel 0 in SysV, which represents the halt state of the machine, is the equivalent of the systemd poweroff target.

Similarly,
runlevel 1 or single user mode finds its systemd equivalent in the rescue target.

Finally, runlevels 5 and 6, used respectively for the graphical mode and to reboot the system, have now been replaced by the graphical and reboot targets. The rescue and the similar emergency targets, are what we will talk about in this tutorial: they are very useful to fix some critical situations.



The emergency target

The emergency target is the most minimal environment the system can be booted in.

Once this target is reached, an emergency shell is started on the main console.

Other than that, only systemd itself is available to the user: only the root filesystem is mounted (in read-only mode) and no services are started (this would also mean that you will have no access to the network).

This is the target we are dropped in when the boot process cannot be successfully completed (when a filesystem check fails, for example).

How the emergency target is defined

To check how the emergency target is defined, we must inspect the dedicated systemd unit.

We can use the systemctl cat command to accomplish this task:

$ systemctl cat emergency.target

# /lib/systemd/system/emergency.target
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Emergency Mode
Documentation=man:systemd.special(7)
Requires=emergency.service
After=emergency.service
AllowIsolate=yes

As we can see from the output above, the emergency.target requires the related emergency.service as a dependency. Let’s take a look at it too:

$ systemctl cat emergency.service

# /lib/systemd/system/emergency.service
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Emergency Shell
Documentation=man:sulogin(8)
DefaultDependencies=no
Conflicts=shutdown.target
Conflicts=rescue.service
Before=shutdown.target
Before=rescue.service

[Service]
Environment=HOME=/root
WorkingDirectory=-/root
ExecStart=-/lib/systemd/systemd-sulogin-shell emergency
Type=idle
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

The definition of the service gives us very clear information.

First of all, the HOME environment variable is defined through the Environment keyword, and corresponds to the home directory of the root user.

This is also the working directory used by default when the emergency.target is reached.

When this service is started, the /lib/systemd/systemd-sulogin-shell executable is called, which, in turn, invokes /usr/sbin/sulogin, responsible for providing us a login for the single user shell.



How to access emergency.target at boot

To force the system to boot in to the emergency.target, we must modify the grub menu.

This is a very easy operation. When the grub menu appears, just select the first entry, and press e to edit:

ubuntu-grub-menu

Once you press the e key, you will be able to modify the boot parameters and the kernel command line.

Search for the line starting with linux:

ubuntu-grub-edit-menu

At this point, hit CTRL-e to reach the end of the line, delete $vt_handoff and add the systemd.unit=emergency.target directive (you can also just use emergency as an alias, for SysV compatibility), so that your line will look this way:

ubuntu-grub-emergency

If you now press CTRL-x or F10, the system will boot in to emergency mode:

ubuntu 18.04 emergency mode

Ubuntu 18.04 emergency mode

The rescue.target

This is the systemd target that can be associated to the old single user mode.

Unlike what happens with the emergency.target, when this target is reached, the base system is pulled in: all filesystems are mounted and the most basic services are launched and made available to the user.

The rescue.target is defined in the /lib/systemd/system/rescue.target file:

# /lib/systemd/system/rescue.target
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Rescue Mode
Documentation=man:systemd.special(7)
Requires=sysinit.target rescue.service
After=sysinit.target rescue.service
AllowIsolate=yes

The rescue.target, just like what happens for the emergency.target, requires the related rescue.service, plus the sysinit.target.

The former, just like the emergency.service, basically provides the single user login, while the latter pulls in the services required for the system initialization (unlike the emergency.target, the rescue.target is more than a simple shell).



Boot into the rescue.target

The procedure to boot the system into rescue.target is the same we followed to make it boot into the emergency target.

The only thing that needs to be changed is the argument added to the kernel command line: instead of systemd.unit=emergency.target, we will use systemd.unit=rescue.target; again we can also use an alias for SysV compatibility, replacing the directive with just 1.

ubuntu-grub-rescue

Once started, the system will boot into the rescue.target, where we can administer the system in single user mode:

ubuntu 18.04 rescue mode

Ubuntu 18.04 rescue mode

Conclusions

We quickly examined what the systemd emergency and rescue targets are, in what they are different, and what kind of environment the provide to the user.

We also saw how to edit the grub menu to change the kernel command line and boot the system directly in to these targets.

It’s important to say that systemd targets can also be reached, from an already running system, by “isolating”, them, using systemctl.

For example, running:

# systemctl isolate rescue.target

will bring the system to the rescue target.

For a more in depth knowledge of the systemd special units, we can consult the related, very clear manpage (SYSTEMD.SPECIAL(7)).