]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add CoredumpReceive= setting
authorNick Rosbrook <enr0n@ubuntu.com>
Fri, 29 Sep 2023 19:39:17 +0000 (15:39 -0400)
committerNick Rosbrook <enr0n@ubuntu.com>
Fri, 13 Oct 2023 19:13:11 +0000 (15:13 -0400)
This setting indicates that the given unit wants to receive coredumps
for processes that crash within the cgroup of this unit. This setting
requires that Delegate= is also true, and therefore is only available
where Delegate= is available.

This will be used by systemd-coredump to support forwarding coredumps to
containers.

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/core/cgroup.c
src/core/cgroup.h
src/core/dbus-cgroup.c
src/core/load-fragment-gperf.gperf.in
src/shared/bus-unit-util.c

index 7df419d60766de54baaf5366348ac51379cc1638..f4012f1c61cdfa430caa907544a52002bdb68c20 100644 (file)
@@ -2287,6 +2287,18 @@ int cg_is_delegated(const char *path) {
         return r;
 }
 
+int cg_has_coredump_receive(const char *path) {
+        int r;
+
+        assert(path);
+
+        r = cg_get_xattr_bool(path, "user.coredump_receive");
+        if (ERRNO_IS_NEG_XATTR_ABSENT(r))
+                return false;
+
+        return r;
+}
+
 const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX] = {
         [CGROUP_IO_RBPS_MAX]    = CGROUP_LIMIT_MAX,
         [CGROUP_IO_WBPS_MAX]    = CGROUP_LIMIT_MAX,
index 7e79735c3f22262cf65b42f4103a59bf01f3a0ea..04370b01ec38613791b4adcf9e11475705240862 100644 (file)
@@ -212,6 +212,8 @@ int cg_is_threaded(const char *path);
 
 int cg_is_delegated(const char *path);
 
+int cg_has_coredump_receive(const char *path);
+
 typedef enum  {
         CG_KEY_MODE_GRACEFUL = 1 << 0,
 } CGroupKeyMode;
index 47bab04f4210681ec8be87614046cfd06ca28620..b17ca72014110cc95a8fa273de55af5cf7bfa768 100644 (file)
@@ -526,7 +526,8 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 "%sManagedOOMMemoryPressure: %s\n"
                 "%sManagedOOMMemoryPressureLimit: " PERMYRIAD_AS_PERCENT_FORMAT_STR "\n"
                 "%sManagedOOMPreference: %s\n"
-                "%sMemoryPressureWatch: %s\n",
+                "%sMemoryPressureWatch: %s\n"
+                "%sCoredumpReceive: %s\n",
                 prefix, yes_no(c->cpu_accounting),
                 prefix, yes_no(c->io_accounting),
                 prefix, yes_no(c->blockio_accounting),
@@ -569,7 +570,8 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 prefix, managed_oom_mode_to_string(c->moom_mem_pressure),
                 prefix, PERMYRIAD_AS_PERCENT_FORMAT_VAL(UINT32_SCALE_TO_PERMYRIAD(c->moom_mem_pressure_limit)),
                 prefix, managed_oom_preference_to_string(c->moom_preference),
-                prefix, cgroup_pressure_watch_to_string(c->memory_pressure_watch));
+                prefix, cgroup_pressure_watch_to_string(c->memory_pressure_watch),
+                prefix, yes_no(c->coredump_receive));
 
         if (c->delegate_subgroup)
                 fprintf(f, "%sDelegateSubgroup: %s\n",
@@ -892,6 +894,21 @@ static void cgroup_invocation_id_xattr_apply(Unit *u) {
         }
 }
 
