/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
  Copyright © 2014 Holger Hans Peter Freyther
***/

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <sys/file.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <unistd.h>

#include "sd-bus.h"
#include "sd-device.h"

#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-util.h"
#include "device-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "fsck-util.h"
#include "main-func.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "special.h"
#include "stdio-util.h"
#include "util.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, const char *mode) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        int r;

        assert(target);

        r = bus_connect_system_systemd(&bus);
        if (r < 0) {
                log_error_errno(r, "Failed to get D-Bus connection: %m");
                return;
        }

        log_info("Running request %s/start/replace", target);

        /* Start these units only if we can replace base.target with it */
        r = sd_bus_call_method(bus,
                               "org.freedesktop.systemd1",
                               "/org/freedesktop/systemd1",
                               "org.freedesktop.systemd1.Manager",
                               "StartUnitReplace",
                               &error,
                               NULL,
                               "sss", "basic.target", target, mode);

        /* 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));
}

static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
        int r;

        assert(key);

        if (streq(key, "fsck.mode")) {

                if (proc_cmdline_value_missing(key, value))
                        return 0;

                if (streq(value, "auto"))
                        arg_force = arg_skip = false;
                else if (streq(value, "force"))
                        arg_force = true;
                else if (streq(value, "skip"))
                        arg_skip = true;
                else
                        log_warning("Invalid fsck.mode= parameter '%s'. Ignoring.", value);

        } else if (streq(key, "fsck.repair")) {

                if (proc_cmdline_value_missing(key, value))
                        return 0;

                if (streq(value, "preen"))
                        arg_repair = "-a";
                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);
                }
        }

#if HAVE_SYSV_COMPAT
        else if (streq(key, "fastboot") && !value) {
                log_warning("Please pass 'fsck.mode=skip' rather than 'fastboot' on the kernel command line.");
                arg_skip = true;

        } else if (streq(key, "forcefsck") && !value) {
                log_warning("Please pass 'fsck.mode=force' rather than 'forcefsck' on the kernel command line.");
                arg_force = true;
        }
#endif

        return 0;
}

static void test_files(void) {

#if HAVE_SYSV_COMPAT
        if (access("/fastboot", F_OK) >= 0) {
                log_error("Please pass 'fsck.mode=skip' on the kernel command line rather than creating /fastboot on the root file system.");
                arg_skip = true;
        }

        if (access("/forcefsck", F_OK) >= 0) {
                log_error("Please pass 'fsck.mode=force' on the kernel command line rather than creating /forcefsck on the root file system.");
                arg_force = true;
        }
#endif

        arg_show_progress = access("/run/systemd/show-status", F_OK) >= 0;
}

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
        };

        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, FILE* console) {
        _cleanup_fclose_ FILE *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, "r");
        if (!f) {
                safe_close(fd);
                return log_debug_errno(errno, "Failed to use pipe: %m");
        }

        for (;;) {
                int pass;
                unsigned long cur, max;
                _cleanup_free_ char *device = NULL;
                double p;
                usec_t t;

                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
                                r = log_warning_errno(SYNTHETIC_ERRNO(errno), "Failed to parse progress pipe data");

                        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);
                if (last + 50 * USEC_PER_MSEC > t)
                        continue;

                last = t;

                p = percent(pass, cur, max);
                r = fprintf(console, "\r%s: fsck %3.1f%% complete...\r", device, p);
                if (r < 0)
                        return -EIO; /* No point in continuing if something happened to our output stream */

                fflush(console);
                clear = MAX(clear, r);
        }

        if (clear > 0) {
                fputc('\r', console);
                for (int j = 0; j < 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",
        };

        _cleanup_close_ int fd = -1;

        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd < 0)
                return log_warning_errno(errno, "socket(): %m");

        if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
                return log_full_errno(IN_SET(errno, ECONNREFUSED, ENOENT) ? LOG_DEBUG : LOG_WARNING,
                                      errno, "Failed to connect to progress socket %s, ignoring: %m", sa.un.sun_path);

        return TAKE_FD(fd);
}

