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,
int cg_is_delegated(const char *path);
+int cg_has_coredump_receive(const char *path);
+
typedef enum {
CG_KEY_MODE_GRACEFUL = 1 << 0,
} CGroupKeyMode;
"%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),
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",
}
}
+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;
/* 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;
* 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 */
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
};
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;
}
{{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 -%}
%{
"IOAccounting",
"BlockIOAccounting",
"TasksAccounting",
- "IPAccounting"))
+ "IPAccounting",
+ "CoredumpReceive"))
return bus_append_parse_boolean(m, field, eq);
if (STR_IN_SET(field, "CPUWeight",