if (!crt || !crt->cgroup_path)
continue;
- (void) unit_get_memory_current(u, ¤t);
+ (void) unit_get_memory_accounting(u, CGROUP_MEMORY_CURRENT, ¤t);
/* in case of error, previous current propagates as lower bound */
if (unit_has_name(u, SPECIAL_ROOT_SLICE))
return 0;
}
-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);
-
- if (!UNIT_CGROUP_BOOL(u, memory_accounting))
- return -ENODATA;
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return -ENODATA;
-
- /* The root cgroup doesn't expose this information, let's get it from /proc instead */
- if (unit_has_host_root_cgroup(u))
- return procfs_memory_get_used(ret);
-
- if ((crt->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
- return -ENODATA;
-
- r = cg_all_unified();
- if (r < 0)
- return r;
-
- return cg_get_attribute_as_uint64("memory", crt->cgroup_path, r > 0 ? "memory.current" : "memory.usage_in_bytes", 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_CURRENT] = "memory.current",
[CGROUP_MEMORY_PEAK] = "memory.peak",
[CGROUP_MEMORY_SWAP_CURRENT] = "memory.swap.current",
[CGROUP_MEMORY_SWAP_PEAK] = "memory.swap.peak",
return -ENODATA;
/* The root cgroup doesn't expose this information. */
- if (unit_has_host_root_cgroup(u))
+ if (unit_has_host_root_cgroup(u)) {
+ /* System-wide memory usage can be acquired from /proc/ */
+ if (metric == CGROUP_MEMORY_CURRENT)
+ return procfs_memory_get_used(ret);
+
return -ENODATA;
+ }
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
if (!crt)
if (!FLAGS_SET(crt->cgroup_realized_mask, CGROUP_MASK_MEMORY))
return -ENODATA;
- r = cg_all_unified();
- if (r < 0)
- return r;
- if (r == 0)
- return -ENODATA;
-
r = cg_get_attribute_as_uint64("memory", crt->cgroup_path, attributes_table[metric], &bytes);
if (r < 0 && r != -ENODATA)
return r;
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_CURRENT] = "MemoryCurrent",
[CGROUP_MEMORY_PEAK] = "MemoryPeak",
[CGROUP_MEMORY_SWAP_CURRENT] = "MemorySwapCurrent",
[CGROUP_MEMORY_SWAP_PEAK] = "MemorySwapPeak",
_CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST = CGROUP_MEMORY_SWAP_PEAK,
/* These attributes are transient, so no need for caching. */
+ CGROUP_MEMORY_CURRENT,
CGROUP_MEMORY_SWAP_CURRENT,
CGROUP_MEMORY_ZSWAP_CURRENT,
int unit_synthesize_cgroup_empty_event(Unit *u);
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);
return sd_bus_message_append(reply, "s", unit_slice_name(u));
}
-static int property_get_current_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_current(u, &sz);
- if (r < 0 && r != -ENODATA)
- log_unit_warning_errno(u, r, "Failed to get current memory usage from cgroup: %m");
-
- return sd_bus_message_append(reply, "t", sz);
-}
-
static int property_get_available_memory(
sd_bus *bus,
const char *path,
SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
SD_BUS_PROPERTY("ControlGroupId", "t", property_get_cgroup_id, 0, 0),
- SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
+ SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_memory_accounting, 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),