CGroupIPAccountingMetric metric,
uint64_t *ret) {
+ uint64_t value;
int fd, r;
assert(u);
return -ENODATA;
if (IN_SET(metric, CGROUP_IP_INGRESS_BYTES, CGROUP_IP_EGRESS_BYTES))
- r = bpf_firewall_read_accounting(fd, ret, NULL);
+ r = bpf_firewall_read_accounting(fd, &value, NULL);
else
- r = bpf_firewall_read_accounting(fd, NULL, ret);
+ r = bpf_firewall_read_accounting(fd, NULL, &value);
+ if (r < 0)
+ return r;
+
+ /* Add in additional metrics from a previous runtime. Note that when reexecing/reloading the daemon we compile
+ * all BPF programs and maps anew, but serialize the old counters. When deserializing we store them in the
+ * ip_accounting_extra[] field, and add them in here transparently. */
+
+ *ret = value + u->ip_accounting_extra[metric];
return r;
}
if (u->ip_accounting_egress_map_fd >= 0)
q = bpf_firewall_reset_accounting(u->ip_accounting_egress_map_fd);
+ zero(u->ip_accounting_extra);
+
return r < 0 ? r : q;
}
return r;
}
+static const char *ip_accounting_metric_field[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
+ [CGROUP_IP_INGRESS_BYTES] = "ip-accounting-ingress-bytes",
+ [CGROUP_IP_INGRESS_PACKETS] = "ip-accounting-ingress-packets",
+ [CGROUP_IP_EGRESS_BYTES] = "ip-accounting-egress-bytes",
+ [CGROUP_IP_EGRESS_PACKETS] = "ip-accounting-egress-packets",
+};
+
int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
+ CGroupIPAccountingMetric m;
int r;
assert(u);
bus_track_serialize(u->bus_track, f, "ref");
+ for (m = 0; m < _CGROUP_IP_ACCOUNTING_METRIC_MAX; m++) {
+ uint64_t v;
+
+ r = unit_get_ip_accounting(u, m, &v);
+ if (r >= 0)
+ unit_serialize_item_format(u, f, ip_accounting_metric_field[m], "%" PRIu64, v);
+ }
+
if (serialize_jobs) {
if (u->job) {
fprintf(f, "job\n");
for (;;) {
char line[LINE_MAX], *l, *v;
+ CGroupIPAccountingMetric m;
size_t k;
if (!fgets(line, sizeof(line), f)) {
continue;
}
+ /* Check if this is an IP accounting metric serialization field */
+ for (m = 0; m < _CGROUP_IP_ACCOUNTING_METRIC_MAX; m++)
+ if (streq(l, ip_accounting_metric_field[m]))
+ break;
+ if (m < _CGROUP_IP_ACCOUNTING_METRIC_MAX) {
+ uint64_t c;
+
+ r = safe_atou64(v, &c);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse IP accounting value %s, ignoring.", v);
+ else
+ u->ip_accounting_extra[m] = c;
+ continue;
+ }
+
if (unit_can_serialize(u)) {
if (rt) {
r = exec_runtime_deserialize_item(u, rt, l, v, fds);