From: Lennart Poettering Date: Tue, 19 Oct 2010 19:53:19 +0000 (+0200) Subject: fsck: atomically replace base.target by rescue.target/reboot.target when fsck fails X-Git-Tag: v12~204 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90bb85e140a238ce76f05c473e2eb68f147671f3;p=systemd fsck: atomically replace base.target by rescue.target/reboot.target when fsck fails --- diff --git a/src/dbus-manager.c b/src/dbus-manager.c index c700abbe..52638435 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -48,6 +48,12 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -408,6 +414,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit")) job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + job_type = JOB_START; else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit")) job_type = JOB_STOP; else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit")) @@ -910,19 +918,40 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, return bus_default_message_handler(m, connection, message, NULL, properties); if (job_type != _JOB_TYPE_INVALID) { - const char *name, *smode; + const char *name, *smode, *old_name = NULL; JobMode mode; Job *j; Unit *u; - - if (!dbus_message_get_args( - message, - &error, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &smode, - DBUS_TYPE_INVALID)) + bool b; + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &old_name, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + else + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + + if (!b) return bus_send_error_reply(m, connection, message, &error, -EINVAL); + if (old_name) + if (!(u = manager_get_unit(m, old_name)) || + !u->meta.job || + u->meta.job->type != JOB_START) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name); + return bus_send_error_reply(m, connection, message, &error, -ENOENT); + } + + if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) { dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); return bus_send_error_reply(m, connection, message, &error, -EINVAL); diff --git a/src/fsck.c b/src/fsck.c index 702f22c9..b0c3620c 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -38,7 +38,7 @@ static bool arg_force = false; static void start_target(const char *target, bool isolate) { DBusMessage *m = NULL, *reply = NULL; DBusError error; - const char *mode; + const char *mode, *base_target = "base.target"; DBusConnection *bus = NULL; assert(target); @@ -57,12 +57,15 @@ static void start_target(const char *target, bool isolate) { log_debug("Running request %s/start/%s", target, mode); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) { log_error("Could not allocate message."); goto finish; } + /* Start these units only if we can replace base.target with it */ + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &base_target, DBUS_TYPE_STRING, &target, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID)) { @@ -196,11 +199,7 @@ int main(int argc, char *argv[]) { } if (status.si_status & ~1) { - - if (access("/dev/.systemd/late-fsck", F_OK) >= 0) { - log_error("fsck failed with error code %i.", status.si_status); - goto finish; - } + log_error("fsck failed with error code %i.", status.si_status); if (status.si_status & 2) /* System should be rebooted. */