chiark / gitweb /
systemctl: introduce -r switch to show units running in local containers in addition...
[elogind.git] / src / libsystemd / sd-bus / bus-util.c
index a468bcad6b81dfb7dbd0c02c9c3d1ed72aaba8cb..df7ab8a83a87f5d84bb276569629a9a7b11c2515 100644 (file)
@@ -26,6 +26,7 @@
 #include "strv.h"
 #include "macro.h"
 #include "def.h"
+#include "path-util.h"
 #include "missing.h"
 
 #include "sd-event.h"
@@ -383,11 +384,11 @@ int bus_verify_polkit_async(
 
         r = sd_bus_message_new_method_call(
                         bus,
+                        &pk,
                         "org.freedesktop.PolicyKit1",
                         "/org/freedesktop/PolicyKit1/Authority",
                         "org.freedesktop.PolicyKit1.Authority",
-                        "CheckAuthorization",
-                        &pk);
+                        "CheckAuthorization");
         if (r < 0)
                 return r;
 
@@ -1054,11 +1055,11 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b
                 break;
 
         case BUS_TRANSPORT_REMOTE:
-                r = sd_bus_open_system_remote(host, bus);
+                r = sd_bus_open_system_remote(bus, host);
                 break;
 
         case BUS_TRANSPORT_CONTAINER:
-                r = sd_bus_open_system_container(host, bus);
+                r = sd_bus_open_system_container(bus, host);
                 break;
 
         default:
@@ -1089,11 +1090,11 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
                 break;
 
         case BUS_TRANSPORT_REMOTE:
-                r = sd_bus_open_system_remote(host, bus);
+                r = sd_bus_open_system_remote(bus, host);
                 break;
 
         case BUS_TRANSPORT_CONTAINER:
-                r = sd_bus_open_system_container(host, bus);
+                r = sd_bus_open_system_container(bus, host);
                 break;
 
         default:
@@ -1191,6 +1192,8 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
         assert(message);
         assert(u);
 
+        u->machine = NULL;
+
         return sd_bus_message_read(
                         message,
                         "(ssssssouso)",
@@ -1230,3 +1233,197 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
 
         return 1;
 }
+
+int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
+        const char *eq, *field;
+        int r;
+
+        assert(m);
+        assert(assignment);
+
+        eq = strchr(assignment, '=');
+        if (!eq) {
+                log_error("Not an assignment: %s", assignment);
+                return -EINVAL;
+        }
+
+        field = strndupa(assignment, eq - assignment);
+        eq ++;
+
+        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        if (STR_IN_SET(field,
+                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+                       "SendSIGHUP", "SendSIGKILL")) {
+
+                r = parse_boolean(eq);
+                if (r < 0) {
+                        log_error("Failed to parse boolean assignment %s.", assignment);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "b", r);
+
+        } else if (streq(field, "MemoryLimit")) {
+                off_t bytes;
+
+                r = parse_size(eq, 1024, &bytes);
+                if (r < 0) {
+                        log_error("Failed to parse bytes specification %s", assignment);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
+
+        } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
+                uint64_t u;
+
+                r = safe_atou64(eq, &u);
+                if (r < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "t", u);
+
+        } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
+                r = sd_bus_message_append(m, "v", "s", eq);
+
+        else if (streq(field, "DeviceAllow")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(ss)", 0);
+                else {
+                        const char *path, *rwm, *e;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                rwm = e+1;
+                        } else {
+                                path = eq;
+                                rwm = "";
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
+                }
+
+        } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(st)", 0);
+                else {
+                        const char *path, *bandwidth, *e;
+                        off_t bytes;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                bandwidth = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = parse_size(bandwidth, 1000, &bytes);
+                        if (r < 0) {
+                                log_error("Failed to parse byte value %s.", bandwidth);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
+                }
+
+        } else if (streq(field, "BlockIODeviceWeight")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(st)", 0);
+                else {
+                        const char *path, *weight, *e;
+                        uint64_t u;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                weight = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = safe_atou64(weight, &u);
+                        if (r < 0) {
+                                log_error("Failed to parse %s value %s.", field, weight);
+                                return -EINVAL;
+                        }
+                        r = sd_bus_message_append(m, "v", "a(st)", path, u);
+                }
+
+        } else if (rlimit_from_string(field) >= 0) {
+                uint64_t rl;
+
+                if (streq(eq, "infinity"))
+                        rl = (uint64_t) -1;
+                else {
+                        r = safe_atou64(eq, &rl);
+                        if (r < 0) {
+                                log_error("Invalid resource limit: %s", eq);
+                                return -EINVAL;
+                        }
+                }
+
+                r = sd_bus_message_append(m, "v", "t", rl);
+
+        } else if (streq(field, "Nice")) {
+                int32_t i;
+
+                r = safe_atoi32(eq, &i);
+                if (r < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "i", i);
+
+        } else if (streq(field, "Environment")) {
+
+                r = sd_bus_message_append(m, "v", "as", 1, eq);
+
+        } else if (streq(field, "KillSignal")) {
+                int sig;
+
+                sig = signal_from_string_try_harder(eq);
+                if (sig < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "i", sig);
+
+        } else {
+                log_error("Unknown assignment %s.", assignment);
+                return -EINVAL;
+        }
+
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        return 0;
+}