-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <stdbool.h>
#include <errno.h>
-#include <unistd.h>
#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
#include <sys/file.h>
-#include <sys/stat.h>
#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "sd-bus.h"
#include "sd-device.h"
-#include "util.h"
-#include "process-util.h"
-#include "signal-util.h"
-#include "special.h"
-#include "bus-util.h"
-#include "bus-error.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 "parse-util.h"
#include "path-util.h"
+#include "proc-cmdline.h"
+#include "process-util.h"
+#include "signal-util.h"
#include "socket-util.h"
+#include "special.h"
+#include "stdio-util.h"
+#include "util.h"
/* exit codes as defined in fsck(8) */
enum {
static bool arg_show_progress = false;
static const char *arg_repair = "-a";
-static void start_target(const char *target) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+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_open_system_systemd(&bus);
+ r = bus_connect_system_systemd(&bus);
if (r < 0) {
log_error_errno(r, "Failed to get D-Bus connection: %m");
return;
"StartUnitReplace",
&error,
NULL,
- "sss", "basic.target", target, "replace");
+ "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) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
assert(key);
- if (streq(key, "fsck.mode") && value) {
+ if (streq(key, "fsck.mode")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (streq(value, "auto"))
arg_force = arg_skip = false;
else
log_warning("Invalid fsck.mode= parameter '%s'. Ignoring.", value);
- } else if (streq(key, "fsck.repair") && value) {
+ } else if (streq(key, "fsck.repair")) {
+
+ if (proc_cmdline_value_missing(key, value))
+ return 0;
if (streq(value, "preen"))
arg_repair = "-a";
}
}
-#ifdef HAVE_SYSV_COMPAT
+#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;
static void test_files(void) {
-#ifdef HAVE_SYSV_COMPAT
+#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 (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,
+ if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
+ r = 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);
safe_close(fd);
return r;
int main(int argc, char *argv[]) {
_cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
- _cleanup_device_unref_ sd_device *dev = NULL;
+ _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
const char *device, *type;
bool root_directory;
siginfo_t status;
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item);
+ 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");
r = sd_device_get_property_value(dev, "ID_FS_TYPE", &type);
if (r >= 0) {
r = fsck_exists(type);
- if (r == -ENOENT) {
- log_info("fsck.%s doesn't exist, not checking file system on %s", type, device);
- r = 0;
+ if (r < 0)
+ log_warning_errno(r, "Couldn't detect if fsck.%s may be used for %s, proceeding: %m", type, device);
+ else if (r == 0) {
+ log_info("fsck.%s doesn't exist, not checking file system on %s.", type, device);
goto finish;
- } else if (r < 0)
- log_warning_errno(r, "Couldn't detect if fsck.%s may be used for %s: %m", type, device);
+ }
}
if (arg_show_progress) {
if (status.si_code == CLD_EXITED && (status.si_status & FSCK_SYSTEM_SHOULD_REBOOT) && root_directory)
/* System should be rebooted. */
- start_target(SPECIAL_REBOOT_TARGET);
+ start_target(SPECIAL_REBOOT_TARGET, "replace-irreversibly");
else if (status.si_code == CLD_EXITED && (status.si_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED)))
/* Some other problem */
- start_target(SPECIAL_EMERGENCY_TARGET);
+ start_target(SPECIAL_EMERGENCY_TARGET, "replace");
else {
log_warning("Ignoring error.");
r = 0;