[systemd-commits] 3 commits - .gitignore Makefile-man.am Makefile.am man/systemd-fsck at .service.xml man/systemd-fsckd.service.xml src/fsck src/fsckd units/.gitignore units/systemd-fsck-root.service.in units/systemd-fsck at .service.in units/systemd-fsckd.service.in units/systemd-fsckd.socket

Lennart Poettering lennart at kemper.freedesktop.org
Tue Apr 28 08:30:26 PDT 2015


 .gitignore                         |    1 
 Makefile-man.am                    |   12 
 Makefile.am                        |   17 
 man/systemd-fsck at .service.xml      |    4 
 man/systemd-fsckd.service.xml      |  162 ---------
 src/fsck/fsck.c                    |  299 +++++++++++------
 src/fsckd/Makefile                 |    1 
 src/fsckd/fsckd.c                  |  642 -------------------------------------
 src/fsckd/fsckd.h                  |   38 --
 units/.gitignore                   |    1 
 units/systemd-fsck-root.service.in |    2 
 units/systemd-fsck at .service.in     |    3 
 units/systemd-fsckd.service.in     |   17 
 units/systemd-fsckd.socket         |   15 
 14 files changed, 196 insertions(+), 1018 deletions(-)

New commits:
commit 96d9117ad2db7d8c13f7898127eee8939e88daf1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Apr 28 17:13:23 2015 +0200

    fsck: remove fsckd again, but keep the door open for external replacement
    
    For a longer discussion see this:
    
    http://lists.freedesktop.org/archives/systemd-devel/2015-April/030175.html
    
    This introduces /run/systemd/fsck.progress as a simply
    AF_UNIX/SOCK_STREAM socket. If it exists and is connectable we'll
    connect fsck's -c switch with it. If external programs want to get
    progress data they should hence listen on this socket and will get
    all they need via that socket. To get information about the connecting
    fsck client they should use SO_PEERCRED.
    
    Unless /run/systemd/fsck.progress is around and connectable this change
    reverts back to v219 behaviour where we'd forward fsck output to
    /dev/console on our own.

diff --git a/.gitignore b/.gitignore
index d4edf99..0376e00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,7 +78,6 @@
 /systemd-export
 /systemd-firstboot
 /systemd-fsck
-/systemd-fsckd
 /systemd-fstab-generator
 /systemd-getty-generator
 /systemd-gnome-ask-password-agent
diff --git a/Makefile-man.am b/Makefile-man.am
index e902e5e..4344ffb 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -66,7 +66,6 @@ MANPAGES += \
 	man/systemd-efi-boot-generator.8 \
 	man/systemd-escape.1 \
 	man/systemd-fsck at .service.8 \
-	man/systemd-fsckd.service.8 \
 	man/systemd-fstab-generator.8 \
 	man/systemd-getty-generator.8 \
 	man/systemd-gpt-auto-generator.8 \
@@ -209,8 +208,6 @@ MANPAGES_ALIAS += \
 	man/systemd-ask-password-wall.service.8 \
 	man/systemd-fsck-root.service.8 \
 	man/systemd-fsck.8 \
-	man/systemd-fsckd.8 \
-	man/systemd-fsckd.socket.8 \
 	man/systemd-hibernate-resume.8 \
 	man/systemd-hibernate.service.8 \
 	man/systemd-hybrid-sleep.service.8 \
@@ -321,8 +318,6 @@ man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8
 man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
 man/systemd-fsck-root.service.8: man/systemd-fsck at .service.8
 man/systemd-fsck.8: man/systemd-fsck at .service.8
-man/systemd-fsckd.8: man/systemd-fsckd.service.8
-man/systemd-fsckd.socket.8: man/systemd-fsckd.service.8
 man/systemd-hibernate-resume.8: man/systemd-hibernate-resume at .service.8
 man/systemd-hibernate.service.8: man/systemd-suspend.service.8
 man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
@@ -601,12 +596,6 @@ man/systemd-fsck-root.service.html: man/systemd-fsck at .service.html
 man/systemd-fsck.html: man/systemd-fsck at .service.html
 	$(html-alias)
 
