chiark / gitweb /
blkio bandwidth: don't clean up all of entries in blockio_device_bandwidths list
[elogind.git] / src / core / load-fragment.c
index 2b10d72ab331893ed07e19de08290eafa6b54f8e..f4a268c1ef0d58a178a6f6c86fb0e01f7c5d71f8 100644 (file)
@@ -2094,7 +2094,44 @@ int config_parse_blockio_weight(
                 void *data,
                 void *userdata) {
 
+        CGroupContext *c = data;
+        unsigned long lu;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                c->blockio_weight = 1000;
+                return 0;
+        }
+
+        r = safe_atolu(rvalue, &lu);
+        if (r < 0 || lu < 10 || lu > 1000) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Block IO weight '%s' invalid. Ignoring.", rvalue);
+                return 0;
+        }
+
+        c->blockio_weight = lu;
+
+        return 0;
+}
+
+int config_parse_blockio_device_weight(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
         _cleanup_free_ char *path = NULL;
+        CGroupBlockIODeviceWeight *w;
         CGroupContext *c = data;
         unsigned long lu;
         const char *weight;
@@ -2106,8 +2143,6 @@ int config_parse_blockio_weight(
         assert(rvalue);
 
         if (isempty(rvalue)) {
-                c->blockio_weight = 1000;
-
                 while (c->blockio_device_weights)
                         cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
 
@@ -2116,23 +2151,23 @@ int config_parse_blockio_weight(
 
         n = strcspn(rvalue, WHITESPACE);
         weight = rvalue + n;
-        if (*weight) {
-                /* Two params, first device name, then weight */
-                path = strndup(rvalue, n);
-                if (!path)
-                        return log_oom();
+        if (!*weight) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Expected block device and device weight. Ignoring.");
+                return 0;
+        }
 
-                if (!path_startswith(path, "/dev")) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Invalid device node path '%s'. Ignoring.", path);
-                        return 0;
-                }
+        path = strndup(rvalue, n);
+        if (!path)
+                return log_oom();
 
-                weight += strspn(weight, WHITESPACE);
-        } else
-                /* One param, only weight */
-                weight = rvalue;
+        if (!path_startswith(path, "/dev")) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid device node path '%s'. Ignoring.", path);
+                return 0;
+        }
 
+        weight += strspn(weight, WHITESPACE);
         r = safe_atolu(weight, &lu);
         if (r < 0 || lu < 10 || lu > 1000) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
@@ -2140,23 +2175,17 @@ int config_parse_blockio_weight(
                 return 0;
         }
 
-        if (!path)
-                c->blockio_weight = lu;
-        else {
-                CGroupBlockIODeviceWeight *w;
 
-                w = new0(CGroupBlockIODeviceWeight, 1);
-                if (!w)
-                        return log_oom();
+        w = new0(CGroupBlockIODeviceWeight, 1);
+        if (!w)
+                return log_oom();
 
-                w->path = path;
-                path = NULL;
+        w->path = path;
+        path = NULL;
 
-                w->weight = lu;
-
-                LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w);
-        }
+        w->weight = lu;
 
+        LIST_PREPEND(CGroupBlockIODeviceWeight, device_weights, c->blockio_device_weights, w);
         return 0;
 }
 
@@ -2176,6 +2205,7 @@ int config_parse_blockio_bandwidth(
         CGroupContext *c = data;
         const char *bandwidth;
         off_t bytes;
+        bool read;
         size_t n;
         int r;
 
@@ -2183,9 +2213,14 @@ int config_parse_blockio_bandwidth(
         assert(lvalue);
         assert(rvalue);
 
+        read = streq("BlockIOReadBandwidth", lvalue);
+
         if (isempty(rvalue)) {
-                while (c->blockio_device_bandwidths)
-                        cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths);
+                CGroupBlockIODeviceBandwidth *next;
+
+                LIST_FOREACH_SAFE (device_bandwidths, b, next, c->blockio_device_bandwidths)
+                        if (b->read == read)
+                                cgroup_context_free_blockio_device_bandwidth(c, b);
 
                 return 0;
         }
@@ -2224,6 +2259,7 @@ int config_parse_blockio_bandwidth(
         b->path = path;
         path = NULL;
         b->bandwidth = (uint64_t) bytes;
+        b->read = read;
 
         LIST_PREPEND(CGroupBlockIODeviceBandwidth, device_bandwidths, c->blockio_device_bandwidths, b);
 
@@ -2618,6 +2654,23 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_condition_string, "CONDITION" },
                 { config_parse_unit_condition_null,   "CONDITION" },
                 { config_parse_unit_slice,            "SLICE" },
+                { config_parse_documentation,         "URL" },
+                { config_parse_service_timeout,       "SECONDS" },
+                { config_parse_start_limit_action,    "ACTION" },
+                { config_parse_set_status,            "STATUS" },
+                { config_parse_service_sockets,       "SOCKETS" },
+                { config_parse_fsck_passno,           "PASSNO" },
+                { config_parse_environ,               "ENVIRON" },
+                { config_parse_syscall_filter,        "SYSCALL" },
+                { config_parse_cpu_shares,            "SHARES" },
+                { config_parse_memory_limit,          "LIMIT" },
+                { config_parse_device_allow,          "DEVICE" },
+                { config_parse_device_policy,         "POLICY" },
+                { config_parse_blockio_bandwidth,     "BANDWIDTH" },
+                { config_parse_blockio_weight,        "WEIGHT" },
+                { config_parse_blockio_device_weight, "DEVICEWEIGHT" },
+                { config_parse_long,                  "LONG" },
+                { config_parse_socket_service,        "SERVICE" },
         };
 
         const char *prev = NULL;