From 6b78d931cdcb10ab9ebd86d463f7e32188d925a8 Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Wed, 16 Jul 2025 06:56:59 -0700 Subject: [PATCH] core: io.systemd.Unit.List can lookup unit by CGroup --- src/core/varlink-unit.c | 26 +++++++++++++++++++++----- src/shared/varlink-io.systemd.Unit.c | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/core/varlink-unit.c b/src/core/varlink-unit.c index 0c4a025b3e1..5a88bb38402 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -10,6 +10,7 @@ #include "install.h" #include "json-util.h" #include "manager.h" +#include "path-util.h" #include "pidref.h" #include "set.h" #include "strv.h" @@ -356,7 +357,7 @@ static int lookup_unit_by_pidref(sd_varlink *link, Manager *manager, PidRef *pid } typedef struct UnitLookupParameters { - const char *name; + const char *name, *cgroup; PidRef pidref; } UnitLookupParameters; @@ -375,9 +376,10 @@ static int varlink_error_no_such_unit(sd_varlink *v, const char *name) { static int varlink_error_conflict_lookup_parameters(sd_varlink *v, const UnitLookupParameters *p) { log_debug_errno( ESRCH, - "Searching unit by lookup parameters name='%s' pid="PID_FMT" resulted in multiple different units", + "Searching unit by lookup parameters name='%s' pid="PID_FMT" cgroup='%s' resulted in multiple different units", p->name, - p->pidref.pid); + p->pidref.pid, + p->cgroup); return varlink_error_no_such_unit(v, /* name= */ NULL); } @@ -413,14 +415,28 @@ static int lookup_unit_by_parameters(sd_varlink *link, Manager *manager, UnitLoo unit = pid_unit; } + if (p->cgroup) { + if (!path_is_safe(p->cgroup)) + return sd_varlink_error_invalid_parameter_name(link, "cgroup"); + + Unit *cgroup_unit = manager_get_unit_by_cgroup(manager, p->cgroup); + if (!cgroup_unit) + return varlink_error_no_such_unit(link, "cgroup"); + if (cgroup_unit != unit && unit != NULL) + return varlink_error_conflict_lookup_parameters(link, p); + + unit = cgroup_unit; + } + *ret_unit = unit; return 0; } int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { static const sd_json_dispatch_field dispatch_table[] = { - { "name", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, offsetof(UnitLookupParameters, name), 0 /* allows UNIT_NAME_PLAIN | UNIT_NAME_INSTANCE */ }, - { "pid", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_pidref, offsetof(UnitLookupParameters, pidref), SD_JSON_RELAX /* allows PID_AUTOMATIC */ }, + { "name", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, offsetof(UnitLookupParameters, name), 0 /* allows UNIT_NAME_PLAIN | UNIT_NAME_INSTANCE */ }, + { "pid", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_pidref, offsetof(UnitLookupParameters, pidref), SD_JSON_RELAX /* allows PID_AUTOMATIC */ }, + { "cgroup", SD_JSON_VARIANT_STRING, json_dispatch_const_path, offsetof(UnitLookupParameters, cgroup), SD_JSON_STRICT /* require normalized path */ }, {} }; diff --git a/src/shared/varlink-io.systemd.Unit.c b/src/shared/varlink-io.systemd.Unit.c index 3f9e7c40f2b..b4c7e22b382 100644 --- a/src/shared/varlink-io.systemd.Unit.c +++ b/src/shared/varlink-io.systemd.Unit.c @@ -1017,6 +1017,8 @@ static SD_VARLINK_DEFINE_METHOD_FULL( SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("If non-null the PID of a unit. Special value 0 means to take pid of the caller."), SD_VARLINK_DEFINE_INPUT_BY_TYPE(pid, ProcessId, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("If non-null the cgroup of a unit"), + SD_VARLINK_DEFINE_INPUT(cgroup, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Configuration of the unit"), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(context, UnitContext, 0), SD_VARLINK_FIELD_COMMENT("Runtime information of the unit"), -- 2.47.3