diff options
Diffstat (limited to 'src/core/cgroup-semantics.c')
-rw-r--r-- | src/core/cgroup-semantics.c | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/src/core/cgroup-semantics.c b/src/core/cgroup-semantics.c deleted file mode 100644 index 7df9d014e9..0000000000 --- a/src/core/cgroup-semantics.c +++ /dev/null @@ -1,333 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "util.h" -#include "strv.h" -#include "path-util.h" -#include "cgroup-util.h" - -#include "cgroup-semantics.h" - -static int parse_cpu_shares(const CGroupSemantics *s, const char *value, char **ret) { - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - if (safe_atolu(value, &ul) < 0 || ul < 1) - return -EINVAL; - - if (asprintf(ret, "%lu", ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_memory_limit(const CGroupSemantics *s, const char *value, char **ret) { - off_t sz; - - assert(s); - assert(value); - assert(ret); - - if (parse_bytes(value, &sz) < 0 || sz <= 0) - return -EINVAL; - - if (asprintf(ret, "%llu", (unsigned long long) sz) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - char *x; - unsigned k; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - k = strv_length(l); - if (k < 1 || k > 2) - return -EINVAL; - - if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) - return -EINVAL; - - if (!isempty(l[1]) && !in_charset(l[1], "rwm")) - return -EINVAL; - - x = strdup(value); - if (!x) - return -ENOMEM; - - *ret = x; - return 1; -} - -static int parse_blkio_weight(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 1) - return 0; /* Returning 0 will cause parse_blkio_weight_device() be tried instead */ - - if (safe_atolu(l[0], &ul) < 0 || ul < 10 || ul > 1000) - return -EINVAL; - - if (asprintf(ret, "%lu", ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_blkio_weight_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned long ul; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 2) - return -EINVAL; - - if (!path_startswith(l[0], "/dev")) - return -EINVAL; - - if (safe_atolu(l[1], &ul) < 0 || ul < 10 || ul > 1000) - return -EINVAL; - - if (asprintf(ret, "%s %lu", l[0], ul) < 0) - return -ENOMEM; - - return 1; -} - -static int parse_blkio_bandwidth(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - off_t bytes; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - if (strv_length(l) != 2) - return -EINVAL; - - if (!path_startswith(l[0], "/dev")) { - return -EINVAL; - } - - if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) - return -EINVAL; - - if (asprintf(ret, "%s %llu", l[0], (unsigned long long) bytes) < 0) - return -ENOMEM; - - return 0; -} - -static int map_device(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - unsigned k; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return -ENOMEM; - - k = strv_length(l); - if (k < 1 || k > 2) - return -EINVAL; - - if (streq(l[0], "*")) { - - if (asprintf(ret, "a *:*%s%s", - isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) - return -ENOMEM; - } else { - struct stat st; - - if (stat(l[0], &st) < 0) { - log_warning("Couldn't stat device %s", l[0]); - return -errno; - } - - if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { - log_warning("%s is not a device.", l[0]); - return -ENODEV; - } - - if (asprintf(ret, "%c %u:%u%s%s", - S_ISCHR(st.st_mode) ? 'c' : 'b', - major(st.st_rdev), minor(st.st_rdev), - isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) - return -ENOMEM; - } - - return 0; -} - -static int map_blkio(const CGroupSemantics *s, const char *value, char **ret) { - _cleanup_strv_free_ char **l = NULL; - struct stat st; - dev_t d; - - assert(s); - assert(value); - assert(ret); - - l = strv_split_quoted(value); - if (!l) - return log_oom(); - - if (strv_length(l) != 2) - return -EINVAL; - - if (stat(l[0], &st) < 0) { - log_warning("Couldn't stat device %s", l[0]); - return -errno; - } - - if (S_ISBLK(st.st_mode)) - d = st.st_rdev; - else if (major(st.st_dev) != 0) { - /* If this is not a device node then find the block - * device this file is stored on */ - d = st.st_dev; - - /* If this is a partition, try to get the originating - * block device */ - block_get_whole_disk(d, &d); - } else { - log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]); - return -ENODEV; - } - - if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) - return -ENOMEM; - - return 0; -} - -static const CGroupSemantics semantics[] = { - { "cpu", "cpu.shares", "CPUShares", false, parse_cpu_shares, NULL, NULL }, - { "memory", "memory.soft_limit_in_bytes", "MemorySoftLimit", false, parse_memory_limit, NULL, NULL }, - { "memory", "memory.limit_in_bytes", "MemoryLimit", false, parse_memory_limit, NULL, NULL }, - { "devices", "devices.allow", "DeviceAllow", true, parse_device, map_device, NULL }, - { "devices", "devices.deny", "DeviceDeny", true, parse_device, map_device, NULL }, - { "blkio", "blkio.weight", "BlockIOWeight", false, parse_blkio_weight, NULL, NULL }, - { "blkio", "blkio.weight_device", "BlockIOWeight", true, parse_blkio_weight_device, map_blkio, NULL }, - { "blkio", "blkio.read_bps_device", "BlockIOReadBandwidth", true, parse_blkio_bandwidth, map_blkio, NULL }, - { "blkio", "blkio.write_bps_device", "BlockIOWriteBandwidth", true, parse_blkio_bandwidth, map_blkio, NULL } -}; - -int cgroup_semantics_find( - const char *controller, - const char *name, - const char *value, - char **ret, - const CGroupSemantics **_s) { - - _cleanup_free_ char *c = NULL; - unsigned i; - int r; - - assert(name); - assert(_s); - assert(!value == !ret); - - if (!controller) { - r = cg_controller_from_attr(name, &c); - if (r < 0) - return r; - - controller = c; - } - - for (i = 0; i < ELEMENTSOF(semantics); i++) { - const CGroupSemantics *s = semantics + i; - bool matches_name, matches_pretty; - - if (controller && s->controller && !streq(s->controller, controller)) - continue; - - matches_name = s->name && streq(s->name, name); - matches_pretty = s->pretty && streq(s->pretty, name); - - if (!matches_name && !matches_pretty) - continue; - - if (value) { - if (matches_pretty && s->map_pretty) { - - r = s->map_pretty(s, value, ret); - if (r < 0) - return r; - - if (r == 0) - continue; - - } else { - char *x; - - x = strdup(value); - if (!x) - return -ENOMEM; - - *ret = x; - } - } - - *_s = s; - return 1; - } - - *ret = NULL; - *_s = NULL; - return 0; -} |