diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:19 +0000 |
commit | b7e8d5af06ee840cc48217ca4629cf28aeeb3c50 (patch) | |
tree | 6aa8dc840b085de50db46e2ad0725eae248fef02 /debian/patches | |
parent | Adding upstream version 252.22. (diff) | |
download | systemd-debian/252.22-1_deb12u1.tar.xz systemd-debian/252.22-1_deb12u1.zip |
Adding debian version 252.22-1~deb12u1.debian/252.22-1_deb12u1debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches')
21 files changed, 2870 insertions, 0 deletions
diff --git a/debian/patches/debian/Add-support-for-TuxOnIce-hibernation.patch b/debian/patches/debian/Add-support-for-TuxOnIce-hibernation.patch new file mode 100644 index 0000000..887b6a1 --- /dev/null +++ b/debian/patches/debian/Add-support-for-TuxOnIce-hibernation.patch @@ -0,0 +1,30 @@ +From: Julien Muchembled <jm@jmuchemb.eu> +Date: Tue, 29 Apr 2014 11:40:50 +0200 +Subject: Add support for TuxOnIce hibernation + +systemd does not support non-mainline kernel features so upstream rejected this +patch. +It is however required for systemd integration by tuxonice-userui package. + +Forwarded: http://lists.freedesktop.org/archives/systemd-devel/2014-April/018960.html +--- + src/shared/sleep-config.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c +index 69b3e35..5664752 100644 +--- a/src/shared/sleep-config.c ++++ b/src/shared/sleep-config.c +@@ -973,6 +973,12 @@ static bool enough_swap_for_hibernation(void) { + if (getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0) + return true; + ++ /* TuxOnIce is an alternate implementation for hibernation. ++ * It can be configured to compress the image to a file or an inactive ++ * swap partition, so there's nothing more we can do here. */ ++ if (access("/sys/power/tuxonice", F_OK) == 0) ++ return true; ++ + r = find_hibernate_location(&hibernate_location); + if (r < 0) + return false; diff --git a/debian/patches/debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch b/debian/patches/debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch new file mode 100644 index 0000000..d99ea42 --- /dev/null +++ b/debian/patches/debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch @@ -0,0 +1,21 @@ +From: Tollef Fog Heen <tfheen@err.no> +Date: Tue, 5 Jun 2012 20:59:36 +0200 +Subject: Bring tmpfiles.d/tmp.conf in line with Debian defaults + +Closes: #675422 +--- + tmpfiles.d/tmp.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf +index fe5225d..39cb5cc 100644 +--- a/tmpfiles.d/tmp.conf ++++ b/tmpfiles.d/tmp.conf +@@ -8,5 +8,5 @@ + # See tmpfiles.d(5) for details + + # Clear tmp directories separately, to make them easier to override +-q /tmp 1777 root root 10d +-q /var/tmp 1777 root root 30d ++D /tmp 1777 root root - ++#q /var/tmp 1777 root root 30d diff --git a/debian/patches/debian/Don-t-enable-audit-by-default.patch b/debian/patches/debian/Don-t-enable-audit-by-default.patch new file mode 100644 index 0000000..67f2b46 --- /dev/null +++ b/debian/patches/debian/Don-t-enable-audit-by-default.patch @@ -0,0 +1,53 @@ +From: Martin Pitt <martin.pitt@ubuntu.com> +Date: Sun, 28 Dec 2014 12:49:35 +0100 +Subject: Don't enable audit by default + +It causes flooding of dmesg and syslog, suppressing actually important +messages. + +Don't enable it for now, until a better solution is found: +http://lists.freedesktop.org/archives/systemd-devel/2014-December/026591.html + +Bug-Debian: https://bugs.debian.org/773528 +--- + man/journald.conf.xml | 2 +- + src/journal/journald-server.c | 2 +- + src/journal/journald.conf | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/man/journald.conf.xml b/man/journald.conf.xml +index 160544a..7e6f175 100644 +--- a/man/journald.conf.xml ++++ b/man/journald.conf.xml +@@ -438,7 +438,7 @@ + <command>systemd-journald</command> collects generated audit records, it just controls whether it + tells the kernel to generate them. This means if another tool turns on auditing even if + <command>systemd-journald</command> left it off, it will still collect the generated +- messages. Defaults to on.</para></listitem> ++ messages. Defaults to off.</para></listitem> + </varlistentry> + + <varlistentry> +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index a78e2c0..efeb50c 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -2279,7 +2279,7 @@ int server_init(Server *s, const char *namespace) { + .compress.threshold_bytes = UINT64_MAX, + .seal = true, + +- .set_audit = true, ++ .set_audit = false, + + .watchdog_usec = USEC_INFINITY, + +diff --git a/src/journal/journald.conf b/src/journal/journald.conf +index 64f4d4b..a690681 100644 +--- a/src/journal/journald.conf ++++ b/src/journal/journald.conf +@@ -44,4 +44,4 @@ + #MaxLevelWall=emerg + #LineMax=48K + #ReadKMsg=yes +-#Audit=yes ++#Audit=no diff --git a/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch b/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch new file mode 100644 index 0000000..1b3ba16 --- /dev/null +++ b/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch @@ -0,0 +1,74 @@ +From: Michael Biebl <biebl@debian.org> +Date: Tue, 16 Feb 2021 00:18:50 +0100 +Subject: Downgrade a couple of warnings to debug + +If a package still ships only a SysV init script or if a service file or +tmpfile uses /var/run, downgrade those messages to debug. We can use +lintian to detect those issues. +For service files and tmpfiles in /etc, keep the warning, as those files +are typically added locally and aren't checked by lintian. + +Closes: #981407 +--- + src/core/load-fragment.c | 4 +++- + src/sysv-generator/sysv-generator.c | 2 +- + src/tmpfiles/tmpfiles.c | 4 +++- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 1001faa..555492e 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -543,6 +543,7 @@ static int patch_var_run( + + const char *e; + char *z; ++ int log_level; + + e = path_startswith(*path, "/var/run/"); + if (!e) +@@ -552,7 +553,8 @@ static int patch_var_run( + if (!z) + return log_oom(); + +- log_syntax(unit, LOG_NOTICE, filename, line, 0, ++ log_level = path_startswith(filename, "/etc") ? LOG_NOTICE : LOG_DEBUG; ++ log_syntax(unit, log_level, filename, line, 0, + "%s= references a path below legacy directory /var/run/, updating %s → %s; " + "please update the unit file accordingly.", lvalue, *path, z); + +diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c +index 3c5df6c..24eff86 100644 +--- a/src/sysv-generator/sysv-generator.c ++++ b/src/sysv-generator/sysv-generator.c +@@ -761,7 +761,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { + if (!fpath) + return log_oom(); + +- log_warning("SysV service '%s' lacks a native systemd unit file. " ++ log_debug("SysV service '%s' lacks a native systemd unit file. " + "Automatically generating a unit file for compatibility. " + "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath); + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 9c3d994..15180a5 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2991,6 +2991,7 @@ static int specifier_expansion_from_arg(const Specifier *specifier_table, Item * + static int patch_var_run(const char *fname, unsigned line, char **path) { + const char *k; + char *n; ++ int log_level; + + assert(path); + assert(*path); +@@ -3016,7 +3017,8 @@ static int patch_var_run(const char *fname, unsigned line, char **path) { + /* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence + * there's no immediate need for action by the user. However, in the interest of making things less confusing + * to the user, let's still inform the user that these snippets should really be updated. */ +- log_syntax(NULL, LOG_NOTICE, fname, line, 0, ++ log_level = path_startswith(fname, "/etc") ? LOG_NOTICE : LOG_DEBUG; ++ log_syntax(NULL, log_level, fname, line, 0, + "Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", + *path, n); + diff --git a/debian/patches/debian/Let-graphical-session-pre.target-be-manually-started.patch b/debian/patches/debian/Let-graphical-session-pre.target-be-manually-started.patch new file mode 100644 index 0000000..cf8db56 --- /dev/null +++ b/debian/patches/debian/Let-graphical-session-pre.target-be-manually-started.patch @@ -0,0 +1,22 @@ +From: Iain Lane <iain@orangesquash.org.uk> +Date: Mon, 22 Aug 2016 07:03:27 +0200 +Subject: Let graphical-session-pre.target be manually started + +This is needed until https://github.com/systemd/systemd/issues/3750 is fixed. + +Forwarded: not-needed +Bug-Ubuntu: https://launchpad.net/bugs/1615341 +--- + units/user/graphical-session-pre.target | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/units/user/graphical-session-pre.target b/units/user/graphical-session-pre.target +index 4b9e3dc..dffaf85 100644 +--- a/units/user/graphical-session-pre.target ++++ b/units/user/graphical-session-pre.target +@@ -12,5 +12,4 @@ Description=Session services which should run early before the graphical session + Documentation=man:systemd.special(7) + Requires=basic.target + Before=graphical-session.target +-RefuseManualStart=yes + StopWhenUnneeded=yes diff --git a/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch b/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch new file mode 100644 index 0000000..574f44d --- /dev/null +++ b/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch @@ -0,0 +1,42 @@ +From: Michael Biebl <biebl@debian.org> +Date: Fri, 5 Sep 2014 01:15:16 +0200 +Subject: Make /run/lock tmpfs an API fs + +The /run/lock directory is world-writable in Debian due to historic +reasons. To avoid user processes filling up /run, we mount a separate +tmpfs for /run/lock. As this directory needs to be available during +early boot, we make it an API fs. + +Drop it from tmpfiles.d/legacy.conf to not clobber the permissions. + +Closes: #751392 +--- + src/shared/mount-setup.c | 2 ++ + tmpfiles.d/legacy.conf.in | 1 - + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c +index 6882b62..c54e632 100644 +--- a/src/shared/mount-setup.c ++++ b/src/shared/mount-setup.c +@@ -86,6 +86,8 @@ static const MountPoint mount_table[] = { + #endif + { "tmpfs", "/run", "tmpfs", "mode=755" TMPFS_LIMITS_RUN, MS_NOSUID|MS_NODEV|MS_STRICTATIME, + NULL, MNT_FATAL|MNT_IN_CONTAINER }, ++ { "tmpfs", "/run/lock", "tmpfs", "mode=1777,size=5242880", MS_NOSUID|MS_NOEXEC|MS_NODEV, ++ NULL, MNT_FATAL|MNT_IN_CONTAINER }, + { "cgroup2", "/sys/fs/cgroup", "cgroup2", "nsdelegate,memory_recursiveprot", MS_NOSUID|MS_NOEXEC|MS_NODEV, + cg_is_unified_wanted, MNT_IN_CONTAINER|MNT_CHECK_WRITABLE }, + { "cgroup2", "/sys/fs/cgroup", "cgroup2", "nsdelegate", MS_NOSUID|MS_NOEXEC|MS_NODEV, +diff --git a/tmpfiles.d/legacy.conf.in b/tmpfiles.d/legacy.conf.in +index 4f2c0d7..fb1d6bf 100644 +--- a/tmpfiles.d/legacy.conf.in ++++ b/tmpfiles.d/legacy.conf.in +@@ -10,7 +10,6 @@ + # These files are considered legacy and are unnecessary on legacy-free + # systems. + +-d /run/lock 0755 root root - + L /var/lock - - - - ../run/lock + {% if CREATE_LOG_DIRS %} + L /var/log/README - - - - ../..{{DOC_DIR}}/README.logs diff --git a/debian/patches/debian/Move-sysusers.d-sysctl.d-binfmt.d-modules-load.d-back-to-.patch b/debian/patches/debian/Move-sysusers.d-sysctl.d-binfmt.d-modules-load.d-back-to-.patch new file mode 100644 index 0000000..9a39629 --- /dev/null +++ b/debian/patches/debian/Move-sysusers.d-sysctl.d-binfmt.d-modules-load.d-back-to-.patch @@ -0,0 +1,68 @@ +From: Michael Biebl <biebl@debian.org> +Date: Thu, 15 Oct 2020 23:11:01 +0200 +Subject: Move sysusers.d/sysctl.d/binfmt.d/modules-load.d back to /usr + +In Debian, late mounting of /usr is no longer supported, so it is safe +to install those files in /usr. +We want those facilities in /usr, not /, as this will make an eventual +switch to a merged-usr setup easier. + +Closes: #971282 +--- + src/core/systemd.pc.in | 8 ++++---- + src/libsystemd/sd-path/sd-path.c | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in +index 693433b..8368a3f 100644 +--- a/src/core/systemd.pc.in ++++ b/src/core/systemd.pc.in +@@ -67,16 +67,16 @@ tmpfilesdir=${tmpfiles_dir} + + user_tmpfiles_dir=${prefix}/share/user-tmpfiles.d + +-sysusers_dir=${rootprefix}/lib/sysusers.d ++sysusers_dir=${prefix}/lib/sysusers.d + sysusersdir=${sysusers_dir} + +-sysctl_dir=${rootprefix}/lib/sysctl.d ++sysctl_dir=${prefix}/lib/sysctl.d + sysctldir=${sysctl_dir} + +-binfmt_dir=${rootprefix}/lib/binfmt.d ++binfmt_dir=${prefix}/lib/binfmt.d + binfmtdir=${binfmt_dir} + +-modules_load_dir=${rootprefix}/lib/modules-load.d ++modules_load_dir=${prefix}/lib/modules-load.d + modulesloaddir=${modules_load_dir} + + catalog_dir=${prefix}/lib/systemd/catalog +diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c +index ac33e34..f0615ff 100644 +--- a/src/libsystemd/sd-path/sd-path.c ++++ b/src/libsystemd/sd-path/sd-path.c +@@ -362,19 +362,19 @@ static int get_path(uint64_t type, char **buffer, const char **ret) { + return 0; + + case SD_PATH_SYSUSERS: +- *ret = ROOTPREFIX_NOSLASH "/lib/sysusers.d"; ++ *ret = "/usr/lib/sysusers.d"; + return 0; + + case SD_PATH_SYSCTL: +- *ret = ROOTPREFIX_NOSLASH "/lib/sysctl.d"; ++ *ret = "/usr/lib/sysctl.d"; + return 0; + + case SD_PATH_BINFMT: +- *ret = ROOTPREFIX_NOSLASH "/lib/binfmt.d"; ++ *ret = "/usr/lib/binfmt.d"; + return 0; + + case SD_PATH_MODULES_LOAD: +- *ret = ROOTPREFIX_NOSLASH "/lib/modules-load.d"; ++ *ret = "/usr/lib/modules-load.d"; + return 0; + + case SD_PATH_CATALOG: diff --git a/debian/patches/debian/Only-start-logind-if-dbus-is-installed.patch b/debian/patches/debian/Only-start-logind-if-dbus-is-installed.patch new file mode 100644 index 0000000..825c767 --- /dev/null +++ b/debian/patches/debian/Only-start-logind-if-dbus-is-installed.patch @@ -0,0 +1,28 @@ +From: Martin Pitt <martin.pitt@ubuntu.com> +Date: Mon, 9 Feb 2015 10:53:43 +0100 +Subject: Only start logind if dbus is installed + +logind fails to start in environments without dbus, such as LXC containers or +servers. Add a startup condition to avoid the very noisy startup failure. + +Consider both dbus-daemon (the reference implementation) and +dbus-broker. + +Part of #772700 +--- + units/systemd-logind.service.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in +index 042ea75..89a7c89 100644 +--- a/units/systemd-logind.service.in ++++ b/units/systemd-logind.service.in +@@ -16,6 +16,8 @@ Documentation=man:org.freedesktop.login1(5) + + Wants=user.slice modprobe@drm.service + After=nss-user-lookup.target user.slice modprobe@drm.service ++ConditionPathExists=|/lib/systemd/system/dbus.service ++ConditionPathExists=|/lib/systemd/system/dbus-broker.service + + # Ask for the dbus socket. + Wants=dbus.socket diff --git a/debian/patches/debian/Re-enable-journal-forwarding-to-syslog.patch b/debian/patches/debian/Re-enable-journal-forwarding-to-syslog.patch new file mode 100644 index 0000000..838c4e4 --- /dev/null +++ b/debian/patches/debian/Re-enable-journal-forwarding-to-syslog.patch @@ -0,0 +1,56 @@ +From: Martin Pitt <martin.pitt@ubuntu.com> +Date: Fri, 28 Nov 2014 14:43:25 +0100 +Subject: Re-enable journal forwarding to syslog + +Revert upstream commit 46b131574fdd7d77 for now, until Debian's sysloggers +can/do all read from the journal directly. See + + http://lists.freedesktop.org/archives/systemd-devel/2014-November/025550.html + +for details. Once we grow a journal.conf.d/ directory, sysloggers can be moved +to pulling from the journal one by one and disable forwarding again in such a +conf.d snippet. +--- + man/journald.conf.xml | 2 +- + src/journal/journald-server.c | 1 + + src/journal/journald.conf | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/man/journald.conf.xml b/man/journald.conf.xml +index 2db6a0f..160544a 100644 +--- a/man/journald.conf.xml ++++ b/man/journald.conf.xml +@@ -356,7 +356,7 @@ + traditional syslog daemon, to the kernel log buffer (kmsg), to the system console, or sent as wall + messages to all logged-in users. These options take boolean arguments. If forwarding to syslog is + enabled but nothing reads messages from the socket, forwarding to syslog has no effect. By default, +- only forwarding to wall is enabled. These settings may be overridden at boot time with the kernel ++ only forwarding to syslog and wall is enabled. These settings may be overridden at boot time with the kernel + command line options <literal>systemd.journald.forward_to_syslog</literal>, + <literal>systemd.journald.forward_to_kmsg</literal>, + <literal>systemd.journald.forward_to_console</literal>, and +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 77aef79..a78e2c0 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -2289,6 +2289,7 @@ int server_init(Server *s, const char *namespace) { + .ratelimit_interval = DEFAULT_RATE_LIMIT_INTERVAL, + .ratelimit_burst = DEFAULT_RATE_LIMIT_BURST, + ++ .forward_to_syslog = true, + .forward_to_wall = true, + + .max_file_usec = DEFAULT_MAX_FILE_USEC, +diff --git a/src/journal/journald.conf b/src/journal/journald.conf +index 5a60a9d..64f4d4b 100644 +--- a/src/journal/journald.conf ++++ b/src/journal/journald.conf +@@ -32,7 +32,7 @@ + #RuntimeMaxFiles=100 + #MaxRetentionSec= + #MaxFileSec=1month +-#ForwardToSyslog=no ++#ForwardToSyslog=yes + #ForwardToKMsg=no + #ForwardToConsole=no + #ForwardToWall=yes diff --git a/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch b/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch new file mode 100644 index 0000000..31d6099 --- /dev/null +++ b/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch @@ -0,0 +1,37 @@ +From: Martin Pitt <martin.pitt@ubuntu.com> +Date: Mon, 27 Apr 2015 15:29:13 +0200 +Subject: Revert "core: one step back again, + for nspawn we actually can't wait for cgroups running empty since systemd + will get exactly zero notifications about it" + +This reverts commit 743970d2ea6d08aa7c7bff8220f6b7702f2b1db7. + +Bug-Debian: https://bugs.debian.org/784720 +Bug-Ubuntu: https://launchpad.net/bugs/1448259 +Bug-Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1141137 +--- + src/core/unit.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 52df7ce..fb9a740 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4646,16 +4646,7 @@ int unit_kill_context( + + } else if (r > 0) { + +- /* FIXME: For now, on the legacy hierarchy, we will not wait for the cgroup members to die if +- * we are running in a container or if this is a delegation unit, simply because cgroup +- * notification is unreliable in these cases. It doesn't work at all in containers, and outside +- * of containers it can be confused easily by left-over directories in the cgroup — which +- * however should not exist in non-delegated units. On the unified hierarchy that's different, +- * there we get proper events. Hence rely on them. */ +- +- if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0 || +- (detect_container() == 0 && !unit_cgroup_delegate(u))) +- wait_for_exit = true; ++ wait_for_exit = true; + + if (send_sighup) { + set_free(pid_set); diff --git a/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch b/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch new file mode 100644 index 0000000..e570fff --- /dev/null +++ b/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch @@ -0,0 +1,71 @@ +From: Martin Pitt <martin.pitt@ubuntu.com> +Date: Sat, 27 Feb 2016 12:27:06 +0100 +Subject: Revert "core: set RLIMIT_CORE to unlimited by default" + +Partially revert commit 15a900327ab as this completely breaks core dumps +without systemd-coredump. It's also contradicting core(8), and it's not +systemd's place to redefine the kernel definitions of core files. + +Commit bdfd7b2c now honours the process' RLIMIT_CORE for systemd-coredump. This +isn't what RLIMIT_CORE is supposed to do (it limits the size of the core +*file*, but the kernel deliberately ignores it for piping), so set a static +2^63 core size limit for systemd-coredump to go back to the previous behaviour +(otherwise the change above would break systemd-coredump). + +Bug-Debian: https://bugs.debian.org/815020 +--- + src/core/main.c | 20 -------------------- + sysctl.d/50-coredump.conf.in | 2 +- + 2 files changed, 1 insertion(+), 21 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 1c4b464..e84e7dd 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1650,24 +1650,6 @@ static void cmdline_take_random_seed(void) { + "This functionality should not be used outside of testing environments."); + } + +-static void initialize_coredump(bool skip_setup) { +-#if ENABLE_COREDUMP +- if (getpid_cached() != 1) +- return; +- +- /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour +- * the limit) will process core dumps for system services by default. */ +- if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0) +- log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m"); +- +- /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored +- * until the systemd-coredump tool is enabled via sysctl. However it can be changed via the kernel +- * command line later so core dumps can still be generated during early startup and in initrd. */ +- if (!skip_setup) +- disable_coredumps(); +-#endif +-} +- + static void initialize_core_pattern(bool skip_setup) { + int r; + +@@ -2814,8 +2796,6 @@ int main(int argc, char *argv[]) { + kernel_timestamp = DUAL_TIMESTAMP_NULL; + } + +- initialize_coredump(skip_setup); +- + r = fixup_environment(); + if (r < 0) { + log_emergency_errno(r, "Failed to fix up PID 1 environment: %m"); +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index 5fb551a..13495f1 100644 +--- a/sysctl.d/50-coredump.conf.in ++++ b/sysctl.d/50-coredump.conf.in +@@ -13,7 +13,7 @@ + # the core dump. + # + # See systemd-coredump(8) and core(5). +-kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h ++kernel.core_pattern=|{{ROOTLIBEXECDIR}}/systemd-coredump %P %u %g %s %t 9223372036854775808 %h + + # Allow 16 coredumps to be dispatched in parallel by the kernel. + # We collect metadata from /proc/%P/, and thus need to make sure the crashed diff --git a/debian/patches/debian/Skip-filesystem-check-if-already-done-by-the-initram.patch b/debian/patches/debian/Skip-filesystem-check-if-already-done-by-the-initram.patch new file mode 100644 index 0000000..c819275 --- /dev/null +++ b/debian/patches/debian/Skip-filesystem-check-if-already-done-by-the-initram.patch @@ -0,0 +1,57 @@ +From: Nis Martensen <nis.martensen@web.de> +Date: Tue, 19 Jan 2016 22:01:43 +0100 +Subject: Skip filesystem check if already done by the initramfs + +Newer versions of initramfs-tools already fsck and mount / and /usr in +the initramfs. Skip the filesystem check in this case. + +Based on a previous patch by Michael Biebl <biebl@debian.org>. + +Closes: #782522 +Closes: #810748 +--- + src/fstab-generator/fstab-generator.c | 11 ++++++++--- + units/systemd-fsck-root.service.in | 1 + + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 63f0f36..8b3c732 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -368,6 +368,7 @@ static int add_mount( + _cleanup_strv_free_ char **wanted_by = NULL, **required_by = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; ++ struct stat sb; + + assert(what); + assert(where); +@@ -455,9 +456,13 @@ static int add_mount( + fprintf(f, "Before=%s\n", target_unit); + + if (passno != 0) { +- r = generator_write_fsck_deps(f, dest, what, where, fstype); +- if (r < 0) +- return r; ++ if (streq(where, "/usr") && stat("/run/initramfs/fsck-usr", &sb) == 0) ++ ; /* skip /usr fsck if it has already been checked in the initramfs */ ++ else { ++ r = generator_write_fsck_deps(f, dest, what, where, fstype); ++ if (r < 0) ++ return r; ++ } + } + + r = generator_write_blockdev_dependency(f, what); +diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in +index 4b1cd43..07590fd 100644 +--- a/units/systemd-fsck-root.service.in ++++ b/units/systemd-fsck-root.service.in +@@ -16,6 +16,7 @@ Before=local-fs.target shutdown.target + Wants=systemd-fsckd.socket + After=systemd-fsckd.socket + ConditionPathIsReadWrite=!/ ++ConditionPathExists=!/run/initramfs/fsck-root + OnFailure=emergency.target + OnFailureJobMode=replace-irreversibly + diff --git a/debian/patches/debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch b/debian/patches/debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch new file mode 100644 index 0000000..82ee455 --- /dev/null +++ b/debian/patches/debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch @@ -0,0 +1,24 @@ +From: Michael Biebl <biebl@debian.org> +Date: Tue, 13 Dec 2022 00:32:17 +0100 +Subject: Skip flaky test_resolved_domain_restricted_dns in networkd-test.py + +This test is part of DnsmasqClientTest and does not work reliably under +LXC/debci, so skip it for the time being. + +Closes: #1025908 +--- + test/networkd-test.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/test/networkd-test.py b/test/networkd-test.py +index 84013e7..172b3b3 100755 +--- a/test/networkd-test.py ++++ b/test/networkd-test.py +@@ -633,6 +633,7 @@ class DnsmasqClientTest(ClientTestBase, unittest.TestCase): + with open(path) as f: + sys.stdout.write('\n\n---- {} ----\n{}\n------\n\n'.format(os.path.basename(path), f.read())) + ++ @unittest.skip("test is flaky: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025908") + def test_resolved_domain_restricted_dns(self): + '''resolved: domain-restricted DNS servers''' + diff --git a/debian/patches/debian/Use-Debian-specific-config-files.patch b/debian/patches/debian/Use-Debian-specific-config-files.patch new file mode 100644 index 0000000..ce1a2b8 --- /dev/null +++ b/debian/patches/debian/Use-Debian-specific-config-files.patch @@ -0,0 +1,363 @@ +From: Michael Biebl <biebl@debian.org> +Date: Thu, 18 Jul 2013 20:11:02 +0200 +Subject: Use Debian specific config files + +Use /etc/default/locale instead of /etc/locale.conf for locale settings. + +Use /etc/default/keyboard instead of /etc/X11/xorg.conf.d/00-keyboard.conf for +keyboard configuration. +--- + src/firstboot/firstboot.c | 12 ++- + src/locale/localed-util.c | 189 ++++++++++++++++++++-------------------------- + src/shared/locale-setup.c | 24 ++++-- + 3 files changed, 108 insertions(+), 117 deletions(-) + +diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c +index dee2742..d66cf87 100644 +--- a/src/firstboot/firstboot.c ++++ b/src/firstboot/firstboot.c +@@ -311,12 +311,16 @@ static int prompt_locale(void) { + } + + static int process_locale(void) { +- const char *etc_localeconf; ++ const char *etc_localeconf, *path = "/etc/locale.conf"; + char* locales[3]; + unsigned i = 0; +- int r; ++ int r = 0; ++ ++ if (laccess(path, F_OK) < 0 && errno == ENOENT) ++ path = "/etc/default/locale"; ++ ++ etc_localeconf = prefix_roota(arg_root, path); + +- etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf"); + if (laccess(etc_localeconf, F_OK) >= 0 && !arg_force) { + log_debug("Found %s, assuming locale information has been configured.", + etc_localeconf); +@@ -326,7 +330,7 @@ static int process_locale(void) { + if (arg_copy_locale && arg_root) { + + (void) mkdir_parents(etc_localeconf, 0755); +- r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644, 0, 0, COPY_REFLINK); ++ r = copy_file(path, etc_localeconf, 0, 0644, 0, 0, COPY_REFLINK); + if (r != -ENOENT) { + if (r < 0) + return log_error_errno(r, "Failed to copy %s: %m", etc_localeconf); +diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c +index 4d021fb..d9050c0 100644 +--- a/src/locale/localed-util.c ++++ b/src/locale/localed-util.c +@@ -128,7 +128,6 @@ int vconsole_read_data(Context *c, sd_bus_message *m) { + + int x11_read_data(Context *c, sd_bus_message *m) { + _cleanup_fclose_ FILE *f = NULL; +- bool in_section = false; + struct stat st; + usec_t t; + int r; +@@ -142,7 +141,7 @@ int x11_read_data(Context *c, sd_bus_message *m) { + c->x11_cache = sd_bus_message_ref(m); + } + +- if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) < 0) { ++ if (stat("/etc/default/keyboard", &st) < 0) { + if (errno != ENOENT) + return -errno; + +@@ -159,60 +158,14 @@ int x11_read_data(Context *c, sd_bus_message *m) { + c->x11_mtime = t; + context_free_x11(c); + +- f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re"); +- if (!f) +- return -errno; +- +- for (;;) { +- _cleanup_free_ char *line = NULL; +- char *l; +- +- r = read_line(f, LONG_LINE_MAX, &line); +- if (r < 0) +- return r; +- if (r == 0) +- break; +- +- l = strstrip(line); +- if (IN_SET(l[0], 0, '#')) +- continue; +- +- if (in_section && first_word(l, "Option")) { +- _cleanup_strv_free_ char **a = NULL; +- +- r = strv_split_full(&a, l, WHITESPACE, EXTRACT_UNQUOTE); +- if (r < 0) +- return r; +- +- if (strv_length(a) == 3) { +- char **p = NULL; +- +- if (streq(a[1], "XkbLayout")) +- p = &c->x11_layout; +- else if (streq(a[1], "XkbModel")) +- p = &c->x11_model; +- else if (streq(a[1], "XkbVariant")) +- p = &c->x11_variant; +- else if (streq(a[1], "XkbOptions")) +- p = &c->x11_options; +- +- if (p) +- free_and_replace(*p, a[2]); +- } +- +- } else if (!in_section && first_word(l, "Section")) { +- _cleanup_strv_free_ char **a = NULL; +- +- r = strv_split_full(&a, l, WHITESPACE, EXTRACT_UNQUOTE); +- if (r < 0) +- return -ENOMEM; +- +- if (strv_length(a) == 2 && streq(a[1], "InputClass")) +- in_section = true; +- +- } else if (in_section && first_word(l, "EndSection")) +- in_section = false; +- } ++ r = parse_env_file(NULL, "/etc/default/keyboard", ++ "XKBMODEL", &c->x11_model, ++ "XKBLAYOUT", &c->x11_layout, ++ "XKBVARIANT", &c->x11_variant, ++ "XKBOPTIONS", &c->x11_options); ++ ++ if (r < 0) ++ return r; + + return 0; + } +@@ -253,69 +206,93 @@ int vconsole_write_data(Context *c) { + } + + int x11_write_data(Context *c) { +- _cleanup_fclose_ FILE *f = NULL; +- _cleanup_free_ char *temp_path = NULL; + struct stat st; + int r; ++ char *t, **l = NULL; + +- if (isempty(c->x11_layout) && +- isempty(c->x11_model) && +- isempty(c->x11_variant) && +- isempty(c->x11_options)) { ++ r = load_env_file(NULL, "/etc/default/keyboard", &l); ++ if (r < 0 && r != -ENOENT) ++ return r; + +- if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) ++ /* This could perhaps be done more elegantly using an array ++ * like we do for the locale, instead of struct ++ */ ++ if (isempty(c->x11_layout)) { ++ l = strv_env_unset(l, "XKBLAYOUT"); ++ } else { ++ if (asprintf(&t, "XKBLAYOUT=%s", c->x11_layout) < 0) { ++ strv_free(l); ++ return -ENOMEM; ++ } ++ ++ r = strv_env_replace_consume(&l, t); ++ if (r < 0) { ++ strv_free(l); ++ return r; ++ } ++ } ++ ++ if (isempty(c->x11_model)) { ++ l = strv_env_unset(l, "XKBMODEL"); ++ } else { ++ if (asprintf(&t, "XKBMODEL=%s", c->x11_model) < 0) { ++ strv_free(l); ++ return -ENOMEM; ++ } ++ ++ r = strv_env_replace_consume(&l, t); ++ if (r < 0) { ++ strv_free(l); ++ return r; ++ } ++ } ++ ++ if (isempty(c->x11_variant)) { ++ l = strv_env_unset(l, "XKBVARIANT"); ++ } else { ++ if (asprintf(&t, "XKBVARIANT=%s", c->x11_variant) < 0) { ++ strv_free(l); ++ return -ENOMEM; ++ } ++ ++ r = strv_env_replace_consume(&l, t); ++ if (r < 0) { ++ strv_free(l); ++ return r; ++ } ++ } ++ ++ if (isempty(c->x11_options)) { ++ l = strv_env_unset(l, "XKBOPTIONS"); ++ } else { ++ if (asprintf(&t, "XKBOPTIONS=%s", c->x11_options) < 0) { ++ strv_free(l); ++ return -ENOMEM; ++ } ++ ++ r = strv_env_replace_consume(&l, t); ++ if (r < 0) { ++ strv_free(l); ++ return r; ++ } ++ } ++ ++ if (strv_isempty(l)) { ++ strv_free(l); ++ ++ if (unlink("/etc/default/keyboard") < 0) + return errno == ENOENT ? 0 : -errno; + + c->vc_mtime = USEC_INFINITY; + return 0; + } + +- (void) mkdir_p_label("/etc/X11/xorg.conf.d", 0755); +- r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path); +- if (r < 0) +- return r; ++ r = write_env_file("/etc/default/keyboard", l); ++ strv_free(l); + +- (void) fchmod(fileno(f), 0644); +- +- fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n" +- "# probably wise not to edit this file manually. Use localectl(1) to\n" +- "# instruct systemd-localed to update it.\n" +- "Section \"InputClass\"\n" +- " Identifier \"system-keyboard\"\n" +- " MatchIsKeyboard \"on\"\n", f); +- +- if (!isempty(c->x11_layout)) +- fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout); +- +- if (!isempty(c->x11_model)) +- fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model); +- +- if (!isempty(c->x11_variant)) +- fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant); +- +- if (!isempty(c->x11_options)) +- fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options); +- +- fputs("EndSection\n", f); +- +- r = fflush_sync_and_check(f); +- if (r < 0) +- goto fail; +- +- if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) { +- r = -errno; +- goto fail; +- } +- +- if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) >= 0) ++ if (r >= 0 && stat("/etc/default/keyboard", &st) >= 0) + c->x11_mtime = timespec_load(&st.st_mtim); + +- return 0; +- +-fail: +- if (temp_path) +- (void) unlink(temp_path); +- + return r; + } + +diff --git a/src/shared/locale-setup.c b/src/shared/locale-setup.c +index b8c6647..be7efcb 100644 +--- a/src/shared/locale-setup.c ++++ b/src/shared/locale-setup.c +@@ -49,14 +49,20 @@ int locale_context_load(LocaleContext *c, LocaleLoadFlag flag) { + } + + if (FLAGS_SET(flag, LOCALE_LOAD_LOCALE_CONF)) { ++ const char *path = "/etc/locale.conf"; + struct stat st; + usec_t t; + +- r = stat("/etc/locale.conf", &st); ++ r = stat(path, &st); ++ if (r < 0 && errno == ENOENT) { ++ path = "/etc/default/locale"; ++ r = stat(path, &st); ++ } + if (r < 0 && errno != ENOENT) +- return log_debug_errno(errno, "Failed to stat /etc/locale.conf: %m"); ++ return log_debug_errno(errno, "Failed to stat %s: %m", path); + + if (r >= 0) { ++ + /* If mtime is not changed, then we do not need to re-read the file. */ + t = timespec_load(&st.st_mtim); + if (c->mtime != USEC_INFINITY && t == c->mtime) +@@ -65,7 +71,7 @@ int locale_context_load(LocaleContext *c, LocaleLoadFlag flag) { + locale_context_clear(c); + c->mtime = t; + +- r = parse_env_file(NULL, "/etc/locale.conf", ++ r = parse_env_file(NULL, path, + "LANG", &c->locale[VARIABLE_LANG], + "LANGUAGE", &c->locale[VARIABLE_LANGUAGE], + "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE], +@@ -81,7 +87,7 @@ int locale_context_load(LocaleContext *c, LocaleLoadFlag flag) { + "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION]); + if (r < 0) +- return log_debug_errno(r, "Failed to read /etc/locale.conf: %m"); ++ return log_debug_errno(r, "Failed to read %s: %m", path); + + goto finalize; + } +@@ -149,17 +155,21 @@ int locale_context_save(LocaleContext *c, char ***ret_set, char ***ret_unset) { + _cleanup_strv_free_ char **set = NULL, **unset = NULL; + struct stat st; + int r; ++ const char *path = "/etc/locale.conf"; + + assert(c); + + /* Set values will be returned as strv in *ret on success. */ + ++ if (access(path, F_OK) < 0 && errno == ENOENT) ++ path = "/etc/default/locale"; ++ + r = locale_context_build_env(c, &set, ret_unset ? &unset : NULL); + if (r < 0) + return r; + + if (strv_isempty(set)) { +- if (unlink("/etc/locale.conf") < 0) ++ if (unlink(path) < 0) + return errno == ENOENT ? 0 : -errno; + + c->mtime = USEC_INFINITY; +@@ -170,11 +180,11 @@ int locale_context_save(LocaleContext *c, char ***ret_set, char ***ret_unset) { + return 0; + } + +- r = write_env_file_label("/etc/locale.conf", set); ++ r = write_env_file_label(path, set); + if (r < 0) + return r; + +- if (stat("/etc/locale.conf", &st) >= 0) ++ if (stat(path, &st) >= 0) + c->mtime = timespec_load(&st.st_mtim); + + if (ret_set) diff --git a/debian/patches/debian/deny-list-upstream-test-02-ppc64el.patch b/debian/patches/debian/deny-list-upstream-test-02-ppc64el.patch new file mode 100644 index 0000000..ee49d27 --- /dev/null +++ b/debian/patches/debian/deny-list-upstream-test-02-ppc64el.patch @@ -0,0 +1,17 @@ +From: Dan Streetman <ddstreet@canonical.com> +Date: Wed, 6 Nov 2019 09:14:54 -0500 +Subject: deny-list-upstream-test-02-ppc64el + +Bug: https://github.com/systemd/systemd/issues/11612 +--- + test/TEST-02-UNITTESTS/deny-list-upstream-ci-ppc64el | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 test/TEST-02-UNITTESTS/deny-list-upstream-ci-ppc64el + +diff --git a/test/TEST-02-UNITTESTS/deny-list-upstream-ci-ppc64el b/test/TEST-02-UNITTESTS/deny-list-upstream-ci-ppc64el +new file mode 100644 +index 0000000..52877fc +--- /dev/null ++++ b/test/TEST-02-UNITTESTS/deny-list-upstream-ci-ppc64el +@@ -0,0 +1 @@ ++# unknown reason for failing, tracked in https://github.com/systemd/systemd/issues/11612 diff --git a/debian/patches/debian/deny-list-upstream-test-25.patch b/debian/patches/debian/deny-list-upstream-test-25.patch new file mode 100644 index 0000000..ec6c211 --- /dev/null +++ b/debian/patches/debian/deny-list-upstream-test-25.patch @@ -0,0 +1,17 @@ +From: Dan Streetman <ddstreet@canonical.com> +Date: Wed, 6 Nov 2019 09:14:50 -0500 +Subject: deny-list-upstream-test-25 + +Bug: https://github.com/systemd/systemd/issues/13973 +--- + test/TEST-25-IMPORT/deny-list-upstream-ci | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 test/TEST-25-IMPORT/deny-list-upstream-ci + +diff --git a/test/TEST-25-IMPORT/deny-list-upstream-ci b/test/TEST-25-IMPORT/deny-list-upstream-ci +new file mode 100644 +index 0000000..47a5f15 +--- /dev/null ++++ b/test/TEST-25-IMPORT/deny-list-upstream-ci +@@ -0,0 +1 @@ ++# unknown failure; tracked in https://github.com/systemd/systemd/issues/13973 diff --git a/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch new file mode 100644 index 0000000..103b44a --- /dev/null +++ b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch @@ -0,0 +1,1068 @@ +From: Didier Roche <didrocks@ubuntu.com> +Date: Fri, 22 May 2015 13:04:38 +0200 +Subject: fsckd daemon for inter-fsckd communication + +Global logic: +Add systemd-fsckd multiplexer which accepts multiple (via systemd-fsck's +/run/systemd/fsck.progress socket) fsck instances to connect to it and sends +progress report. systemd-fsckd then computes and writes to /dev/console the +number of devices currently being checked and the minimum fsck progress. + +Plymouth and user interaction: +Forward the progress to plymouth and support canellation of in progress fsck. +Try to connect and send to plymouth (if running) some checked report progress, +using direct plymouth protocole. + +Update message is the following: +fsckd:<num_devices>:<progress>:<string> +* num_devices corresponds to the current number of devices being checked (int) +* progress corresponds to the current minimum percentage of all devices being + checked (float, from 0 to 100) +* string is a translated message ready to be displayed by the plymouth theme + displaying the information above. It can be overridden by plymouth themes + supporting i18n. + +Grab in fsckd plymouth watch key Control+C, and propagate this cancel request +to systemd-fsck which will terminate fsck. + +Send a message to signal to user what key we are grabbing for fsck cancel. + +Message is: fsckd-cancel-msg:<string> +Where string is a translated string ready to be displayed by the plymouth theme +indicating that Control+C can be used to cancel current checks. It can be +overridden (matching only fsckd-cancel-msg prefix) for themes supporting i18n. + +Misc: +systemd-fsckd stops on idle when no fsck is connected. +Add man page explaining the plymouth theme protocol, usage of the daemon +as well as the socket activation part. Adapt existing fsck man page. + +Note that fsckd had lived in the upstream tree for a while, but was removed. +More information at +http://lists.freedesktop.org/archives/systemd-devel/2015-April/030175.html +- +--- + man/rules/meson.build | 1 + + man/systemd-fsckd.service.xml | 162 +++++++++ + meson.build | 9 + + po/POTFILES.in | 1 + + src/fsckd/fsckd.c | 702 +++++++++++++++++++++++++++++++++++++ + units/meson.build | 2 + + units/systemd-fsck-root.service.in | 2 + + units/systemd-fsck@.service.in | 3 +- + units/systemd-fsckd.service.in | 17 + + units/systemd-fsckd.socket | 15 + + 10 files changed, 913 insertions(+), 1 deletion(-) + create mode 100644 man/systemd-fsckd.service.xml + create mode 100644 src/fsckd/fsckd.c + create mode 100644 units/systemd-fsckd.service.in + create mode 100644 units/systemd-fsckd.socket + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 4819b15..4b52db1 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -892,6 +892,7 @@ manpages = [ + '8', + ['systemd-fsck', 'systemd-fsck-root.service', 'systemd-fsck-usr.service'], + ''], ++ ['systemd-fsckd.service', '8', ['systemd-fsckd.socket', 'systemd-fsckd'], ''], + ['systemd-fstab-generator', '8', [], ''], + ['systemd-getty-generator', '8', [], ''], + ['systemd-gpt-auto-generator', '8', [], 'HAVE_BLKID'], +diff --git a/man/systemd-fsckd.service.xml b/man/systemd-fsckd.service.xml +new file mode 100644 +index 0000000..b7ad58d +--- /dev/null ++++ b/man/systemd-fsckd.service.xml +@@ -0,0 +1,162 @@ ++<?xml version="1.0"?> ++<!--*-nxml-*--> ++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> ++<!-- ++ This file is part of systemd. ++ ++ Copyright 2015 Canonical ++ ++ 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. ++ ++ systemd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with systemd; If not, see <http://www.gnu.org/licenses/>. ++--> ++<refentry id="systemd-fsckd.service" xmlns:xi="http://www.w3.org/2001/XInclude"> ++ ++ <refentryinfo> ++ <title>systemd-fsckd.service</title> ++ <productname>systemd</productname> ++ ++ <authorgroup> ++ <author> ++ <contrib>Developer</contrib> ++ <firstname>Didier</firstname> ++ <surname>Roche</surname> ++ <email>didrocks@ubuntu.com</email> ++ </author> ++ </authorgroup> ++ </refentryinfo> ++ ++ <refmeta> ++ <refentrytitle>systemd-fsckd.service</refentrytitle> ++ <manvolnum>8</manvolnum> ++ </refmeta> ++ ++ <refnamediv> ++ <refname>systemd-fsckd.service</refname> ++ <refname>systemd-fsckd.socket</refname> ++ <refname>systemd-fsckd</refname> ++ <refpurpose>File system check progress reporting</refpurpose> ++ </refnamediv> ++ ++ <refsynopsisdiv> ++ <para><filename>systemd-fsckd.service</filename></para> ++ <para><filename>systemd-fsckd.socket</filename></para> ++ <para><filename>/usr/lib/systemd/systemd-fsckd</filename></para> ++ </refsynopsisdiv> ++ ++ <refsect1> ++ <title>Description</title> ++ ++ <para><filename>systemd-fsckd.service</filename> is a service responsible ++ for receiving file system check progress, and communicating some ++ consolidated data to console and plymouth (if running). It also handles ++ possible check cancellations.</para> ++ ++ <para><command>systemd-fsckd</command> receives messages about file ++ system check progress from <command>fsck</command> through an ++ UNIX domain socket. It can display the progress of the least advanced ++ fsck as well as the total number of devices being checked in parallel ++ to the console. It will also send progress messages to plymouth. ++ Both the raw data and translated messages are sent, so compiled ++ plymouth themes can use the raw data to display custom messages, and ++ scripted themes, not supporting i18n, can display the translated ++ versions.</para> ++ ++ <para><command>systemd-fsckd</command> will instruct plymouth to grab ++ Control+C keypresses. When the key is pressed, running checks will be ++ terminated. It will also cancel any newly connected fsck instances for ++ the lifetime of <filename>systemd-fsckd</filename>.</para> ++ </refsect1> ++ ++ <refsect1> ++ <title>Protocol for communication with plymouth</title> ++ ++ <para><filename>systemd-fsckd</filename> passes the ++ following messages to the theme:</para> ++ ++ <para>Progress update, sent as a plymouth update message: ++ <literal>fsckd:<num_devices>:<progress>:<string></literal> ++ <variablelist> ++ <varlistentry> ++ <term><literal><num_devices></literal></term> ++ <listitem><para>the current number of devices ++ being checked (int)</para></listitem> ++ </varlistentry> ++ <varlistentry> ++ <term><literal><progress></literal></term> ++ <listitem><para>the current minimum percentage of ++ all devices being checking (float, from 0 to 100)</para></listitem> ++ </varlistentry> ++ <varlistentry> ++ <term><literal><string></literal></term> ++ <listitem><para>a translated message ready to be displayed ++ by the plymouth theme displaying the data above. It can be overridden ++ by themes supporting i18n.</para></listitem> ++ </varlistentry> ++ </variablelist> ++ </para> ++ ++ <para>Cancel message, sent as a traditional plymouth message: ++ <literal>fsckd-cancel-msg:<string></literal> ++ <variablelist> ++ <varlistentry> ++ <term><literal><strings></literal></term> ++ <listitem><para>a translated string ready to be displayed ++ by the plymouth theme indicating that Control+C can be used to cancel ++ current checks. It can be overridden (matching only ++ <literal>fsckd-cancel-msg</literal> prefix) ++ by themes supporting i18n.</para></listitem> ++ </varlistentry> ++ </variablelist> ++ </para> ++ </refsect1> ++ ++ <refsect1> ++ <title>Options</title> ++ ++ <para>The following options are understood:</para> ++ ++ <variablelist> ++ <xi:include href="standard-options.xml" xpointer="help" /> ++ <xi:include href="standard-options.xml" xpointer="version" /> ++ </variablelist> ++ ++ </refsect1> ++ ++ <refsect1> ++ <title>Exit status</title> ++ ++ <para>On success, 0 is returned, a non-zero failure ++ code otherwise. Note that the daemon stays idle for ++ a while to accept new <filename>fsck</filename> ++ connections before exiting.</para> ++ </refsect1> ++ ++ <refsect1> ++ <title>See Also</title> ++ <para> ++ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, ++ <citerefentry><refentrytitle>systemd-fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.cramfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.ext4</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.fat</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.hfsplus</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.minix</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.ntfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>, ++ <citerefentry project='man-pages'><refentrytitle>fsck.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry> ++ </para> ++ </refsect1> ++ ++</refentry> +diff --git a/meson.build b/meson.build +index 27d95e7..9ace3e6 100644 +--- a/meson.build ++++ b/meson.build +@@ -3368,6 +3368,15 @@ executable( + install : true, + install_dir : rootlibexecdir) + ++executable( ++ 'systemd-fsckd', ++ 'src/fsckd/fsckd.c', ++ include_directories : includes, ++ link_with : [libshared], ++ install_rpath : rootpkglibdir, ++ install : true, ++ install_dir : rootlibexecdir) ++ + executable( + 'systemd-sleep', + 'src/sleep/sleep.c', +diff --git a/po/POTFILES.in b/po/POTFILES.in +index e045852..131e4bc 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -12,3 +12,4 @@ src/portable/org.freedesktop.portable1.policy + src/resolve/org.freedesktop.resolve1.policy + src/timedate/org.freedesktop.timedate1.policy + src/core/dbus-unit.c ++src/fsckd/fsckd.c +diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c +new file mode 100644 +index 0000000..71dc86d +--- /dev/null ++++ b/src/fsckd/fsckd.c +@@ -0,0 +1,702 @@ ++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ ++ ++/*** ++ This file is part of systemd. ++ ++ Copyright 2015 Canonical ++ ++ Author: ++ Didier Roche <didrocks@ubuntu.com> ++ ++ 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. ++ ++ systemd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with systemd; If not, see <http://www.gnu.org/licenses/>. ++***/ ++ ++#include <getopt.h> ++#include <errno.h> ++#include <libintl.h> ++#include <math.h> ++#include <stdbool.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <sys/socket.h> ++#include <sys/types.h> ++#include <sys/un.h> ++#include <unistd.h> ++ ++#include "sd-daemon.h" ++#include "build.h" ++#include "def.h" ++#include "sd-event.h" ++#include "log.h" ++#include "list.h" ++#include "macro.h" ++#include "socket-netlink.h" ++#include "socket-util.h" ++#include "fd-util.h" ++#include "string-util.h" ++#include "io-util.h" ++#include "util.h" ++#include "alloc-util.h" ++#include "locale-util.h" ++ ++#define FSCKD_SOCKET_PATH "/run/systemd/fsck.progress" ++#define IDLE_TIME_SECONDS 30 ++#define PLYMOUTH_REQUEST_KEY "K\2\2\3" ++#define CLIENTS_MAX 128 ++ ++struct Manager; ++ ++typedef struct Client { ++ struct Manager *manager; ++ char *device_name; ++ /* device id refers to "fd <fd>" until it gets a name as "device_name" */ ++ char *device_id; ++ ++ pid_t fsck_pid; ++ FILE *fsck_f; ++ ++ size_t cur; ++ size_t max; ++ int pass; ++ ++ double percent; ++ ++ bool cancelled; ++ bool bad_input; ++ ++ sd_event_source *event_source; ++ ++ LIST_FIELDS(struct Client, clients); ++} Client; ++ ++typedef struct Manager { ++ sd_event *event; ++ ++ LIST_HEAD(Client, clients); ++ unsigned n_clients; ++ ++ size_t clear; ++ ++ int connection_fd; ++ sd_event_source *connection_event_source; ++ ++ bool show_status_console; ++ ++ double percent; ++ int numdevices; ++ ++ int plymouth_fd; ++ sd_event_source *plymouth_event_source; ++ bool plymouth_cancel_sent; ++ ++ bool cancel_requested; ++} Manager; ++ ++static Client* client_free(Client *c); ++static Manager* manager_free(Manager *m); ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free); ++DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); ++ ++static void init_gettext(void) { ++ setlocale(LC_ALL, ""); ++ textdomain(GETTEXT_PACKAGE); ++} ++ ++static bool plymouth_running(void) { ++ return access("/run/plymouth/pid", F_OK) >= 0; ++} ++ ++static int manager_write_console(Manager *m, const char *message) { ++ _cleanup_fclose_ FILE *console = NULL; ++ int l; ++ size_t j; ++ ++ assert(m); ++ ++ if (!m->show_status_console) ++ return 0; ++ ++ /* Nothing to display, and nothing to clear: return now. */ ++ if (message == NULL && m->clear == 0) { ++ return 0; ++ } ++ ++ /* Reduce the SAK window by opening and closing console on every request */ ++ console = fopen("/dev/console", "we"); ++ if (!console) ++ return -errno; ++ ++ if (message) { ++ fprintf(console, "\r%s\r%n", message, &l); ++ if (m->clear < (size_t)l) ++ m->clear = (size_t)l; ++ } else { ++ fputc('\r', console); ++ for (j = 0; j < m->clear; j++) ++ fputc(' ', console); ++ fputc('\r', console); ++ } ++ fflush(console); ++ ++ return 0; ++} ++ ++static double compute_percent(int pass, size_t cur, size_t max) { ++ /* Values stolen from e2fsck */ ++ ++ static const double pass_table[] = { ++ 0, 70, 90, 92, 95, 100 ++ }; ++ ++ if (pass <= 0) ++ return 0.0; ++ ++ if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0) ++ return 100.0; ++ ++ return pass_table[pass-1] + ++ (pass_table[pass] - pass_table[pass-1]) * ++ (double) cur / max; ++} ++ ++static int client_request_cancel(Client *c) { ++ assert(c); ++ ++ if (c->cancelled) ++ return 0; ++ ++ log_info("Request to cancel fsck for %s from fsckd", c->device_id); ++ if (kill(c->fsck_pid, SIGTERM) < 0) { ++ /* ignore the error and consider that cancel was sent if fsck just exited */ ++ if (errno != ESRCH) ++ return log_error_errno(errno, "Cannot send cancel to fsck for %s: %m", c->device_id); ++ } ++ ++ c->cancelled = true; ++ return 1; ++} ++ ++static Client* client_free(Client *c) { ++ assert(c); ++ ++ if (c->manager) { ++ LIST_REMOVE(clients, c->manager->clients, c); ++ c->manager->n_clients--; ++ } ++ ++ sd_event_source_unref(c->event_source); ++ fclose(c->fsck_f); ++ if (c->device_name) ++ free(c->device_name); ++ if (c->device_id) ++ free(c->device_id); ++ return mfree(c); ++} ++ ++static void manager_disconnect_plymouth(Manager *m) { ++ assert(m); ++ ++ m->plymouth_event_source = sd_event_source_unref(m->plymouth_event_source); ++ m->plymouth_fd = safe_close(m->plymouth_fd); ++ m->plymouth_cancel_sent = false; ++} ++ ++static int manager_plymouth_feedback_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ Manager *m = userdata; ++ char buffer[6]; ++ ssize_t l; ++ ++ assert(m); ++ ++ l = read(m->plymouth_fd, buffer, sizeof(buffer)); ++ if (l < 0) { ++ log_warning_errno(errno, "Got error while reading from plymouth: %m"); ++ manager_disconnect_plymouth(m); ++ return -errno; ++ } ++ if (l == 0) { ++ manager_disconnect_plymouth(m); ++ return 0; ++ } ++ ++ if (l > 1 && buffer[0] == '\15') ++ log_error("Message update to plymouth wasn't delivered successfully"); ++ ++ /* the only answer support type we requested is a key interruption */ ++ if (l > 2 && buffer[0] == '\2' && buffer[5] == '\3') { ++ m->cancel_requested = true; ++ ++ /* cancel all connected clients */ ++ LIST_FOREACH(clients, current, m->clients) ++ client_request_cancel(current); ++ } ++ ++ return 0; ++} ++ ++static int manager_connect_plymouth(Manager *m) { ++ union sockaddr_union sa = PLYMOUTH_SOCKET; ++ int r; ++ ++ if (!plymouth_running()) ++ return 0; ++ ++ /* try to connect or reconnect if sending a message */ ++ if (m->plymouth_fd >= 0) ++ return 1; ++ ++ m->plymouth_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); ++ if (m->plymouth_fd < 0) ++ return log_warning_errno(errno, "Connection to plymouth socket failed: %m"); ++ ++ if (connect(m->plymouth_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { ++ r = log_warning_errno(errno, "Couldn't connect to plymouth: %m"); ++ goto fail; ++ } ++ ++ r = sd_event_add_io(m->event, &m->plymouth_event_source, m->plymouth_fd, EPOLLIN, manager_plymouth_feedback_handler, m); ++ if (r < 0) { ++ log_warning_errno(r, "Can't listen to plymouth socket: %m"); ++ goto fail; ++ } ++ ++ return 1; ++ ++fail: ++ manager_disconnect_plymouth(m); ++ return r; ++} ++ ++static int plymouth_send_message(int plymouth_fd, const char *message, bool update) { ++ _cleanup_free_ char *packet = NULL; ++ int n; ++ char mode = 'M'; ++ ++ if (update) ++ mode = 'U'; ++ ++ if (asprintf(&packet, "%c\002%c%s%n", mode, (int) (strlen(message) + 1), message, &n) < 0) ++ return log_oom(); ++ ++ return loop_write(plymouth_fd, packet, n + 1, true); ++} ++ ++static int manager_send_plymouth_message(Manager *m, const char *message) { ++ const char *plymouth_cancel_message = NULL, *l10n_cancel_message = NULL; ++ int r; ++ ++ r = manager_connect_plymouth(m); ++ if (r < 0) ++ return r; ++ /* 0 means that plymouth isn't running, do not send any message yet */ ++ else if (r == 0) ++ return 0; ++ ++ if (!m->plymouth_cancel_sent) { ++ ++ /* Indicate to plymouth that we listen to Ctrl+C */ ++ r = loop_write(m->plymouth_fd, PLYMOUTH_REQUEST_KEY, sizeof(PLYMOUTH_REQUEST_KEY), true); ++ if (r < 0) ++ return log_warning_errno(r, "Can't send to plymouth cancel key: %m"); ++ ++ m->plymouth_cancel_sent = true; ++ ++ l10n_cancel_message = _("Press Ctrl+C to cancel all filesystem checks in progress"); ++ plymouth_cancel_message = strjoina("fsckd-cancel-msg:", l10n_cancel_message); ++ ++ r = plymouth_send_message(m->plymouth_fd, plymouth_cancel_message, false); ++ if (r < 0) ++ log_warning_errno(r, "Can't send filesystem cancel message to plymouth: %m"); ++ ++ } else if (m->numdevices == 0) { ++ ++ m->plymouth_cancel_sent = false; ++ ++ r = plymouth_send_message(m->plymouth_fd, "", false); ++ if (r < 0) ++ log_warning_errno(r, "Can't clear plymouth filesystem cancel message: %m"); ++ } ++ ++ r = plymouth_send_message(m->plymouth_fd, message, true); ++ if (r < 0) ++ return log_warning_errno(r, "Couldn't send \"%s\" to plymouth: %m", message); ++ ++ return 0; ++} ++ ++static int manager_update_global_progress(Manager *m) { ++ _cleanup_free_ char *console_message = NULL; ++ _cleanup_free_ char *fsck_message = NULL; ++ int current_numdevices = 0, r; ++ double current_percent = 100; ++ ++ /* get the overall percentage */ ++ LIST_FOREACH(clients, current, m->clients) { ++ current_numdevices++; ++ ++ /* right now, we only keep the minimum % of all fsckd processes. We could in the future trying to be ++ linear, but max changes and corresponds to the pass. We have all the informations into fsckd ++ already if we can treat that in a smarter way. */ ++ current_percent = MIN(current_percent, current->percent); ++ } ++ ++ /* update if there is anything user-visible to update */ ++ if (fabs(current_percent - m->percent) > 0.001 || current_numdevices != m->numdevices) { ++ m->numdevices = current_numdevices; ++ m->percent = current_percent; ++ ++ if (asprintf(&console_message, ++ ngettext("Checking in progress on %d disk (%3.1f%% complete)", ++ "Checking in progress on %d disks (%3.1f%% complete)", m->numdevices), ++ m->numdevices, m->percent) < 0) ++ return -ENOMEM; ++ ++ if (asprintf(&fsck_message, "fsckd:%d:%3.1f:%s", m->numdevices, m->percent, console_message) < 0) ++ return -ENOMEM; ++ ++ r = manager_write_console(m, console_message); ++ if (r < 0) ++ return r; ++ ++ /* try to connect to plymouth and send message */ ++ r = manager_send_plymouth_message(m, fsck_message); ++ if (r < 0) ++ return r; ++ } ++ return 0; ++} ++ ++static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ Client *client = userdata; ++ char line[LINE_MAX]; ++ Manager *m; ++ ++ assert(client); ++ m = client->manager; ++ ++ /* check first if we need to cancel this client */ ++ if (m->cancel_requested) ++ client_request_cancel(client); ++ ++ while (fgets(line, sizeof(line), client->fsck_f) != NULL) { ++ int pass; ++ size_t cur, max; ++ _cleanup_free_ char *device = NULL, *old_device_id = NULL; ++ ++ if (sscanf(line, "%i %zu %zu %ms", &pass, &cur, &max, &device) == 4) { ++ if (!client->device_name) { ++ client->device_name = strdup(device); ++ if (!client->device_name) { ++ log_oom(); ++ continue; ++ } ++ old_device_id = client->device_id; ++ client->device_id = strdup(device); ++ if (!client->device_id) { ++ log_oom(); ++ client->device_id = old_device_id; ++ old_device_id = NULL; ++ continue; ++ } ++ } ++ client->pass = pass; ++ client->cur = cur; ++ client->max = max; ++ client->bad_input = false; ++ client->percent = compute_percent(client->pass, client->cur, client->max); ++ log_debug("Getting progress for %s (%zu, %zu, %d) : %3.1f%%", client->device_id, ++ client->cur, client->max, client->pass, client->percent); ++ } else { ++ if (errno == ENOMEM) { ++ log_oom(); ++ continue; ++ } ++ ++ /* if previous input was already garbage, kick it off from progress report */ ++ if (client->bad_input) { ++ log_warning("Closing connection on incorrect input of fsck connection for %s", client->device_id); ++ client_free(client); ++ manager_update_global_progress(m); ++ return 0; ++ } ++ client->bad_input = true; ++ } ++ ++ } ++ ++ if (feof(client->fsck_f)) { ++ log_debug("Fsck client %s disconnected", client->device_id); ++ client_free(client); ++ } ++ ++ manager_update_global_progress(m); ++ return 0; ++} ++ ++static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ _cleanup_(client_freep) Client *c = NULL; ++ _cleanup_close_ int new_fsck_fd = -1; ++ _cleanup_fclose_ FILE *new_fsck_f = NULL; ++ struct ucred ucred = {}; ++ Manager *m = userdata; ++ int r; ++ ++ assert(m); ++ ++ /* Initialize and list new clients */ ++ new_fsck_fd = accept4(m->connection_fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); ++ if (new_fsck_fd < 0) { ++ log_error_errno(errno, "Couldn't accept a new connection: %m"); ++ return 0; ++ } ++ ++ if (m->n_clients >= CLIENTS_MAX) { ++ log_error("Too many clients, refusing connection."); ++ return 0; ++ } ++ ++ ++ new_fsck_f = fdopen(new_fsck_fd, "r"); ++ if (!new_fsck_f) { ++ log_error_errno(errno, "Couldn't fdopen new connection for fd %d: %m", new_fsck_fd); ++ return 0; ++ } ++ new_fsck_fd = -1; ++ ++ r = getpeercred(fileno(new_fsck_f), &ucred); ++ if (r < 0) { ++ log_error_errno(r, "Couldn't get credentials for fsck: %m"); ++ return 0; ++ } ++ ++ c = new0(Client, 1); ++ if (!c) { ++ log_oom(); ++ return 0; ++ } ++ ++ c->fsck_pid = ucred.pid; ++ c->fsck_f = new_fsck_f; ++ new_fsck_f = NULL; ++ ++ if (asprintf(&(c->device_id), "fd %d", fileno(c->fsck_f)) < 0) { ++ log_oom(); ++ return 0; ++ } ++ ++ r = sd_event_add_io(m->event, &c->event_source, fileno(c->fsck_f), EPOLLIN, client_progress_handler, c); ++ if (r < 0) { ++ log_oom(); ++ return 0; ++ } ++ ++ LIST_PREPEND(clients, m->clients, c); ++ m->n_clients++; ++ c->manager = m; ++ ++ log_debug("New fsck client connected: %s", c->device_id); ++ ++ /* only request the client to cancel now in case the request is dropped by the client (chance to recancel) */ ++ if (m->cancel_requested) ++ client_request_cancel(c); ++ ++ c = NULL; ++ return 0; ++} ++ ++static Manager* manager_free(Manager *m) { ++ if (!m) ++ return NULL; ++ ++ /* clear last line */ ++ manager_write_console(m, NULL); ++ ++ sd_event_source_unref(m->connection_event_source); ++ safe_close(m->connection_fd); ++ ++ while (m->clients) ++ client_free(m->clients); ++ ++ manager_disconnect_plymouth(m); ++ ++ sd_event_unref(m->event); ++ ++ return mfree(m); ++} ++ ++static int manager_new(Manager **ret, int fd) { ++ _cleanup_(manager_freep) Manager *m = NULL; ++ int r; ++ ++ assert(ret); ++ ++ m = new0(Manager, 1); ++ if (!m) ++ return -ENOMEM; ++ ++ m->plymouth_fd = -1; ++ m->connection_fd = fd; ++ m->percent = 100; ++ ++ r = sd_event_default(&m->event); ++ if (r < 0) ++ return r; ++ ++ if (access("/run/systemd/show-status", F_OK) >= 0) ++ m->show_status_console = true; ++ ++ r = sd_event_add_io(m->event, &m->connection_event_source, fd, EPOLLIN, manager_new_connection_handler, m); ++ if (r < 0) ++ return r; ++ ++ *ret = m; ++ m = NULL; ++ ++ return 0; ++} ++ ++static int run_event_loop_with_timeout(Manager *m, usec_t timeout) { ++ int r, code; ++ sd_event *e = m->event; ++ ++ assert(e); ++ ++ for (;;) { ++ r = sd_event_get_state(e); ++ if (r < 0) ++ return r; ++ if (r == SD_EVENT_FINISHED) ++ break; ++ ++ r = sd_event_run(e, timeout); ++ if (r < 0) ++ return r; ++ ++ /* Exit if we reached the idle timeout and no more clients are ++ connected. If there is still an fsck process running but ++ simply slow to send us progress updates, exiting would mean ++ that this fsck process receives SIGPIPE resulting in an ++ aborted file system check. */ ++ if (r == 0 && m->n_clients == 0) { ++ sd_event_exit(e, 0); ++ break; ++ } ++ } ++ ++ r = sd_event_get_exit_code(e, &code); ++ if (r < 0) ++ return r; ++ ++ return code; ++} ++ ++static void help(void) { ++ printf("%s [OPTIONS...]\n\n" ++ "Capture fsck progress and forward one stream to plymouth\n\n" ++ " -h --help Show this help\n" ++ " --version Show package version\n", ++ program_invocation_short_name); ++} ++ ++static int parse_argv(int argc, char *argv[]) { ++ ++ enum { ++ ARG_VERSION = 0x100, ++ ARG_ROOT, ++ }; ++ ++ static const struct option options[] = { ++ { "help", no_argument, NULL, 'h' }, ++ { "version", no_argument, NULL, ARG_VERSION }, ++ {} ++ }; ++ ++ int c; ++ ++ assert(argc >= 0); ++ assert(argv); ++ ++ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) ++ switch (c) { ++ ++ case 'h': ++ help(); ++ return 0; ++ ++ case ARG_VERSION: ++ version(); ++ return 0; ++ ++ case '?': ++ return -EINVAL; ++ ++ default: ++ assert_not_reached(); ++ } ++ ++ if (optind < argc) { ++ log_error("Extraneous arguments"); ++ return -EINVAL; ++ } ++ ++ return 1; ++} ++ ++int main(int argc, char *argv[]) { ++ _cleanup_(manager_freep) Manager *m = NULL; ++ int fd = -1; ++ int r, n; ++ ++ log_set_target(LOG_TARGET_AUTO); ++ log_parse_environment(); ++ log_open(); ++ init_gettext(); ++ ++ r = parse_argv(argc, argv); ++ if (r <= 0) ++ goto finish; ++ ++ n = sd_listen_fds(0); ++ if (n > 1) { ++ log_error("Too many file descriptors received."); ++ r = -EINVAL; ++ goto finish; ++ } else if (n == 1) ++ fd = SD_LISTEN_FDS_START + 0; ++ else { ++ fd = make_socket_fd(LOG_DEBUG, FSCKD_SOCKET_PATH, SOCK_STREAM, SOCK_CLOEXEC); ++ if (fd < 0) { ++ r = log_error_errno(fd, "Couldn't create listening socket fd on %s: %m", FSCKD_SOCKET_PATH); ++ goto finish; ++ } ++ } ++ ++ r = manager_new(&m, fd); ++ if (r < 0) { ++ log_error_errno(r, "Failed to allocate manager: %m"); ++ goto finish; ++ } ++ ++ r = run_event_loop_with_timeout(m, IDLE_TIME_SECONDS * USEC_PER_SEC); ++ if (r < 0) { ++ log_error_errno(r, "Failed to run event loop: %m"); ++ goto finish; ++ } ++ ++ sd_event_get_exit_code(m->event, &r); ++ ++finish: ++ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; ++} +diff --git a/units/meson.build b/units/meson.build +index 25e9209..8d3bef3 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -113,6 +113,7 @@ units = [ + ['systemd-exit.service', ''], + ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT', + 'sysinit.target.wants/'], ++ ['systemd-fsckd.socket', ''], + ['systemd-halt.service', ''], + ['systemd-homed-activate.service', 'ENABLE_HOMED'], + ['systemd-initctl.socket', 'HAVE_SYSV_COMPAT', +@@ -194,6 +195,7 @@ in_units = [ + ['systemd-pstore.service', 'ENABLE_PSTORE'], + ['systemd-fsck-root.service', ''], + ['systemd-fsck@.service', ''], ++ ['systemd-fsckd.service', ''], + ['systemd-hibernate-resume@.service', 'ENABLE_HIBERNATE'], + ['systemd-hibernate.service', 'ENABLE_HIBERNATE'], + ['systemd-hybrid-sleep.service', 'ENABLE_HIBERNATE'], +diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in +index 8378df8..4b1cd43 100644 +--- a/units/systemd-fsck-root.service.in ++++ b/units/systemd-fsck-root.service.in +@@ -13,6 +13,8 @@ Documentation=man:systemd-fsck-root.service(8) + DefaultDependencies=no + Conflicts=shutdown.target + Before=local-fs.target shutdown.target ++Wants=systemd-fsckd.socket ++After=systemd-fsckd.socket + ConditionPathIsReadWrite=!/ + OnFailure=emergency.target + OnFailureJobMode=replace-irreversibly +diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in +index 06b91ae..de0b767 100644 +--- a/units/systemd-fsck@.service.in ++++ b/units/systemd-fsck@.service.in +@@ -13,7 +13,8 @@ Documentation=man:systemd-fsck@.service(8) + DefaultDependencies=no + BindsTo=%i.device + Conflicts=shutdown.target +-After=%i.device systemd-fsck-root.service local-fs-pre.target ++Wants=systemd-fsckd.socket ++After=%i.device systemd-fsck-root.service local-fs-pre.target systemd-fsckd.socket + Before=systemd-quotacheck.service shutdown.target + + [Service] +diff --git a/units/systemd-fsckd.service.in b/units/systemd-fsckd.service.in +new file mode 100644 +index 0000000..f075b66 +--- /dev/null ++++ b/units/systemd-fsckd.service.in +@@ -0,0 +1,17 @@ ++# 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=File System Check Daemon to report status ++Documentation=man:systemd-fsckd.service(8) ++DefaultDependencies=no ++Requires=systemd-fsckd.socket ++Before=shutdown.target ++ ++[Service] ++ExecStart={{ROOTLIBEXECDIR}}/systemd-fsckd ++StandardOutput=journal+console +diff --git a/units/systemd-fsckd.socket b/units/systemd-fsckd.socket +new file mode 100644 +index 0000000..61fec97 +--- /dev/null ++++ b/units/systemd-fsckd.socket +@@ -0,0 +1,15 @@ ++# 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=fsck to fsckd communication Socket ++Documentation=man:systemd-fsckd.service(8) man:systemd-fsck@.service(8) man:systemd-fsck-root.service(8) ++DefaultDependencies=no ++ ++[Socket] ++ListenStream=/run/systemd/fsck.progress ++SocketMode=0600 diff --git a/debian/patches/debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch b/debian/patches/debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch new file mode 100644 index 0000000..f157e45 --- /dev/null +++ b/debian/patches/debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch @@ -0,0 +1,34 @@ +From: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com> +Date: Thu, 17 Dec 2020 14:52:07 +0000 +Subject: systemctl: do not shutdown immediately on scheduled shutdown + +When, for whatever reason, a scheduled shutdown fails to be set, systemd +will proceed with immediate shutdown without allowing the user to react. +This is counterintuitive because when a scheduled shutdown is issued, +it means the user wants to shutdown at a specified time in the future, +not immediately. This patch prevents the immediate shutdown and informs +the user that no action will be taken. + +Fixes: #17575 +--- + src/systemctl/systemctl-compat-halt.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/systemctl/systemctl-compat-halt.c b/src/systemctl/systemctl-compat-halt.c +index 8a0e4e6..7eeec9a 100644 +--- a/src/systemctl/systemctl-compat-halt.c ++++ b/src/systemctl/systemctl-compat-halt.c +@@ -148,9 +148,11 @@ int halt_main(void) { + + if (arg_force == 0) { + /* always try logind first */ +- if (arg_when > 0) ++ if (arg_when > 0) { + r = logind_schedule_shutdown(); +- else { ++ if (r < 0) ++ return r; ++ } else { + r = logind_check_inhibitors(arg_action); + if (r < 0) + return r; diff --git a/debian/patches/debian/udev-drop-SystemCallArchitectures-native-from-systemd-ude.patch b/debian/patches/debian/udev-drop-SystemCallArchitectures-native-from-systemd-ude.patch new file mode 100644 index 0000000..5ad154b --- /dev/null +++ b/debian/patches/debian/udev-drop-SystemCallArchitectures-native-from-systemd-ude.patch @@ -0,0 +1,25 @@ +From: Michael Biebl <biebl@debian.org> +Date: Tue, 19 Nov 2019 09:10:23 +0100 +Subject: udev: drop SystemCallArchitectures=native from systemd-udevd.service + +We can't really control what helper programs are run from other udev +rules. E.g. running i386 binaries under amd64 is a valid use case and +should not trigger a SIGSYS failure. + +Closes: #869719 +--- + units/systemd-udevd.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in +index e9dbe85..22ca8b9 100644 +--- a/units/systemd-udevd.service.in ++++ b/units/systemd-udevd.service.in +@@ -37,7 +37,6 @@ RestrictSUIDSGID=yes + SystemCallFilter=@system-service @module @raw-io bpf + SystemCallFilter=~@clock + SystemCallErrorNumber=EPERM +-SystemCallArchitectures=native + LockPersonality=yes + IPAddressDeny=any + {{SERVICE_WATCHDOG}} diff --git a/debian/patches/p11kit-switch-to-dlopen.patch b/debian/patches/p11kit-switch-to-dlopen.patch new file mode 100644 index 0000000..b22bf58 --- /dev/null +++ b/debian/patches/p11kit-switch-to-dlopen.patch @@ -0,0 +1,743 @@ +From: Luca Boccassi <bluca@debian.org> +Date: Sat, 17 Dec 2022 01:33:46 +0000 +Subject: p11kit: switch to dlopen() + +--- + meson.build | 2 + + src/shared/meson.build | 2 +- + src/shared/pkcs11-util.c | 215 ++++++++++++++++++++++++++++++++++------------ + src/shared/pkcs11-util.h | 28 +++++- + src/test/meson.build | 4 +- + src/test/test-dlopen-so.c | 5 ++ + test/test-functions | 6 +- + 7 files changed, 202 insertions(+), 60 deletions(-) + +diff --git a/meson.build b/meson.build +index 9de2309..27d95e7 100644 +--- a/meson.build ++++ b/meson.build +@@ -1462,8 +1462,10 @@ if want_p11kit != 'false' and not skip_deps + version : '>= 0.23.3', + required : want_p11kit == 'true') + have = libp11kit.found() ++ libp11kit_cflags = libp11kit.partial_dependency(includes: true, compile_args: true) + else + have = false ++ libp11kit_cflags = [] + libp11kit = [] + endif + conf.set10('HAVE_P11KIT', have) +diff --git a/src/shared/meson.build b/src/shared/meson.build +index 3e2f327..9c47d2d 100644 +--- a/src/shared/meson.build ++++ b/src/shared/meson.build +@@ -459,7 +459,7 @@ libshared_deps = [threads, + liblz4, + libmount, + libopenssl, +- libp11kit, ++ libp11kit_cflags, + libpam, + librt, + libseccomp, +diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c +index 752a21d..5f5dbae 100644 +--- a/src/shared/pkcs11-util.c ++++ b/src/shared/pkcs11-util.c +@@ -3,6 +3,7 @@ + #include <fcntl.h> + + #include "ask-password-api.h" ++#include "dlfcn-util.h" + #include "env-util.h" + #include "escape.h" + #include "fd-util.h" +@@ -40,17 +41,59 @@ bool pkcs11_uri_valid(const char *uri) { + + #if HAVE_P11KIT + ++static void *p11kit_dl = NULL; ++ ++char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module); ++void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules); ++CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags); ++const char *(*sym_p11_kit_strerror)(CK_RV rv); ++int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string); ++void (*sym_p11_kit_uri_free)(P11KitUri *uri); ++CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs); ++CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri); ++CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri); ++CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri); ++int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info); ++const char *(*sym_p11_kit_uri_message)(int code); ++P11KitUri *(*sym_p11_kit_uri_new)(void); ++int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri); ++ ++int dlopen_p11kit(void) { ++ return dlopen_many_sym_or_warn( ++ &p11kit_dl, ++ "libp11-kit.so.0", LOG_DEBUG, ++ DLSYM_ARG(p11_kit_module_get_name), ++ DLSYM_ARG(p11_kit_modules_finalize_and_release), ++ DLSYM_ARG(p11_kit_modules_load_and_initialize), ++ DLSYM_ARG(p11_kit_strerror), ++ DLSYM_ARG(p11_kit_uri_format), ++ DLSYM_ARG(p11_kit_uri_free), ++ DLSYM_ARG(p11_kit_uri_get_attributes), ++ DLSYM_ARG(p11_kit_uri_get_module_info), ++ DLSYM_ARG(p11_kit_uri_get_slot_info), ++ DLSYM_ARG(p11_kit_uri_get_token_info), ++ DLSYM_ARG(p11_kit_uri_match_token_info), ++ DLSYM_ARG(p11_kit_uri_message), ++ DLSYM_ARG(p11_kit_uri_new), ++ DLSYM_ARG(p11_kit_uri_parse)); ++} ++ + int uri_from_string(const char *p, P11KitUri **ret) { +- _cleanup_(p11_kit_uri_freep) P11KitUri *uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *uri = NULL; ++ int r; + + assert(p); + assert(ret); + +- uri = p11_kit_uri_new(); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return -ENOMEM; + +- if (p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK) ++ if (sym_p11_kit_uri_parse(p, P11_KIT_URI_FOR_ANY, uri) != P11_KIT_URI_OK) + return -EINVAL; + + *ret = TAKE_PTR(uri); +@@ -62,11 +105,14 @@ P11KitUri *uri_from_module_info(const CK_INFO *info) { + + assert(info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_module_info(uri) = *info; ++ *sym_p11_kit_uri_get_module_info(uri) = *info; + return uri; + } + +@@ -75,11 +121,14 @@ P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info) { + + assert(slot_info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_slot_info(uri) = *slot_info; ++ *sym_p11_kit_uri_get_slot_info(uri) = *slot_info; + return uri; + } + +@@ -88,11 +137,14 @@ P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info) { + + assert(token_info); + +- uri = p11_kit_uri_new(); ++ if (dlopen_p11kit() < 0) ++ return NULL; ++ ++ uri = sym_p11_kit_uri_new(); + if (!uri) + return NULL; + +- *p11_kit_uri_get_token_info(uri) = *token_info; ++ *sym_p11_kit_uri_get_token_info(uri) = *token_info; + return uri; + } + +@@ -184,15 +236,20 @@ int pkcs11_token_login_by_pin( + size_t pin_size) { + + CK_RV rv; ++ int r; + + assert(m); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + if (FLAGS_SET(token_info->flags, CKF_PROTECTED_AUTHENTICATION_PATH)) { + rv = m->C_Login(session, CKU_USER, NULL, 0); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + log_info("Successfully logged into security token '%s' via protected authentication path.", token_label); + return 0; +@@ -217,7 +274,7 @@ int pkcs11_token_login_by_pin( + "PIN has been locked, please reset PIN of security token '%s'.", token_label); + if (!IN_SET(rv, CKR_PIN_INCORRECT, CKR_PIN_LEN_RANGE)) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to log into security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + return log_notice_errno(SYNTHETIC_ERRNO(ENOLCK), + "PIN for token '%s' is incorrect, please try again.", +@@ -239,7 +296,7 @@ int pkcs11_token_login( + char **ret_used_pin) { + + _cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + CK_TOKEN_INFO updated_token_info; + int uri_result, r; + CK_RV rv; +@@ -247,6 +304,10 @@ int pkcs11_token_login( + assert(m); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + token_label = pkcs11_token_label(token_info); + if (!token_label) + return log_oom(); +@@ -255,9 +316,9 @@ int pkcs11_token_login( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + r = pkcs11_token_login_by_pin(m, session, token_info, token_label, /* pin= */ NULL, 0); + if (r == 0 && ret_used_pin) +@@ -336,7 +397,7 @@ int pkcs11_token_login( + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to acquire updated security token information for slot %lu: %s", +- slotid, p11_kit_strerror(rv)); ++ slotid, sym_p11_kit_strerror(rv)); + + token_info = &updated_token_info; + } +@@ -357,12 +418,17 @@ int pkcs11_token_find_x509_certificate( + CK_ATTRIBUTE *attributes = NULL; + CK_OBJECT_HANDLE objects[2]; + CK_RV rv, rv2; ++ int r; + + assert(m); + assert(search_uri); + assert(ret_object); + +- attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes); + for (a = 0; a < n_attributes; a++) { + + /* We use the URI's included match attributes, but make them more strict. This allows users +@@ -435,16 +501,16 @@ int pkcs11_token_find_x509_certificate( + rv = m->C_FindObjectsInit(session, attributes, n_attributes); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv)); + + rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects); + rv2 = m->C_FindObjectsFinal(session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to find objects: %s", p11_kit_strerror(rv)); ++ "Failed to find objects: %s", sym_p11_kit_strerror(rv)); + if (rv2 != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to finalize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv)); + if (n_objects == 0) + return log_error_errno(SYNTHETIC_ERRNO(ENOENT), + "Failed to find selected X509 certificate on token."); +@@ -472,11 +538,16 @@ int pkcs11_token_read_x509_certificate( + _cleanup_(X509_freep) X509 *x509 = NULL; + X509_NAME *name = NULL; + const unsigned char *p; ++ int r; ++ ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; + + rv = m->C_GetAttributeValue(session, object, &attribute, 1); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to read X.509 certificate size off token: %s", p11_kit_strerror(rv)); ++ "Failed to read X.509 certificate size off token: %s", sym_p11_kit_strerror(rv)); + + buffer = malloc(attribute.ulValueLen); + if (!buffer) +@@ -487,7 +558,7 @@ int pkcs11_token_read_x509_certificate( + rv = m->C_GetAttributeValue(session, object, &attribute, 1); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to read X.509 certificate data off token: %s", p11_kit_strerror(rv)); ++ "Failed to read X.509 certificate data off token: %s", sym_p11_kit_strerror(rv)); + + p = attribute.pValue; + x509 = d2i_X509(NULL, &p, attribute.ulValueLen); +@@ -521,12 +592,17 @@ int pkcs11_token_find_private_key( + CK_ATTRIBUTE *attributes = NULL; + CK_OBJECT_HANDLE objects[2]; + CK_RV rv, rv2; ++ int r; + + assert(m); + assert(search_uri); + assert(ret_object); + +- attributes = p11_kit_uri_get_attributes(search_uri, &n_attributes); ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ ++ attributes = sym_p11_kit_uri_get_attributes(search_uri, &n_attributes); + for (a = 0; a < n_attributes; a++) { + + /* We use the URI's included match attributes, but make them more strict. This allows users +@@ -625,16 +701,16 @@ int pkcs11_token_find_private_key( + rv = m->C_FindObjectsInit(session, attributes, n_attributes); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to initialize object find call: %s", sym_p11_kit_strerror(rv)); + + rv = m->C_FindObjects(session, objects, ELEMENTSOF(objects), &n_objects); + rv2 = m->C_FindObjectsFinal(session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to find objects: %s", p11_kit_strerror(rv)); ++ "Failed to find objects: %s", sym_p11_kit_strerror(rv)); + if (rv2 != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to finalize object find call: %s", p11_kit_strerror(rv)); ++ "Failed to finalize object find call: %s", sym_p11_kit_strerror(rv)); + if (n_objects == 0) + return log_error_errno(SYNTHETIC_ERRNO(ENOENT), + "Failed to find selected private key suitable for decryption on token."); +@@ -661,6 +737,7 @@ int pkcs11_token_decrypt_data( + _cleanup_(erase_and_freep) CK_BYTE *dbuffer = NULL; + CK_ULONG dbuffer_size = 0; + CK_RV rv; ++ int r; + + assert(m); + assert(encrypted_data); +@@ -668,10 +745,14 @@ int pkcs11_token_decrypt_data( + assert(ret_decrypted_data); + assert(ret_decrypted_data_size); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + rv = m->C_DecryptInit(session, (CK_MECHANISM*) &mechanism, object); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to initialize decryption on security token: %s", p11_kit_strerror(rv)); ++ "Failed to initialize decryption on security token: %s", sym_p11_kit_strerror(rv)); + + dbuffer_size = encrypted_data_size; /* Start with something reasonable */ + dbuffer = malloc(dbuffer_size); +@@ -690,7 +771,7 @@ int pkcs11_token_decrypt_data( + } + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to decrypt key on security token: %s", p11_kit_strerror(rv)); ++ "Failed to decrypt key on security token: %s", sym_p11_kit_strerror(rv)); + + log_info("Successfully decrypted key with security token."); + +@@ -710,6 +791,10 @@ int pkcs11_token_acquire_rng( + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* While we are at it, let's read some RNG data from the PKCS#11 token and pass it to the kernel + * random pool. This should be cheap if we are talking to the device already. Note that we don't + * credit any entropy, since we don't know about the quality of the pkcs#11 token's RNG. Why bother +@@ -726,7 +811,7 @@ int pkcs11_token_acquire_rng( + rv = m->C_GenerateRandom(session, buffer, rps); + if (rv != CKR_OK) + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), +- "Failed to generate RNG data on security token: %s", p11_kit_strerror(rv)); ++ "Failed to generate RNG data on security token: %s", sym_p11_kit_strerror(rv)); + + r = random_write_entropy(-1, buffer, rps, false); + if (r < 0) +@@ -762,7 +847,7 @@ static int token_process( + rv = m->C_OpenSession(slotid, CKF_SERIAL_SESSION, NULL, NULL, &session); + if (rv != CKR_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), +- "Failed to create session for security token '%s': %s", token_label, p11_kit_strerror(rv)); ++ "Failed to create session for security token '%s': %s", token_label, sym_p11_kit_strerror(rv)); + + if (callback) + r = callback(m, session, slotid, slot_info, token_info, search_uri, userdata); +@@ -771,7 +856,7 @@ static int token_process( + + rv = m->C_CloseSession(session); + if (rv != CKR_OK) +- log_warning("Failed to close session on PKCS#11 token, ignoring: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to close session on PKCS#11 token, ignoring: %s", sym_p11_kit_strerror(rv)); + + return r; + } +@@ -783,21 +868,25 @@ static int slot_process( + pkcs11_find_token_callback_t callback, + void *userdata) { + +- _cleanup_(p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri* slot_uri = NULL, *token_uri = NULL; + _cleanup_free_ char *token_uri_string = NULL; + CK_TOKEN_INFO token_info; + CK_SLOT_INFO slot_info; +- int uri_result; ++ int uri_result, r; + CK_RV rv; + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We return -EAGAIN for all failures we can attribute to a specific slot in some way, so that the + * caller might try other slots before giving up. */ + + rv = m->C_GetSlotInfo(slotid, &slot_info); + if (rv != CKR_OK) { +- log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv)); ++ log_warning("Failed to acquire slot info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -808,9 +897,9 @@ static int slot_process( + if (DEBUG_LOGGING) { + _cleanup_free_ char *slot_uri_string = NULL; + +- uri_result = p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string); ++ uri_result = sym_p11_kit_uri_format(slot_uri, P11_KIT_URI_FOR_ANY, &slot_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format slot URI, ignoring slot: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format slot URI, ignoring slot: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +@@ -822,7 +911,7 @@ static int slot_process( + return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), + "Token not present in slot, ignoring."); + } else if (rv != CKR_OK) { +- log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, p11_kit_strerror(rv)); ++ log_warning("Failed to acquire token info for slot %lu, ignoring slot: %s", slotid, sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -830,13 +919,13 @@ static int slot_process( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +- if (search_uri && !p11_kit_uri_match_token_info(search_uri, &token_info)) ++ if (search_uri && !sym_p11_kit_uri_match_token_info(search_uri, &token_info)) + return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), + "Found non-matching token with URI %s.", + token_uri_string); +@@ -859,8 +948,8 @@ static int module_process( + pkcs11_find_token_callback_t callback, + void *userdata) { + ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri* module_uri = NULL; + _cleanup_free_ char *name = NULL, *module_uri_string = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri* module_uri = NULL; + _cleanup_free_ CK_SLOT_ID *slotids = NULL; + CK_ULONG n_slotids = 0; + int uri_result; +@@ -871,11 +960,15 @@ static int module_process( + + assert(m); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We ignore most errors from modules here, in order to skip over faulty modules: one faulty module + * should not have the effect that we don't try the others anymore. We indicate such per-module + * failures with -EAGAIN, which let's the caller try the next module. */ + +- name = p11_kit_module_get_name(m); ++ name = sym_p11_kit_module_get_name(m); + if (!name) + return log_oom(); + +@@ -883,7 +976,7 @@ static int module_process( + + rv = m->C_GetInfo(&info); + if (rv != CKR_OK) { +- log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to get info on PKCS#11 module, ignoring module: %s", sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + +@@ -891,9 +984,9 @@ static int module_process( + if (!module_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string); ++ uri_result = sym_p11_kit_uri_format(module_uri, P11_KIT_URI_FOR_ANY, &module_uri_string); + if (uri_result != P11_KIT_URI_OK) { +- log_warning("Failed to format module URI, ignoring module: %s", p11_kit_uri_message(uri_result)); ++ log_warning("Failed to format module URI, ignoring module: %s", sym_p11_kit_uri_message(uri_result)); + return -EAGAIN; + } + +@@ -901,7 +994,7 @@ static int module_process( + + rv = pkcs11_get_slot_list_malloc(m, &slotids, &n_slotids); + if (rv != CKR_OK) { +- log_warning("Failed to get slot list, ignoring module: %s", p11_kit_strerror(rv)); ++ log_warning("Failed to get slot list, ignoring module: %s", sym_p11_kit_strerror(rv)); + return -EAGAIN; + } + if (n_slotids == 0) +@@ -927,10 +1020,14 @@ int pkcs11_find_token( + pkcs11_find_token_callback_t callback, + void *userdata) { + +- _cleanup_(p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *search_uri = NULL; ++ _cleanup_(sym_p11_kit_modules_finalize_and_releasep) CK_FUNCTION_LIST **modules = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *search_uri = NULL; + int r; + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* Execute the specified callback for each matching token found. If nothing is found returns + * -EAGAIN. Logs about all errors, except for EAGAIN, which the caller has to log about. */ + +@@ -940,7 +1037,7 @@ int pkcs11_find_token( + return log_error_errno(r, "Failed to parse PKCS#11 URI '%s': %m", pkcs11_uri); + } + +- modules = p11_kit_modules_load_and_initialize(0); ++ modules = sym_p11_kit_modules_load_and_initialize(0); + if (!modules) + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize pkcs11 modules"); + +@@ -1068,13 +1165,17 @@ static int list_callback( + void *userdata) { + + _cleanup_free_ char *token_uri_string = NULL, *token_label = NULL, *token_manufacturer_id = NULL, *token_model = NULL; +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + Table *t = userdata; + int uri_result, r; + + assert(slot_info); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + /* We only care about hardware devices here with a token inserted. Let's filter everything else + * out. (Note that the user can explicitly specify non-hardware tokens if they like, but during + * enumeration we'll filter those, since software tokens are typically the system certificate store +@@ -1098,9 +1199,9 @@ static int list_callback( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + r = table_add_many( + t, +@@ -1154,13 +1255,17 @@ static int auto_callback( + P11KitUri *uri, + void *userdata) { + +- _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL; ++ _cleanup_(sym_p11_kit_uri_freep) P11KitUri *token_uri = NULL; + char **t = userdata; +- int uri_result; ++ int uri_result, r; + + assert(slot_info); + assert(token_info); + ++ r = dlopen_p11kit(); ++ if (r < 0) ++ return r; ++ + if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT)) + return -EAGAIN; + +@@ -1172,9 +1277,9 @@ static int auto_callback( + if (!token_uri) + return log_oom(); + +- uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t); ++ uri_result = sym_p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t); + if (uri_result != P11_KIT_URI_OK) +- return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result)); ++ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", sym_p11_kit_uri_message(uri_result)); + + return 0; + } +diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h +index 7c88848..5bc23c1 100644 +--- a/src/shared/pkcs11-util.h ++++ b/src/shared/pkcs11-util.h +@@ -16,14 +16,30 @@ + bool pkcs11_uri_valid(const char *uri); + + #if HAVE_P11KIT ++ ++extern char *(*sym_p11_kit_module_get_name)(CK_FUNCTION_LIST *module); ++extern void (*sym_p11_kit_modules_finalize_and_release)(CK_FUNCTION_LIST **modules); ++extern CK_FUNCTION_LIST **(*sym_p11_kit_modules_load_and_initialize)(int flags); ++extern const char *(*sym_p11_kit_strerror)(CK_RV rv); ++extern int (*sym_p11_kit_uri_format)(P11KitUri *uri, P11KitUriType uri_type, char **string); ++extern void (*sym_p11_kit_uri_free)(P11KitUri *uri); ++extern CK_ATTRIBUTE_PTR (*sym_p11_kit_uri_get_attributes)(P11KitUri *uri, CK_ULONG *n_attrs); ++extern CK_INFO_PTR (*sym_p11_kit_uri_get_module_info)(P11KitUri *uri); ++extern CK_SLOT_INFO_PTR (*sym_p11_kit_uri_get_slot_info)(P11KitUri *uri); ++extern CK_TOKEN_INFO_PTR (*sym_p11_kit_uri_get_token_info)(P11KitUri *uri); ++extern int (*sym_p11_kit_uri_match_token_info)(const P11KitUri *uri, const CK_TOKEN_INFO *token_info); ++extern const char *(*sym_p11_kit_uri_message)(int code); ++extern P11KitUri *(*sym_p11_kit_uri_new)(void); ++extern int (*sym_p11_kit_uri_parse)(const char *string, P11KitUriType uri_type, P11KitUri *uri); ++ + int uri_from_string(const char *p, P11KitUri **ret); + + P11KitUri *uri_from_module_info(const CK_INFO *info); + P11KitUri *uri_from_slot_info(const CK_SLOT_INFO *slot_info); + P11KitUri *uri_from_token_info(const CK_TOKEN_INFO *token_info); + +-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, p11_kit_uri_free, NULL); +-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, p11_kit_modules_finalize_and_release, NULL); ++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(P11KitUri*, sym_p11_kit_uri_free, NULL); ++DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(CK_FUNCTION_LIST**, sym_p11_kit_modules_finalize_and_release, NULL); + + CK_RV pkcs11_get_slot_list_malloc(CK_FUNCTION_LIST *m, CK_SLOT_ID **ret_slotids, CK_ULONG *ret_n_slotids); + +@@ -74,6 +90,14 @@ int pkcs11_crypt_device_callback( + P11KitUri *uri, + void *userdata); + ++int dlopen_p11kit(void); ++ ++#else ++ ++static inline int dlopen_p11kit(void) { ++ return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "p11kit support is not compiled in."); ++} ++ + #endif + + typedef struct { +diff --git a/src/test/meson.build b/src/test/meson.build +index 2a4dfe2..082566b 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -74,7 +74,9 @@ tests += [ + [], + core_includes], + +- [files('test-dlopen-so.c')], ++ [files('test-dlopen-so.c'), ++ [], ++ libp11kit_cflags], + + [files('test-job-type.c'), + [libcore, +diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c +index 85dbb81..55728c2 100644 +--- a/src/test/test-dlopen-so.c ++++ b/src/test/test-dlopen-so.c +@@ -11,6 +11,7 @@ + #include "macro.h" + #include "main-func.h" + #include "pcre2-util.h" ++#include "pkcs11-util.h" + #include "pwquality-util.h" + #include "qrcode-util.h" + #include "tests.h" +@@ -60,6 +61,10 @@ static int run(int argc, char **argv) { + assert_se(dlopen_pcre2() >= 0); + #endif + ++#if HAVE_P11KIT ++ assert_se(dlopen_p11kit() >= 0); ++#endif ++ + return 0; + } + +diff --git a/test/test-functions b/test/test-functions +index 73fbef8..0ba7ce2 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -1386,7 +1386,7 @@ install_missing_libraries() { + local lib path + # A number of dependencies is now optional via dlopen, so the install + # script will not pick them up, since it looks at linkage. +- for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon; do ++ for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1; do + ddebug "Searching for $lib via pkg-config" + if pkg-config --exists "$lib"; then + path="$(pkg-config --variable=libdir "$lib")" +@@ -1398,6 +1398,10 @@ install_missing_libraries() { + if ! [[ ${lib} =~ ^lib ]]; then + lib="lib${lib}" + fi ++ # p11-kit-1's .so doesn't have the API level in the name ++ if [[ ${lib} =~ p11-kit-1$ ]]; then ++ lib="libp11-kit" ++ fi + # Some pkg-config files are broken and give out the wrong paths + # (eg: libcryptsetup), so just ignore them + inst_libs "${path}/${lib}.so" || true diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..661f0c4 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,20 @@ +p11kit-switch-to-dlopen.patch +debian/Use-Debian-specific-config-files.patch +debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch +debian/Make-run-lock-tmpfs-an-API-fs.patch +debian/Add-support-for-TuxOnIce-hibernation.patch +debian/Re-enable-journal-forwarding-to-syslog.patch +debian/Don-t-enable-audit-by-default.patch +debian/Only-start-logind-if-dbus-is-installed.patch +debian/fsckd-daemon-for-inter-fsckd-communication.patch +debian/Skip-filesystem-check-if-already-done-by-the-initram.patch +debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch +debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch +debian/Let-graphical-session-pre.target-be-manually-started.patch +debian/deny-list-upstream-test-25.patch +debian/deny-list-upstream-test-02-ppc64el.patch +debian/udev-drop-SystemCallArchitectures-native-from-systemd-ude.patch +debian/Move-sysusers.d-sysctl.d-binfmt.d-modules-load.d-back-to-.patch +debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch +debian/Downgrade-a-couple-of-warnings-to-debug.patch +debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch |