cgroup, unit, fragment parser: make use of new firewall functions
This commit is contained in:
committed by
Lennart Poettering
parent
1988a9d120
commit
906c06f64a
+171
-19
@@ -21,6 +21,7 @@
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bpf-firewall.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "cgroup.h"
|
||||
#include "fd-util.h"
|
||||
@@ -30,9 +31,9 @@
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "special.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "stdio-util.h"
|
||||
|
||||
#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
|
||||
|
||||
@@ -648,7 +649,27 @@ static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_
|
||||
"Failed to set %s: %m", file);
|
||||
}
|
||||
|
||||
static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
static void cgroup_apply_firewall(Unit *u, CGroupContext *c) {
|
||||
int r;
|
||||
|
||||
if (u->type == UNIT_SLICE) /* Skip this for slice units, they are inner cgroup nodes, and since bpf/cgroup is
|
||||
* not recursive we don't ever touch the bpf on them */
|
||||
return;
|
||||
|
||||
r = bpf_firewall_compile(u);
|
||||
if (r < 0)
|
||||
return;
|
||||
|
||||
(void) bpf_firewall_install(u);
|
||||
return;
|
||||
}
|
||||
|
||||
static void cgroup_context_apply(
|
||||
Unit *u,
|
||||
CGroupMask apply_mask,
|
||||
bool apply_bpf,
|
||||
ManagerState state) {
|
||||
|
||||
const char *path;
|
||||
CGroupContext *c;
|
||||
bool is_root;
|
||||
@@ -662,7 +683,8 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
assert(c);
|
||||
assert(path);
|
||||
|
||||
if (mask == 0)
|
||||
/* Nothing to do? Exit early! */
|
||||
if (apply_mask == 0 && !apply_bpf)
|
||||
return;
|
||||
|
||||
/* Some cgroup attributes are not supported on the root cgroup,
|
||||
@@ -676,9 +698,11 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
* cgroup trees (assuming we are running in a container then),
|
||||
* and missing cgroups, i.e. EROFS and ENOENT. */
|
||||
|
||||
if ((mask & CGROUP_MASK_CPU) && !is_root) {
|
||||
bool has_weight = cgroup_context_has_cpu_weight(c);
|
||||
bool has_shares = cgroup_context_has_cpu_shares(c);
|
||||
if ((apply_mask & CGROUP_MASK_CPU) && !is_root) {
|
||||
bool has_weight, has_shares;
|
||||
|
||||
has_weight = cgroup_context_has_cpu_weight(c);
|
||||
has_shares = cgroup_context_has_cpu_shares(c);
|
||||
|
||||
if (cg_all_unified() > 0) {
|
||||
uint64_t weight;
|
||||
@@ -715,7 +739,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & CGROUP_MASK_IO) {
|
||||
if (apply_mask & CGROUP_MASK_IO) {
|
||||
bool has_io = cgroup_context_has_io_config(c);
|
||||
bool has_blockio = cgroup_context_has_blockio_config(c);
|
||||
|
||||
@@ -792,7 +816,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & CGROUP_MASK_BLKIO) {
|
||||
if (apply_mask & CGROUP_MASK_BLKIO) {
|
||||
bool has_io = cgroup_context_has_io_config(c);
|
||||
bool has_blockio = cgroup_context_has_blockio_config(c);
|
||||
|
||||
@@ -859,7 +883,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((mask & CGROUP_MASK_MEMORY) && !is_root) {
|
||||
if ((apply_mask & CGROUP_MASK_MEMORY) && !is_root) {
|
||||
if (cg_all_unified() > 0) {
|
||||
uint64_t max, swap_max = CGROUP_LIMIT_MAX;
|
||||
|
||||
@@ -899,7 +923,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((mask & CGROUP_MASK_DEVICES) && !is_root) {
|
||||
if ((apply_mask & CGROUP_MASK_DEVICES) && !is_root) {
|
||||
CGroupDeviceAllow *a;
|
||||
|
||||
/* Changing the devices list of a populated cgroup
|
||||
@@ -963,7 +987,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((mask & CGROUP_MASK_PIDS) && !is_root) {
|
||||
if ((apply_mask & CGROUP_MASK_PIDS) && !is_root) {
|
||||
|
||||
if (c->tasks_max != CGROUP_LIMIT_MAX) {
|
||||
char buf[DECIMAL_STR_MAX(uint64_t) + 2];
|
||||
@@ -977,6 +1001,9 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
|
||||
log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to set pids.max: %m");
|
||||
}
|
||||
|
||||
if (apply_bpf)
|
||||
cgroup_apply_firewall(u, c);
|
||||
}
|
||||
|
||||
CGroupMask cgroup_context_get_mask(CGroupContext *c) {
|
||||
@@ -1123,6 +1150,39 @@ CGroupMask unit_get_enable_mask(Unit *u) {
|
||||
return mask;
|
||||
}
|
||||
|
||||
bool unit_get_needs_bpf(Unit *u) {
|
||||
CGroupContext *c;
|
||||
Unit *p;
|
||||
assert(u);
|
||||
|
||||
/* We never attach BPF to slice units, as they are inner cgroup nodes and cgroup/BPF is not recursive at the
|
||||
* moment. */
|
||||
if (u->type == UNIT_SLICE)
|
||||
return false;
|
||||
|
||||
c = unit_get_cgroup_context(u);
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
if (c->ip_accounting ||
|
||||
c->ip_address_allow ||
|
||||
c->ip_address_deny)
|
||||
return true;
|
||||
|
||||
/* If any parent slice has an IP access list defined, it applies too */
|
||||
for (p = UNIT_DEREF(u->slice); p; p = UNIT_DEREF(p->slice)) {
|
||||
c = unit_get_cgroup_context(p);
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
if (c->ip_address_allow ||
|
||||
c->ip_address_deny)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Recurse from a unit up through its containing slices, propagating
|
||||
* mask bits upward. A unit is also member of itself. */
|
||||
void unit_update_cgroup_members_masks(Unit *u) {
|
||||
@@ -1298,7 +1358,8 @@ int unit_watch_cgroup(Unit *u) {
|
||||
static int unit_create_cgroup(
|
||||
Unit *u,
|
||||
CGroupMask target_mask,
|
||||
CGroupMask enable_mask) {
|
||||
CGroupMask enable_mask,
|
||||
bool needs_bpf) {
|
||||
|
||||
CGroupContext *c;
|
||||
int r;
|
||||
@@ -1340,6 +1401,7 @@ static int unit_create_cgroup(
|
||||
u->cgroup_realized = true;
|
||||
u->cgroup_realized_mask = target_mask;
|
||||
u->cgroup_enabled_mask = enable_mask;
|
||||
u->cgroup_bpf_state = needs_bpf ? UNIT_CGROUP_BPF_ON : UNIT_CGROUP_BPF_OFF;
|
||||
|
||||
if (u->type != UNIT_SLICE && !c->delegate) {
|
||||
|
||||
@@ -1389,10 +1451,19 @@ static void cgroup_xattr_apply(Unit *u) {
|
||||
log_unit_warning_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path);
|
||||
}
|
||||
|
||||
static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask, CGroupMask enable_mask) {
|
||||
static bool unit_has_mask_realized(
|
||||
Unit *u,
|
||||
CGroupMask target_mask,
|
||||
CGroupMask enable_mask,
|
||||
bool needs_bpf) {
|
||||
|
||||
assert(u);
|
||||
|
||||
return u->cgroup_realized && u->cgroup_realized_mask == target_mask && u->cgroup_enabled_mask == enable_mask;
|
||||
return u->cgroup_realized &&
|
||||
u->cgroup_realized_mask == target_mask &&
|
||||
u->cgroup_enabled_mask == enable_mask &&
|
||||
((needs_bpf && u->cgroup_bpf_state == UNIT_CGROUP_BPF_ON) ||
|
||||
(!needs_bpf && u->cgroup_bpf_state == UNIT_CGROUP_BPF_OFF));
|
||||
}
|
||||
|
||||
/* Check if necessary controllers and attributes for a unit are in place.
|
||||
@@ -1403,6 +1474,7 @@ static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask, CGroupMask e
|
||||
* Returns 0 on success and < 0 on failure. */
|
||||
static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
|
||||
CGroupMask target_mask, enable_mask;
|
||||
bool needs_bpf, apply_bpf;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
@@ -1414,10 +1486,16 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
|
||||
|
||||
target_mask = unit_get_target_mask(u);
|
||||
enable_mask = unit_get_enable_mask(u);
|
||||
needs_bpf = unit_get_needs_bpf(u);
|
||||
|
||||
if (unit_has_mask_realized(u, target_mask, enable_mask))
|
||||
if (unit_has_mask_realized(u, target_mask, enable_mask, needs_bpf))
|
||||
return 0;
|
||||
|
||||
/* Make sure we apply the BPF filters either when one is configured, or if none is configured but previously
|
||||
* the state was anything but off. This way, if a unit with a BPF filter applied is reconfigured to lose it
|
||||
* this will trickle down properly to cgroupfs. */
|
||||
apply_bpf = needs_bpf || u->cgroup_bpf_state != UNIT_CGROUP_BPF_OFF;
|
||||
|
||||
/* First, realize parents */
|
||||
if (UNIT_ISSET(u->slice)) {
|
||||
r = unit_realize_cgroup_now(UNIT_DEREF(u->slice), state);
|
||||
@@ -1426,12 +1504,12 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
|
||||
}
|
||||
|
||||
/* And then do the real work */
|
||||
r = unit_create_cgroup(u, target_mask, enable_mask);
|
||||
r = unit_create_cgroup(u, target_mask, enable_mask, needs_bpf);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Finally, apply the necessary attributes. */
|
||||
cgroup_context_apply(u, target_mask, state);
|
||||
cgroup_context_apply(u, target_mask, apply_bpf, state);
|
||||
cgroup_xattr_apply(u);
|
||||
|
||||
return 0;
|
||||
@@ -1495,7 +1573,10 @@ static void unit_queue_siblings(Unit *u) {
|
||||
/* If the unit doesn't need any new controllers
|
||||
* and has current ones realized, it doesn't need
|
||||
* any changes. */
|
||||
if (unit_has_mask_realized(m, unit_get_target_mask(m), unit_get_enable_mask(m)))
|
||||
if (unit_has_mask_realized(m,
|
||||
unit_get_target_mask(m),
|
||||
unit_get_enable_mask(m),
|
||||
unit_get_needs_bpf(m)))
|
||||
continue;
|
||||
|
||||
unit_add_to_cgroup_queue(m);
|
||||
@@ -2121,7 +2202,34 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unit_reset_cpu_usage(Unit *u) {
|
||||
int unit_get_ip_accounting(
|
||||
Unit *u,
|
||||
CGroupIPAccountingMetric metric,
|
||||
uint64_t *ret) {
|
||||
|
||||
int fd, r;
|
||||
|
||||
assert(u);
|
||||
assert(metric >= 0);
|
||||
assert(metric < _CGROUP_IP_ACCOUNTING_METRIC_MAX);
|
||||
assert(ret);
|
||||
|
||||
fd = IN_SET(metric, CGROUP_IP_INGRESS_BYTES, CGROUP_IP_INGRESS_PACKETS) ?
|
||||
u->ip_accounting_ingress_map_fd :
|
||||
u->ip_accounting_egress_map_fd;
|
||||
|
||||
if (fd < 0)
|
||||
return -ENODATA;
|
||||
|
||||
if (IN_SET(metric, CGROUP_IP_INGRESS_BYTES, CGROUP_IP_EGRESS_BYTES))
|
||||
r = bpf_firewall_read_accounting(fd, ret, NULL);
|
||||
else
|
||||
r = bpf_firewall_read_accounting(fd, NULL, ret);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unit_reset_cpu_accounting(Unit *u) {
|
||||
nsec_t ns;
|
||||
int r;
|
||||
|
||||
@@ -2139,6 +2247,20 @@ int unit_reset_cpu_usage(Unit *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unit_reset_ip_accounting(Unit *u) {
|
||||
int r = 0, q = 0;
|
||||
|
||||
assert(u);
|
||||
|
||||
if (u->ip_accounting_ingress_map_fd >= 0)
|
||||
r = bpf_firewall_reset_accounting(u->ip_accounting_ingress_map_fd);
|
||||
|
||||
if (u->ip_accounting_egress_map_fd >= 0)
|
||||
q = bpf_firewall_reset_accounting(u->ip_accounting_egress_map_fd);
|
||||
|
||||
return r < 0 ? r : q;
|
||||
}
|
||||
|
||||
bool unit_cgroup_delegate(Unit *u) {
|
||||
CGroupContext *c;
|
||||
|
||||
@@ -2174,6 +2296,36 @@ void unit_invalidate_cgroup(Unit *u, CGroupMask m) {
|
||||
unit_add_to_cgroup_queue(u);
|
||||
}
|
||||
|
||||
void unit_invalidate_cgroup_bpf(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
if (!UNIT_HAS_CGROUP_CONTEXT(u))
|
||||
return;
|
||||
|
||||
if (u->cgroup_bpf_state == UNIT_CGROUP_BPF_INVALIDATED)
|
||||
return;
|
||||
|
||||
u->cgroup_bpf_state = UNIT_CGROUP_BPF_INVALIDATED;
|
||||
unit_add_to_cgroup_queue(u);
|
||||
|
||||
/* If we are a slice unit, we also need to put compile a new BPF program for all our children, as the IP access
|
||||
* list of our children includes our own. */
|
||||
if (u->type == UNIT_SLICE) {
|
||||
Unit *member;
|
||||
Iterator i;
|
||||
|
||||
SET_FOREACH(member, u->dependencies[UNIT_BEFORE], i) {
|
||||
if (member == u)
|
||||
continue;
|
||||
|
||||
if (UNIT_DEREF(member->slice) != u)
|
||||
continue;
|
||||
|
||||
unit_invalidate_cgroup_bpf(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void manager_invalidate_startup_units(Manager *m) {
|
||||
Iterator i;
|
||||
Unit *u;
|
||||
|
||||
+17
-1
@@ -128,6 +128,16 @@ struct CGroupContext {
|
||||
bool delegate;
|
||||
};
|
||||
|
||||
/* Used when querying IP accounting data */
|
||||
typedef enum CGroupIPAccountingMetric {
|
||||
CGROUP_IP_INGRESS_BYTES,
|
||||
CGROUP_IP_INGRESS_PACKETS,
|
||||
CGROUP_IP_EGRESS_BYTES,
|
||||
CGROUP_IP_EGRESS_PACKETS,
|
||||
_CGROUP_IP_ACCOUNTING_METRIC_MAX,
|
||||
_CGROUP_IP_ACCOUNTING_METRIC_INVALID = -1,
|
||||
} CGroupIPAccountingMetric;
|
||||
|
||||
#include "unit.h"
|
||||
|
||||
void cgroup_context_init(CGroupContext *c);
|
||||
@@ -150,6 +160,8 @@ CGroupMask unit_get_subtree_mask(Unit *u);
|
||||
CGroupMask unit_get_target_mask(Unit *u);
|
||||
CGroupMask unit_get_enable_mask(Unit *u);
|
||||
|
||||
bool unit_get_needs_bpf(Unit *u);
|
||||
|
||||
void unit_update_cgroup_members_masks(Unit *u);
|
||||
|
||||
char *unit_default_cgroup_path(Unit *u);
|
||||
@@ -177,7 +189,10 @@ int unit_watch_all_pids(Unit *u);
|
||||
int unit_get_memory_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_tasks_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_cpu_usage(Unit *u, nsec_t *ret);
|
||||
int unit_reset_cpu_usage(Unit *u);
|
||||
int unit_get_ip_accounting(Unit *u, CGroupIPAccountingMetric metric, uint64_t *ret);
|
||||
|
||||
int unit_reset_cpu_accounting(Unit *u);
|
||||
int unit_reset_ip_accounting(Unit *u);
|
||||
|
||||
bool unit_cgroup_delegate(Unit *u);
|
||||
|
||||
@@ -185,6 +200,7 @@ int unit_notify_cgroup_empty(Unit *u);
|
||||
int manager_notify_cgroup_empty(Manager *m, const char *group);
|
||||
|
||||
void unit_invalidate_cgroup(Unit *u, CGroupMask m);
|
||||
void unit_invalidate_cgroup_bpf(Unit *u);
|
||||
|
||||
void manager_invalidate_startup_units(Manager *m);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bpf-firewall.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "dbus-job.h"
|
||||
@@ -1051,6 +1052,39 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu
|
||||
return sd_bus_send(NULL, reply, NULL);
|
||||
}
|
||||
|
||||
static int property_get_ip_counter(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
CGroupIPAccountingMetric metric;
|
||||
uint64_t value = (uint64_t) -1;
|
||||
Unit *u = userdata;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(property);
|
||||
assert(u);
|
||||
|
||||
if (streq(property, "IPIngressBytes"))
|
||||
metric = CGROUP_IP_INGRESS_BYTES;
|
||||
else if (streq(property, "IPIngressPackets"))
|
||||
metric = CGROUP_IP_INGRESS_PACKETS;
|
||||
else if (streq(property, "IPEgressBytes"))
|
||||
metric = CGROUP_IP_EGRESS_BYTES;
|
||||
else {
|
||||
assert(streq(property, "IPEgressPackets"));
|
||||
metric = CGROUP_IP_EGRESS_PACKETS;
|
||||
}
|
||||
|
||||
(void) unit_get_ip_accounting(u, metric, &value);
|
||||
return sd_bus_message_append(reply, "t", value);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_unit_cgroup_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
|
||||
@@ -1058,6 +1092,10 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
|
||||
SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
|
||||
SD_BUS_PROPERTY("IPIngressBytes", "t", property_get_ip_counter, 0, 0),
|
||||
SD_BUS_PROPERTY("IPIngressPackets", "t", property_get_ip_counter, 0, 0),
|
||||
SD_BUS_PROPERTY("IPEgressBytes", "t", property_get_ip_counter, 0, 0),
|
||||
SD_BUS_PROPERTY("IPEgressPackets", "t", property_get_ip_counter, 0, 0),
|
||||
SD_BUS_METHOD("GetProcesses", NULL, "a(sus)", bus_unit_method_get_processes, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
@@ -174,6 +174,9 @@ $1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0,
|
||||
$1.TasksAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.tasks_accounting)
|
||||
$1.TasksMax, config_parse_tasks_max, 0, offsetof($1, cgroup_context.tasks_max)
|
||||
$1.Delegate, config_parse_bool, 0, offsetof($1, cgroup_context.delegate)
|
||||
$1.IPAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.ip_accounting)
|
||||
$1.IPAddressAllow, config_parse_ip_address_access, 0, offsetof($1, cgroup_context.ip_address_allow)
|
||||
$1.IPAddressDeny, config_parse_ip_address_access, 0, offsetof($1, cgroup_context.ip_address_deny)
|
||||
$1.NetClass, config_parse_warn_compat, DISABLED_LEGACY, 0'
|
||||
)m4_dnl
|
||||
Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description)
|
||||
|
||||
+5
-4
@@ -754,9 +754,10 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
|
||||
assert(_pid);
|
||||
|
||||
(void) unit_realize_cgroup(UNIT(m));
|
||||
if (m->reset_cpu_usage) {
|
||||
(void) unit_reset_cpu_usage(UNIT(m));
|
||||
m->reset_cpu_usage = false;
|
||||
if (m->reset_accounting) {
|
||||
(void) unit_reset_cpu_accounting(UNIT(m));
|
||||
(void) unit_reset_ip_accounting(UNIT(m));
|
||||
m->reset_accounting = false;
|
||||
}
|
||||
|
||||
r = unit_setup_exec_runtime(UNIT(m));
|
||||
@@ -1044,7 +1045,7 @@ static int mount_start(Unit *u) {
|
||||
|
||||
m->result = MOUNT_SUCCESS;
|
||||
m->reload_result = MOUNT_SUCCESS;
|
||||
m->reset_cpu_usage = true;
|
||||
m->reset_accounting = true;
|
||||
|
||||
mount_enter_mounting(m);
|
||||
return 1;
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ struct Mount {
|
||||
bool just_mounted:1;
|
||||
bool just_changed:1;
|
||||
|
||||
bool reset_cpu_usage:1;
|
||||
bool reset_accounting:1;
|
||||
|
||||
bool sloppy_options;
|
||||
|
||||
|
||||
+2
-1
@@ -333,7 +333,8 @@ static int scope_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
(void) unit_realize_cgroup(u);
|
||||
(void) unit_reset_cpu_usage(u);
|
||||
(void) unit_reset_cpu_accounting(u);
|
||||
(void) unit_reset_ip_accounting(u);
|
||||
|
||||
r = unit_attach_pids_to_cgroup(u);
|
||||
if (r < 0) {
|
||||
|
||||
+5
-4
@@ -1244,9 +1244,10 @@ static int service_spawn(
|
||||
}
|
||||
|
||||
(void) unit_realize_cgroup(UNIT(s));
|
||||
if (s->reset_cpu_usage) {
|
||||
(void) unit_reset_cpu_usage(UNIT(s));
|
||||
s->reset_cpu_usage = false;
|
||||
if (s->reset_accounting) {
|
||||
(void) unit_reset_cpu_accounting(UNIT(s));
|
||||
(void) unit_reset_ip_accounting(UNIT(s));
|
||||
s->reset_accounting = false;
|
||||
}
|
||||
|
||||
r = unit_setup_exec_runtime(UNIT(s));
|
||||
@@ -2138,7 +2139,7 @@ static int service_start(Unit *u) {
|
||||
s->main_pid_known = false;
|
||||
s->main_pid_alien = false;
|
||||
s->forbid_restart = false;
|
||||
s->reset_cpu_usage = true;
|
||||
s->reset_accounting = true;
|
||||
|
||||
s->status_text = mfree(s->status_text);
|
||||
s->status_errno = 0;
|
||||
|
||||
+1
-1
@@ -165,7 +165,7 @@ struct Service {
|
||||
bool forbid_restart:1;
|
||||
bool start_timeout_defined:1;
|
||||
|
||||
bool reset_cpu_usage:1;
|
||||
bool reset_accounting:1;
|
||||
|
||||
char *bus_name;
|
||||
char *bus_name_owner; /* unique name of the current owner */
|
||||
|
||||
+2
-1
@@ -222,7 +222,8 @@ static int slice_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
(void) unit_realize_cgroup(u);
|
||||
(void) unit_reset_cpu_usage(u);
|
||||
(void) unit_reset_cpu_accounting(u);
|
||||
(void) unit_reset_ip_accounting(u);
|
||||
|
||||
slice_set_state(t, SLICE_ACTIVE);
|
||||
return 1;
|
||||
|
||||
+5
-4
@@ -1775,9 +1775,10 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
|
||||
assert(_pid);
|
||||
|
||||
(void) unit_realize_cgroup(UNIT(s));
|
||||
if (s->reset_cpu_usage) {
|
||||
(void) unit_reset_cpu_usage(UNIT(s));
|
||||
s->reset_cpu_usage = false;
|
||||
if (s->reset_accounting) {
|
||||
(void) unit_reset_cpu_accounting(UNIT(s));
|
||||
(void) unit_reset_ip_accounting(UNIT(s));
|
||||
s->reset_accounting = false;
|
||||
}
|
||||
|
||||
r = unit_setup_exec_runtime(UNIT(s));
|
||||
@@ -2373,7 +2374,7 @@ static int socket_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
s->result = SOCKET_SUCCESS;
|
||||
s->reset_cpu_usage = true;
|
||||
s->reset_accounting = true;
|
||||
|
||||
socket_enter_start_pre(s);
|
||||
return 1;
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ struct Socket {
|
||||
|
||||
char *user, *group;
|
||||
|
||||
bool reset_cpu_usage:1;
|
||||
bool reset_accounting:1;
|
||||
|
||||
char *fdname;
|
||||
|
||||
|
||||
+5
-4
@@ -620,9 +620,10 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
|
||||
assert(_pid);
|
||||
|
||||
(void) unit_realize_cgroup(UNIT(s));
|
||||
if (s->reset_cpu_usage) {
|
||||
(void) unit_reset_cpu_usage(UNIT(s));
|
||||
s->reset_cpu_usage = false;
|
||||
if (s->reset_accounting) {
|
||||
(void) unit_reset_cpu_accounting(UNIT(s));
|
||||
(void) unit_reset_ip_accounting(UNIT(s));
|
||||
s->reset_accounting = false;
|
||||
}
|
||||
|
||||
r = unit_setup_exec_runtime(UNIT(s));
|
||||
@@ -861,7 +862,7 @@ static int swap_start(Unit *u) {
|
||||
return r;
|
||||
|
||||
s->result = SWAP_SUCCESS;
|
||||
s->reset_cpu_usage = true;
|
||||
s->reset_accounting = true;
|
||||
|
||||
swap_enter_activating(s);
|
||||
return 1;
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ struct Swap {
|
||||
bool is_active:1;
|
||||
bool just_activated:1;
|
||||
|
||||
bool reset_cpu_usage:1;
|
||||
bool reset_accounting:1;
|
||||
|
||||
SwapResult result;
|
||||
|
||||
|
||||
@@ -2818,6 +2818,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
|
||||
unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized));
|
||||
(void) unit_serialize_cgroup_mask(f, "cgroup-realized-mask", u->cgroup_realized_mask);
|
||||
(void) unit_serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
|
||||
unit_serialize_item_format(u, f, "cgroup-bpf-realized", "%i", u->cgroup_bpf_state);
|
||||
|
||||
if (uid_is_valid(u->ref_uid))
|
||||
unit_serialize_item_format(u, f, "ref-uid", UID_FMT, u->ref_uid);
|
||||
@@ -3089,6 +3090,20 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
log_unit_debug(u, "Failed to parse cgroup-enabled-mask %s, ignoring.", v);
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "cgroup-bpf-realized")) {
|
||||
int i;
|
||||
|
||||
r = safe_atoi(v, &i);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to parse cgroup BPF state %s, ignoring.", v);
|
||||
else
|
||||
u->cgroup_bpf_state =
|
||||
i < 0 ? UNIT_CGROUP_BPF_INVALIDATED :
|
||||
i > 0 ? UNIT_CGROUP_BPF_ON :
|
||||
UNIT_CGROUP_BPF_OFF;
|
||||
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "ref-uid")) {
|
||||
uid_t uid;
|
||||
|
||||
|
||||
@@ -71,6 +71,12 @@ struct UnitRef {
|
||||
LIST_FIELDS(UnitRef, refs);
|
||||
};
|
||||
|
||||
typedef enum UnitCGroupBPFState {
|
||||
UNIT_CGROUP_BPF_OFF = 0,
|
||||
UNIT_CGROUP_BPF_ON = 1,
|
||||
UNIT_CGROUP_BPF_INVALIDATED = -1,
|
||||
} UnitCGroupBPFState;
|
||||
|
||||
struct Unit {
|
||||
Manager *manager;
|
||||
|
||||
@@ -267,6 +273,8 @@ struct Unit {
|
||||
bool cgroup_members_mask_valid:1;
|
||||
bool cgroup_subtree_mask_valid:1;
|
||||
|
||||
UnitCGroupBPFState cgroup_bpf_state:2;
|
||||
|
||||
bool start_limit_hit:1;
|
||||
|
||||
/* Did we already invoke unit_coldplug() for this unit? */
|
||||
|
||||
Reference in New Issue
Block a user