cgroup.c revision e41969e3d1a8bda8b0b2f7eb012cef1c8835509a
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek This file is part of systemd.
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek Copyright 2013 Lennart Poettering
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek (at your option) any later version.
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_init(CGroupContext *c) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering /* Initialize everything to the kernel defaults, assuming the
613b411c947635136637f8cdd66b94512f761eabLennart Poettering * structure is preinitialized to 0 */
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering LIST_REMOVE(device_allow, c->device_allow, a);
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering LIST_REMOVE(device_weights, c->blockio_device_weights, w);
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering LIST_REMOVE(device_bandwidths, c->blockio_device_bandwidths, b);
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_done(CGroupContext *c) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
613b411c947635136637f8cdd66b94512f761eabLennart Poettering cgroup_context_free_blockio_device_bandwidth(c, c->blockio_device_bandwidths);
613b411c947635136637f8cdd66b94512f761eabLennart Poettering cgroup_context_free_device_allow(c, c->device_allow);
613b411c947635136637f8cdd66b94512f761eabLennart Poetteringvoid cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sCPUAccounting=%s\n"
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sBlockIOAccounting=%s\n"
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sMemoryAccounting=%s\n"
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sCPUShares=%lu\n"
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sBlockIOWeight=%lu\n"
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sDevicePolicy=%s\n",
613b411c947635136637f8cdd66b94512f761eabLennart Poettering prefix, cgroup_device_policy_to_string(c->device_policy));
613b411c947635136637f8cdd66b94512f761eabLennart Poettering LIST_FOREACH(device_allow, a, c->device_allow)
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sDeviceAllow=%s %s%s%s\n",
613b411c947635136637f8cdd66b94512f761eabLennart Poettering a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
613b411c947635136637f8cdd66b94512f761eabLennart Poettering LIST_FOREACH(device_weights, w, c->blockio_device_weights)
613b411c947635136637f8cdd66b94512f761eabLennart Poettering "%sBlockIODeviceWeight=%s %lu",
d8c9d3a468e61ee2a2b2c3454e662398b0885411Zbigniew Jędrzejewski-Szmek LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
6b46ea73e3b1d8a1e65f58ac04772821bd4a72fbLennart Poettering b->read ? "BlockIOReadBandwidth" : "BlockIOWriteBandwidth",
6b46ea73e3b1d8a1e65f58ac04772821bd4a72fbLennart Poettering format_bytes(buf, sizeof(buf), b->bandwidth));
6b46ea73e3b1d8a1e65f58ac04772821bd4a72fbLennart Poetteringstatic int lookup_blkio_device(const char *p, dev_t *dev) {
613b411c947635136637f8cdd66b94512f761eabLennart Poettering log_warning("Couldn't stat device %s: %m", p);
log_warning("%s is not a block device and file system block device cannot be determined or is not local.", p);
return -ENODEV;
return -errno;
return -ENODEV;
acc);
bool good = false;
return -errno;
unsigned maj;
good = true;
good = true;
good = false;
if (!good)
if (maj <= 0)
type,
maj,
acc);
fail:
return -errno;
bool is_root;
assert(c);
if (mask == 0)
if (!is_root) {
static const char auto_devices[] =
acc[k++] = 0;
if (c->blockio_accounting ||
c->blockio_device_weights ||
if (c->memory_accounting ||
return mask;
CGroupContext *c;
c = unit_get_cgroup_context(u);
return cgroup_context_get_mask(c);
assert(u);
if (u->cgroup_members_mask_valid)
return u->cgroup_members_mask;
u->cgroup_members_mask = 0;
Iterator i;
if (member == u)
u->cgroup_members_mask |=
u->cgroup_members_mask_valid = true;
return u->cgroup_members_mask;
assert(u);
return mask;
bool more;
assert(u);
more =
((m & ~u->cgroup_subtree_mask) != 0) &&
((~m & u->cgroup_subtree_mask) == 0);
u->cgroup_subtree_mask = m;
u->cgroup_subtree_mask_valid = true;
if (more)
s->cgroup_members_mask |= m;
s->cgroup_members_mask_valid = false;
assert(u);
if (u->cgroup_path &&
u->cgroup_realized &&
return u->cgroup_path;
return NULL;
assert(u);
if (!path)
return log_oom();
log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
u->cgroup_realized = true;
r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, u->cgroup_path, migrate_callback, u);
assert(u);
assert(u);
if (u->in_cgroup_queue) {
u->in_cgroup_queue = false;
if (u->in_cgroup_queue)
u->in_cgroup_queue = true;
Unit *i;
while ((i = m->cgroup_queue)) {
r = unit_realize_cgroup_now(i);
Iterator i;
Unit *m;
u = slice;
CGroupContext *c;
assert(u);
c = unit_get_cgroup_context(u);
return unit_realize_cgroup_now(u);
assert(u);
if (!u->cgroup_path)
r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
u->cgroup_realized = false;
u->cgroup_realized_mask = 0;
assert(u);
if (!u->cgroup_path)
if (pid != 0) {
pid = 0;
return pid;
assert(m);
/* LEGACY: Already in /system.slice? If so, let's cut this
m->cgroup_root[0] = 0;
log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
if (m->pin_cgroupfs_fd >= 0)
return -errno;
assert(m);
if (m->pin_cgroupfs_fd >= 0) {
Unit *u;
assert(m);
return NULL;
assert(m);
return NULL;
return NULL;
Unit *u;
assert(m);