-man/systemd-fsckd.html: man/systemd-fsckd.service.html
-	$(html-alias)
-
-man/systemd-fsckd.socket.html: man/systemd-fsckd.service.html
-	$(html-alias)
-
 man/systemd-hibernate-resume.html: man/systemd-hibernate-resume at .service.html
 	$(html-alias)
 
@@ -1764,7 +1753,6 @@ EXTRA_DIST += \
 	man/systemd-escape.xml \
 	man/systemd-firstboot.xml \
 	man/systemd-fsck at .service.xml \
-	man/systemd-fsckd.service.xml \
 	man/systemd-fstab-generator.xml \
 	man/systemd-getty-generator.xml \
 	man/systemd-gpt-auto-generator.xml \
diff --git a/Makefile.am b/Makefile.am
index 292cf91..29ffcbb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -398,7 +398,6 @@ rootlibexec_PROGRAMS = \
 	systemd-remount-fs \
 	systemd-reply-password \
 	systemd-fsck \
-	systemd-fsckd \
 	systemd-machine-id-commit \
 	systemd-ac-power \
 	systemd-sysctl \
@@ -501,7 +500,6 @@ dist_systemunit_DATA = \
 	units/slices.target \
 	units/system.slice \
 	units/x-.slice \
-	units/systemd-fsckd.socket \
 	units/systemd-initctl.socket \
 	units/syslog.socket \
 	units/dev-hugepages.mount \
@@ -552,7 +550,6 @@ nodist_systemunit_DATA = \
 	units/systemd-kexec.service \
 	units/systemd-fsck at .service \
 	units/systemd-fsck-root.service \
-	units/systemd-fsckd.service \
 	units/systemd-machine-id-commit.service \
 	units/systemd-udevd.service \
 	units/systemd-udev-trigger.service \
@@ -605,7 +602,6 @@ EXTRA_DIST += \
 	units/user/systemd-exit.service.in \
 	units/systemd-fsck at .service.in \
 	units/systemd-fsck-root.service.in \
-	units/systemd-fsckd.service.in \
 	units/systemd-machine-id-commit.service.in \
 	units/user at .service.m4.in \
 	units/debug-shell.service.in \
@@ -2378,19 +2374,6 @@ systemd_fsck_LDADD = \
 	libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
-systemd_fsckd_SOURCES = \
-	src/fsckd/fsckd.c \
-	src/fsckd/fsckd.h \
-	$(NULL)
-
-systemd_fsckd_LDADD = \
-	libsystemd-internal.la \
-	libsystemd-label.la \
-	libsystemd-shared.la \
-	libudev-internal.la \
-	$(NULL)
-
-# ------------------------------------------------------------------------------
 systemd_machine_id_commit_SOURCES = \
 	src/machine-id-commit/machine-id-commit.c \
 	src/core/machine-id-setup.c \
diff --git a/man/systemd-fsck at .service.xml b/man/systemd-fsck at .service.xml
index 69b8fdd..e4ffcba 100644
--- a/man/systemd-fsck at .service.xml
+++ b/man/systemd-fsck at .service.xml
@@ -80,9 +80,7 @@
     the filesystem should actually be checked based on the time since
     last check, number of mounts, unclean unmount, etc.</para>
 
-    <para><filename>systemd-fsck</filename> will forward file system
-    checking progress to <filename>systemd-fsckd.service</filename>
-    socket. If a file system check fails for a service without
+    <para>If a file system check fails for a service without
     <option>nofail</option>, emergency mode is activated, by isolating
     to <filename>emergency.target</filename>.</para>
   </refsect1>
