diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-10-19 21:53:19 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-10-19 21:53:19 +0200 |
commit | 90bb85e140a238ce76f05c473e2eb68f147671f3 (patch) | |
tree | 9d6b28bf28a4ba26acee450fd63485e29101808e | |
parent | 3e33a44a01078ea0699dca160b93f0399fbc994b (diff) |
fsck: atomically replace base.target by rescue.target/reboot.target when fsck fails
-rw-r--r-- | src/dbus-manager.c | 45 | ||||
-rw-r--r-- | src/fsck.c | 13 |
2 files changed, 43 insertions, 15 deletions
diff --git a/src/dbus-manager.c b/src/dbus-manager.c index c700abbe22..52638435c2 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -48,6 +48,12 @@ " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ " </method>\n" \ + " <method name=\"StartUnitReplace\">\n" \ + " <arg name=\"old_unit\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"new_unit\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ + " </method>\n" \ " <method name=\"StopUnit\">\n" \ " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\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 702f22c95d..b0c3620c8c 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. */ |