static int run(int argc, char *argv[]) {
        _cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
        _cleanup_free_ char *dpath = NULL;
        _cleanup_fclose_ FILE *console = NULL;
        const char *device, *type;
        bool root_directory;
        struct stat st;
        int r, exit_status;
        pid_t pid;

        log_setup();

        if (argc > 2)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                       "This program expects one or no arguments.");

        umask(0022);

        r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
        if (r < 0)
                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

        test_files();

        if (!arg_force && arg_skip)
                return 0;

        if (argc > 1) {
                dpath = strdup(argv[1]);
                if (!dpath)
                        return log_oom();

                device = dpath;

                if (stat(device, &st) < 0)
                        return log_error_errno(errno, "Failed to stat %s: %m", device);

                if (!S_ISBLK(st.st_mode))
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                               "%s is not a block device.",
                                               device);

                r = sd_device_new_from_stat_rdev(&dev, &st);
                if (r < 0)
                        return log_error_errno(r, "Failed to detect device %s: %m", device);

                root_directory = false;
        } else {
                struct timespec times[2];

                /* Find root device */

                if (stat("/", &st) < 0)
                        return log_error_errno(errno, "Failed to stat() the root directory: %m");

                /* Virtual root devices don't need an fsck */
                if (major(st.st_dev) == 0) {
                        log_debug("Root directory is virtual or btrfs, skipping check.");
                        return 0;
                }

                /* 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.");
                        return 0;
                }

                r = sd_device_new_from_devnum(&dev, 'b', st.st_dev);
                if (r < 0)
                        return log_error_errno(r, "Failed to detect root device: %m");

                r = sd_device_get_devname(dev, &device);
                if (r < 0)
                        return log_device_error_errno(dev, r, "Failed to detect device node of root directory: %m");

                root_directory = true;
        }

        if (sd_device_get_property_value(dev, "ID_FS_TYPE", &type) >= 0) {
                r = fsck_exists(type);
                if (r < 0)
                        log_device_warning_errno(dev, r, "Couldn't detect if fsck.%s may be used, proceeding: %m", type);
                else if (r == 0) {
                        log_device_info(dev, "fsck.%s doesn't exist, not checking file system.", type);
                        return 0;
                }
        }

        console = fopen("/dev/console", "we");
        if (console &&
            arg_show_progress &&
            pipe(progress_pipe) < 0)
                return log_error_errno(errno, "pipe(): %m");

        r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
        if (r < 0)
                return r;
        if (r == 0) {
                char dash_c[STRLEN("-C") + DECIMAL_STR_MAX(int) + 1];
                int progress_socket = -1;
                const char *cmdline[9];
                int i = 0;

                /* Child */

                /* 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;

                (void) rlimit_nofile_safe();

                execv(cmdline[0], (char**) cmdline);
                _exit(FSCK_OPERATIONAL_ERROR);
        }

        if (console) {
                progress_pipe[1] = safe_close(progress_pipe[1]);
                (void) process_progress(TAKE_FD(progress_pipe[0]), console);
        }

        exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL);
        if (exit_status < 0)
                return exit_status;
        if ((exit_status & ~FSCK_ERROR_CORRECTED) != FSCK_SUCCESS) {
                log_error("fsck failed with exit status %i.", exit_status);

                if ((exit_status & FSCK_SYSTEM_SHOULD_REBOOT) && root_directory) {
                        /* System should be rebooted. */
                        start_target(SPECIAL_REBOOT_TARGET, "replace-irreversibly");
                        return -EINVAL;
                } else if (exit_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED))
                        /* Some other problem */
                        start_target(SPECIAL_EMERGENCY_TARGET, "replace");
                else
                        log_warning("Ignoring error.");
        }

        if (exit_status & FSCK_ERROR_CORRECTED)
                (void) touch("/run/systemd/quotacheck");

        return !!(exit_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED));
}

DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
