X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=4a55c566eca136fe9b1fcc62199eb589b37aacb5;hp=723be76cdbad6a7b168d9a2224d4677a69d5596c;hb=1b12a7b5896f94bdf33b3a6661ebabd761ea6adc;hpb=23ade460e5a118daa575a961b405d089f95e0617 diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 723be76cd..4a55c566e 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -136,7 +136,7 @@ static void pager_open_if_enabled(void) { if (arg_no_pager) return; - pager_open(); + pager_open(false); } static void ask_password_agent_open_if_enabled(void) { @@ -1045,7 +1045,7 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { if (!n) return log_oom(); - r = bus_method_call_with_reply ( + r = bus_method_call_with_reply( bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -1518,53 +1518,39 @@ static int start_unit_one( return 0; } +static const struct { + const char *target; + const char *verb; + const char *mode; +} action_table[_ACTION_MAX] = { + [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" }, + [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" }, + [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" }, + [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" }, + [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" }, + [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" }, + [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" }, + [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" }, + [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" }, + [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" }, + [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" }, + [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" }, + [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" }, + [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" }, + [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" }, +}; + static enum action verb_to_action(const char *verb) { - if (streq(verb, "halt")) - return ACTION_HALT; - else if (streq(verb, "poweroff")) - return ACTION_POWEROFF; - else if (streq(verb, "reboot")) - return ACTION_REBOOT; - else if (streq(verb, "kexec")) - return ACTION_KEXEC; - else if (streq(verb, "rescue")) - return ACTION_RESCUE; - else if (streq(verb, "emergency")) - return ACTION_EMERGENCY; - else if (streq(verb, "default")) - return ACTION_DEFAULT; - else if (streq(verb, "exit")) - return ACTION_EXIT; - else if (streq(verb, "suspend")) - return ACTION_SUSPEND; - else if (streq(verb, "hibernate")) - return ACTION_HIBERNATE; - else if (streq(verb, "hybrid-sleep")) - return ACTION_HYBRID_SLEEP; - else - return ACTION_INVALID; + enum action i; + + for (i = ACTION_INVALID; i < _ACTION_MAX; i++) + if (action_table[i].verb && streq(verb, action_table[i].verb)) + return i; + return ACTION_INVALID; } static int start_unit(DBusConnection *bus, char **args) { - static const char * const table[_ACTION_MAX] = { - [ACTION_HALT] = SPECIAL_HALT_TARGET, - [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET, - [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET, - [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET, - [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET, - [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET, - [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET, - [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET, - [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET, - [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET, - [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET, - [ACTION_EXIT] = SPECIAL_EXIT_TARGET, - [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET, - [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET, - [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET - }; - int r, ret = 0; const char *method, *mode, *one_name; Set _cleanup_set_free_free_ *s = NULL; @@ -1578,6 +1564,7 @@ static int start_unit(DBusConnection *bus, char **args) { ask_password_agent_open_if_enabled(); if (arg_action == ACTION_SYSTEMCTL) { + enum action action; method = streq(args[0], "stop") || streq(args[0], "condstop") ? "StopUnit" : @@ -1594,29 +1581,21 @@ static int start_unit(DBusConnection *bus, char **args) { streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" : "StartUnit"; + action = verb_to_action(args[0]); - mode = - (streq(args[0], "isolate") || - streq(args[0], "rescue") || - streq(args[0], "emergency") || - streq(args[0], "default")) ? "isolate" : arg_job_mode; + mode = streq(args[0], "isolate") ? "isolate" : + action_table[action].mode ?: arg_job_mode; - one_name = table[verb_to_action(args[0])]; + one_name = action_table[action].target; } else { - assert(arg_action < ELEMENTSOF(table)); - assert(table[arg_action]); + assert(arg_action < ELEMENTSOF(action_table)); + assert(action_table[arg_action].target); method = "StartUnit"; - mode = (arg_action == ACTION_EMERGENCY || - arg_action == ACTION_RESCUE || - arg_action == ACTION_RUNLEVEL2 || - arg_action == ACTION_RUNLEVEL3 || - arg_action == ACTION_RUNLEVEL4 || - arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace"; - - one_name = table[arg_action]; + mode = action_table[arg_action].mode; + one_name = action_table[arg_action].target; } if (!arg_no_block) { @@ -1839,12 +1818,7 @@ static int check_inhibitors(DBusConnection *bus, enum action a) { return 0; log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.", - a == ACTION_HALT ? "halt" : - a == ACTION_POWEROFF ? "poweroff" : - a == ACTION_REBOOT ? "reboot" : - a == ACTION_KEXEC ? "kexec" : - a == ACTION_SUSPEND ? "suspend" : - a == ACTION_HIBERNATE ? "hibernate" : "hybrid-sleep"); + action_table[a].verb); return -EPERM; #else @@ -1989,53 +1963,41 @@ static int kill_unit(DBusConnection *bus, char **args) { } static int set_cgroup(DBusConnection *bus, char **args) { - _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - DBusError error; - const char *method; - DBusMessageIter iter; - int r; _cleanup_free_ char *n = NULL; - const char *runtime; + const char *method, *runtime; + char **argument; + int r; assert(bus); assert(args); - dbus_error_init(&error); - method = - streq(args[0], "set-cgroup") ? "SetUnitControlGroups" : - streq(args[0], "unset-group") ? "UnsetUnitControlGroups" - : "UnsetUnitControlGroupAttributes"; + streq(args[0], "set-cgroup") ? "SetUnitControlGroup" : + streq(args[0], "unset-cgroup") ? "UnsetUnitControlGroup" + : "UnsetUnitControlGroupAttribute"; + + runtime = arg_runtime ? "runtime" : "persistent"; n = unit_name_mangle(args[1]); if (!n) return log_oom(); - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - method); - if (!m) - return log_oom(); - - dbus_message_iter_init_append(m, &iter); - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n)) - return log_oom(); - - r = bus_append_strv_iter(&iter, args + 2); - if (r < 0) - return log_oom(); - - runtime = arg_runtime ? "runtime" : "persistent"; - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &runtime)) - return log_oom(); + STRV_FOREACH(argument, args + 2) { - reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); - if (!reply) { - log_error("Failed to issue method call: %s", bus_error_message(&error)); - dbus_error_free(&error); - return -EIO; + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method, + NULL, + NULL, + DBUS_TYPE_STRING, &n, + DBUS_TYPE_STRING, argument, + DBUS_TYPE_STRING, &runtime, + DBUS_TYPE_INVALID); + if (r < 0) + return r; } return 0; @@ -2044,20 +2006,17 @@ static int set_cgroup(DBusConnection *bus, char **args) { static int set_cgroup_attr(DBusConnection *bus, char **args) { _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; DBusError error; - DBusMessageIter iter, sub, sub2; - char **x, **y; + DBusMessageIter iter; _cleanup_free_ char *n = NULL; const char *runtime; + int r; assert(bus); assert(args); dbus_error_init(&error); - if (strv_length(args) % 2 != 0) { - log_error("Expecting an uneven number of arguments!"); - return -EINVAL; - } + runtime = arg_runtime ? "runtime" : "persistent"; n = unit_name_mangle(args[1]); if (!n) @@ -2067,26 +2026,20 @@ static int set_cgroup_attr(DBusConnection *bus, char **args) { "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "SetUnitControlGroupAttributes"); + "SetUnitControlGroupAttribute"); if (!m) return log_oom(); dbus_message_iter_init_append(m, &iter); if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) || - !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub)) + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[2])) return log_oom(); - STRV_FOREACH_PAIR(x, y, args + 2) { - if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, x) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, y) || - !dbus_message_iter_close_container(&sub, &sub2)) - return log_oom(); - } + r = bus_append_strv_iter(&iter, args + 3); + if (r < 0) + return log_oom(); - runtime = arg_runtime ? "runtime" : "persistent"; - if (!dbus_message_iter_close_container(&iter, &sub) || - !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &runtime)) + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &runtime)) return log_oom(); reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); @@ -2101,57 +2054,53 @@ static int set_cgroup_attr(DBusConnection *bus, char **args) { static int get_cgroup_attr(DBusConnection *bus, char **args) { _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; - DBusError error; - DBusMessageIter iter; - int r; _cleanup_free_ char *n = NULL; - _cleanup_strv_free_ char **list = NULL; - char **a; + char **argument; + int r; assert(bus); assert(args); - dbus_error_init(&error); - n = unit_name_mangle(args[1]); if (!n) return log_oom(); - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnitControlGroupAttributes"); - if (!m) - return log_oom(); + STRV_FOREACH(argument, args + 2) { + _cleanup_strv_free_ char **list = NULL; + DBusMessageIter iter; + char **a; - dbus_message_iter_init_append(m, &iter); - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n)) - return log_oom(); - - r = bus_append_strv_iter(&iter, args + 2); - if (r < 0) - return log_oom(); + r = bus_method_call_with_reply( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitControlGroupAttribute", + &reply, + NULL, + DBUS_TYPE_STRING, &n, + DBUS_TYPE_STRING, argument, + DBUS_TYPE_INVALID); + if (r < 0) + return r; - reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); - if (!reply) { - log_error("Failed to issue method call: %s", bus_error_message(&error)); - dbus_error_free(&error); - return -EIO; - } + if (!dbus_message_iter_init(reply, &iter)) { + log_error("Failed to initialize iterator."); + return -EIO; + } - dbus_message_iter_init(reply, &iter); - r = bus_parse_strv_iter(&iter, &list); - if (r < 0) { - log_error("Failed to parse value list."); - return r; - } + r = bus_parse_strv_iter(&iter, &list); + if (r < 0) { + log_error("Failed to parse value list."); + return r; + } - STRV_FOREACH(a, list) { - if (endswith(*a, "\n")) - fputs(*a, stdout); - else - puts(*a); + STRV_FOREACH(a, list) { + if (endswith(*a, "\n")) + fputs(*a, stdout); + else + puts(*a); + } } return 0; @@ -4011,16 +3960,15 @@ static int enable_unit(DBusConnection *bus, char **args) { } if (carries_install_info == 0) - log_warning( -"The unit files have no [Install] section. They are not meant to be enabled\n" -"using systemctl.\n" -"Possible reasons for having this kind of units are:\n" -"1) A unit may be statically enabled by being symlinked from another unit's\n" -" .wants/ or .requires/ directory.\n" -"2) A unit's purpose may be to act as a helper for some other unit which has\n" -" a requirement dependency on it.\n" -"3) A unit may be started when needed via activation (socket, path, timer,\n" -" D-Bus, udev, scripted systemctl call, ...).\n"); + log_warning("The unit files have no [Install] section. They are not meant to be enabled\n" + "using systemctl.\n" + "Possible reasons for having this kind of units are:\n" + "1) A unit may be statically enabled by being symlinked from another unit's\n" + " .wants/ or .requires/ directory.\n" + "2) A unit's purpose may be to act as a helper for some other unit which has\n" + " a requirement dependency on it.\n" + "3) A unit may be started when needed via activation (socket, path, timer,\n" + " D-Bus, udev, scripted systemctl call, ...).\n"); finish: unit_file_changes_free(changes, n_changes); @@ -4034,6 +3982,7 @@ static int unit_is_enabled(DBusConnection *bus, char **args) { DBusMessage _cleanup_dbus_message_unref_ *reply = NULL; bool enabled; char **name; + char *n; dbus_error_init(&error); @@ -4048,7 +3997,14 @@ static int unit_is_enabled(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { UnitFileState state; - state = unit_file_get_state(arg_scope, arg_root, *name); + n = unit_name_mangle(*name); + if (!n) + return log_oom(); + + state = unit_file_get_state(arg_scope, arg_root, n); + + free(n); + if (state < 0) return state; @@ -4065,6 +4021,10 @@ static int unit_is_enabled(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { const char *s; + n = unit_name_mangle(*name); + if (!n) + return log_oom(); + r = bus_method_call_with_reply ( bus, "org.freedesktop.systemd1", @@ -4073,8 +4033,11 @@ static int unit_is_enabled(DBusConnection *bus, char **args) { "GetUnitFileState", &reply, NULL, - DBUS_TYPE_STRING, name, + DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID); + + free(n); + if (r) return r; @@ -5150,11 +5113,11 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ { "isolate", EQUAL, 2, start_unit }, - { "set-cgroup", MORE, 2, set_cgroup }, - { "unset-cgroup", MORE, 2, set_cgroup }, - { "get-cgroup-attr", MORE, 2, get_cgroup_attr }, - { "set-cgroup-attr", MORE, 2, set_cgroup_attr }, - { "unset-cgroup-attr", MORE, 2, set_cgroup }, + { "set-cgroup", MORE, 3, set_cgroup }, + { "unset-cgroup", MORE, 3, set_cgroup }, + { "get-cgroup-attr", MORE, 3, get_cgroup_attr }, + { "set-cgroup-attr", MORE, 4, set_cgroup_attr }, + { "unset-cgroup-attr", MORE, 3, set_cgroup }, { "kill", MORE, 2, kill_unit }, { "is-active", MORE, 2, check_unit_active }, { "check", MORE, 2, check_unit_active },