1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

machined: port all varlink APIs over to new PidRef serialization

This commit is contained in:
Lennart Poettering 2024-10-11 13:51:25 +02:00
parent de34ec188c
commit 6bca1a7c6c
5 changed files with 62 additions and 44 deletions

View File

@ -200,8 +200,8 @@ static int lookup_machine_by_name(sd_varlink *link, Manager *manager, const char
return 0;
}
static int lookup_machine_by_pid(sd_varlink *link, Manager *manager, pid_t pid, Machine **ret_machine) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
static int lookup_machine_by_pidref(sd_varlink *link, Manager *manager, const PidRef *pidref, Machine **ret_machine) {
_cleanup_(pidref_done) PidRef peer = PIDREF_NULL;
Machine *machine;
int r;
@ -209,16 +209,16 @@ static int lookup_machine_by_pid(sd_varlink *link, Manager *manager, pid_t pid,
assert(manager);
assert(ret_machine);
if (pid == PID_AUTOMATIC) {
r = varlink_get_peer_pidref(link, &pidref);
if (pidref_is_automatic(pidref)) {
r = varlink_get_peer_pidref(link, &peer);
if (r < 0)
return log_debug_errno(r, "Failed to get peer pidref: %m");
}
if (!pidref_is_set(&pidref))
pidref = &peer;
} else if (!pidref_is_set(pidref))
return -EINVAL;
r = manager_get_machine_by_pidref(manager, &pidref, &machine);
r = manager_get_machine_by_pidref(manager, pidref, &machine);
if (r < 0)
return r;
if (!machine)
@ -228,7 +228,7 @@ static int lookup_machine_by_pid(sd_varlink *link, Manager *manager, pid_t pid,
return 0;
}
int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char *machine_name, pid_t pid, Machine **ret_machine) {
int lookup_machine_by_name_or_pidref(sd_varlink *link, Manager *manager, const char *machine_name, const PidRef *pidref, Machine **ret_machine) {
Machine *machine = NULL, *pid_machine = NULL;
int r;
@ -244,8 +244,8 @@ int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char
return r;
}
if (pid_is_valid_or_automatic(pid)) {
r = lookup_machine_by_pid(link, manager, pid, &pid_machine);
if (pidref_is_set(pidref) || pidref_is_automatic(pidref)) {
r = lookup_machine_by_pidref(link, manager, pidref, &pid_machine);
if (r == -EINVAL)
return sd_varlink_error_invalid_parameter_name(link, "pid");
if (r < 0)
@ -253,7 +253,7 @@ int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char
}
if (machine && pid_machine && machine != pid_machine)
return log_debug_errno(SYNTHETIC_ERRNO(ESRCH), "Search by machine name '%s' and pid %d resulted in two different machines", machine_name, pid);
return log_debug_errno(SYNTHETIC_ERRNO(ESRCH), "Search by machine name '%s' and pid " PID_FMT " resulted in two different machines", machine_name, pidref->pid);
if (machine)
*ret_machine = machine;
else if (pid_machine)
@ -308,24 +308,32 @@ 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;
};
typedef struct MachineKillParameters {
const char *name;
PidRef pidref;
const char *swhom;
int32_t signo;
} MachineKillParameters;
static void machine_kill_paramaters_done(MachineKillParameters *p) {
assert(p);
pidref_done(&p->pidref);
}
int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
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_signal, offsetof(struct params, signo), SD_JSON_MANDATORY },
VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineKillParameters),
{ "whom", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MachineKillParameters, swhom), 0 },
{ "signal", _SD_JSON_VARIANT_TYPE_INVALID , sd_json_dispatch_signal, offsetof(MachineKillParameters, signo), SD_JSON_MANDATORY },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
Manager *manager = ASSERT_PTR(userdata);
struct params p = {};
_cleanup_(machine_kill_paramaters_done) MachineKillParameters p = {
.pidref = PIDREF_NULL,
};
KillWhom whom;
int r;
@ -337,7 +345,7 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
return r;
Machine *machine;
r = lookup_machine_by_name_or_pid(link, manager, p.machine_name, p.pid, &machine);
r = lookup_machine_by_name_or_pidref(link, manager, p.name, &p.pidref, &machine);
if (r == -ESRCH)
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
if (r < 0)

View File

