core: add CoredumpReceive= setting

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.
This commit is contained in:
Nick Rosbrook
2023-10-13 15:13:11 -04:00
parent b426b4eed8
commit 6cf96ab456
7 changed files with 59 additions and 3 deletions
+12
View 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,
+2
View 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;
+20 -2
View 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;
+4
View 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 */
+18
View 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;
}
+1
View File
@@ -260,6 +260,7 @@
{{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 -%}
%{
+2 -1
View 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",