From cb3801a4c913a924cb4e339af9a27610febe6c47 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Fri, 29 Nov 2024 11:29:17 +0100 Subject: [PATCH 1/2] man/debug-generator: add a section for kernel command line options --- man/systemd-debug-generator.xml | 97 +++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml index 744fcb9c7a3..90fc9c6d67f 100644 --- a/man/systemd-debug-generator.xml +++ b/man/systemd-debug-generator.xml @@ -31,45 +31,71 @@ Description - systemd-debug-generator is a generator - that reads the kernel command line and understands three - options: + systemd-debug-generator is a generator that provides some debugging + functionality. - If the or - option is specified and followed by a unit name, this unit is - masked for the runtime (i.e. for this session — from boot to shutdown), similarly to the effect of - systemctl1's - mask command. This is useful to boot with - certain units removed from the initial boot transaction for - debugging system startup. May be specified more than once. - is honored only by initial - RAM disk (initrd) while is - honored only in the main system. - - If the or - option is specified - and followed by a unit name, a start job for this unit is added to - the initial transaction. This is useful to start one or more - additional units at boot. May be specified more than once. - is honored only by initial - RAM disk (initrd) while is - honored only in the main system. - - If the or option is - specified, the debug shell service debug-shell.service is pulled into the boot - transaction and a debug shell will be spawned during early boot. By default, - &DEBUGTTY; is used, but a specific tty can also be specified, either with or without - the /dev/ prefix. To set the tty to use without enabling the debug shell, the - option can be used which also takes a tty with or without the - /dev/ prefix. Note that the shell may also be turned on persistently by enabling it - with systemctl1's - enable command. is honored only by initial - RAM disk (initrd) while is honored only in the main system. - - systemd-debug-generator implements + systemd-debug-generator implements systemd.generator7. + + Kernel Command Line + + systemd-debug-generator understands the following kernel command line + parameters: + + + + + systemd.mask= + rd.systemd.mask= + + These options take a unit name as argument. The unit specified is masked for the + runtime (i.e. for this session — from boot to shutdown), similarly to the effect of + systemctl1's + mask command. This is useful to boot with certain units removed from the initial + boot transaction for debugging system startup. May be specified more than once. The option prefixed + with rd. is honored only in the initrd, while the one without prefix is only + honored in the main system. + + + + + + systemd.wants= + rd.systemd.wants= + + These options take a unit name as argument. A start job for this unit is added to the + initial transaction. This is useful to start one or more additional units at boot. May be specified + more than once. The option prefixed with rd. is honored only in the initrd, while + the one that is not prefixed only in the main system. + + + + + + systemd.debug_shell + rd.systemd.debug_shell + systemd.default_debug_tty= + rd.systemd.default_debug_tty= + + If the or + option is specified, the debug shell service + debug-shell.service is pulled into the boot transaction and a debug shell will be + spawned during early boot. By default, &DEBUGTTY; is used, but a specific tty + can also be specified, either with or without the /dev/ prefix. To set the tty + to use without enabling the debug shell, the option can + be used which also takes a tty with or without the /dev/ prefix. Note that the + shell may also be turned on persistently by enabling it with + systemctl1's + enable command. The options prefixed with rd. are honored only + in the initrd, while the ones without prefix are only honored in the main system. + + + + + + System Credentials @@ -108,6 +134,7 @@ systemd1 systemctl1 kernel-command-line7 + systemd.system-credentials7 From e9f781a5a4721d3e58798b37e30bb4dcdbe54c02 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Fri, 20 Dec 2024 08:51:23 +0100 Subject: [PATCH 2/2] debug-generator: add a kernel cmdline option to pause the boot process Introduce the `systemd.break=` kernel command line option to allow stopping the boot process at a certain point and spawn a debug shell. After exiting this shell, the system will resume booting. It accepts the following values: - `pre-udev`: before starting to process kernel uevents (initrd and host). - `pre-basic`: before leaving early boot and regular services start (initrd and host). - `pre-mount`: before the root filesystem is mounted (initrd). - `pre-switch-root`: before switching root (initrd). --- man/kernel-command-line.xml | 12 +++ man/systemd-debug-generator.xml | 61 +++++++++++ src/debug-generator/debug-generator.c | 101 ++++++++++++++++++ .../TEST-81-GENERATORS.debug-generator.sh | 89 +++++++++++++++ units/breakpoint-pre-basic.service.in | 35 ++++++ units/breakpoint-pre-mount.service.in | 36 +++++++ units/breakpoint-pre-switch-root.service.in | 37 +++++++ units/breakpoint-pre-udev.service.in | 36 +++++++ units/meson.build | 4 + 9 files changed, 411 insertions(+) create mode 100644 units/breakpoint-pre-basic.service.in create mode 100644 units/breakpoint-pre-mount.service.in create mode 100644 units/breakpoint-pre-switch-root.service.in create mode 100644 units/breakpoint-pre-udev.service.in diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index baa71222040..94bc8740094 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -97,6 +97,18 @@ + + systemd.break= + rd.systemd.break= + + Parameters understood by + systemd-debug-generator8, + to pause the boot process at a certain point and spawn a debug shell. + + + + + systemd.run= systemd.run_success_action= diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml index 90fc9c6d67f..529d834b83b 100644 --- a/man/systemd-debug-generator.xml +++ b/man/systemd-debug-generator.xml @@ -93,6 +93,66 @@ + + + systemd.break= + rd.systemd.break= + + Takes one of , , + , or (the default for the + rd. option). It also accepts multiple values separated by comma + (,). These options allow to pause the boot process at a certain point and spawn a + debug shell. After exiting this shell, the system will resume booting. The option prefixed with + rd. is honored only in the initrd, while the one without prefix is only honored in + the main system. + + + Available breakpoints + + + + + + + + + Breakpoints + Description + Can be used in the initrd + Can be used in the main system + + + + + + Before starting to process kernel uevents, i.e., before systemd-udevd.service starts. + + + + + + Before leaving early boot and regular services start, i.e., before basic.target is reached. + + + + + + Before the root filesystem is mounted, i.e., before sysroot.mount starts. + + + + + + Before switching from the initrd to the real root. + + + + + +
+ +
+
@@ -135,6 +195,7 @@ systemctl1 kernel-command-line7 systemd.system-credentials7 + bootup7 diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c index 664d57d452f..edc8e5f5f49 100644 --- a/src/debug-generator/debug-generator.c +++ b/src/debug-generator/debug-generator.c @@ -3,9 +3,11 @@ #include #include "alloc-util.h" +#include "bitfield.h" #include "creds-util.h" #include "dropin.h" #include "errno-util.h" +#include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "generator.h" @@ -27,6 +29,7 @@ static char **arg_wants = NULL; static bool arg_debug_shell = false; static char *arg_debug_tty = NULL; static char *arg_default_debug_tty = NULL; +static uint32_t arg_breakpoints = 0; STATIC_DESTRUCTOR_REGISTER(arg_default_unit, freep); STATIC_DESTRUCTOR_REGISTER(arg_mask, strv_freep); @@ -34,6 +37,91 @@ STATIC_DESTRUCTOR_REGISTER(arg_wants, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_debug_tty, freep); STATIC_DESTRUCTOR_REGISTER(arg_default_debug_tty, freep); +typedef enum BreakpointType { + BREAKPOINT_PRE_UDEV, + BREAKPOINT_PRE_BASIC, + BREAKPOINT_PRE_SYSROOT_MOUNT, + BREAKPOINT_PRE_SWITCH_ROOT, + _BREAKPOINT_TYPE_MAX, + _BREAKPOINT_TYPE_INVALID = -EINVAL, +} BreakpointType; + +typedef enum BreakpointValidity { + BREAKPOINT_DEFAULT = 1 << 0, + BREAKPOINT_IN_INITRD = 1 << 1, + BREAKPOINT_ON_HOST = 1 << 2, +} BreakpointValidity; + +typedef struct BreakpointInfo { + BreakpointType type; + const char *name; + const char *unit; + BreakpointValidity validity; +} BreakpointInfo; + +static const struct BreakpointInfo breakpoint_info_table[_BREAKPOINT_TYPE_MAX] = { + { BREAKPOINT_PRE_UDEV, "pre-udev", "breakpoint-pre-udev.service", BREAKPOINT_IN_INITRD | BREAKPOINT_ON_HOST }, + { BREAKPOINT_PRE_BASIC, "pre-basic", "breakpoint-pre-basic.service", BREAKPOINT_IN_INITRD | BREAKPOINT_ON_HOST }, + { BREAKPOINT_PRE_SYSROOT_MOUNT, "pre-mount", "breakpoint-pre-mount.service", BREAKPOINT_IN_INITRD }, + { BREAKPOINT_PRE_SWITCH_ROOT, "pre-switch-root", "breakpoint-pre-switch-root.service", BREAKPOINT_IN_INITRD | BREAKPOINT_DEFAULT }, +}; + +static BreakpointType parse_breakpoint_from_string_one(const char *s) { + assert(s); + + FOREACH_ARRAY(i, breakpoint_info_table, ELEMENTSOF(breakpoint_info_table)) + if (streq(i->name, s)) + return i->type; + + return _BREAKPOINT_TYPE_INVALID; +} + +static int parse_breakpoint_from_string(const char *s, uint32_t *ret_breakpoints) { + uint32_t breakpoints = 0; + int r; + + assert(ret_breakpoints); + + /* Empty value? set default breakpoint */ + if (isempty(s)) { + if (in_initrd()) { + FOREACH_ARRAY(i, breakpoint_info_table, ELEMENTSOF(breakpoint_info_table)) + if (i->validity & BREAKPOINT_DEFAULT) { + breakpoints |= 1 << i->type; + break; + } + } else + log_warning("No default breakpoint defined on the host, ignoring breakpoint request from kernel command line."); + } else + for (;;) { + _cleanup_free_ char *t = NULL; + BreakpointType tt; + + r = extract_first_word(&s, &t, ",", EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return r; + if (r == 0) + break; + + tt = parse_breakpoint_from_string_one(t); + if (tt < 0) { + log_warning("Invalid breakpoint value '%s', ignoring.", t); + continue; + } + + if (in_initrd() && !FLAGS_SET(breakpoint_info_table[tt].validity, BREAKPOINT_IN_INITRD)) + log_warning("Breakpoint '%s' not valid in the initrd, ignoring.", t); + else if (!in_initrd() && !FLAGS_SET(breakpoint_info_table[tt].validity, BREAKPOINT_ON_HOST)) + log_warning("Breakpoint '%s' not valid on the host, ignoring.", t); + else + breakpoints |= 1 << tt; + } + + *ret_breakpoints = breakpoints; + + return 0; +} + static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { int r; @@ -88,6 +176,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return free_and_strdup_warn(&arg_default_unit, value); + } else if (streq(key, "systemd.break")) { + uint32_t breakpoints = 0; + + r = parse_breakpoint_from_string(value, &breakpoints); + if (r < 0) + return log_warning_errno(r, "Failed to parse breakpoint value '%s': %m", value); + + arg_breakpoints |= breakpoints; + } else if (!value) { const char *target; @@ -269,6 +366,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late) RET_GATHER(r, install_debug_shell_dropin()); } + BIT_FOREACH(i, arg_breakpoints) + if (strv_extend(&arg_wants, breakpoint_info_table[i].unit) < 0) + return log_oom(); + if (get_credentials_dir(&credentials_dir) >= 0) RET_GATHER(r, process_unit_credentials(credentials_dir)); diff --git a/test/units/TEST-81-GENERATORS.debug-generator.sh b/test/units/TEST-81-GENERATORS.debug-generator.sh index ef1e205aacf..08ce2d66af4 100755 --- a/test/units/TEST-81-GENERATORS.debug-generator.sh +++ b/test/units/TEST-81-GENERATORS.debug-generator.sh @@ -69,6 +69,51 @@ SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" link_endswith "$OUT_DIR/early/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service grep -F "/dev/tty666" "$OUT_DIR/early/debug-shell.service.d/50-tty.conf" +# systemd.break (default) +: "debug-shell: regular + systemd.break" +CMDLINE="$CMDLINE systemd.break" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service" + +# systemd.break=pre-switch-root +: "debug-shell: regular + systemd.break=pre-switch-root" +CMDLINE="$CMDLINE systemd.break=pre-switch-root" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service" + +# systemd.break=pre-mount +: "debug-shell: regular + systemd.break=pre-mount" +CMDLINE="$CMDLINE systemd.break=pre-mount" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-mount.service" +test ! -h "$OUT_DIR/early/default.target.wants/breakpoint-pre-switch-root.service" + +# systemd.break=pre-basic +: "debug-shell: regular + systemd.break=pre-basic" +CMDLINE="$CMDLINE systemd.break=pre-basic" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service + +# systemd.break=pre-udev +: "debug-shell: regular + systemd.break=pre-udev" +CMDLINE="$CMDLINE systemd.break=pre-udev" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service + +# systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root +: "debug-shell: regular + systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root" +rm -f "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" +rm -f "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service" +CMDLINE="$CMDLINE systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root" +SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service +link_endswith "$OUT_DIR/early/default.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service + # Now override the default target via systemd.unit= : "debug-shell: regular + systemd.unit=" CMDLINE="$CMDLINE systemd.unit=my-fancy.target" @@ -103,6 +148,50 @@ CMDLINE="$CMDLINE rd.systemd.debug_shell" SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" link_endswith "$OUT_DIR/early/initrd.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service +# rd.systemd.break (default) +: "debug-shell: initrd + rd.systemd.break" +CMDLINE="$CMDLINE rd.systemd.break" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service + +# rd.systemd.break=pre-udev +: "debug-shell: initrd + rd.systemd.break=pre-udev" +CMDLINE="$CMDLINE rd.systemd.break=pre-udev" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service + +# rd.systemd.break=pre-basic +: "debug-shell: initrd + rd.systemd.break=pre-basic" +CMDLINE="$CMDLINE rd.systemd.break=pre-basic" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service + +# rd.systemd.break=pre-mount +: "debug-shell: initrd + rd.systemd.break=pre-mount" +CMDLINE="$CMDLINE rd.systemd.break=pre-mount" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service" /lib/systemd/system/breakpoint-pre-mount.service + +# rd.systemd.break=pre-switch-root +: "debug-shell: initrd + rd.systemd.break=pre-switch-root" +rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" +CMDLINE="$CMDLINE rd.systemd.break=pre-switch-root" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service + +# rd.systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root +: "debug-shell: initrd + rd.systemd.break=pre-udev,pre-mount,pre-switch-root" +rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service" +rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service" +rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service" +rm -f "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" +CMDLINE="$CMDLINE rd.systemd.break=pre-udev,pre-basic,pre-mount,pre-switch-root" +SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR" +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-udev.service" /lib/systemd/system/breakpoint-pre-udev.service +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-basic.service" /lib/systemd/system/breakpoint-pre-basic.service +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-mount.service" /lib/systemd/system/breakpoint-pre-mount.service +link_endswith "$OUT_DIR/early/initrd.target.wants/breakpoint-pre-switch-root.service" /lib/systemd/system/breakpoint-pre-switch-root.service + # Override the default target : "debug-shell: initrd + rd.systemd.unit" CMDLINE="$CMDLINE rd.systemd.unit=my-fancy-initrd.target" diff --git a/units/breakpoint-pre-basic.service.in b/units/breakpoint-pre-basic.service.in new file mode 100644 index 00000000000..69a406149d9 --- /dev/null +++ b/units/breakpoint-pre-basic.service.in @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# 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=Breakpoint Before Basic System +Documentation=man:systemd-debug-generator(8) +DefaultDependencies=no +Conflicts=shutdown.target emergency.target +After=sysinit.target sockets.target paths.target slices.target tmp.mount systemd-vconsole-setup.service +Before=basic.target + +[Service] +Environment=SHELL_PROMPT_PREFIX="pre-basic " +Type=oneshot +ExecStartPre=-plymouth --wait quit +# Execute shell with "-" prefix to not consider the unit failed if it exits with +# a non-zero value +ExecStart=-{{SUSHELL}} +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION diff --git a/units/breakpoint-pre-mount.service.in b/units/breakpoint-pre-mount.service.in new file mode 100644 index 00000000000..b50c780f01c --- /dev/null +++ b/units/breakpoint-pre-mount.service.in @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# 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=Breakpoint Before Mounting the Root Filesystem on /sysroot +Documentation=man:systemd-debug-generator(8) +AssertPathExists=/etc/initrd-release +DefaultDependencies=no +Conflicts=shutdown.target emergency.target +After=basic.target systemd-vconsole-setup.service +Before=initrd-root-fs.target sysroot.mount systemd-fsck-root.service + +[Service] +Environment=SHELL_PROMPT_PREFIX="pre-mount " +Type=oneshot +ExecStartPre=-plymouth --wait quit +# Execute shell with "-" prefix to not consider the unit failed if it exits with +# a non-zero value +ExecStart=-{{SUSHELL}} +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION diff --git a/units/breakpoint-pre-switch-root.service.in b/units/breakpoint-pre-switch-root.service.in new file mode 100644 index 00000000000..76eaa8039a9 --- /dev/null +++ b/units/breakpoint-pre-switch-root.service.in @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# 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=Breakpoint Before Switching Root +Documentation=man:systemd-debug-generator(8) +AssertPathExists=/etc/initrd-release +DefaultDependencies=no +Conflicts=shutdown.target emergency.target +Wants=remote-fs.target +After=initrd.target initrd-parse-etc.service sysroot.mount remote-fs.target systemd-vconsole-setup.service +Before=initrd-cleanup.service + +[Service] +Environment=SHELL_PROMPT_PREFIX="pre-switch-root " +Type=oneshot +ExecStartPre=-plymouth --wait quit +# Execute shell with "-" prefix to not consider the unit failed if it exits with +# a non-zero value +ExecStart=-{{SUSHELL}} +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION diff --git a/units/breakpoint-pre-udev.service.in b/units/breakpoint-pre-udev.service.in new file mode 100644 index 00000000000..baf0e033515 --- /dev/null +++ b/units/breakpoint-pre-udev.service.in @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# 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=Breakpoint Before Starting to Process Kernel uevents +Documentation=man:systemd-debug-generator(8) +DefaultDependencies=no +Conflicts=shutdown.target emergency.target +Wants=systemd-journald.socket +After=systemd-journald.socket systemd-vconsole-setup.service +Before=systemd-udevd.service systemd-udev-trigger.service + +[Service] +Environment=SHELL_PROMPT_PREFIX="pre-udev " +Type=oneshot +ExecStartPre=-plymouth --wait quit +# Execute shell with "-" prefix to not consider the unit failed if it exits with +# a non-zero value +ExecStart=-{{SUSHELL}} +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION diff --git a/units/meson.build b/units/meson.build index 792c4250c0e..00978a18b00 100644 --- a/units/meson.build +++ b/units/meson.build @@ -7,6 +7,10 @@ units = [ { 'file' : 'blockdev@.target' }, { 'file' : 'bluetooth.target' }, { 'file' : 'boot-complete.target' }, + { 'file' : 'breakpoint-pre-basic.service.in' }, + { 'file' : 'breakpoint-pre-mount.service.in' }, + { 'file' : 'breakpoint-pre-switch-root.service.in' }, + { 'file' : 'breakpoint-pre-udev.service.in' }, { 'file' : 'capsule@.service.in' }, { 'file' : 'capsule.slice' }, { 'file' : 'console-getty.service.in' },