From ea6075a26e29dbda7a47d65715e4cdf7790a2c98 Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Thu, 6 Mar 2025 08:37:10 -0800 Subject: [PATCH] core: common rlimits code and structures --- src/core/meson.build | 1 + src/core/varlink-common.c | 53 +++++++++++++++++++++++++++++++++ src/core/varlink-common.h | 8 +++++ src/shared/varlink-idl-common.c | 34 +++++++++++++++++++++ src/shared/varlink-idl-common.h | 3 ++ 5 files changed, 99 insertions(+) create mode 100644 src/core/varlink-common.c create mode 100644 src/core/varlink-common.h diff --git a/src/core/meson.build b/src/core/meson.build index 500fb13f9ba..c40893223de 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -63,6 +63,7 @@ libcore_sources = files( 'unit-serialize.c', 'unit.c', 'varlink.c', + 'varlink-common.c', ) subdir('bpf/socket_bind') diff --git a/src/core/varlink-common.c b/src/core/varlink-common.c new file mode 100644 index 00000000000..eb3fafa2fa9 --- /dev/null +++ b/src/core/varlink-common.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "json-util.h" +#include "rlimit-util.h" +#include "varlink-common.h" + +int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata) { + const struct rlimit *rl = userdata; + struct rlimit buf = {}; + + assert(ret); + assert(name); + + if (!rl) { + int z = rlimit_from_string(name); + if (z < 0) + return log_debug_errno(z, "Failed to get rlimit for '%s': %m", name); + + if (getrlimit(z, &buf) < 0) { + log_debug_errno(errno, "Failed to getrlimit(%s), ignoring: %m", name); + *ret = NULL; + return 0; + } + + rl = &buf; + } + + if (rl->rlim_cur == RLIM_INFINITY && rl->rlim_max == RLIM_INFINITY) { + *ret = NULL; + return 0; + } + + return sd_json_buildo(ret, + JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("soft", rl->rlim_cur, RLIM_INFINITY), + JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("hard", rl->rlim_max, RLIM_INFINITY)); +} + +int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata) { + struct rlimit **rl = ASSERT_PTR(userdata); + int r; + + assert(ret); + + for (int i = 0; i < _RLIMIT_MAX; i++) { + r = sd_json_variant_merge_objectbo( + ret, + JSON_BUILD_PAIR_CALLBACK_NON_NULL(rlimit_to_string(i), rlimit_build_json, rl[i])); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/core/varlink-common.h b/src/core/varlink-common.h new file mode 100644 index 00000000000..94a8682a218 --- /dev/null +++ b/src/core/varlink-common.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "sd-json.h" +#include "sd-varlink.h" + +int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata); +int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata); diff --git a/src/shared/varlink-idl-common.c b/src/shared/varlink-idl-common.c index e48fd46e0f5..a20ec4c4296 100644 --- a/src/shared/varlink-idl-common.c +++ b/src/shared/varlink-idl-common.c @@ -19,3 +19,37 @@ SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_FIELD(pidfdId, SD_VARLINK_INT, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Boot ID of the system the inode number belongs to"), SD_VARLINK_DEFINE_FIELD(bootId, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + +SD_VARLINK_DEFINE_STRUCT_TYPE( + RateLimit, + SD_VARLINK_FIELD_COMMENT("The ratelimit interval"), + SD_VARLINK_DEFINE_FIELD(intervalUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The ratelimit burst"), + SD_VARLINK_DEFINE_FIELD(burst, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + +SD_VARLINK_DEFINE_STRUCT_TYPE( + ResourceLimit, + SD_VARLINK_FIELD_COMMENT("The soft resource limit. RLIM_INFINITY is mapped to unset value"), + SD_VARLINK_DEFINE_FIELD(soft, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The hard resource limit. RLIM_INFINITY is mapped to unset value"), + SD_VARLINK_DEFINE_FIELD(hard, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + +SD_VARLINK_DEFINE_STRUCT_TYPE( + ResourceLimitTable, + SD_VARLINK_FIELD_COMMENT("See setrlimit(2) for details"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(CPU, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(FSIZE, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(DATA, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(STACK, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(CORE, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RSS, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(NOFILE, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(AS, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(NPROC, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(MEMLOCK, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(LOCKS, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(SIGPENDING, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(MSGQUEUE, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(NICE, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RTPRIO, ResourceLimit, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RTTIME, ResourceLimit, SD_VARLINK_NULLABLE)); diff --git a/src/shared/varlink-idl-common.h b/src/shared/varlink-idl-common.h index 91b643f8100..de5177de4b3 100644 --- a/src/shared/varlink-idl-common.h +++ b/src/shared/varlink-idl-common.h @@ -5,3 +5,6 @@ extern const sd_varlink_symbol vl_type_Timestamp; extern const sd_varlink_symbol vl_type_ProcessId; +extern const sd_varlink_symbol vl_type_RateLimit; +extern const sd_varlink_symbol vl_type_ResourceLimit; +extern const sd_varlink_symbol vl_type_ResourceLimitTable; -- 2.47.3