chiark / gitweb /
journalctl: use _COMM= match for scripts
[elogind.git] / src / login / loginctl.c
index 3637a408dcdf0a339a2e8f8fe3f7b086a5a2076b..736db6a11b6d1919a6b4a0b4fd2207206afdf2d0 100644 (file)
 #include "dbus-common.h"
 #include "build.h"
 #include "strv.h"
-#include "cgroup-show.h"
+#include "unit-name.h"
 #include "sysfs-show.h"
+#include "cgroup-show.h"
+#include "cgroup-util.h"
 #include "spawn-polkit-agent.h"
 
 static char **arg_property = NULL;
@@ -261,66 +263,74 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int list_machines(DBusConnection *bus, char **args, unsigned n) {
+static int show_unit_cgroup(DBusConnection *bus, const char *interface, const char *unit, pid_t leader) {
+        const char *property = "ControlGroup";
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
-        DBusMessageIter iter, sub, sub2;
-        unsigned k = 0;
-        int r;
+        _cleanup_free_ char *path = NULL;
+        DBusMessageIter iter, sub;
+        const char *cgroup;
+        DBusError error;
+        int r, output_flags;
+        unsigned c;
 
-        pager_open_if_enabled();
+        assert(bus);
+        assert(unit);
 
-        r = bus_method_call_with_reply (
+        if (arg_transport == TRANSPORT_SSH)
+                return 0;
+
+        path = unit_dbus_path_from_name(unit);
+        if (!path)
+                return log_oom();
+
+        r = bus_method_call_with_reply(
                         bus,
-                        "org.freedesktop.login1",
-                        "/org/freedesktop/login1",
-                        "org.freedesktop.login1.Manager",
-                        "ListMachines",
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "Get",
                         &reply,
-                        NULL,
+                        &error,
+                        DBUS_TYPE_STRING, &interface,
+                        DBUS_TYPE_STRING, &property,
                         DBUS_TYPE_INVALID);
-        if (r)
+        if (r < 0) {
+                log_error("Failed to query ControlGroup: %s", bus_error(&error, r));
+                dbus_error_free(&error);
                 return r;
+        }
 
         if (!dbus_message_iter_init(reply, &iter) ||
-            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
-            dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)  {
+            dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
                 log_error("Failed to parse reply.");
-                return -EIO;
+                return -EINVAL;
         }
 
         dbus_message_iter_recurse(&iter, &sub);
+        if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
+                log_error("Failed to parse reply.");
+                return -EINVAL;
+        }
 
-        if (on_tty())
-                printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
-
-        while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
-                const char *name, *class, *service, *object;
-
-                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
-                        log_error("Failed to parse reply.");
-                        return -EIO;
-                }
-
-                dbus_message_iter_recurse(&sub, &sub2);
+        dbus_message_iter_get_basic(&sub, &cgroup);
 
-                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 ||
-                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &class, true) < 0 ||
-                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &service, true) < 0 ||
-                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
-                        log_error("Failed to parse reply.");
-                        return -EIO;
-                }
-
-                printf("%-32s %-9s %-16s\n", name, class, service);
+        if (isempty(cgroup))
+                return 0;
 
-                k++;
+        if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
+                return 0;
 
-                dbus_message_iter_next(&sub);
-        }
+        output_flags =
+                arg_all * OUTPUT_SHOW_ALL |
+                arg_full * OUTPUT_FULL_WIDTH;
 
-        if (on_tty())
-                printf("\n%u machines listed.\n", k);
+        c = columns();
+        if (c > 18)
+                c -= 18;
+        else
+                c = 0;
 
+        show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t  ", c, false, &leader, leader > 0, output_flags);
         return 0;
 }
 
