summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/missing_prctl.h4
-rw-r--r--src/core/dbus-execute.c4
-rw-r--r--src/core/execute.c11
-rw-r--r--src/core/execute.h1
-rw-r--r--src/core/load-fragment-gperf.gperf.in1
-rw-r--r--src/shared/bus-unit-util.c1
-rw-r--r--src/shared/exit-status.c1
-rw-r--r--src/shared/exit-status.h1
8 files changed, 24 insertions, 0 deletions
diff --git a/src/basic/missing_prctl.h b/src/basic/missing_prctl.h
index 016085bb02..7d9e395c92 100644
--- a/src/basic/missing_prctl.h
+++ b/src/basic/missing_prctl.h
@@ -20,3 +20,7 @@
#ifndef PR_MDWE_REFUSE_EXEC_GAIN
#define PR_MDWE_REFUSE_EXEC_GAIN 1
#endif
+
+#ifndef PR_SET_MEMORY_MERGE
+#define PR_SET_MEMORY_MERGE 67
+#endif
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index a8553c962c..fb22a9769d 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -1347,6 +1347,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProtectHostname", "b", bus_property_get_bool, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MemoryKSM", "b", bus_property_get_tristate, offsetof(ExecContext, memory_ksm), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IPCNamespacePath", "s", NULL, offsetof(ExecContext, ipc_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootImagePolicy", "s", property_get_image_policy, offsetof(ExecContext, root_image_policy), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -2024,6 +2025,9 @@ int bus_exec_context_set_transient_property(
if (streq(name, "ProtectHostname"))
return bus_set_transient_bool(u, name, &c->protect_hostname, message, flags, error);
+ if (streq(name, "MemoryKSM"))
+ return bus_set_transient_tristate(u, name, &c->memory_ksm, message, flags, error);
+
if (streq(name, "UtmpIdentifier"))
return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
diff --git a/src/core/execute.c b/src/core/execute.c
index 3b327ac88d..1802ae05b3 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -5193,6 +5193,16 @@ static int exec_child(
return r;
}
+ if (context->memory_ksm >= 0)
+ if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm) < 0) {
+ if (ERRNO_IS_NOT_SUPPORTED(errno))
+ log_unit_debug_errno(unit, errno, "KSM support not available, ignoring.");
+ else {
+ *exit_status = EXIT_KSM;
+ return log_unit_error_errno(unit, errno, "Failed to set KSM: %m");
+ }
+ }
+
/* Drop groups as early as possible.
* This needs to be done after PrivateDevices=y setup as device nodes should be owned by the host's root.
* For non-root in a userns, devices will be owned by the user/group before the group change, and nobody. */
@@ -5773,6 +5783,7 @@ void exec_context_init(ExecContext *c) {
c->tty_cols = UINT_MAX;
numa_policy_reset(&c->numa_policy);
c->private_mounts = -1;
+ c->memory_ksm = -1;
}
void exec_context_done(ExecContext *c) {
diff --git a/src/core/execute.h b/src/core/execute.h
index e46f31037e..1c8378c8b0 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -310,6 +310,7 @@ struct ExecContext {
ProcSubset proc_subset; /* subset= */
int private_mounts;
+ int memory_ksm;
bool private_tmp;
bool private_network;
bool private_devices;
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
index 83efe84456..64a00fef28 100644
--- a/src/core/load-fragment-gperf.gperf.in
+++ b/src/core/load-fragment-gperf.gperf.in
@@ -176,6 +176,7 @@
{{type}}.SmackProcessLabel, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
{% endif %}
{{type}}.ProtectHostname, config_parse_bool, 0, offsetof({{type}}, exec_context.protect_hostname)
+{{type}}.MemoryKSM, config_parse_tristate, 0, offsetof({{type}}, exec_context.memory_ksm)
{%- endmacro -%}
{%- macro KILL_CONTEXT_CONFIG_ITEMS(type) -%}
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index b32071104b..8b1a353a9b 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -991,6 +991,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"CPUSchedulingResetOnFork",
"LockPersonality",
"ProtectHostname",
+ "MemoryKSM",
"RestrictSUIDSGID"))
return bus_append_parse_boolean(m, field, eq);
diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c
index 9063f231e1..623adda89e 100644
--- a/src/shared/exit-status.c
+++ b/src/shared/exit-status.c
@@ -72,6 +72,7 @@ const ExitStatusMapping exit_status_mappings[256] = {
[EXIT_NUMA_POLICY] = { "NUMA_POLICY", EXIT_STATUS_SYSTEMD },
[EXIT_CREDENTIALS] = { "CREDENTIALS", EXIT_STATUS_SYSTEMD },
[EXIT_BPF] = { "BPF", EXIT_STATUS_SYSTEMD },
+ [EXIT_KSM] = { "KSM", EXIT_STATUS_SYSTEMD },
[EXIT_EXCEPTION] = { "EXCEPTION", EXIT_STATUS_SYSTEMD },
diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h
index 3f9a2ad54f..c22cba05b2 100644
--- a/src/shared/exit-status.h
+++ b/src/shared/exit-status.h
@@ -72,6 +72,7 @@ enum {
EXIT_NUMA_POLICY,
EXIT_CREDENTIALS,
EXIT_BPF,
+ EXIT_KSM,
EXIT_EXCEPTION = 255, /* Whenever we want to propagate an abnormal/signal exit, in line with bash */
};