@ -5,20 +5,20 @@
#include "machine.h"
#define VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(t) { \
.name = "name", \
.type = SD_JSON_VARIANT_STRING, \
.callback = sd_json_dispatch_const_string, \
.offset = offsetof(t, machine_name) \
}, { \
.name = "pid", \
.type = _SD_JSON_VARIANT_TYPE_INVALID, \
.callback = sd_json_dispatch_pid, \
.offset = offsetof(t, pid), \
.flags = SD_JSON_RELAX /* allows pid=0 */ \
#define VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(t) { \
.name = "name", \
.type = SD_JSON_VARIANT_STRING, \
.callback = sd_json_dispatch_const_string, \
.offset = offsetof(t, name) \
}, { \
.name = "pid", \
.type = _SD_JSON_VARIANT_TYPE_INVALID, \
.callback = json_dispatch_pidref, \
.offset = offsetof(t, pidref), \
.flags = SD_JSON_RELAX /* allows PID_AUTOMATIC */ \
}
int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char *machine_name, pid_t pid, Machine **ret_machine);
int lookup_machine_by_name_or_pidref(sd_varlink *link, Manager *manager, const char *machine_name, const PidRef *pidref, Machine **ret_machine);
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);

View File

@ -419,10 +419,16 @@ static int list_machine_one(sd_varlink *link, Machine *m, bool more) {
}
typedef struct MachineLookupParameters {
const char *machine_name;
pid_t pid;
const char *name;
PidRef pidref;
} MachineLookupParameters;
static void machine_lookup_parameters_done(MachineLookupParameters *p) {
assert(p);
pidref_done(&p->pidref);
}
static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
static const sd_json_dispatch_field dispatch_table[] = {
VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineLookupParameters),
@ -431,7 +437,9 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
};
Manager *m = ASSERT_PTR(userdata);
MachineLookupParameters p = {};
_cleanup_(machine_lookup_parameters_done) MachineLookupParameters p = {
.pidref = PIDREF_NULL,
};
Machine *machine;
int r;
@ -442,8 +450,8 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
if (r != 0)
return r;
if (p.machine_name || pid_is_valid_or_automatic(p.pid)) {
r = lookup_machine_by_name_or_pid(link, m, p.machine_name, p.pid, &machine);
if (p.name || pidref_is_set(&p.pidref) || pidref_is_automatic(&p.pidref)) {
r = lookup_machine_by_name_or_pidref(link, m, p.name, &p.pidref, &machine);
if (r == -ESRCH)
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
if (r < 0)
@ -480,7 +488,9 @@ static int lookup_machine_and_call_method(sd_varlink *link, sd_json_variant *par
};
Manager *manager = ASSERT_PTR(userdata);
MachineLookupParameters p = {};
_cleanup_(machine_lookup_parameters_done) MachineLookupParameters p = {
.pidref = PIDREF_NULL,
};
Machine *machine;
int r;
@ -491,7 +501,7 @@ static int lookup_machine_and_call_method(sd_varlink *link, sd_json_variant *par
if (r != 0)
return r;
r = lookup_machine_by_name_or_pid(link, manager, p.machine_name, p.pid, &machine);
r = lookup_machine_by_name_or_pidref(link, manager, p.name, &p.pidref, &machine);
if (r == -ESRCH)
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
if (r < 0)

View File

@ -10,7 +10,7 @@
SD_VARLINK_FIELD_COMMENT("If non-null the name of a machine."), \
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), \
SD_VARLINK_FIELD_COMMENT("If non-null the PID of a machine. Special value 0 means to take pid of the machine the caller is part of."), \
SD_VARLINK_DEFINE_INPUT(pid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), \
SD_VARLINK_DEFINE_INPUT_BY_TYPE(pid, ProcessId, SD_VARLINK_NULLABLE), \
VARLINK_DEFINE_POLKIT_INPUT
static SD_VARLINK_DEFINE_METHOD(

View File

@ -251,7 +251,7 @@ varlinkctl --more call /run/systemd/machine/io.systemd.Machine io.systemd.Machin
varlinkctl --more call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List '{}' | grep '.host'
varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List '{"name":"long-running"}'
pid=$(varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List '{"name":"long-running"}' | jq '.leader.pid')
pid=$(varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List '{"name":"long-running"}' | jq '.leader')
varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List '{"name":"long-running"}' >/tmp/expected
varlinkctl call /run/systemd/machine/io.systemd.Machine io.systemd.Machine.List "{\"pid\":$pid}" >/tmp/got
diff -u /tmp/expected /tmp/got