chiark / gitweb /
cgroups: simplify CPUQuota= logic
[elogind.git] / src / libsystemd / sd-bus / bus-util.c
index d0ae43da4ed06da74672ab1342534369e6bde490..6c9548f9aa6863b92ac819b8b9738fd55a277d52 100644 (file)
@@ -77,7 +77,7 @@ int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
         if (r < 0)
                 return -ENOMEM;
 
-        r = sd_bus_add_match(bus, match, name_owner_change_callback, e);
+        r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
         if (r < 0)
                 return r;
 
@@ -251,17 +251,16 @@ typedef struct AsyncPolkitQuery {
         sd_bus_message *request, *reply;
         sd_bus_message_handler_t callback;
         void *userdata;
-        uint64_t serial;
+        sd_bus_slot *slot;
         Hashmap *registry;
 } AsyncPolkitQuery;
 
-static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
+static void async_polkit_query_free(AsyncPolkitQuery *q) {
 
         if (!q)
                 return;
 
-        if (q->serial > 0 && b)
-                sd_bus_call_async_cancel(b, q->serial);
+        sd_bus_slot_unref(q->slot);
 
         if (q->registry && q->request)
                 hashmap_remove(q->registry, q->request);
@@ -281,8 +280,8 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
         assert(reply);
         assert(q);
 
+        q->slot = sd_bus_slot_unref(q->slot);
         q->reply = sd_bus_message_ref(reply);
-        q->serial = 0;
 
         r = sd_bus_message_rewind(q->request, true);
         if (r < 0) {
@@ -294,7 +293,8 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
         r = bus_maybe_reply_error(q->request, r, &error_buffer);
 
 finish:
-        async_polkit_query_free(bus, q);
+        async_polkit_query_free(q);
+
         return r;
 }
 
@@ -413,15 +413,15 @@ int bus_verify_polkit_async(
 
         r = hashmap_put(*registry, m, q);
         if (r < 0) {
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
                 return r;
         }
 
         q->registry = *registry;
 
-        r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
+        r = sd_bus_call_async(bus, &q->slot, pk, async_polkit_callback, q, 0);
         if (r < 0) {
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
                 return r;
         }
 
@@ -436,7 +436,7 @@ void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) {
         AsyncPolkitQuery *q;
 
         while ((q = hashmap_steal_first(registry)))
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
 
         hashmap_free(registry);
 #endif
@@ -537,7 +537,7 @@ int bus_open_user_systemd(sd_bus **_bus) {
         if (r < 0)
                 return r;
 
-        if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid()) < 0)
+        if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, getuid()) < 0)
                 return -ENOMEM;
 
         bus->bus_client = true;
@@ -1192,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)",
@@ -1248,11 +1250,47 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
         field = strndupa(assignment, eq - assignment);
         eq ++;
 
+        if (streq(field, "CPUQuota")) {
+
+                if (isempty(eq)) {
+
+                        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = sd_bus_message_append(m, "v", "t", (usec_t) -1);
+
+                } else if (endswith(eq, "%")) {
+                        double percent;
+
+                        if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
+                                log_error("CPU quota '%s' invalid.", eq);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
+                } else {
+                        log_error("CPU quota needs to be in percent.");
+                        return -EINVAL;
+                }
+
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 0;
+        }
+
         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")) {
+        if (STR_IN_SET(field,
+                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+                       "SendSIGHUP", "SendSIGKILL")) {
 
                 r = parse_boolean(eq);
                 if (r < 0) {
@@ -1284,7 +1322,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 r = sd_bus_message_append(m, "v", "t", u);
 
-        } else if (streq(field, "DevicePolicy"))
+        } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
                 r = sd_bus_message_append(m, "v", "s", eq);
 
         else if (streq(field, "DeviceAllow")) {
@@ -1387,6 +1425,32 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 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;