Beim Hochfahren des Rechners zeigen die zahlreichen Meldungen, die auf der Konsole vorüberrollen, viele selbsttätig ausgeführte Initialisierungen und Konfigurationen an. Manchmal möchten Sie vielleicht den Ablauf dieser Phase etwas verändern, weshalb Sie sie gut verstehen müssen. Das ist der Zweck dieses Abschnitts.
On systems with a BIOS, first, the BIOS takes control of the computer, initializes the controllers and hardware, detects the disks, and bridges everything together. Then it looks up the Master Boot Record (MBR) of the first disk in the boot order and loads the code stored there (first stage). This code then launches the second stage and finally executes the bootloader.
In contrast to the BIOS, UEFI is more sophisticated, it knows filesystems and can read the partition tables. The interface searches the system storage for a partition labeled with a specific globally unique identifier (
GUID) that marks it as the
EFI System Partition (
ESP), where the bootloaders, boot managers, UEFI shell, etc., are located, and launches the desired bootloader. If Secure Boot is enabled, the boot process will verify authenticity of the EFI binaries there by signature (thus
grub-efi-arch-signed is required in this case). The UEFI specification also defines support for booting in legacy BIOS mode. This is called the
Compatibility Support Module (
CSM). If CSM is enabled, it will attempt to boot from a drive's MBR. However, many new systems do no longer support the CSM mode.
In both cases then the actual bootloader takes over, finds either a chained bootloader or the kernel on the disk, loads, and executes it. The kernel is then initialized, and starts to search for and mount the partition containing the root filesystem, and finally executes the first program — init
. Frequently, this “root partition” and this init
are, in fact, located in a virtual filesystem that only exists in RAM (hence its name, “initramfs”, formerly called “initrd” for “initialization RAM disk”). This filesystem is loaded in memory by the bootloader, often from a file on a hard drive or from the network. It contains the bare minimum required by the kernel to load the “true” root filesystem: this may be driver modules for the hard drive, or other devices without which the system cannot boot, or, more frequently, initialization scripts and modules for assembling RAID arrays, opening encrypted partitions, activating LVM volumes, etc. Once the root partition is mounted, the initramfs hands over control to the real init, and the machine goes back to the standard boot process.
9.1.1. Das systemd Initialisierungssystem
Das "tatsächliche init" wird zur Zeit von systemd bereitgestellt und dieser Abschnitt beschreibt das Init-System.
Systemd führt mehrere Prozesse aus, die für die Einrichtung des Systems verantwortlich sind: Tastatur, Treiber, Dateisysteme, Netzwerk, Dienste. Dabei behält es den Überblick über das Gesamtsystem und die Anforderungen der Komponenten. Jede Komponente wird durch eine "Unit-Datei" (manchmal auch mehrere) beschrieben; die allgemeine Syntax ergibt sich aus der weit verbreiteten "*.ini-Dateien" Syntax, mit key = value
Paare gruppiert zwischen [section]
headers. Unit-Dateien werden unter /lib/system/system/
und /etc/systemd/system/
gespeichert; es gibt sie in verschiedenen Varianten, aber wir werden uns hier auf "services" und "targets" konzentrieren.
A systemd “.service
file” describes a process managed by systemd. It contains roughly the same information as old-style init-scripts, but expressed in a declaratory (and much more concise) way. Systemd handles the bulk of the repetitive tasks (starting and stopping the process, checking its status, logging, dropping privileges, and so on), and the service file only needs to fill in the specifics of the process. For instance, here is the service file for SSH:
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
Alias=sshd.service
The [Unit]
section contains generic information about the service, like its description and manual page resources, as well as relations (dependency and order) to other services. The [Service]
part contains the declarations related to the service execution (starting, stopping, killing, restarting), directories and configuration file(s) used. The last section, [Install]
, again carries generic information into which targets to install the service and, in this case, the alias that can be used instead of the service name. As you can see, there is very little code in there, only declarations. Systemd takes care of displaying progress reports, keeping track of the processes, and even restarting them when needed. The syntax of these files is fully described in several manual pages (e.g. systemd.service(5), systemd.unit(5), systemd.exec(5), etc.).
A systemd “.target
file” describes a state of the system where a set of services are known to be operational. It can be thought of as an equivalent of the old-style runlevel. One of the pre-defined targets is local-fs.target
; when it is reached, the rest of the system can assume that all local filesystems are mounted and accessible. Other targets include network-online.target
and sound.target
(for a full list of special targets see systemd.special(7)). The dependencies of a target can be listed either within the target file (in the Requires=
line), or using a symbolic link to a service file in the /lib/systemd/system/targetname.target.wants/
directory. For instance, /etc/systemd/system/printer.target.wants/
contains a link to /lib/systemd/system/cups.service
; systemd will therefore ensure CUPS is running in order to reach printer.target
.
Da Unit-Dateien, anders als Skripte oder Programme, eher deklarativ sind, können sie nicht direkt ausgeführt werden und werden von systemd nur interpretiert. Mehrere Dienstprogramme erlauben es dem Administrator daher, mit systemd zu interagieren und den Zustand des Systems und jeder Komponente zu kontrollieren.
Das erste derartige Dienstprogramm ist systemctl
. Wenn es ohne Argumente ausgeführt wird, listet es alle dem System bekannten Unit-Dateien (mit Ausnahme derjenigen, die deaktiviert wurden) sowie deren Status auf. systemctl status
gibt einen besseren Überblick über die Dienste und die damit verbundenen Prozesse. Wenn der Name eines Dienstes angegeben wird (wie in systemctl status ntp.service
), gibt er noch mehr Details zurück, sowie die letzten Log-Zeilen, die sich auf den Dienst beziehen (mehr dazu später).
Das Starten eines Dienstes von Hand ist einfach das Starten von systemctl start servicename.service
. Wie man leicht erraten kann, wird der Dienst mit systemctl stop servicename.service
beendet; andere Unterbefehle beinhalten reload
und restart
.
Um zu steuern, ob ein Dienst aktiv ist (d.h. ob er beim Booten automatisch gestartet wird), verwenden Sie systemctl enable servicename.service
(oder disable
). is-enabled
ermöglicht die Überprüfung des Status des Dienstes.
Eine interessante Eigenschaft von systemd ist, dass es eine Protokollierungskomponente namens journald
enthält. Es ist eine Ergänzung zu herkömmlichen Protokollierungssystemen wie syslogd
, aber es fügt interessante Funktionen hinzu, wie eine formale Verbindung zwischen einem Dienst und den von ihm erzeugten Nachrichten und die Fähigkeit, Fehlermeldungen zu erfassen, die durch seine Initialisierungssequenz erzeugt werden. Die Meldungen können später mithilfe des Befehls journalctl
angezeigt werden. Ohne Argumente spuckt es einfach alle Logmeldungen aus, die seit dem Systemstart aufgetreten sind; es wird selten so verwendet. Meistens wird es mit einer Service-Kennung verwendet:
#
journalctl -u ssh.service
-- Logs begin at Tue 2015-03-31 10:08:49 CEST, end at Tue 2015-03-31 17:06:02 CEST. --
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:08:55 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Received SIGHUP; restarting.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
Mar 31 10:09:00 mirtuel sshd[430]: Server listening on :: port 22.
Mar 31 10:09:32 mirtuel sshd[1151]: Accepted password for roland from 192.168.1.129 port 53394 ssh2
Mar 31 10:09:32 mirtuel sshd[1151]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Ein weiterer nützlicher Kommandozeilenparameter ist -f
, der journalctl
anweist, neue Nachrichten so anzuzeigen, wie sie ausgegeben werden (ziemlich so wie tail -f file
).
Wenn ein Dienst nicht wie erwartet funktioniert, ist der erste Schritt zur Lösung des Problems die Überprüfung, ob der Dienst tatsächlich läuft: systemctl status
. Wenn dies nicht der Fall ist und die Meldungen des ersten Befehls nicht ausreichen, um das Problem zu diagnostizieren, überprüfen Sie die von journald über diesen Dienst gesammelten Protokolle. Angenommen, der SSH-Server funktioniert nicht:
#
systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
Active: failed (Result: start-limit) since Tue 2015-03-31 17:30:36 CEST; 1s ago
Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 1188 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)
Main PID: 1188 (code=exited, status=255)
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
#
journalctl -u ssh.service
-- Logs begin at Tue 2015-03-31 17:29:27 CEST, end at Tue 2015-03-31 17:30:36 CEST. --
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:27 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Received SIGHUP; restarting.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
Mar 31 17:29:29 mirtuel sshd[424]: Server listening on :: port 22.
Mar 31 17:30:10 mirtuel sshd[1147]: Accepted password for roland from 192.168.1.129 port 38742 ssh2
Mar 31 17:30:10 mirtuel sshd[1147]: pam_unix(sshd:session): session opened for user roland by (uid=0)
Mar 31 17:30:35 mirtuel sshd[1180]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1182]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:35 mirtuel sshd[1184]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1186]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel sshd[1188]: /etc/ssh/sshd_config line 28: unsupported option "yess".
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
Mar 31 17:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
Mar 31 17:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
Mar 31 17:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
#
vi /etc/ssh/sshd_config
#
systemctl start ssh.service
#
systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
Active: active (running) since Tue 2015-03-31 17:31:09 CEST; 2s ago
Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
Main PID: 1222 (sshd)
CGroup: /system.slice/ssh.service
└─1222 /usr/sbin/sshd -D
#
Nachdem wir den Status des Dienstes überprüft haben (failed), haben wir die Protokolle überprüft; sie zeigen einen Fehler in der Konfigurationsdatei an. Nachdem wir die Konfigurationsdatei bearbeitet und den Fehler behoben haben, starten wir den Dienst neu und überprüfen, ob er tatsächlich läuft.
9.1.2. Das System V Initialisierungssystem
The System V init system (which we'll call init for brevity) executes several processes, following instructions from the /etc/inittab
file. The first program that is executed (which corresponds to the sysinit step) is /etc/init.d/rcS
, a script that executes all of the programs in the /etc/rcS.d/
directory.
Unter diesen befinden sich nacheinander Programme, die zuständig sind für:
das Konfigurieren der Konsolentastatur;
das Laden von Treibern: die meisten Kernelmodule werden beim Erkennen der Hardware vom Kernel selbst geladen; zusätzliche Treiber werden selbsttätig geladen, wenn die entsprechenden Module in der Datei /etc/modules
aufgeführt sind;
die Integritätsprüfung von Dateisystemen;
das Einhängen lokaler Partitionen;
das Konfigurieren des Netzwerks;
das Einhängen von Netzwerkdateisystemen (NFS).
Nach dieser Phase übernimmt init
und startet die im Standard-Runlevel (der normalerweise Runlevel 2 ist) aktivierten Programme. Es führt /etc/init.d/rc 2
aus, ein Skript, das alle Dienste startet, die in /etc/rc2.d/
aufgeführt sind und mit dem Buchstaben „S“ beginnen. Die anschließenden zweistelligen Zahlen wurden früher dazu benutzt, die Reihenfolge festzulegen, in der die Dienste gestartet werden mussten, aber heute verwendet das Standard-Bootsystem insserv
, das ausgehend von den Abhängigkeiten der Skripten alles selbsttätig zeitlich festlegt. Jedes Boot-Skript legt die Bedingungen fest, die gelten müssen, damit ein Dienst gestartet oder beendet wird (ob er zum Beispiel vor oder nach einem anderen Dienst gestartet werden muss); init
startet sie dann in der Reihenfolge, die diese Bedingungen erfüllt. Die feststehende Nummerierung der Skripten wird daher nicht mehr berücksichtigt (sie müssen trotzdem weiterhin einen Namen haben, der mit „S“ beginnt gefolgt von zwei Zahlen und dem Namen des Skripts, das für die Abhängigkeiten verwendet wird). Im Allgemeinen werden grundlegende Dienste (wie das Protokollieren mit rsyslog
oder die Portzuweisung mit portmap
) als erste gestartet, gefolgt von Standarddiensten und der grafischen Schnittstelle (gdm3
).
Dieses Bootsystem auf der Grundlage von Abhängigkeiten ermöglicht es, die Neu-Nummerierung zu automatisieren, die recht mühsam wäre, wenn sie von Hand erledigt werden müsste, und es begrenzt das Risiko menschlichen Versagens, da die Festlegung der zeitlichen Abfolge in Übereinstimmung mit den angegebenen Parametern erfolgt. Ein weiterer Vorteil besteht darin, dass voneinander unabhängige Dienste zeitgleich gestartet werden können, was den Prozess des Hochfahrens beschleunigt.
init
unterscheidet zwischen verschiedenen Runleveln, so dass es mit dem Befehl telinit neuer-level
von einem zum anderen umschalten kann. init
führt bei einem neuen Runlevel unmittelbar ein weiteres Mal /etc/init.d/rc
aus. Dieses Skript startet dann die fehlenden Dienste und beendet die nicht mehr benötigten. Hierzu bezieht es sich auf den Inhalt der Datei /etc/rcX.d
(wobei X den neuen Runlevel bezeichnet). Skripten, deren Namen mit „S“ beginnen (wie in „Start“), verweisen auf zu startende Dienste, solche mit „K“ (wie in „Kill“) auf zu beendende. Das Skript startet keine Dienste, die im vorherigen Runlevel bereits aktiv waren.
Standardmäßig verwendet System V init in Debian vier verschiedene Runlevel:
Level 0 wird nur vorübergehend beim Herunterfahren des Rechners benutzt. Daher enthält er nur zahlreiche „K“-Skripten.
Level 1, auch Single-User Modus genannt, entspricht dem System in rudimentärem Zustand. Er umfasst einzig grundlegende Dienste und ist hauptsächlich für die Systemwartung gedacht, bei dem Interaktionen mit normalen Benutzern nicht erwünscht sind.
Level 2 ist der Level für den Normalbetrieb, der Netzwerkdienste, eine grafische Schnittstelle, Benutzeranmeldungen usw. umfasst.
Level 6 gleicht Level 0, nur dass er während des Herunterfahrens vor einem Neustart verwendet wird.
Es gibt weitere Level, insbesondere 3 bis 5. Standardmäßig sind sie so konfiguriert, dass sie sich wie Level 2 verhalten. Jedoch kann der Administrator sie verändern (indem er in den entsprechenden Verzeichnissen unter /etc/rcX.d
Skripten hinzufügt oder löscht), um sie so besonderen Bedürfnissen anzupassen.
All the scripts contained in the various /etc/rcX.d
directories are really only symbolic links — created upon package installation by the update-rc.d
program — pointing to the actual scripts which are stored in /etc/init.d/
. The administrator can fine tune the services available in each runlevel by re-running update-rc.d
with adjusted parameters. The update-rc.d(1) manual page describes the syntax in detail. Please note that removing all symbolic links (with the remove
parameter) is not a good method to disable a service. Instead you should simply configure it to not start in the desired runlevel (while preserving the corresponding calls to stop it in the event that the service runs in the previous runlevel). Since update-rc.d
has a somewhat convoluted interface, you may prefer using rcconf
(from the rcconf package) which provides a more user-friendly interface.
Schließlich startet init
Steuerprogramme für mehrere virtuelle Konsolen (getty
). Es zeigt eine Eingabeaufforderung an, in der es auf einen Benutzernamen wartet, und führt dann login benutzer
aus, um eine Sitzung zu starten.