@@ -329,7 +339,6 @@ typedef struct SessionStatusInfo {
         uid_t uid;
         const char *name;
         usec_t timestamp;
-        const char *default_control_group;
         int vtnr;
         const char *seat;
         const char *tty;
@@ -342,14 +351,13 @@ typedef struct SessionStatusInfo {
         const char *type;
         const char *class;
         const char *state;
-        const char *slice;
+        const char *scope;
 } SessionStatusInfo;
 
 typedef struct UserStatusInfo {
         uid_t uid;
         const char *name;
         usec_t timestamp;
-        const char *default_control_group;
         const char *state;
         char **sessions;
         const char *display;
@@ -362,19 +370,7 @@ typedef struct SeatStatusInfo {
         char **sessions;
 } SeatStatusInfo;
 
-typedef struct MachineStatusInfo {
-        const char *name;
-        sd_id128_t id;
-        const char *default_control_group;
-        const char *class;
-        const char *service;
-        const char *slice;
-        const char *root_directory;
-        pid_t leader;
-        usec_t timestamp;
-} MachineStatusInfo;
-
-static void print_session_status_info(SessionStatusInfo *i) {
+static void print_session_status_info(DBusConnection *bus, SessionStatusInfo *i) {
         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
         char since2[FORMAT_TIMESTAMP_MAX], *s2;
         assert(i);
@@ -450,33 +446,13 @@ static void print_session_status_info(SessionStatusInfo *i) {
         if (i->state)
                 printf("\t   State: %s\n", i->state);
 
-        if (i->slice)
-                printf("\t   Slice: %s\n", i->slice);
-
-        if (i->default_control_group) {
-                unsigned c;
-                int output_flags =
-                        arg_all * OUTPUT_SHOW_ALL |
-                        arg_full * OUTPUT_FULL_WIDTH;
-
-                printf("\t  CGroup: %s\n", i->default_control_group);
-
-                if (arg_transport != TRANSPORT_SSH) {
-                        c = columns();
-                        if (c > 18)
-                                c -= 18;
-                        else
-                                c = 0;
-
-                        show_cgroup_and_extra_by_spec(i->default_control_group,
-                                                      "\t\t  ", c, false, &i->leader,
-                                                      i->leader > 0 ? 1 : 0,
-                                                      output_flags);
-                }
+        if (i->scope) {
+                printf("\t    Unit: %s\n", i->scope);
+                show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i->scope, i->leader);
         }
 }
 
-static void print_user_status_info(UserStatusInfo *i) {
+static void print_user_status_info(DBusConnection *bus, UserStatusInfo *i) {
         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
         char since2[FORMAT_TIMESTAMP_MAX], *s2;
         assert(i);
@@ -497,8 +473,6 @@ static void print_user_status_info(UserStatusInfo *i) {
         if (!isempty(i->state))
                 printf("\t   State: %s\n", i->state);
 
-        if (i->slice)
-                printf("\t   Slice: %s\n", i->slice);
 
         if (!strv_isempty(i->sessions)) {
                 char **l;
@@ -514,24 +488,9 @@ static void print_user_status_info(UserStatusInfo *i) {
                 printf("\n");
         }
 
-        if (i->default_control_group) {
-                unsigned c;
-                int output_flags =
-                        arg_all * OUTPUT_SHOW_ALL |
-                        arg_full * OUTPUT_FULL_WIDTH;
-
-                printf("\t  CGroup: %s\n", i->default_control_group);
-
-                if (arg_transport != TRANSPORT_SSH) {
-                        c = columns();
-                        if (c > 18)
-                                c -= 18;
-                        else
-                                c = 0;
-
-                        show_cgroup_by_path(i->default_control_group, "\t\t  ",
-                                            c, false, output_flags);
-                }
+        if (i->slice) {
+                printf("\t    Unit: %s\n", i->slice);
+                show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i->slice, 0);
         }
 }
 
@@ -569,76 +528,6 @@ static void print_seat_status_info(SeatStatusInfo *i) {
         }
 }
 
-static void print_machine_status_info(MachineStatusInfo *i) {
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
-        char since2[FORMAT_TIMESTAMP_MAX], *s2;
-        assert(i);
-
-        fputs(strna(i->name), stdout);
-
-        if (!sd_id128_equal(i->id, SD_ID128_NULL))
-                printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
-        else
-                putchar('\n');
-
-        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
-        s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
-
-        if (s1)
-                printf("\t   Since: %s; %s\n", s2, s1);
-        else if (s2)
-                printf("\t   Since: %s\n", s2);
-
-        if (i->leader > 0) {
-                _cleanup_free_ char *t = NULL;
-
-                printf("\t  Leader: %u", (unsigned) i->leader);
-
-                get_process_comm(i->leader, &t);
-                if (t)
-                        printf(" (%s)", t);
-
-                putchar('\n');
-        }
-
-        if (i->service) {
-                printf("\t Service: %s", i->service);
-
-                if (i->class)
-                        printf("; class %s", i->class);
-
-                putchar('\n');
-        } else if (i->class)
-                printf("\t   Class: %s\n", i->class);
-
-        if (i->slice)
-                printf("\t   Slice: %s\n", i->slice);
-        if (i->root_directory)
-                printf("\t    Root: %s\n", i->root_directory);
-
-        if (i->default_control_group) {
-                unsigned c;
-                int output_flags =
-                        arg_all * OUTPUT_SHOW_ALL |
-                        arg_full * OUTPUT_FULL_WIDTH;
-
-                printf("\t  CGroup: %s\n", i->default_control_group);
-
-                if (arg_transport != TRANSPORT_SSH) {
-                        c = columns();
-                        if (c > 18)
-                                c -= 18;
-                        else
-                                c = 0;
-
-                        show_cgroup_and_extra_by_spec(i->default_control_group,
-                                                      "\t\t  ", c, false, &i->leader,
-                                                      i->leader > 0 ? 1 : 0,
-                                                      output_flags);
-                }
-        }
-}
-
 static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) {
         assert(name);
         assert(iter);
@@ -656,8 +545,6 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
                                 i->id = s;
                         else if (streq(name, "Name"))
                                 i->name = s;
-                        else if (streq(name, "DefaultControlGroup"))
-                                i->default_control_group = s;
                         else if (streq(name, "TTY"))
                                 i->tty = s;
                         else if (streq(name, "Display"))
@@ -672,8 +559,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
                                 i->type = s;
                         else if (streq(name, "Class"))
                                 i->class = s;
-                        else if (streq(name, "Slice"))
-                                i->slice = s;
+                        else if (streq(name, "Scope"))
+                                i->scope = s;
                         else if (streq(name, "State"))
                                 i->state = s;
                 }
@@ -757,8 +644,6 @@ static int status_property_user(const char *name, DBusMessageIter *iter, UserSta
                 if (!isempty(s)) {
                         if (streq(name, "Name"))
                                 i->name = s;
-                        else if (streq(name, "DefaultControlGroup"))
-                                i->default_control_group = s;
                         else if (streq(name, "Slice"))
                                 i->slice = s;
                         else if (streq(name, "State"))
@@ -912,80 +797,6 @@ static int status_property_seat(const char *name, DBusMessageIter *iter, SeatSta
         return 0;
 }
 
-static int status_property_machine(const char *name, DBusMessageIter *iter, MachineStatusInfo *i) {
-        assert(name);
-        assert(iter);
-        assert(i);
-
-        switch (dbus_message_iter_get_arg_type(iter)) {
-
-        case DBUS_TYPE_STRING: {
-                const char *s;
-
-                dbus_message_iter_get_basic(iter, &s);
-
-                if (!isempty(s)) {
-                        if (streq(name, "Name"))
-                                i->name = s;
-                        else if (streq(name, "DefaultControlGroup"))
-                                i->default_control_group = s;
-                        else if (streq(name, "Class"))
-                                i->class = s;
-                        else if (streq(name, "Service"))
-                                i->service = s;
-                        else if (streq(name, "Slice"))
-                                i->slice = s;
-                        else if (streq(name, "RootDirectory"))
-                                i->root_directory = s;
-                }
-                break;
-        }
-
-        case DBUS_TYPE_UINT32: {
-                uint32_t u;
-
-                dbus_message_iter_get_basic(iter, &u);
-
-                if (streq(name, "Leader"))
-                        i->leader = (pid_t) u;
-
-                break;
-        }
-
-        case DBUS_TYPE_UINT64: {
-                uint64_t u;
-
-                dbus_message_iter_get_basic(iter, &u);
-
-                if (streq(name, "Timestamp"))
-                        i->timestamp = (usec_t) u;
-
-                break;
-        }
-
-        case DBUS_TYPE_ARRAY: {
-                DBusMessageIter sub;
-
-                dbus_message_iter_recurse(iter, &sub);
-
-                if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE && streq(name, "Id")) {
-                        void *v;
-                        int n;
-
-                        dbus_message_iter_get_fixed_array(&sub, &v, &n);
-                        if (n == 0)
-                                i->id = SD_ID128_NULL;
-                        else if (n == 16)
-                                memcpy(&i->id, v, n);
-                }
-
-                break;
-        }
-        }
-
-        return 0;
-}
-
 static int print_property(const char *name, DBusMessageIter *iter) {
         assert(name);
         assert(iter);
@@ -1067,7 +878,6 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
         SessionStatusInfo session_info = {};
         UserStatusInfo user_info = {};
         SeatStatusInfo seat_info = {};
-        MachineStatusInfo machine_info = {};
 
         assert(path);
         assert(new_line);
@@ -1131,10 +941,8 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
                         r = status_property_session(name, &sub3, &session_info);
                 else if (strstr(verb, "user"))
                         r = status_property_user(name, &sub3, &user_info);
-                else if (strstr(verb, "seat"))
-                        r = status_property_seat(name, &sub3, &seat_info);
                 else
-                        r = status_property_machine(name, &sub3, &machine_info);
+                        r = status_property_seat(name, &sub3, &seat_info);
 
                 if (r < 0) {
                         log_error("Failed to parse reply.");
@@ -1146,13 +954,11 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
 
         if (!show_properties) {
                 if (strstr(verb, "session"))
-                        print_session_status_info(&session_info);
+                        print_session_status_info(bus, &session_info);
                 else if (strstr(verb, "user"))
-                        print_user_status_info(&user_info);
-                else if (strstr(verb, "seat"))
-                        print_seat_status_info(&seat_info);
+                        print_user_status_info(bus, &user_info);
                 else
-                        print_machine_status_info(&machine_info);
+                        print_seat_status_info(&seat_info);
         }
 
         r = 0;
@@ -1226,7 +1032,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
                                         DBUS_TYPE_UINT32, &u,
                                         DBUS_TYPE_INVALID);
 
-                } else if (strstr(args[0], "seat")) {
+                } else {
 
                         ret = bus_method_call_with_reply(
                                         bus,
@@ -1239,18 +1045,6 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
                                         DBUS_TYPE_STRING, &args[i],
                                         DBUS_TYPE_INVALID);
 
-                } else  {
-
-                        ret = bus_method_call_with_reply(
-                                        bus,
-                                        "org.freedesktop.login1",
-                                        "/org/freedesktop/login1",
-                                        "org.freedesktop.login1.Manager",
-                                        "GetMachine",
-                                        &reply,
-                                        NULL,
-                                        DBUS_TYPE_STRING, &args[i],
-                                        DBUS_TYPE_INVALID);
                 }
 
                 if (ret < 0)
@@ -1334,36 +1128,6 @@ static int kill_session(DBusConnection *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int kill_machine(DBusConnection *bus, char **args, unsigned n) {
-        unsigned i;
-
-        assert(args);
-
-        if (!arg_kill_who)
-                arg_kill_who = "all";
-
-        for (i = 1; i < n; i++) {
-                int r;
-
-                r = bus_method_call_with_reply (
-                        bus,
-                        "org.freedesktop.login1",
-                        "/org/freedesktop/login1",
-                        "org.freedesktop.login1.Manager",
-                        "KillMachine",
-                        NULL,
-                        NULL,
-                        DBUS_TYPE_STRING, &args[i],
-                        DBUS_TYPE_STRING, &arg_kill_who,
-                        DBUS_TYPE_INT32, &arg_signal,
-                        DBUS_TYPE_INVALID);
-                if (r)
-                        return r;
-        }
-
-        return 0;
-}
-
 static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
         unsigned i;
         dbus_bool_t b, interactive = true;
@@ -1567,31 +1331,6 @@ static int terminate_seat(DBusConnection *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int terminate_machine(DBusConnection *bus, char **args, unsigned n) {
-        unsigned i;
-
-        assert(args);
-
-        for (i = 1; i < n; i++) {
-                int r;
-
-                r = bus_method_call_with_reply (
-                        bus,
-                        "org.freedesktop.login1",
-                        "/org/freedesktop/login1",
-                        "org.freedesktop.login1.Manager",
-                        "TerminateMachine",
-                        NULL,
-                        NULL,
-                        DBUS_TYPE_STRING, &args[i],
-                        DBUS_TYPE_INVALID);
-                if (r)
-                        return r;
-        }
-
-        return 0;
-}
-
 static int help(void) {
 
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
@@ -1630,12 +1369,7 @@ static int help(void) {
                "  show-seat [NAME...]             Show properties of one or more seats\n"
                "  attach [NAME] [DEVICE...]       Attach one or more devices to a seat\n"
                "  flush-devices                   Flush all device associations\n"
-               "  terminate-seat [NAME...]        Terminate all sessions on one or more seats\n"
-               "  list-machines                   List running VMs and containers\n"
-               "  machine-status [NAME...]        Show VM/container status\n"
-               "  show-machine [NAME...]          Show properties of one or more VMs/containers\n"
-               "  terminate-machine [NAME...]     Terminate one or more VMs/containers\n"
-               "  kill-machine [NAME...]          Send signal to processes of a VM/container\n",
+               "  terminate-seat [NAME...]        Terminate all sessions on one or more seats\n",
                program_invocation_short_name);
 
         return 0;
@@ -1784,11 +1518,6 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
                 { "attach",                MORE,   3, attach            },
                 { "flush-devices",         EQUAL,  1, flush_devices     },
                 { "terminate-seat",        MORE,   2, terminate_seat    },
-                { "list-machines",         EQUAL,  1, list_machines     },
-                { "machine-status",        MORE,   2, show              },
-                { "show-machine",          MORE,   1, show              },
-                { "terminate-machine",     MORE,   2, terminate_machine },
-                { "kill-machine",          MORE,   2, kill_machine      },
         };
 
         int left;