diff options
Diffstat (limited to '')
10 files changed, 1478 insertions, 0 deletions
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/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..1c839bd --- /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 f442bd8..a92f683 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -544,6 +544,7 @@ static int patch_var_run( + + const char *e; + char *z; ++ int log_level; + + e = path_startswith(*path, "/var/run/"); + if (!e) +@@ -553,7 +554,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 4485e2e..d0e8ed8 100644 +--- a/src/sysv-generator/sysv-generator.c ++++ b/src/sysv-generator/sysv-generator.c +@@ -762,7 +762,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { + if (!fpath) + return log_oom(); + +- log_struct(LOG_WARNING, ++ log_struct(LOG_DEBUG, + LOG_MESSAGE("SysV service '%s' lacks a native systemd unit file. " + "%s Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it safe, robust and future-proof. " + "%s This compatibility logic is deprecated, expect removal soon. %s", +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 230ec09..d513d40 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -3266,6 +3266,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); +@@ -3291,7 +3292,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/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..a93e7a3 --- /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 1226ca1..2d59955 100644 +--- a/src/shared/mount-setup.c ++++ b/src/shared/mount-setup.c +@@ -101,6 +101,8 @@ static const MountPoint mount_table[] = { + #endif + { "tmpfs", "/run", "tmpfs", "mode=0755" 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, + check_recursiveprot_supported, 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/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..267c2b4 --- /dev/null +++ b/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch @@ -0,0 +1,69 @@ +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 | 18 ------------------ + sysctl.d/50-coredump.conf.in | 2 +- + 2 files changed, 1 insertion(+), 19 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 3f71cc0..876c7d5 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1653,22 +1653,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 (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(); +-} +- + static void initialize_core_pattern(bool skip_setup) { + int r; + +@@ -2922,8 +2906,6 @@ int main(int argc, char *argv[]) { + kernel_timestamp = DUAL_TIMESTAMP_NULL; + } + +- initialize_coredump(skip_setup); +- + r = fixup_environment(); + if (r < 0) { + log_struct_errno(LOG_EMERG, r, +diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in +index 90c080b..1730841 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=|{{LIBEXECDIR}}/systemd-coredump %P %u %g %s %t %c %h ++kernel.core_pattern=|{{LIBEXECDIR}}/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..6353b8b --- /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 016f3ba..f63a1d1 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -519,6 +519,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); +@@ -604,9 +605,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 ca9c7ce..27783a9 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..a57191d --- /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 512137c..1bf1538 100755 +--- a/test/networkd-test.py ++++ b/test/networkd-test.py +@@ -639,6 +639,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/fsckd-daemon-for-inter-fsckd-communication.patch b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch new file mode 100644 index 0000000..7ec4439 --- /dev/null +++ b/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch @@ -0,0 +1,1072 @@ +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 | 1 + + po/POTFILES.in | 1 + + src/fsckd/fsckd.c | 705 +++++++++++++++++++++++++++++++++++++ + src/fsckd/meson.build | 8 + + 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 + + 11 files changed, 916 insertions(+), 1 deletion(-) + create mode 100644 man/systemd-fsckd.service.xml + create mode 100644 src/fsckd/fsckd.c + create mode 100644 src/fsckd/meson.build + 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 5dc3e08..5feb43d 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -933,6 +933,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 f1f4e7e..24f5bd2 100644 +--- a/meson.build ++++ b/meson.build +@@ -2152,6 +2152,7 @@ subdir('src/environment-d-generator') + subdir('src/escape') + subdir('src/firstboot') + subdir('src/fsck') ++subdir('src/fsckd') + subdir('src/fstab-generator') + subdir('src/getty-generator') + subdir('src/gpt-auto-generator') +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 16899fd..6bba341 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -13,3 +13,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..e9a8019 +--- /dev/null ++++ b/src/fsckd/fsckd.c +@@ -0,0 +1,705 @@ ++/*-*- 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 "constants.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 "alloc-util.h" ++#include "locale-util.h" ++#include "logarithm.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 = { ++ .un.sun_family = AF_UNIX, ++ .un.sun_path = "\0/org/freedesktop/plymouthd", ++ }; ++ 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_full(plymouth_fd, packet, n + 1, USEC_INFINITY); ++} ++ ++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_full(m->plymouth_fd, PLYMOUTH_REQUEST_KEY, sizeof(PLYMOUTH_REQUEST_KEY), USEC_INFINITY); ++ 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/src/fsckd/meson.build b/src/fsckd/meson.build +new file mode 100644 +index 0000000..6d3c125 +--- /dev/null ++++ b/src/fsckd/meson.build +@@ -0,0 +1,8 @@ ++# SPDX-License-Identifier: LGPL-2.1-or-later ++ ++executables += [ ++ libexec_template + { ++ 'name' : 'systemd-fsckd', ++ 'sources' : files('fsckd.c'), ++ }, ++] +diff --git a/units/meson.build b/units/meson.build +index e7bfb7f..0aee573 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -288,6 +288,8 @@ units = [ + }, + { 'file' : 'systemd-fsck-root.service.in' }, + { 'file' : 'systemd-fsck@.service.in' }, ++ { 'file' : 'systemd-fsckd.socket' }, ++ { 'file' : 'systemd-fsckd.service.in' }, + { 'file' : 'systemd-growfs-root.service.in' }, + { 'file' : 'systemd-growfs@.service.in' }, + { 'file' : 'systemd-halt.service' }, +diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in +index ebe8262..ca9c7ce 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 65521b1..cd8bac1 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..845788c +--- /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={{LIBEXECDIR}}/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/localectl-disable-keymap-support.patch b/debian/patches/debian/localectl-disable-keymap-support.patch new file mode 100644 index 0000000..50fad4c --- /dev/null +++ b/debian/patches/debian/localectl-disable-keymap-support.patch @@ -0,0 +1,76 @@ +From: Luca Boccassi <bluca@debian.org> +Date: Wed, 8 Feb 2023 20:34:38 +0000 +Subject: localectl-disable-keymap-support + +We no longer support old debianisms such as /etc/default/keyboard, +so disable the keymap interface in localectl until a definitive +solution is found. + +Update the test suite to skip tests for unsupported localectl features. +--- + src/locale/localectl.c | 11 ++++++----- + test/units/testsuite-73.sh | 6 ++++++ + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/locale/localectl.c b/src/locale/localectl.c +index 3235402..c4fb1f2 100644 +--- a/src/locale/localectl.c ++++ b/src/locale/localectl.c +@@ -383,6 +383,10 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) { + return 0; + } + ++static int not_supported(int argc, char **argv, void *userdata) { ++ return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Setting X11 and console keymaps is not supported in Debian."); ++} ++ + static int help(void) { + _cleanup_free_ char *link = NULL; + int r; +@@ -397,10 +401,7 @@ static int help(void) { + " status Show current locale settings\n" + " set-locale LOCALE... Set system locale\n" + " list-locales Show known locales\n" +- " set-keymap MAP [MAP] Set console and X11 keyboard mappings\n" + " list-keymaps Show known virtual console keyboard mappings\n" +- " set-x11-keymap LAYOUT [MODEL [VARIANT [OPTIONS]]]\n" +- " Set X11 and console keyboard mappings\n" + " list-x11-keymap-models Show known X11 keyboard mapping models\n" + " list-x11-keymap-layouts Show known X11 keyboard mapping layouts\n" + " list-x11-keymap-variants [LAYOUT]\n" +@@ -500,9 +501,9 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) { + { "status", VERB_ANY, 1, VERB_DEFAULT, show_status }, + { "set-locale", 2, VERB_ANY, 0, set_locale }, + { "list-locales", VERB_ANY, 1, 0, list_locales }, +- { "set-keymap", 2, 3, 0, set_vconsole_keymap }, ++ { "set-keymap", 2, 3, 0, not_supported }, + { "list-keymaps", VERB_ANY, 1, 0, list_vconsole_keymaps }, +- { "set-x11-keymap", 2, 5, 0, set_x11_keymap }, ++ { "set-x11-keymap", 2, 5, 0, not_supported }, + { "list-x11-keymap-models", VERB_ANY, 1, 0, list_x11_keymaps }, + { "list-x11-keymap-layouts", VERB_ANY, 1, 0, list_x11_keymaps }, + { "list-x11-keymap-variants", VERB_ANY, 2, 0, list_x11_keymaps }, +diff --git a/test/units/testsuite-73.sh b/test/units/testsuite-73.sh +index df5af4b..ec3fa6c 100755 +--- a/test/units/testsuite-73.sh ++++ b/test/units/testsuite-73.sh +@@ -227,6 +227,9 @@ wait_vconsole_setup() { + testcase_vc_keymap() { + local i output vc + ++ echo "Setting X11 and console keymaps is not supported in Debian, skipping test." ++ return ++ + if [[ -z "$(localectl list-keymaps)" ]]; then + echo "No vconsole keymap installed, skipping test." + return +@@ -297,6 +300,9 @@ testcase_vc_keymap() { + testcase_x11_keymap() { + local output + ++ echo "Setting X11 and console keymaps is not supported in Debian, skipping test." ++ return ++ + if [[ -z "$(localectl list-x11-keymap-layouts)" ]]; then + echo "No x11 keymap installed, skipping test." + return 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..902612d --- /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 4f6e304..520e794 100644 +--- a/src/systemctl/systemctl-compat-halt.c ++++ b/src/systemctl/systemctl-compat-halt.c +@@ -155,9 +155,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(arg_action); +- else { ++ if (r < 0) ++ return r; ++ } else { + r = logind_check_inhibitors(arg_action); + if (r < 0) + return r; diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..145e173 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,9 @@ +debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch +debian/Make-run-lock-tmpfs-an-API-fs.patch +debian/fsckd-daemon-for-inter-fsckd-communication.patch +debian/Skip-filesystem-check-if-already-done-by-the-initram.patch +debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.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 +debian/localectl-disable-keymap-support.patch |