X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=2ebfff8daf94e3ef71491401eb3aeb3cdc585df0;hp=6d01756ffb3b3c9ceaa0d0d62f9338e6c27ea300;hb=bc2708414babc5c99bb8000e63c84e87606cc15d;hpb=d9847b32462d3943c9788e05454364f544617b9d diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6d01756ff..2ebfff8da 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1366,7 +1366,7 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { return r; } -static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { +static int check_one_unit(DBusConnection *bus, char *name, char **check_states, bool quiet) { DBusMessage *reply = NULL; DBusMessageIter iter, sub; const char @@ -1440,7 +1440,7 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { if (!quiet) puts(state); - if (streq(state, "active") || streq(state, "reloading")) + if (strv_find(check_states, state)) r = 0; else r = 3; /* According to LSB: "program is not running" */ @@ -1503,6 +1503,7 @@ static void check_triggering_units( sub = iter; while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + char **check_states = NULL; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { log_error("Failed to parse reply."); @@ -1511,7 +1512,9 @@ static void check_triggering_units( dbus_message_iter_get_basic(&sub, &service_trigger); - r = check_one_unit(bus, service_trigger, true); + check_states = strv_new("active", "reloading", NULL); + r = check_one_unit(bus, service_trigger, check_states, true); + strv_free(check_states); if (r < 0) return; if (r == 0) { @@ -1847,7 +1850,7 @@ static int start_special(DBusConnection *bus, char **args) { return r; } -static int check_unit(DBusConnection *bus, char **args) { +static int check_unit_active(DBusConnection *bus, char **args) { char **name; int r = 3; /* According to LSB: "program is not running" */ @@ -1855,7 +1858,29 @@ static int check_unit(DBusConnection *bus, char **args) { assert(args); STRV_FOREACH(name, args+1) { - int state = check_one_unit(bus, *name, arg_quiet); + char **check_states = strv_new("active", "reloading", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); + if (state < 0) + return state; + if (state == 0) + r = 0; + } + + return r; +} + +static int check_unit_failed(DBusConnection *bus, char **args) { + char **name; + int r = 1; + + assert(bus); + assert(args); + + STRV_FOREACH(name, args+1) { + char **check_states = strv_new("failed", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); if (state < 0) return state; if (state == 0) @@ -2265,7 +2290,8 @@ static void print_status_info(UnitStatusInfo *i) { if (i->status_text) printf("\t Status: \"%s\"\n", i->status_text); - if (i->default_control_group) { + if (i->default_control_group && + (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) { unsigned c; printf("\t CGroup: %s\n", i->default_control_group); @@ -3323,7 +3349,8 @@ finish: static int switch_root(DBusConnection *bus, char **args) { unsigned l; - const char *root, *init; + const char *root; + _cleanup_free_ char *init = NULL; l = strv_length(args); if (l < 2 || l > 3) { @@ -3332,7 +3359,23 @@ static int switch_root(DBusConnection *bus, char **args) { } root = args[1]; - init = l >= 3 ? args[2] : ""; + + if (l >= 3) + init = strdup(args[2]); + else { + parse_env_file("/proc/cmdline", WHITESPACE, + "init", &init, + NULL); + + if (!init) + init = strdup(""); + + if (!init) + return log_oom(); + + } + + log_debug("switching root - root: %s; init: %s", root, init); return bus_method_call_with_reply ( bus, @@ -3393,7 +3436,7 @@ finish: static int enable_sysv_units(char **args) { int r = 0; -#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA)) +#if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG) const char *verb = args[0]; unsigned f = 1, t = 1; LookupPaths paths; @@ -3782,7 +3825,16 @@ 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 using systemctl."); + 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: if (m) @@ -3940,6 +3992,7 @@ static int systemctl_help(void) { " isolate [NAME] Start one unit and stop all others\n" " kill [NAME...] Send signal to processes of a unit\n" " is-active [NAME...] Check whether units are active\n" + " is-failed [NAME...] Check whether units are failed\n" " status [NAME...|PID...] Show runtime status of one or more units\n" " show [NAME...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" @@ -4148,7 +4201,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { case ARG_VERSION: puts(PACKAGE_STRING); - puts(DISTRIBUTION); puts(SYSTEMD_FEATURES); return 0; @@ -4918,8 +4970,9 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ { "isolate", EQUAL, 2, start_unit }, { "kill", MORE, 2, kill_unit }, - { "is-active", MORE, 2, check_unit }, - { "check", MORE, 2, check_unit }, + { "is-active", MORE, 2, check_unit_active }, + { "check", MORE, 2, check_unit_active }, + { "is-failed", MORE, 2, check_unit_failed }, { "show", MORE, 1, show }, { "status", MORE, 2, show }, { "help", MORE, 2, show },