X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsystemctl.c;h=5db094fc159a65ea6212c616c42df435522db595;hp=b733b47c84420eb90d0b1a12ff42a260723f040d;hb=6f79c579ec9c188173dde41395bbfb86c547fdd3;hpb=8c7be95e5a80c4bd82d86e9640a071fd98618172 diff --git a/src/systemctl.c b/src/systemctl.c index b733b47c8..5db094fc1 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -108,6 +108,12 @@ static enum dot { DOT_ORDER, DOT_REQUIRE } arg_dot = DOT_ALL; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static const char *arg_host = NULL; static bool private_bus = false; @@ -1249,7 +1255,7 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { log_error("Job canceled."); else if (streq(d.result, "dependency")) log_error("A dependency job failed. See system logs for details."); - else if (!streq(d.result, "done")) + else if (!streq(d.result, "done") && !streq(d.result, "skipped")) log_error("Job failed. See system logs and 'systemctl status' for details."); } @@ -1257,7 +1263,7 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { r = -ETIME; else if (streq_ptr(d.result, "canceled")) r = -ECANCELED; - else if (!streq_ptr(d.result, "done")) + else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped")) r = -EIO; else r = 0; @@ -1417,11 +1423,15 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) { streq(args[0], "stop") ? "StopUnit" : streq(args[0], "reload") ? "ReloadUnit" : streq(args[0], "restart") ? "RestartUnit" : + streq(args[0], "try-restart") || streq(args[0], "condrestart") ? "TryRestartUnit" : + streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" : + streq(args[0], "reload-or-try-restart") || streq(args[0], "condreload") || + streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" : "StartUnit"; @@ -1827,6 +1837,9 @@ typedef struct UnitStatusInfo { int exit_code, exit_status; + usec_t condition_timestamp; + bool condition_result; + /* Socket */ unsigned n_accepted; unsigned n_connections; @@ -1918,6 +1931,16 @@ static void print_status_info(UnitStatusInfo *i) { else printf("\n"); + if (!i->condition_result && i->condition_timestamp > 0) { + s1 = format_timestamp_pretty(since1, sizeof(since1), i->condition_timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); + + if (s1) + printf("\t start condition failed at %s; %s\n", s2, s1); + else if (s2) + printf("\t start condition failed at %s\n", s2); + } + if (i->sysfs_path) printf("\t Device: %s\n", i->sysfs_path); if (i->where) @@ -2044,12 +2067,14 @@ static void print_status_info(UnitStatusInfo *i) { printf("\t CGroup: %s\n", i->default_control_group); - if ((c = columns()) > 18) - c -= 18; - else - c = 0; + if (arg_transport != TRANSPORT_SSH) { + if ((c = columns()) > 18) + c -= 18; + else + c = 0; - show_cgroup_by_path(i->default_control_group, "\t\t ", c); + show_cgroup_by_path(i->default_control_group, "\t\t ", c); + } } if (i->need_daemon_reload) @@ -2113,6 +2138,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->accept = b; else if (streq(name, "NeedDaemonReload")) i->need_daemon_reload = b; + else if (streq(name, "ConditionResult")) + i->condition_result = b; break; } @@ -2170,6 +2197,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->inactive_exit_timestamp = (usec_t) u; else if (streq(name, "ActiveExitTimestamp")) i->active_exit_timestamp = (usec_t) u; + else if (streq(name, "ConditionTimestamp")) + i->condition_timestamp = (usec_t) u; break; } @@ -4038,7 +4067,7 @@ static int install_info_apply(const char *verb, LookupPaths *paths, InstallInfo } if (!f) { -#if defined(TARGET_FEDORA) && defined (HAVE_SYSV_COMPAT) +#if (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA)) && defined (HAVE_SYSV_COMPAT) if (endswith(i->name, ".service")) { char *sysv; @@ -4068,7 +4097,7 @@ static int install_info_apply(const char *verb, LookupPaths *paths, InstallInfo argv[1] = file_name_from_path(sysv); argv[2] = streq(verb, "enable") ? "on" : - streq(verb, "disable") ? "off" : NULL; + streq(verb, "disable") ? "off" : "--level=3"; log_info("Executing %s %s %s", argv[0], argv[1], strempty(argv[2])); @@ -4087,10 +4116,15 @@ static int install_info_apply(const char *verb, LookupPaths *paths, InstallInfo return r; if (status.si_code == CLD_EXITED) { - if (status.si_status == 0 && (streq(verb, "enable") || streq(verb, "disable"))) + + if (streq(verb, "is-enabled")) + return status.si_status == 0 ? 1 : 0; + + if (status.si_status == 0) n_symlinks ++; return status.si_status == 0 ? 0 : -EINVAL; + } else return -EPROTO; } @@ -4193,6 +4227,8 @@ static int enable_unit(DBusConnection *bus, char **args, unsigned n) { goto finish; } + r = 0; + while ((i = hashmap_first(will_install))) { int q; @@ -4262,22 +4298,25 @@ static int systemctl_help(void) { " pending\n" " --ignore-dependencies\n" " When queueing a new job, ignore all its dependencies\n" + " --kill-mode=MODE How to send signal\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " -H --host=[user@]host\n" + " Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" " -q --quiet Suppress output\n" " --no-block Do not wait until operation finished\n" - " --no-pager Do not pipe output into a pager.\n" - " --system Connect to system manager\n" - " --user Connect to user service manager\n" - " --order When generating graph for dot, show only order\n" - " --require When generating graph for dot, show only requirement\n" " --no-wall Don't send wall message before halt/power-off/reboot\n" - " --global Enable/disable unit files globally\n" " --no-reload When enabling/disabling unit files, don't reload daemon\n" " configuration\n" + " --no-pager Do not pipe output into a pager.\n" " --no-ask-password\n" " Do not ask for system passwords\n" - " --kill-mode=MODE How to send signal\n" - " --kill-who=WHO Who to send signal to\n" - " -s --signal=SIGNAL Which signal to send\n" + " --order When generating graph for dot, show only order\n" + " --require When generating graph for dot, show only requirement\n" + " --system Connect to system manager\n" + " --user Connect to user service manager\n" + " --global Enable/disable unit files globally\n" " -f --force When enabling unit files, override existing symlinks\n" " When shutting down, execute action immediately\n" " --defaults When disabling unit files, remove default symlinks only\n\n" @@ -4444,6 +4483,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "kill-who", required_argument, NULL, ARG_KILL_WHO }, { "signal", required_argument, NULL, 's' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "host", required_argument, NULL, 'H' }, + { "privileged",no_argument, NULL, 'P' }, { NULL, 0, NULL, 0 } }; @@ -4455,7 +4496,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { /* Only when running as systemctl we ask for passwords */ arg_ask_password = true; - while ((c = getopt_long(argc, argv, "ht:p:aqfs:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:P", options, NULL)) >= 0) { switch (c) { @@ -4577,6 +4618,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_ask_password = false; break; + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + case '?': return -EINVAL; @@ -4586,6 +4636,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) { } } + if (arg_transport != TRANSPORT_NORMAL && arg_user) { + log_error("Cannot access user instance remotely."); + return -EINVAL; + } + return 1; } @@ -5309,7 +5364,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(sockaddr); sockaddr.sa.sa_family = AF_UNIX; sockaddr.un.sun_path[0] = 0; - strncpy(sockaddr.un.sun_path+1, "/org/freedesktop/systemd1/shutdownd", sizeof(sockaddr.un.sun_path)-1); + strncpy(sockaddr.un.sun_path, "/dev/.run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); zero(iovec); iovec.iov_base = (char*) &c; @@ -5317,7 +5372,7 @@ static int send_shutdownd(usec_t t, char mode, bool warn, const char *message) { zero(msghdr); msghdr.msg_name = &sockaddr; - msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + 1 + sizeof("/org/freedesktop/systemd1/shutdownd") - 1; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/dev/.run/systemd/shutdownd") - 1; msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; @@ -5594,7 +5649,16 @@ int main(int argc, char*argv[]) { goto finish; } - bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); + if (arg_transport == TRANSPORT_NORMAL) + bus_connect(arg_user ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); + else if (arg_transport == TRANSPORT_POLKIT) { + bus_connect_system_polkit(&bus, &error); + private_bus = false; + } else if (arg_transport == TRANSPORT_SSH) { + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + private_bus = false; + } else + assert_not_reached("Uh, invalid transport..."); switch (arg_action) {