diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 4a110d1e24..03ff1401e0 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -2778,6 +2778,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -3409,6 +3411,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
@@ -4045,6 +4049,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
@@ -4845,6 +4851,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -5486,6 +5494,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
@@ -6104,6 +6114,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
@@ -6778,6 +6790,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -7347,6 +7361,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
@@ -7879,6 +7895,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
@@ -8676,6 +8694,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -9231,6 +9251,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
@@ -9749,6 +9771,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
@@ -10405,6 +10429,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -10586,6 +10612,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
+
+
@@ -10768,6 +10796,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
+
+
@@ -10978,6 +11008,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly t MemorySwapCurrent = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemorySwapPeak = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryAvailable = ...;
@@ -11179,6 +11211,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
+
+
@@ -11391,6 +11425,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
+
+
@@ -11790,7 +11826,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
NFTSet,
SetLoginEnvironment,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
@@ -11819,7 +11856,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
NFTSet,
SetLoginEnvironment,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
@@ -11846,7 +11884,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
NFTSet,
SetLoginEnvironment,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
@@ -11873,7 +11912,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
NFTSet,
SetLoginEnvironment,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
@@ -11891,7 +11931,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
MemoryPressureThresholdUSec were added in version 254.
NFTSet,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
@@ -11910,7 +11951,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
MemoryPressureThresholdUSec were added in version 254.
NFTSet,
CoredumpReceive,
- MemoryPeak, and
+ MemoryPeak,
+ MemorySwapCurrent, and
MemorySwapPeak were added in version 255.
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index c81cc16202..2aa4431ceb 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -4047,6 +4047,9 @@ static int unit_get_memory_attr_raw(Unit *u, const char* mem_attribute, uint64_t
assert(mem_attribute);
assert(ret);
+ if (!UNIT_CGROUP_BOOL(u, memory_accounting))
+ return -ENODATA;
+
if (!u->cgroup_path)
return -ENODATA;
@@ -4100,6 +4103,10 @@ 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);
}
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 836946192a..40c394f109 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -354,6 +354,7 @@ 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_available(Unit *u, uint64_t *ret);
int unit_get_tasks_current(Unit *u, uint64_t *ret);
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index c229972af5..40cc16c28f 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -1103,6 +1103,29 @@ static int property_get_peak_memory(
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,
@@ -1583,6 +1606,7 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
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("MemoryAvailable", "t", property_get_available_memory, 0, 0),
SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c
index a91abfc78e..71d93833f7 100644
--- a/src/systemctl/systemctl-show.c
+++ b/src/systemctl/systemctl-show.c
@@ -251,6 +251,7 @@ typedef struct UnitStatusInfo {
/* CGroup */
uint64_t memory_current;
uint64_t memory_peak;
+ uint64_t memory_swap_current;
uint64_t memory_swap_peak;
uint64_t memory_min;
uint64_t memory_low;
@@ -704,9 +705,11 @@ static void print_status_info(
if (i->memory_current != UINT64_MAX) {
printf(" Memory: %s", FORMAT_BYTES(i->memory_current));
- bool show_memory_swap_peak = !IN_SET(i->memory_swap_peak, 0, CGROUP_LIMIT_MAX);
+ /* Only show current swap if it ever was non-zero or is currently non-zero. In both cases
+ memory_swap_peak will be non-zero (and not CGROUP_LIMIT_MAX). */
+ bool show_memory_swap = !IN_SET(i->memory_swap_peak, 0, CGROUP_LIMIT_MAX);
if (i->memory_peak != CGROUP_LIMIT_MAX ||
- show_memory_swap_peak ||
+ show_memory_swap ||
i->memory_min > 0 ||
i->memory_low > 0 || i->startup_memory_low > 0 ||
i->memory_high != CGROUP_LIMIT_MAX || i->startup_memory_high != CGROUP_LIMIT_MAX ||
@@ -774,7 +777,11 @@ static void print_status_info(
printf("%speak: %s", prefix, FORMAT_BYTES(i->memory_peak));
prefix = " ";
}
- if (show_memory_swap_peak) {
+ if (show_memory_swap) {
+ printf("%sswap: %s", prefix, FORMAT_BYTES(i->memory_swap_current));
+ prefix = " ";
+ }
+ if (show_memory_swap) {
printf("%sswap peak: %s", prefix, FORMAT_BYTES(i->memory_swap_peak));
prefix = " ";
}
@@ -2045,6 +2052,7 @@ static int show_one(
{ "What", "s", NULL, offsetof(UnitStatusInfo, what) },
{ "MemoryCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_current) },
{ "MemoryPeak", "t", NULL, offsetof(UnitStatusInfo, memory_peak) },
+ { "MemorySwapCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_swap_current) },
{ "MemorySwapPeak", "t", NULL, offsetof(UnitStatusInfo, memory_swap_peak) },
{ "MemoryAvailable", "t", NULL, offsetof(UnitStatusInfo, memory_available) },
{ "DefaultMemoryMin", "t", NULL, offsetof(UnitStatusInfo, default_memory_min) },
@@ -2103,6 +2111,7 @@ static int show_one(
.startup_memory_zswap_max = CGROUP_LIMIT_MAX,
.memory_limit = CGROUP_LIMIT_MAX,
.memory_peak = CGROUP_LIMIT_MAX,
+ .memory_swap_current = CGROUP_LIMIT_MAX,
.memory_swap_peak = CGROUP_LIMIT_MAX,
.memory_available = CGROUP_LIMIT_MAX,
.cpu_usage_nsec = UINT64_MAX,