diff --git a/man/systemd-fsckd.service.xml b/man/systemd-fsckd.service.xml
deleted file mode 100644
index 2ad7844..0000000
--- a/man/systemd-fsckd.service.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?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 at 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>systemd-fsck</command> through a
-    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 overriden
-          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 overriden (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>systemd-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/src/fsck/fsck.c b/src/fsck/fsck.c
index f030dd3..56d880a 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+#include <sys/prctl.h>
 
 #include "sd-bus.h"
 #include "sd-device.h"
@@ -40,10 +41,10 @@
 #include "device-util.h"
 #include "path-util.h"
 #include "socket-util.h"
-#include "fsckd/fsckd.h"
 
 static bool arg_skip = false;
 static bool arg_force = false;
+static bool arg_show_progress = false;
 static const char *arg_repair = "-a";
 
 static void start_target(const char *target) {
@@ -135,39 +136,74 @@ static void test_files(void) {
         }
 #endif
 
+        arg_show_progress = access("/run/systemd/show-status", F_OK) >= 0;
 }
 
-static int process_progress(int fd, pid_t fsck_pid, dev_t device_num) {
-        _cleanup_fclose_ FILE *f = NULL;
-        usec_t last = 0;
-        _cleanup_close_ int fsckd_fd = -1;
-        static const union sockaddr_union sa = {
-                .un.sun_family = AF_UNIX,
-                .un.sun_path = FSCKD_SOCKET_PATH,
+static double percent(int pass, unsigned long cur, unsigned long max) {
+        /* Values stolen from e2fsck */
+
+        static const int pass_table[] = {
+                0, 70, 90, 92, 95, 100
         };
 
-        fsckd_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-        if (fsckd_fd < 0)
-                return log_warning_errno(errno, "Cannot open fsckd socket, we won't report fsck progress: %m");
-        if (connect(fsckd_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0)
-                return log_warning_errno(errno, "Cannot connect to fsckd socket, we won't report fsck progress: %m");
-
-        f = fdopen(fd, "r");
-        if (!f)
-                return log_warning_errno(errno, "Cannot connect to fsck, we won't report fsck progress: %m");
-
-        while (!feof(f)) {
-                int pass;
-                size_t buflen;
-                size_t cur, max;
-                ssize_t r;
-                usec_t t;
+        if (pass <= 0)
+                return 0.0;
+
+        if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0)
+                return 100.0;
+
+        return (double) pass_table[pass-1] +
+                ((double) pass_table[pass] - (double) pass_table[pass-1]) *
+                (double) cur / (double) max;
+}
+
+static int process_progress(int fd) {
+        _cleanup_fclose_ FILE *console = NULL, *f = NULL;
+        usec_t last = 0;
+        bool locked = false;
+        int clear = 0, r;
+
+        /* No progress pipe to process? Then we are a NOP. */
+        if (fd < 0)
+                return 0;
+
+        f = fdopen(fd, "re");
+        if (!f) {
+                safe_close(fd);
+                return -errno;
+        }
+
+        console = fopen("/dev/console", "we");
+        if (!console)
+                return -ENOMEM;
+
+        for (;;) {
+                int pass, m;
+                unsigned long cur, max;
                 _cleanup_free_ char *device = NULL;
-                FsckProgress progress;
-                FsckdMessage fsckd_message;
+                double p;
+                usec_t t;
 
-                if (fscanf(f, "%i %zu %zu %ms", &pass, &cur, &max, &device) != 4)
+                if (fscanf(f, "%i %lu %lu %ms", &pass, &cur, &max, &device) != 4) {
+
+                        if (ferror(f))
+                                r = log_warning_errno(errno, "Failed to read from progress pipe: %m");
+                        else if (feof(f))
+                                r = 0;
+                        else {
+                                log_warning("Failed to parse progress pipe data");
+                                r = -EBADMSG;
+                        }
                         break;
+                }
+
+                /* Only show one progress counter at max */
+                if (!locked) {
+                        if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0)
+                                continue;
+
+                        locked = true;
+                }
 
                 /* Only update once every 50ms */
                 t = now(CLOCK_MONOTONIC);
@@ -176,42 +212,58 @@ static int process_progress(int fd, pid_t fsck_pid, dev_t device_num) {
 
                 last = t;
 
-                /* send progress to fsckd */
-                progress.devnum = device_num;
-                progress.cur = cur;
-                progress.max = max;
-                progress.pass = pass;
-
-                r = send(fsckd_fd, &progress, sizeof(FsckProgress), 0);
-                if (r < 0 || (size_t) r < sizeof(FsckProgress))
-                        log_warning_errno(errno, "Cannot communicate fsck progress to fsckd: %m");
-
-                /* get fsckd requests, only read when we have coherent size data */
-                r = ioctl(fsckd_fd, FIONREAD, &buflen);
-                if (r == 0 && (size_t) buflen >= sizeof(FsckdMessage)) {
-                        r = recv(fsckd_fd, &fsckd_message, sizeof(FsckdMessage), 0);
-                        if (r > 0 && fsckd_message.cancel == 1) {
-                                log_info("Request to cancel fsck from fsckd");
-                                kill(fsck_pid, SIGTERM);
-                        }
-                }
+                p = percent(pass, cur, max);
+                fprintf(console, "\r%s: fsck %3.1f%% complete...\r%n", device, p, &m);
+                fflush(console);
+
+                if (m > clear)
+                        clear = m;
         }
 
-        return 0;
+        if (clear > 0) {
+                unsigned j;
+
+                fputc('\r', console);
+                for (j = 0; j < (unsigned) clear; j++)
+                        fputc(' ', console);
+                fputc('\r', console);
+                fflush(console);
+        }
+
+        return r;
+}
+
+static int fsck_progress_socket(void) {
+        static const union sockaddr_union sa = {
+                .un.sun_family = AF_UNIX,
+                .un.sun_path = "/run/systemd/fsck.progress",
+        };
+
+        int fd, r;
+
+        fd = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (fd < 0)
+                return log_warning_errno(errno, "socket(): %m");
+
+        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
+                r = log_full_errno(errno == ECONNREFUSED || errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
+                                   errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);
+                safe_close(fd);
+                return r;
+        }
+
+        return fd;
 }
 
 int main(int argc, char *argv[]) {
-        const char *cmdline[9];
-        int i = 0, r = EXIT_FAILURE, q;
-        pid_t pid;
-        int progress_rc;
-        siginfo_t status;
+        _cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
         _cleanup_device_unref_ sd_device *dev = NULL;
         const char *device, *type;
         bool root_directory;
-        _cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
-        char dash_c[sizeof("-C")-1 + DECIMAL_STR_MAX(int) + 1];
+        siginfo_t status;
         struct stat st;
+        int r;
+        pid_t pid;
 
         if (argc > 2) {
                 log_error("This program expects one or no arguments.");
@@ -309,48 +361,74 @@ int main(int argc, char *argv[]) {
                         log_warning_errno(r, "Couldn't detect if fsck.%s may be used for %s: %m", type, device);
         }
 
-        if (pipe(progress_pipe) < 0) {
-                r = log_error_errno(errno, "pipe(): %m");
-                goto finish;
+        if (arg_show_progress) {
+                if (pipe(progress_pipe) < 0) {
+                        r = log_error_errno(errno, "pipe(): %m");
+                        goto finish;
+                }
         }
 
-        cmdline[i++] = "/sbin/fsck";
-        cmdline[i++] =  arg_repair;
-        cmdline[i++] = "-T";
-
-        /*
-         * Since util-linux v2.25 fsck uses /run/fsck/<diskname>.lock files.
-         * The previous versions use flock for the device and conflict with
-         * udevd, see https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
-         */
-        cmdline[i++] = "-l";
-
-        if (!root_directory)
-                cmdline[i++] = "-M";
-
-        if (arg_force)
-                cmdline[i++] = "-f";
-
-        xsprintf(dash_c, "-C%i", progress_pipe[1]);
-        cmdline[i++] = dash_c;
-
-        cmdline[i++] = device;
-        cmdline[i++] = NULL;
-
         pid = fork();
         if (pid < 0) {
                 r = log_error_errno(errno, "fork(): %m");
                 goto finish;
-        } else if (pid == 0) {
+        }
+        if (pid == 0) {
+                char dash_c[sizeof("-C")-1 + DECIMAL_STR_MAX(int) + 1];
+                int progress_socket = -1;
+                const char *cmdline[9];
+                int i = 0;
+
                 /* Child */
+
+                reset_all_signal_handlers();
+                reset_signal_mask();
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+                /* Close the reading side of the progress pipe */
                 progress_pipe[0] = safe_close(progress_pipe[0]);
+
+                /* Try to connect to a progress management daemon, if there is one */
+                progress_socket = fsck_progress_socket();
+                if (progress_socket >= 0) {
+                        /* If this worked we close the progress pipe early, and just use the socket */
+                        progress_pipe[1] = safe_close(progress_pipe[1]);
+                        xsprintf(dash_c, "-C%i", progress_socket);
+                } else if (progress_pipe[1] >= 0) {
+                        /* Otherwise if we have the progress pipe to our own local handle, we use it */
+                        xsprintf(dash_c, "-C%i", progress_pipe[1]);
+                } else
+                        dash_c[0] = 0;
+
+                cmdline[i++] = "/sbin/fsck";
+                cmdline[i++] =  arg_repair;
+                cmdline[i++] = "-T";
+
+                /*
+                 * Since util-linux v2.25 fsck uses /run/fsck/<diskname>.lock files.
+                 * The previous versions use flock for the device and conflict with
+                 * udevd, see https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
+                 */
+                cmdline[i++] = "-l";
+
+                if (!root_directory)
+                        cmdline[i++] = "-M";
+
+                if (arg_force)
+                        cmdline[i++] = "-f";
+
+                if (!isempty(dash_c))
+                        cmdline[i++] = dash_c;
+
+                cmdline[i++] = device;
+                cmdline[i++] = NULL;
+
                 execv(cmdline[0], (char**) cmdline);
                 _exit(8); /* Operational error */
         }
 
         progress_pipe[1] = safe_close(progress_pipe[1]);
-
-        progress_rc = process_progress(progress_pipe[0], pid, st.st_rdev);
+        (void) process_progress(progress_pipe[0]);
         progress_pipe[0] = -1;
 
         r = wait_for_terminate(pid, &status);
@@ -359,14 +437,13 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if (status.si_code != CLD_EXITED || (status.si_status & ~1) || progress_rc != 0) {
+        if (status.si_code != CLD_EXITED || (status.si_status & ~1)) {
 
-                /* cancel will kill fsck (but process_progress returns 0) */
-                if ((progress_rc != 0 && status.si_code == CLD_KILLED) || status.si_code == CLD_DUMPED)
+                if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED)
                         log_error("fsck terminated by signal %s.", signal_to_string(status.si_status));
                 else if (status.si_code == CLD_EXITED)
                         log_error("fsck failed with error code %i.", status.si_status);
-                else if (progress_rc != 0)
+                else
                         log_error("fsck failed due to unknown reason.");
 
                 r = -EINVAL;
@@ -378,9 +455,8 @@ int main(int argc, char *argv[]) {
                         /* Some other problem */
                         start_target(SPECIAL_EMERGENCY_TARGET);
                 else {
+                        log_warning("Ignoring error.");
                         r = 0;
-                        if (progress_rc != 0)
-                                log_warning("Ignoring error.");
                 }
 
         } else
diff --git a/src/fsckd/Makefile b/src/fsckd/Makefile
deleted file mode 120000
index d0b0e8e..0000000
--- a/src/fsckd/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c
deleted file mode 100644
index 6b35fc2..0000000
--- a/src/fsckd/fsckd.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2015 Canonical
-
-  Author:
-    Didier Roche <didrocks at 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 "event-util.h"
-#include "log.h"
-#include "list.h"
-#include "macro.h"
-#include "socket-util.h"
-#include "util.h"
-#include "fsckd.h"
-
-#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;
-        int fd;
-        dev_t devnum;
-
-        size_t cur;
-        size_t max;
-        int pass;
-
-        double percent;
-
-        size_t buflen;
-        bool cancelled;
-
-        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 void client_free(Client *c);
-static void manager_free(Manager *m);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
-
-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;
-
-        /* 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) {
-        FsckdMessage cancel_msg = {
-                .cancel = 1,
-        };
-
-        ssize_t n;
-
-        assert(c);
-
-        if (c->cancelled)
-                return 0;
-
-        n = send(c->fd, &cancel_msg, sizeof(FsckdMessage), 0);
-        if (n < 0)
-                return log_warning_errno(errno, "Cannot send cancel to fsck on (%u:%u): %m", major(c->devnum), minor(c->devnum));
-        if ((size_t) n < sizeof(FsckdMessage)) {
-                log_warning("Short send when sending cancel to fsck on (%u:%u).", major(c->devnum), minor(c->devnum));
-                return -EIO;
-        }
-
-        c->cancelled = true;
-        return 1;
-}
-
-static void 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);
-
-        safe_close(c->fd);
-        free(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;
-        Client *current;
-        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) {
-        Client *current = NULL;
-        _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;
-        FsckProgress fsck_data;
-        size_t buflen;
-        Manager *m;
-        int r;
-
-        assert(client);
-
-        m = client->manager;
-
-        /* check first if we need to cancel this client */
-        if (m->cancel_requested)
-                client_request_cancel(client);
-
-        /* ensure we have enough data to read */
-        r = ioctl(fd, FIONREAD, &buflen);
-        if (r == 0 && buflen != 0 && (size_t) buflen < sizeof(FsckProgress)) {
-                if (client->buflen != buflen)
-                        client->buflen = buflen;
-                /* we got twice the same size from a bad behaving client, kick it off the list */
-                else {
-                        log_warning("Closing bad behaving fsck client connection at fd %d", client->fd);
-                        client_free(client);
-                        manager_update_global_progress(m);
-                }
-                return 0;
-        }
-
-        /* read actual data */
-        r = recv(fd, &fsck_data, sizeof(FsckProgress), 0);
-        if (r == 0) {
-                log_debug("Fsck client connected to fd %d disconnected", client->fd);
-                client_free(client);
-        } else if (r > 0 && r != sizeof(FsckProgress))
-                log_warning("Unexpected data structure sent to fsckd socket from fd: %d. Ignoring", client->fd);
-        else if (r > 0 && r == sizeof(FsckProgress)) {
-                client->devnum = fsck_data.devnum;
-                client->cur = fsck_data.cur;
-                client->max = fsck_data.max;
-                client->pass = fsck_data.pass;
-                client->percent = compute_percent(client->pass, client->cur, client->max);
-                log_debug("Getting progress for %u:%u (%lu, %lu, %d) : %3.1f%%",
-                          major(client->devnum), minor(client->devnum),
-                          client->cur, client->max, client->pass, client->percent);
-        } else
-                log_error_errno(r, "Unknown error while trying to read fsck data: %m");
-
-        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_client_fd = -1;
-        Manager *m = userdata;
-        int r;
-
-        assert(m);
-
-        /* Initialize and list new clients */
-        new_client_fd = accept4(m->connection_fd, NULL, NULL, SOCK_CLOEXEC);
-        if (new_client_fd < 0)
-                return log_error_errno(errno, "Couldn't accept a new connection: %m");
-
-        if (m->n_clients >= CLIENTS_MAX) {
-                log_error("Too many clients, refusing connection.");
-                return 0;
-        }
-
-        log_debug("New fsck client connected to fd: %d", new_client_fd);
-
-        c = new0(Client, 1);
-        if (!c) {
-                log_oom();
-                return 0;
-        }
-
-        c->fd = new_client_fd;
-        new_client_fd = -1;
-
-        r = sd_event_add_io(m->event, &c->event_source, c->fd, EPOLLIN, client_progress_handler, c);
-        if (r < 0) {
-                log_oom();
-                return 0;
-        }
-
-        LIST_PREPEND(clients, m->clients, c);
-        m->n_clients++;
-        c->manager = m;
-
-        /* 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 void manager_free(Manager *m) {
-        if (!m)
-                return;
-
-        /* 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);
-
-        free(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(sd_event *e, usec_t timeout) {
-        int r, code;
-
-        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;
-
-                /* timeout reached */
-                if (r == 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, "hv", options, NULL)) >= 0)
-                switch (c) {
-
-                case 'h':
-                        help();
-                        return 0;
-
-                case ARG_VERSION:
-                        puts(PACKAGE_STRING);
-                        puts(SYSTEMD_FEATURES);
-                        return 0;
-
-                case '?':
-                        return -EINVAL;
-
-                default:
-                        assert_not_reached("Unhandled option");
-                }
-
-        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->event, 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/fsckd.h b/src/fsckd/fsckd.h
deleted file mode 100644
index 8239273..0000000
--- a/src/fsckd/fsckd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2015 Canonical
-
-  Author:
-    Didier Roche <didrocks at 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/>.
-***/
-
-#define FSCKD_SOCKET_PATH "/run/systemd/fsckd"
-
-#include "libudev.h"
-
-typedef struct FsckProgress {
-        dev_t devnum;
-        size_t cur;
-        size_t max;
-        int pass;
-} FsckProgress;
-
-typedef struct FsckdMessage {
-        uint8_t cancel;
-} FsckdMessage;
diff --git a/units/.gitignore b/units/.gitignore
index d81d0c5..b8f0a0b 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -28,7 +28,6 @@
 /systemd-firstboot.service
 /systemd-fsck-root.service
 /systemd-fsck at .service
-/systemd-fsckd.service
 /systemd-machine-id-commit.service
 /systemd-halt.service
 /systemd-hibernate.service
diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in
index f493445..3617abf 100644
--- a/units/systemd-fsck-root.service.in
+++ b/units/systemd-fsck-root.service.in
@@ -9,9 +9,7 @@
 Description=File System Check on Root Device
 Documentation=man:systemd-fsck-root.service(8)
 DefaultDependencies=no
-Wants=systemd-fsckd.socket
 Before=local-fs.target shutdown.target
-After=systemd-fsckd.socket
 ConditionPathIsReadWrite=!/
 
 [Service]
diff --git a/units/systemd-fsck at .service.in b/units/systemd-fsck at .service.in
index e6d98c0..0468392 100644
--- a/units/systemd-fsck at .service.in
+++ b/units/systemd-fsck at .service.in
@@ -10,8 +10,7 @@ Description=File System Check on %f
 Documentation=man:systemd-fsck at .service(8)
 DefaultDependencies=no
 BindsTo=%i.device
-Wants=systemd-fsckd.socket
-After=%i.device systemd-fsck-root.service local-fs-pre.target systemd-fsckd.socket
+After=%i.device systemd-fsck-root.service local-fs-pre.target
 Before=shutdown.target
 
 [Service]
diff --git a/units/systemd-fsckd.service.in b/units/systemd-fsckd.service.in
deleted file mode 100644
index 9c7ed51..0000000
--- a/units/systemd-fsckd.service.in
+++ /dev/null
@@ -1,17 +0,0 @@
-#  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
deleted file mode 100644
index 92e8eef..0000000
--- a/units/systemd-fsckd.socket
+++ /dev/null
@@ -1,15 +0,0 @@
-#  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 at .service(8) man:systemd-fsck-root.service(8)
-DefaultDependencies=no
-
-[Socket]
-ListenStream=/run/systemd/fsckd
-SocketMode=0600

commit e7a3aa3df640993ce9aace39b946543305f3af53
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Apr 28 16:49:43 2015 +0200

    fsck: minor improvements
    
    Among other smaller fixes, explicitly check if we are invoked on a block
    device before making use of st.st_rdev.

diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 297ea9e..f030dd3 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -224,9 +224,9 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        q = parse_proc_cmdline(parse_proc_cmdline_item);
-        if (q < 0)
-                log_warning_errno(q, "Failed to parse kernel command line, ignoring: %m");
+        r = parse_proc_cmdline(parse_proc_cmdline_item);
+        if (r < 0)
+                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
 
         test_files();
 
@@ -237,10 +237,15 @@ int main(int argc, char *argv[]) {
 
         if (argc > 1) {
                 device = argv[1];
-                root_directory = false;
 
                 if (stat(device, &st) < 0) {
-                        r = log_error_errno(errno, "Failed to stat '%s': %m", device);
+                        r = log_error_errno(errno, "Failed to stat %s: %m", device);
+                        goto finish;
+                }
+
+                if (!S_ISBLK(st.st_mode)) {
+                        log_error("%s is not a block device.", device);
+                        r = -EINVAL;
                         goto finish;
                 }
 
@@ -249,6 +254,8 @@ int main(int argc, char *argv[]) {
                         log_error_errno(r, "Failed to detect device %s: %m", device);
                         goto finish;
                 }
+
+                root_directory = false;
         } else {
                 struct timespec times[2];
 
@@ -261,7 +268,7 @@ int main(int argc, char *argv[]) {
 
                 /* Virtual root devices don't need an fsck */
                 if (major(st.st_dev) == 0) {
-                        log_debug("Root directory is virtual, skipping check.");
+                        log_debug("Root directory is virtual or btrfs, skipping check.");
                         r = 0;
                         goto finish;
                 }
@@ -269,6 +276,7 @@ int main(int argc, char *argv[]) {
                 /* check if we are already writable */
                 times[0] = st.st_atim;
                 times[1] = st.st_mtim;
+
                 if (utimensat(AT_FDCWD, "/", times, 0) == 0) {
                         log_info("Root directory is writable, skipping check.");
                         r = 0;
@@ -284,7 +292,6 @@ int main(int argc, char *argv[]) {
                 r = sd_device_get_devname(dev, &device);
                 if (r < 0) {
                         log_error_errno(r, "Failed to detect device node of root directory: %m");
-                        r = -ENXIO;
                         goto finish;
                 }
 
@@ -299,7 +306,7 @@ int main(int argc, char *argv[]) {
                         r = 0;
                         goto finish;
                 } else if (r < 0)
-                        log_warning_errno(r, "fsck.%s cannot be used for %s: %m", type, device);
+                        log_warning_errno(r, "Couldn't detect if fsck.%s may be used for %s: %m", type, device);
         }
 
         if (pipe(progress_pipe) < 0) {
@@ -380,7 +387,7 @@ int main(int argc, char *argv[]) {
                 r = 0;
 
         if (status.si_code == CLD_EXITED && (status.si_status & 1))
-                touch("/run/systemd/quotacheck");
+                (void) touch("/run/systemd/quotacheck");
 
 finish:
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;

commit 24b52437dd3c06bfdbead8f08114e4b6575dea69
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Apr 28 16:46:06 2015 +0200

    fsck: parse kernel cmdline booleans the same ways as the rest

diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 6a0f67f..297ea9e 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -73,10 +73,13 @@ static void start_target(const char *target) {
 
         /* Don't print a warning if we aren't called during startup */
         if (r < 0 && !sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB))
-                log_error("Failed to start unit: %s", bus_error_message(&error, -r));
+                log_error("Failed to start unit: %s", bus_error_message(&error, r));
 }
 
 static int parse_proc_cmdline_item(const char *key, const char *value) {
+        int r;
+
+        assert(key);
 
         if (streq(key, "fsck.mode") && value) {
 
@@ -93,12 +96,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
 
                 if (streq(value, "preen"))
                         arg_repair = "-a";
-                else if (streq(value, "yes"))
-                        arg_repair = "-y";
-                else if (streq(value, "no"))
-                        arg_repair = "-n";
-                else
-                        log_warning("Invalid fsck.repair= parameter '%s'. Ignoring.", value);
+                else {
+                        r = parse_boolean(value);
+                        if (r > 0)
+                                arg_repair = "-y";
+                        else if (r == 0)
+                                arg_repair = "-n";
+                        else
+                                log_warning("Invalid fsck.repair= parameter '%s'. Ignoring.", value);
+                }
         }
 
 #ifdef HAVE_SYSV_COMPAT



More information about the systemd-commits mailing list