From: Ivan Kruglov Date: Mon, 7 Oct 2024 09:27:41 +0000 (+0200) Subject: machine: introduce io.systemd.Machine.Kill varlink method X-Git-Tag: v257-rc1~301^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17d9f172ebbe6ab6f23775a2756696e0ab2f582a;p=thirdparty%2Fsystemd.git machine: introduce io.systemd.Machine.Kill varlink method --- diff --git a/src/machine/machine-varlink.c b/src/machine/machine-varlink.c index 06c59887aa7..d565859cae1 100644 --- a/src/machine/machine-varlink.c +++ b/src/machine/machine-varlink.c @@ -14,6 +14,7 @@ #include "path-util.h" #include "pidref.h" #include "process-util.h" +#include "signal-util.h" #include "socket-util.h" #include "string-util.h" #include "varlink-util.h" @@ -319,3 +320,66 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters, return sd_varlink_reply(link, NULL); } + +int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + struct params { + const char *machine_name; + pid_t pid; + const char *swhom; + int32_t signo; + }; + + static const sd_json_dispatch_field dispatch_table[] = { + VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(struct params), + { "whom", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(struct params, swhom), 0 }, + { "signal", _SD_JSON_VARIANT_TYPE_INVALID , sd_json_dispatch_int32, offsetof(struct params, signo), SD_JSON_MANDATORY }, + VARLINK_DISPATCH_POLKIT_FIELD, + {} + }; + + Manager *manager = ASSERT_PTR(userdata); + struct params p = { .pid = -1 }; + KillWhom whom; + int r; + + assert(link); + assert(parameters); + + r = sd_varlink_dispatch(link, parameters, dispatch_table, &p); + if (r != 0) + return r; + + Machine *machine; + r = lookup_machine_by_name_or_pid(link, manager, p.machine_name, p.pid, &machine); + if (r == -ESRCH) + return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL); + if (r < 0) + return r; + + if (isempty(p.swhom)) + whom = KILL_ALL; + else { + whom = kill_whom_from_string(p.swhom); + if (whom < 0) + return sd_varlink_error_invalid_parameter_name(link, "whom"); + } + + if (!SIGNAL_VALID(p.signo)) + return sd_varlink_error_invalid_parameter_name(link, "signal"); + + r = varlink_verify_polkit_async( + link, + manager->bus, + "org.freedesktop.machine1.manage-machines", + (const char**) STRV_MAKE("name", machine->name, + "verb", "kill"), + &manager->polkit_registry); + if (r <= 0) + return r; + + r = machine_kill(machine, whom, p.signo); + if (r < 0) + return log_debug_errno(r, "Failed to send signal to machine: %m"); + + return sd_varlink_reply(link, NULL); +} diff --git a/src/machine/machine-varlink.h b/src/machine/machine-varlink.h index 8b0efc2a639..4ee15ce40b5 100644 --- a/src/machine/machine-varlink.h +++ b/src/machine/machine-varlink.h @@ -22,3 +22,4 @@ int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); +int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index fbf03ad4a16..57ef866b2cf 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -571,7 +571,8 @@ static int manager_varlink_init_machine(Manager *m) { "io.systemd.Machine.Register", vl_method_register, "io.systemd.Machine.List", vl_method_list, "io.systemd.Machine.Unregister", vl_method_unregister, - "io.systemd.Machine.Terminate", vl_method_terminate); + "io.systemd.Machine.Terminate", vl_method_terminate, + "io.systemd.Machine.Kill", vl_method_kill); if (r < 0) return log_error_errno(r, "Failed to register varlink methods: %m"); diff --git a/src/shared/varlink-io.systemd.Machine.c b/src/shared/varlink-io.systemd.Machine.c index d37f31bc3f1..dfcf210b8a2 100644 --- a/src/shared/varlink-io.systemd.Machine.c +++ b/src/shared/varlink-io.systemd.Machine.c @@ -38,6 +38,15 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_FIELD_COMMENT("The name of a machine to terminate."), SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0)); +static SD_VARLINK_DEFINE_METHOD( + Kill, + SD_VARLINK_FIELD_COMMENT("The name of a machine to send signal to."), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("Identifier that specifies what precisely to send the signal to (either 'leader' or 'all')."), + SD_VARLINK_DEFINE_INPUT(whom, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Numeric UNIX signal integer."), + SD_VARLINK_DEFINE_INPUT(signal, SD_VARLINK_INT, 0)); + static SD_VARLINK_DEFINE_METHOD_FULL( List, SD_VARLINK_SUPPORTS_MORE, @@ -78,6 +87,8 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_method_Unregister, SD_VARLINK_SYMBOL_COMMENT("Terminate machine, killing its processes"), &vl_method_Terminate, + SD_VARLINK_SYMBOL_COMMENT("Send a UNIX signal to the machine's processes"), + &vl_method_Kill, SD_VARLINK_SYMBOL_COMMENT("List running machines"), &vl_method_List, SD_VARLINK_SYMBOL_COMMENT("No matching machine currently running"),