mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
machine: io.systemd.Machine.List supports 'pid' filter
This commit is contained in:
parent
5540c37bb8
commit
1bd979dddb
@ -188,3 +188,90 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
|
||||
|
||||
return sd_varlink_reply(link, NULL);
|
||||
}
|
||||
|
||||
static int lookup_machine_by_name(sd_varlink *link, Manager *manager, const char *machine_name, Machine **ret_machine) {
|
||||
assert(link);
|
||||
assert(manager);
|
||||
assert(ret_machine);
|
||||
|
||||
if (!machine_name)
|
||||
return -EINVAL;
|
||||
|
||||
if (!hostname_is_valid(machine_name, /* flags= */ VALID_HOSTNAME_DOT_HOST))
|
||||
return -EINVAL;
|
||||
|
||||
Machine *machine = hashmap_get(manager->machines, machine_name);
|
||||
if (!machine)
|
||||
return -ESRCH;
|
||||
|
||||
*ret_machine = machine;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lookup_machine_by_pid(sd_varlink *link, Manager *manager, pid_t pid, Machine **ret_machine) {
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(manager);
|
||||
assert(ret_machine);
|
||||
assert_cc(sizeof(pid_t) == sizeof(uint32_t));
|
||||
|
||||
if (pid == 0) {
|
||||
int pidfd = sd_varlink_get_peer_pidfd(link);
|
||||
if (pidfd < 0)
|
||||
return log_debug_errno(pidfd, "Failed to get peer pidfd: %m");
|
||||
|
||||
r = pidfd_get_pid(pidfd, &pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get pid from pidfd: %m");
|
||||
}
|
||||
|
||||
if (pid <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = manager_get_machine_by_pid(manager, pid, &machine);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!machine)
|
||||
return -ESRCH;
|
||||
|
||||
*ret_machine = machine;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char *machine_name, pid_t pid, Machine **ret_machine) {
|
||||
Machine *machine = NULL, *pid_machine = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(manager);
|
||||
assert(ret_machine);
|
||||
|
||||
if (machine_name) {
|
||||
r = lookup_machine_by_name(link, manager, machine_name, &machine);
|
||||
if (r == -EINVAL)
|
||||
return sd_varlink_error_invalid_parameter_name(link, "name");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pid >= 0) {
|
||||
r = lookup_machine_by_pid(link, manager, pid, &pid_machine);
|
||||
if (r == -EINVAL)
|
||||
return sd_varlink_error_invalid_parameter_name(link, "pid");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
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);
|
||||
else if (machine)
|
||||
*ret_machine = machine;
|
||||
else if (pid_machine)
|
||||
*ret_machine = pid_machine;
|
||||
else
|
||||
return -ESRCH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,4 +3,20 @@
|
||||
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#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_uint32, \
|
||||
.offset = offsetof(t, pid) \
|
||||
}
|
||||
|
||||
int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char *machine_name, pid_t pid, Machine **ret_machine);
|
||||
|
||||
int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "format-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "json-util.h"
|
||||
@ -415,29 +416,36 @@ static int list_machine_one(sd_varlink *link, Machine *m, bool more) {
|
||||
return sd_varlink_reply(link, v);
|
||||
}
|
||||
|
||||
typedef struct MachineLookupParameters {
|
||||
const char *machine_name;
|
||||
pid_t pid;
|
||||
} MachineLookupParameters;
|
||||
|
||||
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[] = {
|
||||
{ "name", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, 0 },
|
||||
VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineLookupParameters),
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
const char *mn = NULL;
|
||||
MachineLookupParameters p = { .pid = -1 };
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(parameters);
|
||||
|
||||
r = sd_varlink_dispatch(link, parameters, dispatch_table, &mn);
|
||||
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (mn) {
|
||||
if (!hostname_is_valid(mn, /* flags= */ VALID_HOSTNAME_DOT_HOST))
|
||||
return sd_varlink_error_invalid_parameter_name(link, "name");
|
||||
|
||||
Machine *machine = hashmap_get(m->machines, mn);
|
||||
if (!machine)
|
||||
if (p.machine_name || p.pid >= 0) {
|
||||
r = lookup_machine_by_name_or_pid(link, m, p.machine_name, p.pid, &machine);
|
||||
if (r == -ESRCH)
|
||||
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return list_machine_one(link, machine, /* more= */ false);
|
||||
}
|
||||
|
@ -31,8 +31,10 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
List,
|
||||
SD_VARLINK_SUPPORTS_MORE,
|
||||
SD_VARLINK_FIELD_COMMENT("If non-null the name of a running machine to report details on. If null/unspecified enumerates all running machines."),
|
||||
SD_VARLINK_FIELD_COMMENT("If non-null the name of a running machine to report details on. If both 'name' and 'pid' are null/unspecified enumerates all running machines."),
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("If non-null the PID of a running machine to report details on."),
|
||||
SD_VARLINK_DEFINE_INPUT(pid, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Name of the machine"),
|
||||
SD_VARLINK_DEFINE_OUTPUT(name, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("128bit ID identifying this machine, formatted in hexadecimal"),
|
||||
|
Loading…
Reference in New Issue
Block a user