mirror of
https://github.com/systemd/systemd.git
synced 2024-10-28 20:25:38 +03:00
shared: split out BusObjectImplementor APIs
Just some refactoring, no code changes
This commit is contained in:
parent
7aee1e7304
commit
c664cf5607
@ -4,7 +4,7 @@
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "unit.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
|
||||
extern const sd_bus_vtable bus_job_vtable[];
|
||||
extern const BusObjectImplementation job_object;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
#include "homed-home.h"
|
||||
|
||||
int bus_home_client_is_trusted(Home *h, sd_bus_message *message);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "bus-internal.h"
|
||||
#include "bus-track.h"
|
||||
#include "bus-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
struct track_item {
|
||||
unsigned n_ref;
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "logind.h"
|
||||
#include "bus-object.h"
|
||||
#include "logind-session.h"
|
||||
#include "logind-user.h"
|
||||
#include "logind.h"
|
||||
|
||||
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret);
|
||||
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret);
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-object.h"
|
||||
#include "logind-seat.h"
|
||||
#include "bus-util.h"
|
||||
|
||||
extern const BusObjectImplementation seat_object;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-object.h"
|
||||
#include "logind-session.h"
|
||||
|
||||
extern const BusObjectImplementation session_object;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
#include "machined.h"
|
||||
|
||||
extern const BusObjectImplementation image_object;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
#include "resolved-manager.h"
|
||||
|
||||
extern const BusObjectImplementation manager_object;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
|
||||
extern const BusObjectImplementation dnssd_object;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
|
||||
extern const BusObjectImplementation log_control_object;
|
||||
static inline int bus_log_control_api_register(sd_bus *bus) {
|
||||
|
177
src/shared/bus-object.c
Normal file
177
src/shared/bus-object.c
Normal file
@ -0,0 +1,177 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "bus-introspect.h"
|
||||
#include "bus-object.h"
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
|
||||
int r;
|
||||
|
||||
log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = sd_bus_add_object_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
*p,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
p->vtable,
|
||||
p->object_find,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
if (impl->node_enumerator) {
|
||||
r = sd_bus_add_node_enumerator(bus, NULL,
|
||||
impl->path,
|
||||
impl->node_enumerator,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add node enumerator for %s: %m",
|
||||
impl->path);
|
||||
}
|
||||
|
||||
if (impl->manager) {
|
||||
r = sd_bus_add_object_manager(bus, NULL, impl->path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add object manager for %s: %m", impl->path);
|
||||
}
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = bus_add_implementation(bus, impl->children[i], userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const BusObjectImplementation* find_implementation(
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
|
||||
const BusObjectImplementation *impl = bus_objects[i];
|
||||
|
||||
if (STR_IN_SET(pattern, impl->path, impl->interface))
|
||||
return impl;
|
||||
|
||||
impl = find_implementation(pattern, impl->children);
|
||||
if (impl)
|
||||
return impl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int bus_introspect_implementation(
|
||||
struct introspect *intro,
|
||||
const BusObjectImplementation *impl) {
|
||||
int r;
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, *p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, p->vtable);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void list_paths(
|
||||
FILE *out,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects[i]; i++) {
|
||||
fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
|
||||
if (bus_objects[i]->children)
|
||||
list_paths(out, bus_objects[i]->children);
|
||||
}
|
||||
}
|
||||
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
const BusObjectImplementation *impl, *main_impl = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
if (streq(pattern, "list")) {
|
||||
list_paths(out, bus_objects);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct introspect intro = {};
|
||||
bool is_interface = sd_bus_interface_name_is_valid(pattern);
|
||||
|
||||
impl = find_implementation(pattern, bus_objects);
|
||||
if (!impl)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"%s %s not found",
|
||||
is_interface ? "Interface" : "Object path",
|
||||
pattern);
|
||||
|
||||
/* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
|
||||
r = introspect_begin(&intro, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
r = introspect_write_default_interfaces(&intro, impl->manager);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
/* Check if there is a non-fallback path that applies to the given interface, also
|
||||
* print it. This is useful in the case of units: o.fd.systemd1.Service is declared
|
||||
* as a fallback vtable for o/fd/systemd1/unit, and we also want to print
|
||||
* o.fd.systemd1.Unit, which is the non-fallback implementation. */
|
||||
if (impl->fallback_vtables && is_interface)
|
||||
main_impl = find_implementation(impl->path, bus_objects);
|
||||
|
||||
if (main_impl)
|
||||
bus_introspect_implementation(&intro, main_impl);
|
||||
|
||||
if (impl != main_impl)
|
||||
bus_introspect_implementation(&intro, impl);
|
||||
|
||||
_cleanup_set_free_ Set *nodes = NULL;
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = set_put_strdup(&nodes, impl->children[i]->path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = introspect_write_child_nodes(&intro, nodes, impl->path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = introspect_finish(&intro, &s);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
fputs(s, out);
|
||||
return 0;
|
||||
}
|
34
src/shared/bus-object.h
Normal file
34
src/shared/bus-object.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
typedef struct BusObjectImplementation BusObjectImplementation;
|
||||
|
||||
typedef struct BusObjectVtablePair {
|
||||
const sd_bus_vtable *vtable;
|
||||
sd_bus_object_find_t object_find;
|
||||
} BusObjectVtablePair;
|
||||
|
||||
struct BusObjectImplementation {
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const sd_bus_vtable **vtables;
|
||||
const BusObjectVtablePair *fallback_vtables;
|
||||
sd_bus_node_enumerator_t node_enumerator;
|
||||
bool manager;
|
||||
const BusObjectImplementation **children;
|
||||
};
|
||||
|
||||
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
|
||||
#define BUS_FALLBACK_VTABLES(...) ((const BusObjectVtablePair[]) { __VA_ARGS__, {} })
|
||||
#define BUS_IMPLEMENTATIONS(...) ((const BusObjectImplementation* []) { __VA_ARGS__, NULL })
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata);
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects);
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-internal.h"
|
||||
#include "bus-introspect.h"
|
||||
#include "bus-label.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-util.h"
|
||||
@ -30,6 +29,7 @@
|
||||
#include "rlimit-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
|
||||
@ -1546,173 +1546,3 @@ int bus_message_new_method_call(
|
||||
|
||||
return sd_bus_message_new_method_call(bus, m, locator->destination, locator->path, locator->interface, member);
|
||||
}
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
|
||||
int r;
|
||||
|
||||
log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = sd_bus_add_object_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
*p,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = sd_bus_add_fallback_vtable(bus, NULL,
|
||||
impl->path,
|
||||
impl->interface,
|
||||
p->vtable,
|
||||
p->object_find,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
|
||||
impl->path,
|
||||
impl->interface);
|
||||
}
|
||||
|
||||
if (impl->node_enumerator) {
|
||||
r = sd_bus_add_node_enumerator(bus, NULL,
|
||||
impl->path,
|
||||
impl->node_enumerator,
|
||||
userdata);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add node enumerator for %s: %m",
|
||||
impl->path);
|
||||
}
|
||||
|
||||
if (impl->manager) {
|
||||
r = sd_bus_add_object_manager(bus, NULL, impl->path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add object manager for %s: %m", impl->path);
|
||||
}
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = bus_add_implementation(bus, impl->children[i], userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const BusObjectImplementation* find_implementation(
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
|
||||
const BusObjectImplementation *impl = bus_objects[i];
|
||||
|
||||
if (STR_IN_SET(pattern, impl->path, impl->interface))
|
||||
return impl;
|
||||
|
||||
impl = find_implementation(pattern, impl->children);
|
||||
if (impl)
|
||||
return impl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int bus_introspect_implementation(
|
||||
struct introspect *intro,
|
||||
const BusObjectImplementation *impl) {
|
||||
int r;
|
||||
|
||||
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, *p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
|
||||
r = introspect_write_interface(intro, impl->interface, p->vtable);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void list_paths(
|
||||
FILE *out,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
for (size_t i = 0; bus_objects[i]; i++) {
|
||||
fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
|
||||
if (bus_objects[i]->children)
|
||||
list_paths(out, bus_objects[i]->children);
|
||||
}
|
||||
}
|
||||
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects) {
|
||||
|
||||
const BusObjectImplementation *impl, *main_impl = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
if (streq(pattern, "list")) {
|
||||
list_paths(out, bus_objects);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct introspect intro = {};
|
||||
bool is_interface = sd_bus_interface_name_is_valid(pattern);
|
||||
|
||||
impl = find_implementation(pattern, bus_objects);
|
||||
if (!impl)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"%s %s not found",
|
||||
is_interface ? "Interface" : "Object path",
|
||||
pattern);
|
||||
|
||||
/* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
|
||||
r = introspect_begin(&intro, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
r = introspect_write_default_interfaces(&intro, impl->manager);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
/* Check if there is a non-fallback path that applies to the given interface, also
|
||||
* print it. This is useful in the case of units: o.fd.systemd1.Service is declared
|
||||
* as a fallback vtable for o/fd/systemd1/unit, and we also want to print
|
||||
* o.fd.systemd1.Unit, which is the non-fallback implementation. */
|
||||
if (impl->fallback_vtables && is_interface)
|
||||
main_impl = find_implementation(impl->path, bus_objects);
|
||||
|
||||
if (main_impl)
|
||||
bus_introspect_implementation(&intro, main_impl);
|
||||
|
||||
if (impl != main_impl)
|
||||
bus_introspect_implementation(&intro, impl);
|
||||
|
||||
_cleanup_set_free_ Set *nodes = NULL;
|
||||
|
||||
for (size_t i = 0; impl->children && impl->children[i]; i++) {
|
||||
r = set_put_strdup(&nodes, impl->children[i]->path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = introspect_write_child_nodes(&intro, nodes, impl->path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = introspect_finish(&intro, &s);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write introspection data: %m");
|
||||
|
||||
fputs(s, out);
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,26 +23,6 @@ typedef enum BusTransport {
|
||||
_BUS_TRANSPORT_INVALID = -1
|
||||
} BusTransport;
|
||||
|
||||
typedef struct BusObjectImplementation BusObjectImplementation;
|
||||
|
||||
typedef struct BusObjectVtablePair {
|
||||
const sd_bus_vtable *vtable;
|
||||
sd_bus_object_find_t object_find;
|
||||
} BusObjectVtablePair;
|
||||
|
||||
struct BusObjectImplementation {
|
||||
const char *path;
|
||||
const char *interface;
|
||||
const sd_bus_vtable **vtables;
|
||||
const BusObjectVtablePair *fallback_vtables;
|
||||
sd_bus_node_enumerator_t node_enumerator;
|
||||
bool manager;
|
||||
const BusObjectImplementation **children;
|
||||
};
|
||||
|
||||
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
|
||||
#define BUS_FALLBACK_VTABLES(...) ((const BusObjectVtablePair[]) { __VA_ARGS__, {} })
|
||||
#define BUS_IMPLEMENTATIONS(...) ((const BusObjectImplementation* []) { __VA_ARGS__, NULL })
|
||||
|
||||
typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
|
||||
|
||||
@ -215,9 +195,3 @@ int bus_set_property(sd_bus *bus, const BusLocator *locator, const char *member,
|
||||
int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, void *userdata);
|
||||
int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata);
|
||||
int bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const BusLocator *locator, const char *member);
|
||||
|
||||
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata);
|
||||
int bus_introspect_implementations(
|
||||
FILE *out,
|
||||
const char *pattern,
|
||||
const BusObjectImplementation* const* bus_objects);
|
||||
|
@ -31,6 +31,8 @@ shared_sources = files('''
|
||||
bus-locator.h
|
||||
bus-log-control-api.c
|
||||
bus-log-control-api.h
|
||||
bus-object.c
|
||||
bus-object.h
|
||||
bus-polkit.c
|
||||
bus-polkit.h
|
||||
bus-unit-procs.c
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "bus-object.h"
|
||||
|
||||
int service_parse_argv(
|
||||
const char *service,
|
||||
|
Loading…
Reference in New Issue
Block a user