diff options
author | Daniel Mack <daniel@zonque.org> | 2015-01-15 20:08:42 +0100 |
---|---|---|
committer | Daniel Mack <daniel@zonque.org> | 2015-09-16 00:21:55 +0200 |
commit | 32ee7d3309816994a02b3ff000e9734120d71214 (patch) | |
tree | 1c36747a33ddbeac78e72ea1fdafd807afbc98a7 /src/core/unit.c | |
parent | 0d9f6d4f615077a948af220e18d1b257ab466ba6 (diff) |
cgroup: add support for net_cls controllers
Add a new config directive called NetClass= to CGroup enabled units.
Allowed values are positive numbers for fix assignments and "auto" for
picking a free value automatically, for which we need to keep track of
dynamically assigned net class IDs of units. Introduce a hash table for
this, and also record the last ID that was given out, so the allocator
can start its search for the next 'hole' from there. This could
eventually be optimized with something like an irb.
The class IDs up to 65536 are considered reserved and won't be
assigned automatically by systemd. This barrier can be made a config
directive in the future.
Values set in unit files are stored in the CGroupContext of the
unit and considered read-only. The actually assigned number (which
may have been chosen dynamically) is stored in the unit itself and
is guaranteed to remain stable as long as the unit is active.
In the CGroup controller, set the configured CGroup net class to
net_cls.classid. Multiple unit may share the same net class ID,
and those which do are linked together.
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index 3bfc2460bc..3356b97522 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -452,6 +452,7 @@ static void unit_free_requires_mounts_for(Unit *u) { static void unit_done(Unit *u) { ExecContext *ec; CGroupContext *cc; + int r; assert(u); @@ -468,6 +469,10 @@ static void unit_done(Unit *u) { cc = unit_get_cgroup_context(u); if (cc) cgroup_context_done(cc); + + r = unit_remove_from_netclass_cgroup(u); + if (r < 0) + log_warning_errno(r, "Unable to remove unit from netclass group: %m"); } void unit_free(Unit *u) { @@ -1241,6 +1246,14 @@ int unit_load(Unit *u) { } unit_update_cgroup_members_masks(u); + + /* If we are reloading, we need to wait for the deserializer + * to restore the net_cls ids that have been set previously */ + if (u->manager->n_reloading <= 0) { + r = unit_add_to_netclass_cgroup(u); + if (r < 0) + return r; + } } assert((u->load_state != UNIT_MERGED) == !u->merged_into); @@ -2591,6 +2604,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { unit_serialize_item(u, f, "cgroup", u->cgroup_path); unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized)); + if (u->cgroup_netclass_id) + unit_serialize_item_format(u, f, "netclass-id", "%" PRIu32, u->cgroup_netclass_id); + if (serialize_jobs) { if (u->job) { fprintf(f, "job\n"); @@ -2778,6 +2794,17 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { u->cgroup_realized = b; continue; + } else if (streq(l, "netclass-id")) { + r = safe_atou32(v, &u->cgroup_netclass_id); + if (r < 0) + log_unit_debug(u, "Failed to parse netclass ID %s, ignoring.", v); + else { + r = unit_add_to_netclass_cgroup(u); + if (r < 0) + log_unit_debug_errno(u, r, "Failed to add unit to netclass cgroup, ignoring: %m"); + } + + continue; } if (unit_can_serialize(u)) { |