]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/dbus-cgroup.c
core: add IODeviceLatencyTargetSec
[thirdparty/systemd.git] / src / core / dbus-cgroup.c
index 137bd47d87cce43827f8f50223f19fe98864882b..856d9d91b222f174a4cb73b5f39f2963d68315e5 100644 (file)
@@ -119,6 +119,36 @@ static int property_get_io_device_limits(
         return sd_bus_message_close_container(reply);
 }
 
+static int property_get_io_device_latency(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        CGroupContext *c = userdata;
+        CGroupIODeviceLatency *l;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        r = sd_bus_message_open_container(reply, 'a', "(st)");
+        if (r < 0)
+                return r;
+
+        LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
+                r = sd_bus_message_append(reply, "(st)", l->path, l->target_usec);
+                if (r < 0)
+                        return r;
+        }
+
+        return sd_bus_message_close_container(reply);
+}
+
 static int property_get_blockio_device_weight(
                 sd_bus *bus,
                 const char *path,
@@ -291,6 +321,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
         SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
         SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
+        SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency, 0, 0),
         SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
         SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0),
         SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0),
@@ -846,6 +877,86 @@ int bus_cgroup_set_property(
 
                 return 1;
 
+        } else if (streq(name, "IODeviceLatencyTargetUSec")) {
+                const char *path;
+                uint64_t target;
+                unsigned n = 0;
+
+                r = sd_bus_message_enter_container(message, 'a', "(st)");
+                if (r < 0)
+                        return r;
+
+                while ((r = sd_bus_message_read(message, "(st)", &path, &target)) > 0) {
+
+                        if (!path_is_normalized(path))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
+
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                CGroupIODeviceLatency *a = NULL, *b;
+
+                                LIST_FOREACH(device_latencies, b, c->io_device_latencies) {
+                                        if (path_equal(b->path, path)) {
+                                                a = b;
+                                                break;
+                                        }
+                                }
+
+                                if (!a) {
+                                        a = new0(CGroupIODeviceLatency, 1);
+                                        if (!a)
+                                                return -ENOMEM;
+
+                                        a->path = strdup(path);
+                                        if (!a->path) {
+                                                free(a);
+                                                return -ENOMEM;
+                                        }
+                                        LIST_PREPEND(device_latencies, c->io_device_latencies, a);
+                                }
+
+                                a->target_usec = target;
+                        }
+
+                        n++;
+                }
+
+                r = sd_bus_message_exit_container(message);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        _cleanup_free_ char *buf = NULL;
+                        _cleanup_fclose_ FILE *f = NULL;
+                        char ts[FORMAT_TIMESPAN_MAX];
+                        CGroupIODeviceLatency *a;
+                        size_t size = 0;
+
+                        if (n == 0) {
+                                while (c->io_device_latencies)
+                                        cgroup_context_free_io_device_latency(c, c->io_device_latencies);
+                        }
+
+                        unit_invalidate_cgroup(u, CGROUP_MASK_IO);
+
+                        f = open_memstream(&buf, &size);
+                        if (!f)
+                                return -ENOMEM;
+
+                        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+
+                        fputs("IODeviceLatencyTargetSec=\n", f);
+                        LIST_FOREACH(device_latencies, a, c->io_device_latencies)
+                                fprintf(f, "IODeviceLatencyTargetSec=%s %s\n",
+                                        a->path, format_timespan(ts, sizeof(ts), a->target_usec, 1));
+
+                        r = fflush_and_check(f);
+                        if (r < 0)
+                                return r;
+                        unit_write_setting(u, flags, name, buf);
+                }
+
+                return 1;
+
         } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
                 const char *path;
                 bool read = true;