+static void cgroup_coredump_xattr_apply(Unit *u) {
+        CGroupContext *c;
+
+        assert(u);
+
+        c = unit_get_cgroup_context(u);
+        if (!c)
+                return;
+
+        if (unit_cgroup_delegate(u) && c->coredump_receive)
+                unit_set_xattr_graceful(u, "user.coredump_receive", "1", 1);
+        else
+                unit_remove_xattr_graceful(u, "user.coredump_receive");
+}
+
 static void cgroup_delegate_xattr_apply(Unit *u) {
         bool b;
 
@@ -952,6 +969,7 @@ static void cgroup_xattr_apply(Unit *u) {
         /* The 'user.*' xattrs can be set from a user manager. */
         cgroup_oomd_xattr_apply(u);
         cgroup_log_xattr_apply(u);
+        cgroup_coredump_xattr_apply(u);
 
         if (!MANAGER_IS_SYSTEM(u->manager))
                 return;
index 072c92f0117980f9306a146c7324a83571e03aa9..7f456b99ee696acc9b05a18d4fa4e55bd4c617e2 100644 (file)
@@ -227,6 +227,10 @@ struct CGroupContext {
          * triggers, nor triggers for non-memory pressure. We might add that later. */
 
         NFTSetContext nft_set_context;
+
+        /* Forward coredumps for processes that crash within this cgroup.
+         * Requires 'delegate' to also be true. */
+        bool coredump_receive;
 };
 
 /* Used when querying IP accounting data */
index d38e8a6aeb4142542ac5c9749f89514815b675a4..e8c6a764e70c00feaba608cf20d74289f61e7952 100644 (file)
@@ -521,6 +521,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("MemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, memory_pressure_watch), 0),
         SD_BUS_PROPERTY("MemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, memory_pressure_threshold_usec), 0),
         SD_BUS_PROPERTY("NFTSet", "a(iiss)", property_get_cgroup_nft_set, 0, 0),
+        SD_BUS_PROPERTY("CoredumpReceive", "b", bus_property_get_bool, offsetof(CGroupContext, coredump_receive), 0),
         SD_BUS_VTABLE_END
 };
 
@@ -839,6 +840,23 @@ static int bus_cgroup_set_transient_property(
                                 unit_write_settingf(u, flags, name, "MemoryPressureThresholdUSec=%" PRIu64, t);
                 }
 
+                return 1;
+        } else if (streq(name, "CoredumpReceive")) {
+                int b;
+
+                if (!UNIT_VTABLE(u)->can_delegate)
+                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Delegation not available for unit type");
+
+                r = sd_bus_message_read(message, "b", &b);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->coredump_receive = b;
+
+                        unit_write_settingf(u, flags, name, "CoredumpReceive=%s", yes_no(b));
+                }
+
                 return 1;
         }
 
index 0ab468ba176a4f5dd736d6abe88785f1b7b96526..45f9ab03c4cce926f29c4f76597b1e3924edbed5 100644 (file)
 {{type}}.MemoryPressureThresholdSec,       config_parse_sec,                            0,                                  offsetof({{type}}, cgroup_context.memory_pressure_threshold_usec)
 {{type}}.MemoryPressureWatch,              config_parse_memory_pressure_watch,          0,                                  offsetof({{type}}, cgroup_context.memory_pressure_watch)
 {{type}}.NFTSet,                           config_parse_cgroup_nft_set,                 NFT_SET_PARSE_CGROUP,               offsetof({{type}}, cgroup_context)
+{{type}}.CoredumpReceive,                  config_parse_bool,                           0,                                  offsetof({{type}}, cgroup_context.coredump_receive)
 {%- endmacro -%}
 
 %{
index 634a8f08c29b008800556f654e4cae41c38eab67..4ee9706847d93231d1dc3fefd56b26d7f1d9a8fe 100644 (file)
@@ -565,7 +565,8 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                               "IOAccounting",
                               "BlockIOAccounting",
                               "TasksAccounting",
-                              "IPAccounting"))
+                              "IPAccounting",
+                              "CoredumpReceive"))
                 return bus_append_parse_boolean(m, field, eq);
 
         if (STR_IN_SET(field, "CPUWeight",