cgroup-semantics.c revision 26d04f86a36595e3565c74d67863e076c3e3c773
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2013 Lennart Poettering
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"
unsigned long ul;
assert(s);
return -EINVAL;
return -ENOMEM;
return 1;
}
assert(s);
return -EINVAL;
return -ENOMEM;
return 1;
}
_cleanup_strv_free_ char **l = NULL;
char *x;
unsigned k;
assert(s);
l = strv_split_quoted(value);
if (!l)
return -ENOMEM;
k = strv_length(l);
if (k < 1 || k > 2)
return -EINVAL;
return -EINVAL;
return -EINVAL;
if (!x)
return -ENOMEM;
*ret = x;
return 1;
}
_cleanup_strv_free_ char **l = NULL;
unsigned long ul;
assert(s);
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 */
return -EINVAL;
return -ENOMEM;
return 1;
}
_cleanup_strv_free_ char **l = NULL;
unsigned long ul;
assert(s);
l = strv_split_quoted(value);
if (!l)
return -ENOMEM;
if (strv_length(l) != 2)
return -EINVAL;
if (!path_startswith(l[0], "/dev"))
return -EINVAL;
return -EINVAL;
return -ENOMEM;
return 1;
}
_cleanup_strv_free_ char **l = NULL;
assert(s);
l = strv_split_quoted(value);
if (!l)
return -ENOMEM;
if (strv_length(l) != 2)
return -EINVAL;
if (!path_startswith(l[0], "/dev")) {
return -EINVAL;
}
return -EINVAL;
return -ENOMEM;
return 0;
}
_cleanup_strv_free_ char **l = NULL;
unsigned k;
assert(s);
l = strv_split_quoted(value);
if (!l)
return -ENOMEM;
k = strv_length(l);
if (k < 1 || k > 2)
return -EINVAL;
if (streq(l[0], "*")) {
return -ENOMEM;
} else {
log_warning("Couldn't stat device %s", l[0]);
return -errno;
}
log_warning("%s is not a device.", l[0]);
return -ENODEV;
}
return -ENOMEM;
}
return 0;
}
_cleanup_strv_free_ char **l = NULL;
dev_t d;
assert(s);
l = strv_split_quoted(value);
if (!l)
return log_oom();
if (strv_length(l) != 2)
return -EINVAL;
log_warning("Couldn't stat device %s", l[0]);
return -errno;
}
/* If this is not a device node then find the block
* device this file is stored on */
/* 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;
}
return -ENOMEM;
return 0;
}
static const CGroupSemantics semantics[] = {
{ "memory", "memory.soft_limit_in_bytes", "MemorySoftLimit", false, parse_memory_limit, 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 }
};
const char *controller,
const char *name,
const char *value,
char **ret,
const CGroupSemantics **_s) {
_cleanup_free_ char *c = NULL;
unsigned i;
int r;
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;
continue;
if (!matches_name && !matches_pretty)
continue;
if (value) {
if (matches_pretty && s->map_pretty) {
if (r < 0)
return r;
if (r == 0)
continue;
} else {
char *x;
if (!x)
return -ENOMEM;
*ret = x;
}
}
*_s = s;
return 1;
}
return 0;
}