mirror of
https://github.com/systemd/systemd.git
synced 2025-02-18 21:57:48 +03:00
Merge pull request #34681 from ikruglov/ikruglov/io-systemd-Machine-post-merge-review
machine: address post-merge review #34623
This commit is contained in:
commit
373c810e04
@ -148,10 +148,21 @@ static inline bool sched_priority_is_valid(int i) {
|
||||
return i >= 0 && i <= sched_get_priority_max(SCHED_RR);
|
||||
}
|
||||
|
||||
#define PID_AUTOMATIC ((pid_t) INT_MIN) /* special value indicating "acquire pid from connection peer */
|
||||
#define PID_INVALID ((pid_t) 0) /* default value for "invalid pid" */
|
||||
|
||||
static inline bool pid_is_valid(pid_t p) {
|
||||
return p > 0;
|
||||
}
|
||||
|
||||
static inline bool pid_is_automatic(pid_t p) {
|
||||
return p == PID_AUTOMATIC;
|
||||
}
|
||||
|
||||
static inline bool pid_is_valid_or_automatic(pid_t p) {
|
||||
return pid_is_valid(p) || pid_is_automatic(p);
|
||||
}
|
||||
|
||||
pid_t getpid_cached(void);
|
||||
void reset_cached_pid(void);
|
||||
|
||||
|
@ -46,6 +46,7 @@ static inline void block_signals_reset(sigset_t *ss) {
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__) >= 0); \
|
||||
_t; \
|
||||
})
|
||||
#define SIGNO_INVALID (-EINVAL)
|
||||
|
||||
static inline bool SIGNAL_VALID(int signo) {
|
||||
return signo > 0 && signo < _NSIG;
|
||||
|
@ -864,10 +864,12 @@ global:
|
||||
sd_json_dispatch_strv;
|
||||
sd_json_dispatch_tristate;
|
||||
sd_json_dispatch_uid_gid;
|
||||
sd_json_dispatch_pid;
|
||||
sd_json_dispatch_uint16;
|
||||
sd_json_dispatch_uint32;
|
||||
sd_json_dispatch_uint64;
|
||||
sd_json_dispatch_uint8;
|
||||
sd_json_dispatch_signal;
|
||||
sd_json_dispatch_unsupported;
|
||||
sd_json_dispatch_variant;
|
||||
sd_json_dispatch_variant_noref;
|
||||
|
@ -29,7 +29,9 @@
|
||||
#include "memory-util.h"
|
||||
#include "memstream-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "set.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@ -5506,6 +5508,44 @@ _public_ int sd_json_dispatch_uid_gid(const char *name, sd_json_variant *variant
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_json_dispatch_pid(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
/* pid_t is a signed type, but we don't consider negative values as valid.
|
||||
* There is a special treatment for 0 if SD_JSON_RELAX flag present. */
|
||||
|
||||
pid_t *pid = userdata;
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert_return(variant, -EINVAL);
|
||||
assert_cc(sizeof(pid_t) == sizeof(uint32_t));
|
||||
|
||||
if (sd_json_variant_is_null(variant)) {
|
||||
*pid = PID_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_json_dispatch_uint32(name, variant, flags, &k);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (k == 0) {
|
||||
if (!FLAGS_SET(flags, SD_JSON_RELAX))
|
||||
goto invalid_value;
|
||||
|
||||
*pid = PID_AUTOMATIC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pid_is_valid(k))
|
||||
goto invalid_value;
|
||||
|
||||
*pid = k;
|
||||
return 0;
|
||||
|
||||
invalid_value:
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid PID.", strna(name));
|
||||
}
|
||||
|
||||
_public_ int sd_json_dispatch_id128(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
sd_id128_t *uuid = userdata;
|
||||
int r;
|
||||
@ -5527,6 +5567,29 @@ _public_ int sd_json_dispatch_id128(const char *name, sd_json_variant *variant,
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_json_dispatch_signal(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
int *signo = userdata;
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert_return(variant, -EINVAL);
|
||||
|
||||
if (sd_json_variant_is_null(variant)) {
|
||||
*signo = SIGNO_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_json_dispatch_uint32(name, variant, flags, &k);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!SIGNAL_VALID(k))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid signal.", strna(name));
|
||||
|
||||
*signo = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_json_dispatch_unsupported(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not allowed in this object.", strna(name));
|
||||
}
|
||||
|
@ -995,23 +995,23 @@ static int machine_object_find(sd_bus *bus, const char *path, const char *interf
|
||||
assert(found);
|
||||
|
||||
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
message = sd_bus_get_current_message(bus);
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
r = bus_creds_get_pidref(creds, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_machine_by_pid(m, pid, &machine);
|
||||
r = manager_get_machine_by_pidref(m, &pidref, &machine);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -210,28 +210,24 @@ static int lookup_machine_by_name(sd_varlink *link, Manager *manager, const char
|
||||
}
|
||||
|
||||
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);
|
||||
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 (pid == PID_AUTOMATIC) {
|
||||
r = varlink_get_peer_pidref(link, &pidref);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get pid from pidfd: %m");
|
||||
return log_debug_errno(r, "Failed to get peer pidref: %m");
|
||||
}
|
||||
|
||||
if (pid <= 0)
|
||||
if (!pidref_is_set(&pidref))
|
||||
return -EINVAL;
|
||||
|
||||
r = manager_get_machine_by_pid(manager, pid, &machine);
|
||||
r = manager_get_machine_by_pidref(manager, &pidref, &machine);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!machine)
|
||||
@ -257,7 +253,7 @@ int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pid >= 0) {
|
||||
if (pid_is_valid_or_automatic(pid)) {
|
||||
r = lookup_machine_by_pid(link, manager, pid, &pid_machine);
|
||||
if (r == -EINVAL)
|
||||
return sd_varlink_error_invalid_parameter_name(link, "pid");
|
||||
@ -267,7 +263,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);
|
||||
else if (machine)
|
||||
if (machine)
|
||||
*ret_machine = machine;
|
||||
else if (pid_machine)
|
||||
*ret_machine = pid_machine;
|
||||
@ -332,13 +328,13 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
|
||||
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 },
|
||||
{ "signal", _SD_JSON_VARIANT_TYPE_INVALID , sd_json_dispatch_signal, offsetof(struct params, signo), SD_JSON_MANDATORY },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
struct params p = { .pid = -1 };
|
||||
struct params p = {};
|
||||
KillWhom whom;
|
||||
int r;
|
||||
|
||||
@ -364,9 +360,6 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
|
||||
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,
|
||||
|
@ -13,8 +13,9 @@
|
||||
}, { \
|
||||
.name = "pid", \
|
||||
.type = _SD_JSON_VARIANT_TYPE_INVALID, \
|
||||
.callback = sd_json_dispatch_uint32, \
|
||||
.offset = offsetof(t, pid) \
|
||||
.callback = sd_json_dispatch_pid, \
|
||||
.offset = offsetof(t, pid), \
|
||||
.flags = SD_JSON_RELAX /* allows pid=0 */ \
|
||||
}
|
||||
|
||||
int lookup_machine_by_name_or_pid(sd_varlink *link, Manager *manager, const char *machine_name, pid_t pid, Machine **ret_machine);
|
||||
|
@ -12,19 +12,19 @@
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **ret) {
|
||||
int manager_get_machine_by_pidref(Manager *m, const PidRef *pidref, Machine **ret) {
|
||||
Machine *mm;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(pid_is_valid(pid));
|
||||
assert(pidref_is_set(pidref));
|
||||
assert(ret);
|
||||
|
||||
mm = hashmap_get(m->machines_by_leader, &PIDREF_MAKE_FROM_PID(pid));
|
||||
mm = hashmap_get(m->machines_by_leader, pidref);
|
||||
if (!mm) {
|
||||
_cleanup_free_ char *unit = NULL;
|
||||
|
||||
r = cg_pid_get_unit(pid, &unit);
|
||||
r = cg_pidref_get_unit(pidref, &unit);
|
||||
if (r >= 0)
|
||||
mm = hashmap_get(m->machines_by_unit, unit);
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_erro
|
||||
}
|
||||
|
||||
static int method_get_machine_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
Machine *machine = NULL;
|
||||
@ -154,19 +155,21 @@ static int method_get_machine_by_pid(sd_bus_message *message, void *userdata, sd
|
||||
if (pid < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pidref = PIDREF_MAKE_FROM_PID(pid);
|
||||
|
||||
if (pid == 0) {
|
||||
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
r = bus_creds_get_pidref(creds, &pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = manager_get_machine_by_pid(m, pid, &machine);
|
||||
r = manager_get_machine_by_pidref(m, &pidref, &machine);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "machine-varlink.h"
|
||||
#include "machined-varlink.h"
|
||||
#include "mkdir.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "user-util.h"
|
||||
#include "varlink-io.systemd.Machine.h"
|
||||
@ -430,7 +431,7 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
|
||||
};
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
MachineLookupParameters p = { .pid = -1 };
|
||||
MachineLookupParameters p = {};
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
@ -441,7 +442,7 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (p.machine_name || p.pid >= 0) {
|
||||
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 (r == -ESRCH)
|
||||
return sd_varlink_error(link, "io.systemd.Machine.NoSuchMachine", NULL);
|
||||
@ -479,7 +480,7 @@ static int lookup_machine_and_call_method(sd_varlink *link, sd_json_variant *par
|
||||
};
|
||||
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
MachineLookupParameters p = { .pid = -1 };
|
||||
MachineLookupParameters p = {};
|
||||
Machine *machine;
|
||||
int r;
|
||||
|
||||
|
@ -16,6 +16,7 @@ typedef struct Manager Manager;
|
||||
#include "machine-dbus.h"
|
||||
#include "machine.h"
|
||||
#include "operation.h"
|
||||
#include "pidref.h"
|
||||
|
||||
struct Manager {
|
||||
sd_event *event;
|
||||
@ -44,7 +45,7 @@ struct Manager {
|
||||
};
|
||||
|
||||
int manager_add_machine(Manager *m, const char *name, Machine **ret);
|
||||
int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **ret);
|
||||
int manager_get_machine_by_pidref(Manager *m, const PidRef *pidref, Machine **ret);
|
||||
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
||||
|
@ -5,6 +5,13 @@
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.Machine.h"
|
||||
|
||||
#define VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS \
|
||||
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), \
|
||||
VARLINK_DEFINE_POLKIT_INPUT
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Register,
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0),
|
||||
@ -30,18 +37,15 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Unregister,
|
||||
SD_VARLINK_FIELD_COMMENT("The name of a machine to unregister."),
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0));
|
||||
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Terminate,
|
||||
SD_VARLINK_FIELD_COMMENT("The name of a machine to terminate."),
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0));
|
||||
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS);
|
||||
|
||||
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),
|
||||
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS,
|
||||
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."),
|
||||
@ -50,10 +54,7 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
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 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),
|
||||
VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS,
|
||||
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"),
|
||||
|
@ -328,7 +328,9 @@ int sd_json_dispatch_int8(const char *name, sd_json_variant *variant, sd_json_di
|
||||
int sd_json_dispatch_uint8(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_double(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_uid_gid(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_pid(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_id128(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_signal(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int sd_json_dispatch_unsupported(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
|
||||
#define sd_json_dispatch_uint sd_json_dispatch_uint32
|
||||
|
Loading…
x
Reference in New Issue
Block a user