mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #30007 from YHNdnzj/memory-attr-followup
core: generalize memory accounting attribute handling
This commit is contained in:
@@ -4017,6 +4017,8 @@ int unit_get_memory_available(Unit *u, uint64_t *ret) {
|
||||
int unit_get_memory_current(Unit *u, uint64_t *ret) {
|
||||
int r;
|
||||
|
||||
// FIXME: Merge this into unit_get_memory_accounting after support for cgroup v1 is dropped
|
||||
|
||||
assert(u);
|
||||
assert(ret);
|
||||
|
||||
@@ -4040,12 +4042,21 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
|
||||
return cg_get_attribute_as_uint64("memory", u->cgroup_path, r > 0 ? "memory.current" : "memory.usage_in_bytes", ret);
|
||||
}
|
||||
|
||||
static int unit_get_memory_attr_raw(Unit *u, const char* mem_attribute, uint64_t *ret) {
|
||||
int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, uint64_t *ret) {
|
||||
|
||||
static const char* const attributes_table[_CGROUP_MEMORY_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_MEMORY_PEAK] = "memory.peak",
|
||||
[CGROUP_MEMORY_SWAP_CURRENT] = "memory.swap.current",
|
||||
[CGROUP_MEMORY_SWAP_PEAK] = "memory.swap.peak",
|
||||
[CGROUP_MEMORY_ZSWAP_CURRENT] = "memory.zswap.current",
|
||||
};
|
||||
|
||||
uint64_t bytes;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(mem_attribute);
|
||||
assert(ret);
|
||||
assert(metric >= 0);
|
||||
assert(metric < _CGROUP_MEMORY_ACCOUNTING_METRIC_MAX);
|
||||
|
||||
if (!UNIT_CGROUP_BOOL(u, memory_accounting))
|
||||
return -ENODATA;
|
||||
@@ -4057,64 +4068,36 @@ static int unit_get_memory_attr_raw(Unit *u, const char* mem_attribute, uint64_t
|
||||
if (unit_has_host_root_cgroup(u))
|
||||
return -ENODATA;
|
||||
|
||||
if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
|
||||
if (!FLAGS_SET(u->cgroup_realized_mask, CGROUP_MASK_MEMORY))
|
||||
return -ENODATA;
|
||||
|
||||
r = cg_all_unified();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!r)
|
||||
if (r == 0)
|
||||
return -ENODATA;
|
||||
|
||||
return cg_get_attribute_as_uint64("memory", u->cgroup_path, mem_attribute, ret);
|
||||
}
|
||||
|
||||
static int unit_get_memory_attr_cached(Unit *u, const char* mem_attribute, uint64_t* last, uint64_t *ret) {
|
||||
uint64_t bytes;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(mem_attribute);
|
||||
assert(last);
|
||||
|
||||
if (!UNIT_CGROUP_BOOL(u, memory_accounting))
|
||||
return -ENODATA;
|
||||
|
||||
r = unit_get_memory_attr_raw(u, mem_attribute, &bytes);
|
||||
if (r == -ENODATA && *last != UINT64_MAX) {
|
||||
/* If we can't get the memory peak anymore (because the cgroup was already removed, for example),
|
||||
* use our cached value. */
|
||||
|
||||
if (ret)
|
||||
*ret = *last;
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
r = cg_get_attribute_as_uint64("memory", u->cgroup_path, attributes_table[metric], &bytes);
|
||||
if (r < 0 && (r != -ENODATA || metric > _CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST))
|
||||
return r;
|
||||
|
||||
*last = bytes;
|
||||
if (metric <= _CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST) {
|
||||
uint64_t *last = &u->memory_accounting_last[metric];
|
||||
|
||||
if (r >= 0)
|
||||
*last = bytes;
|
||||
else if (*last != UINT64_MAX)
|
||||
bytes = *last;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
*ret = bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unit_get_memory_peak(Unit *u, uint64_t *ret) {
|
||||
return unit_get_memory_attr_cached(u, "memory.peak", &u->memory_peak_last, ret);
|
||||
}
|
||||
|
||||
int unit_get_memory_swap_current(Unit *u, uint64_t *ret) {
|
||||
return unit_get_memory_attr_raw(u, "memory.swap.current", ret);
|
||||
}
|
||||
|
||||
int unit_get_memory_swap_peak(Unit *u, uint64_t *ret) {
|
||||
return unit_get_memory_attr_cached(u, "memory.swap.peak", &u->memory_swap_peak_last, ret);
|
||||
}
|
||||
|
||||
int unit_get_memory_zswap_current(Unit *u, uint64_t *ret) {
|
||||
return unit_get_memory_attr_raw(u, "memory.zswap.current", ret);
|
||||
}
|
||||
|
||||
int unit_get_tasks_current(Unit *u, uint64_t *ret) {
|
||||
assert(u);
|
||||
assert(ret);
|
||||
@@ -4390,20 +4373,34 @@ int unit_reset_cpu_accounting(Unit *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void unit_reset_memory_accounting_last(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
FOREACH_ARRAY(i, u->memory_accounting_last, ELEMENTSOF(u->memory_accounting_last))
|
||||
*i = UINT64_MAX;
|
||||
}
|
||||
|
||||
int unit_reset_ip_accounting(Unit *u) {
|
||||
int r = 0, q = 0;
|
||||
int r = 0;
|
||||
|
||||
assert(u);
|
||||
|
||||
if (u->ip_accounting_ingress_map_fd >= 0)
|
||||
r = bpf_firewall_reset_accounting(u->ip_accounting_ingress_map_fd);
|
||||
RET_GATHER(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);
|
||||
RET_GATHER(r, bpf_firewall_reset_accounting(u->ip_accounting_egress_map_fd));
|
||||
|
||||
zero(u->ip_accounting_extra);
|
||||
|
||||
return r < 0 ? r : q;
|
||||
return r;
|
||||
}
|
||||
|
||||
void unit_reset_io_accounting_last(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
FOREACH_ARRAY(i, u->io_accounting_last, _CGROUP_IO_ACCOUNTING_METRIC_MAX)
|
||||
*i = UINT64_MAX;
|
||||
}
|
||||
|
||||
int unit_reset_io_accounting(Unit *u) {
|
||||
@@ -4411,8 +4408,7 @@ int unit_reset_io_accounting(Unit *u) {
|
||||
|
||||
assert(u);
|
||||
|
||||
for (CGroupIOAccountingMetric i = 0; i < _CGROUP_IO_ACCOUNTING_METRIC_MAX; i++)
|
||||
u->io_accounting_last[i] = UINT64_MAX;
|
||||
unit_reset_io_accounting_last(u);
|
||||
|
||||
r = unit_get_io_accounting_raw(u, u->io_accounting_base);
|
||||
if (r < 0) {
|
||||
@@ -4424,15 +4420,16 @@ int unit_reset_io_accounting(Unit *u) {
|
||||
}
|
||||
|
||||
int unit_reset_accounting(Unit *u) {
|
||||
int r, q, v;
|
||||
int r = 0;
|
||||
|
||||
assert(u);
|
||||
|
||||
r = unit_reset_cpu_accounting(u);
|
||||
q = unit_reset_io_accounting(u);
|
||||
v = unit_reset_ip_accounting(u);
|
||||
RET_GATHER(r, unit_reset_cpu_accounting(u));
|
||||
RET_GATHER(r, unit_reset_io_accounting(u));
|
||||
RET_GATHER(r, unit_reset_ip_accounting(u));
|
||||
unit_reset_memory_accounting_last(u);
|
||||
|
||||
return r < 0 ? r : q < 0 ? q : v;
|
||||
return r;
|
||||
}
|
||||
|
||||
void unit_invalidate_cgroup(Unit *u, CGroupMask m) {
|
||||
@@ -4650,3 +4647,12 @@ static const char* const cgroup_io_accounting_metric_table[_CGROUP_IO_ACCOUNTING
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(cgroup_io_accounting_metric, CGroupIOAccountingMetric);
|
||||
|
||||
static const char* const cgroup_memory_accounting_metric_table[_CGROUP_MEMORY_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_MEMORY_PEAK] = "MemoryPeak",
|
||||
[CGROUP_MEMORY_SWAP_CURRENT] = "MemorySwapCurrent",
|
||||
[CGROUP_MEMORY_SWAP_PEAK] = "MemorySwapPeak",
|
||||
[CGROUP_MEMORY_ZSWAP_CURRENT] = "MemoryZSwapCurrent",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(cgroup_memory_accounting_metric, CGroupMemoryAccountingMetric);
|
||||
|
||||
@@ -261,6 +261,21 @@ typedef enum CGroupIOAccountingMetric {
|
||||
_CGROUP_IO_ACCOUNTING_METRIC_INVALID = -EINVAL,
|
||||
} CGroupIOAccountingMetric;
|
||||
|
||||
typedef enum CGroupMemoryAccountingMetric {
|
||||
CGROUP_MEMORY_PEAK,
|
||||
CGROUP_MEMORY_SWAP_PEAK,
|
||||
/* We cache the above attributes, so that they can be fetched even after the cgroup is gone, e.g.
|
||||
* when systemd-run exits. */
|
||||
_CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST = CGROUP_MEMORY_SWAP_PEAK,
|
||||
|
||||
/* These attributes are transient, so no need for caching. */
|
||||
CGROUP_MEMORY_SWAP_CURRENT,
|
||||
CGROUP_MEMORY_ZSWAP_CURRENT,
|
||||
|
||||
_CGROUP_MEMORY_ACCOUNTING_METRIC_MAX,
|
||||
_CGROUP_MEMORY_ACCOUNTING_METRIC_INVALID = -EINVAL,
|
||||
} CGroupMemoryAccountingMetric;
|
||||
|
||||
typedef struct Unit Unit;
|
||||
typedef struct Manager Manager;
|
||||
typedef enum ManagerState ManagerState;
|
||||
@@ -352,19 +367,18 @@ int unit_watch_all_pids(Unit *u);
|
||||
|
||||
int unit_synthesize_cgroup_empty_event(Unit *u);
|
||||
|
||||
int unit_get_memory_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_peak(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_swap_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_swap_peak(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_zswap_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_available(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_current(Unit *u, uint64_t *ret);
|
||||
int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, 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_get_io_accounting(Unit *u, CGroupIOAccountingMetric metric, bool allow_cache, uint64_t *ret);
|
||||
int unit_get_ip_accounting(Unit *u, CGroupIPAccountingMetric metric, uint64_t *ret);
|
||||
|
||||
int unit_reset_cpu_accounting(Unit *u);
|
||||
void unit_reset_memory_accounting_last(Unit *u);
|
||||
int unit_reset_ip_accounting(Unit *u);
|
||||
void unit_reset_io_accounting_last(Unit *u);
|
||||
int unit_reset_io_accounting(Unit *u);
|
||||
int unit_reset_accounting(Unit *u);
|
||||
|
||||
@@ -410,3 +424,6 @@ CGroupIPAccountingMetric cgroup_ip_accounting_metric_from_string(const char *s)
|
||||
|
||||
const char* cgroup_io_accounting_metric_to_string(CGroupIOAccountingMetric m) _const_;
|
||||
CGroupIOAccountingMetric cgroup_io_accounting_metric_from_string(const char *s) _pure_;
|
||||
|
||||
const char* cgroup_memory_accounting_metric_to_string(CGroupMemoryAccountingMetric m) _const_;
|
||||
CGroupMemoryAccountingMetric cgroup_memory_accounting_metric_from_string(const char *s) _pure_;
|
||||
|
||||
@@ -1080,98 +1080,6 @@ static int property_get_current_memory(
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_peak_memory(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
uint64_t sz = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = unit_get_memory_peak(u, &sz);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
log_unit_warning_errno(u, r, "Failed to get memory.peak attribute: %m");
|
||||
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_current_swap_memory(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
uint64_t sz = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = unit_get_memory_swap_current(u, &sz);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
log_unit_warning_errno(u, r, "Failed to get memory.swap.current attribute: %m");
|
||||
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_peak_swap_memory(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
uint64_t sz = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = unit_get_memory_swap_peak(u, &sz);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
log_unit_warning_errno(u, r, "Failed to get memory.swap.peak attribute: %m");
|
||||
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_current_zswap_memory(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
uint64_t sz = UINT64_MAX;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = unit_get_memory_swap_current(u, &sz);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
log_unit_warning_errno(u, r, "Failed to get memory.zswap.current attribute: %m");
|
||||
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_available_memory(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -1195,6 +1103,27 @@ static int property_get_available_memory(
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_memory_accounting(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
CGroupMemoryAccountingMetric metric;
|
||||
uint64_t sz = UINT64_MAX;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
assert_se((metric = cgroup_memory_accounting_metric_from_string(property)) >= 0);
|
||||
(void) unit_get_memory_accounting(u, metric, &sz);
|
||||
return sd_bus_message_append(reply, "t", sz);
|
||||
}
|
||||
|
||||
static int property_get_current_tasks(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -1628,10 +1557,10 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
|
||||
SD_BUS_PROPERTY("ControlGroupId", "t", NULL, offsetof(Unit, cgroup_id), 0),
|
||||
SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryPeak", "t", property_get_peak_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("MemorySwapCurrent", "t", property_get_current_swap_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("MemorySwapPeak", "t", property_get_peak_swap_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryZSwapCurrent", "t", property_get_current_zswap_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryPeak", "t", property_get_memory_accounting, 0, 0),
|
||||
SD_BUS_PROPERTY("MemorySwapCurrent", "t", property_get_memory_accounting, 0, 0),
|
||||
SD_BUS_PROPERTY("MemorySwapPeak", "t", property_get_memory_accounting, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryZSwapCurrent", "t", property_get_memory_accounting, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryAvailable", "t", property_get_available_memory, 0, 0),
|
||||
SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
|
||||
SD_BUS_PROPERTY("EffectiveCPUs", "ay", property_get_cpuset_cpus, 0, 0),
|
||||
|
||||
@@ -69,27 +69,40 @@ static int deserialize_markers(Unit *u, const char *value) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const ip_accounting_metric_field[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IP_INGRESS_BYTES] = "ip-accounting-ingress-bytes",
|
||||
static const char* const ip_accounting_metric_field_table[_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",
|
||||
[CGROUP_IP_EGRESS_BYTES] = "ip-accounting-egress-bytes",
|
||||
[CGROUP_IP_EGRESS_PACKETS] = "ip-accounting-egress-packets",
|
||||
};
|
||||
|
||||
static const char *const io_accounting_metric_field_base[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "io-accounting-read-bytes-base",
|
||||
[CGROUP_IO_WRITE_BYTES] = "io-accounting-write-bytes-base",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "io-accounting-read-operations-base",
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(ip_accounting_metric_field, CGroupIPAccountingMetric);
|
||||
|
||||
static const char* const io_accounting_metric_field_base_table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "io-accounting-read-bytes-base",
|
||||
[CGROUP_IO_WRITE_BYTES] = "io-accounting-write-bytes-base",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "io-accounting-read-operations-base",
|
||||
[CGROUP_IO_WRITE_OPERATIONS] = "io-accounting-write-operations-base",
|
||||
};
|
||||
|
||||
static const char *const io_accounting_metric_field_last[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "io-accounting-read-bytes-last",
|
||||
[CGROUP_IO_WRITE_BYTES] = "io-accounting-write-bytes-last",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "io-accounting-read-operations-last",
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(io_accounting_metric_field_base, CGroupIOAccountingMetric);
|
||||
|
||||
static const char* const io_accounting_metric_field_last_table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IO_READ_BYTES] = "io-accounting-read-bytes-last",
|
||||
[CGROUP_IO_WRITE_BYTES] = "io-accounting-write-bytes-last",
|
||||
[CGROUP_IO_READ_OPERATIONS] = "io-accounting-read-operations-last",
|
||||
[CGROUP_IO_WRITE_OPERATIONS] = "io-accounting-write-operations-last",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(io_accounting_metric_field_last, CGroupIOAccountingMetric);
|
||||
|
||||
static const char* const memory_accounting_metric_field_last_table[_CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST + 1] = {
|
||||
[CGROUP_MEMORY_PEAK] = "memory-accounting-peak",
|
||||
[CGROUP_MEMORY_SWAP_PEAK] = "memory-accounting-swap-peak",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(memory_accounting_metric_field_last, CGroupMemoryAccountingMetric);
|
||||
|
||||
int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
|
||||
int r;
|
||||
|
||||
@@ -153,10 +166,18 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
|
||||
(void) serialize_item_format(f, "oom-kill-last", "%" PRIu64, u->oom_kill_last);
|
||||
|
||||
for (CGroupIOAccountingMetric im = 0; im < _CGROUP_IO_ACCOUNTING_METRIC_MAX; im++) {
|
||||
(void) serialize_item_format(f, io_accounting_metric_field_base[im], "%" PRIu64, u->io_accounting_base[im]);
|
||||
(void) serialize_item_format(f, io_accounting_metric_field_base_to_string(im), "%" PRIu64, u->io_accounting_base[im]);
|
||||
|
||||
if (u->io_accounting_last[im] != UINT64_MAX)
|
||||
(void) serialize_item_format(f, io_accounting_metric_field_last[im], "%" PRIu64, u->io_accounting_last[im]);
|
||||
(void) serialize_item_format(f, io_accounting_metric_field_last_to_string(im), "%" PRIu64, u->io_accounting_last[im]);
|
||||
}
|
||||
|
||||
for (CGroupMemoryAccountingMetric metric = 0; metric <= _CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST; metric++) {
|
||||
uint64_t v;
|
||||
|
||||
r = unit_get_memory_accounting(u, metric, &v);
|
||||
if (r >= 0)
|
||||
(void) serialize_item_format(f, memory_accounting_metric_field_last_to_string(metric), "%" PRIu64, v);
|
||||
}
|
||||
|
||||
if (u->cgroup_path)
|
||||
@@ -195,7 +216,7 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
|
||||
|
||||
r = unit_get_ip_accounting(u, m, &v);
|
||||
if (r >= 0)
|
||||
(void) serialize_item_format(f, ip_accounting_metric_field[m], "%" PRIu64, v);
|
||||
(void) serialize_item_format(f, ip_accounting_metric_field_to_string(m), "%" PRIu64, v);
|
||||
}
|
||||
|
||||
if (!switching_root) {
|
||||
@@ -468,8 +489,20 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m = memory_accounting_metric_field_last_from_string(l);
|
||||
if (m >= 0) {
|
||||
uint64_t c;
|
||||
|
||||
r = safe_atou64(v, &c);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to parse memory accounting last value %s, ignoring.", v);
|
||||
else
|
||||
u->memory_accounting_last[m] = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if this is an IP accounting metric serialization field */
|
||||
m = string_table_lookup(ip_accounting_metric_field, ELEMENTSOF(ip_accounting_metric_field), l);
|
||||
m = ip_accounting_metric_field_from_string(l);
|
||||
if (m >= 0) {
|
||||
uint64_t c;
|
||||
|
||||
@@ -481,7 +514,7 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m = string_table_lookup(io_accounting_metric_field_base, ELEMENTSOF(io_accounting_metric_field_base), l);
|
||||
m = io_accounting_metric_field_base_from_string(l);
|
||||
if (m >= 0) {
|
||||
uint64_t c;
|
||||
|
||||
@@ -493,7 +526,7 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m = string_table_lookup(io_accounting_metric_field_last, ELEMENTSOF(io_accounting_metric_field_last), l);
|
||||
m = io_accounting_metric_field_last_from_string(l);
|
||||
if (m >= 0) {
|
||||
uint64_t c;
|
||||
|
||||
|
||||
@@ -114,15 +114,16 @@ Unit* unit_new(Manager *m, size_t size) {
|
||||
u->ref_uid = UID_INVALID;
|
||||
u->ref_gid = GID_INVALID;
|
||||
u->cpu_usage_last = NSEC_INFINITY;
|
||||
u->memory_peak_last = UINT64_MAX;
|
||||
u->memory_swap_peak_last = UINT64_MAX;
|
||||
|
||||
unit_reset_memory_accounting_last(u);
|
||||
|
||||
unit_reset_io_accounting_last(u);
|
||||
|
||||
u->cgroup_invalidated_mask |= CGROUP_MASK_BPF_FIREWALL;
|
||||
u->failure_action_exit_status = u->success_action_exit_status = -1;
|
||||
|
||||
u->ip_accounting_ingress_map_fd = -EBADF;
|
||||
u->ip_accounting_egress_map_fd = -EBADF;
|
||||
for (CGroupIOAccountingMetric i = 0; i < _CGROUP_IO_ACCOUNTING_METRIC_MAX; i++)
|
||||
u->io_accounting_last[i] = UINT64_MAX;
|
||||
|
||||
u->ipv4_allow_map_fd = -EBADF;
|
||||
u->ipv6_allow_map_fd = -EBADF;
|
||||
@@ -2371,7 +2372,7 @@ static int unit_log_resources(Unit *u) {
|
||||
nsec > NOTICEWORTHY_CPU_NSEC);
|
||||
}
|
||||
|
||||
(void) unit_get_memory_peak(u, &memory_peak);
|
||||
(void) unit_get_memory_accounting(u, CGROUP_MEMORY_PEAK, &memory_peak);
|
||||
if (memory_peak != UINT64_MAX) {
|
||||
/* Format peak memory for inclusion in the structured log message */
|
||||
if (asprintf(&t, "MEMORY_PEAK=%" PRIu64, memory_peak) < 0) {
|
||||
@@ -2389,7 +2390,7 @@ static int unit_log_resources(Unit *u) {
|
||||
message_parts[n_message_parts++] = t;
|
||||
}
|
||||
|
||||
(void) unit_get_memory_swap_peak(u, &memory_swap_peak);
|
||||
(void) unit_get_memory_accounting(u, CGROUP_MEMORY_SWAP_PEAK, &memory_swap_peak);
|
||||
if (memory_swap_peak != UINT64_MAX) {
|
||||
/* Format peak swap memory for inclusion in the structured log message */
|
||||
if (asprintf(&t, "MEMORY_SWAP_PEAK=%" PRIu64, memory_swap_peak) < 0) {
|
||||
|
||||
@@ -365,11 +365,8 @@ typedef struct Unit {
|
||||
nsec_t cpu_usage_base;
|
||||
nsec_t cpu_usage_last; /* the most recently read value */
|
||||
|
||||
/* Most recently read value of memory.peak */
|
||||
uint64_t memory_peak_last;
|
||||
|
||||
/* Most recently read value of memory.swap.peak */
|
||||
uint64_t memory_swap_peak_last;
|
||||
/* Most recently read value of memory accounting metrics */
|
||||
uint64_t memory_accounting_last[_CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST + 1];
|
||||
|
||||
/* The current counter of OOM kills initiated by systemd-oomd */
|
||||
uint64_t managed_oom_kill_last;
|
||||
|
||||
Reference in New Issue
Block a user