From 61d0df3919c1184e47a387c34cef8b2fd25bdbcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 13 Apr 2020 13:34:09 +0200 Subject: [PATCH 01/30] bus-introspect: write from within introspect_write_interface() --- src/libsystemd/sd-bus/bus-introspect.c | 30 ++++++++++++++++++++- src/libsystemd/sd-bus/bus-introspect.h | 6 ++++- src/libsystemd/sd-bus/bus-objects.c | 15 +---------- src/libsystemd/sd-bus/test-bus-introspect.c | 8 +++--- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 07bd98967d..3e2bfc566b 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -40,12 +40,27 @@ int introspect_write_default_interfaces(struct introspect *i, bool object_manage return 0; } +static int set_interface_name(struct introspect *intro, const char *interface_name) { + if (streq_ptr(intro->interface_name, interface_name)) + return 0; + + if (intro->interface_name) + fputs(" \n", intro->f); + + if (interface_name) + fprintf(intro->f, " \n", interface_name); + + return free_and_strdup(&intro->interface_name, interface_name); +} + int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix) { char *node; assert(i); assert(prefix); + assert_se(set_interface_name(i, NULL) >= 0); + while ((node = set_steal_first(s))) { const char *e; @@ -115,13 +130,23 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur } } -int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) { +int introspect_write_interface( + struct introspect *i, + const char *interface_name, + const sd_bus_vtable *v) { + const sd_bus_vtable *vtable = v; const char *names = ""; + int r; assert(i); + assert(interface_name); assert(v); + r = set_interface_name(i, interface_name); + if (r < 0) + return r; + for (; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(vtable, v)) { /* Ignore methods, signals and properties that are @@ -178,6 +203,8 @@ int introspect_finish(struct introspect *i, char **ret) { assert(i); + assert_se(set_interface_name(i, NULL) >= 0); + fputs("\n", i->f); r = fflush_and_check(i->f); @@ -196,5 +223,6 @@ void introspect_free(struct introspect *i) { /* Normally introspect_finish() does all the work, this is just a backup for error paths */ safe_fclose(i->f); + free(i->interface_name); free(i->introspection); } diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h index ccbb543d0c..19d39923e5 100644 --- a/src/libsystemd/sd-bus/bus-introspect.h +++ b/src/libsystemd/sd-bus/bus-introspect.h @@ -9,6 +9,7 @@ struct introspect { FILE *f; + char *interface_name; char *introspection; size_t size; bool trusted; @@ -17,6 +18,9 @@ struct introspect { int introspect_begin(struct introspect *i, bool trusted); int introspect_write_default_interfaces(struct introspect *i, bool object_manager); int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix); -int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v); +int introspect_write_interface( + struct introspect *i, + const char *interface_name, + const sd_bus_vtable *v); int introspect_finish(struct introspect *i, char **ret); void introspect_free(struct introspect *i); diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 913d6eca8a..eaf230709b 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -939,7 +939,6 @@ int introspect_path( sd_bus_error *error) { _cleanup_set_free_free_ Set *s = NULL; - const char *previous_interface = NULL; _cleanup_(introspect_free) struct introspect intro = {}; struct node_vtable *c; bool empty; @@ -984,23 +983,11 @@ int introspect_path( if (c->vtable[0].flags & SD_BUS_VTABLE_HIDDEN) continue; - if (!streq_ptr(previous_interface, c->interface)) { - if (previous_interface) - fputs(" \n", intro.f); - - fprintf(intro.f, " \n", c->interface); - } - - r = introspect_write_interface(&intro, c->vtable); + r = introspect_write_interface(&intro, c->interface, c->vtable); if (r < 0) return r; - - previous_interface = c->interface; } - if (previous_interface) - fputs(" \n", intro.f); - if (empty) { /* Nothing?, let's see if we exist at all, and if not * refuse to do anything */ diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c index 9c8d1434b1..cbc3158924 100644 --- a/src/libsystemd/sd-bus/test-bus-introspect.c +++ b/src/libsystemd/sd-bus/test-bus-introspect.c @@ -14,11 +14,11 @@ static void test_manual_introspection(const sd_bus_vtable vtable[]) { assert_se(introspect_begin(&intro, false) >= 0); - fprintf(intro.f, " \n"); - assert_se(introspect_write_interface(&intro, vtable) >= 0); - fputs(" \n", intro.f); - + assert_se(introspect_write_interface(&intro, "org.foo", vtable) >= 0); + /* write again to check if output looks OK for a different interface */ + assert_se(introspect_write_interface(&intro, "org.foo.bar", vtable) >= 0); assert_se(introspect_finish(&intro, &s) == 0); + fputs(s, stdout); fputs("\n", stdout); } From 2b6a1d155d935a7ee0b0e26304a134f47a8e7ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 13 Apr 2020 14:45:19 +0200 Subject: [PATCH 02/30] bus-introspect: move xml string defines into the .c file --- src/libsystemd/sd-bus/bus-introspect.c | 57 ++++++++++++++++++++++++++ src/libsystemd/sd-bus/bus-protocol.h | 57 -------------------------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 3e2bfc566b..734abcf3fd 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -10,6 +10,63 @@ #include "memory-util.h" #include "string-util.h" +#define BUS_INTROSPECT_DOCTYPE \ + "\n" + +#define BUS_INTROSPECT_INTERFACE_PEER \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_INTROSPECT_INTERFACE_PROPERTIES \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + int introspect_begin(struct introspect *i, bool trusted) { assert(i); diff --git a/src/libsystemd/sd-bus/bus-protocol.h b/src/libsystemd/sd-bus/bus-protocol.h index d01fd8e6a3..7e1cd3c31e 100644 --- a/src/libsystemd/sd-bus/bus-protocol.h +++ b/src/libsystemd/sd-bus/bus-protocol.h @@ -103,60 +103,3 @@ enum { BUS_START_REPLY_SUCCESS = 1, BUS_START_REPLY_ALREADY_RUNNING = 2, }; - -#define BUS_INTROSPECT_DOCTYPE \ - "\n" - -#define BUS_INTROSPECT_INTERFACE_PEER \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" - -#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" - -#define BUS_INTROSPECT_INTERFACE_PROPERTIES \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" - -#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" From b49ca3bc37bce48754f97c0e06ad5422bd70b7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 13 Apr 2020 15:04:06 +0200 Subject: [PATCH 03/30] sd-bus: use STR_IN_SET() in one more place --- src/libsystemd/sd-bus/bus-objects.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index eaf230709b..ad66d634d7 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -827,10 +827,10 @@ static int property_get_all_callbacks_run( if (r < 0) return r; - found_interface = !iface || - streq(iface, "org.freedesktop.DBus.Properties") || - streq(iface, "org.freedesktop.DBus.Peer") || - streq(iface, "org.freedesktop.DBus.Introspectable"); + found_interface = !iface || STR_IN_SET(iface, + "org.freedesktop.DBus.Properties", + "org.freedesktop.DBus.Peer", + "org.freedesktop.DBus.Introspectable"); LIST_FOREACH(vtables, c, first) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; From ab09bf9007fe9e2a1684e831261102699ab97540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 13 Apr 2020 13:47:32 +0200 Subject: [PATCH 04/30] importd: wrap long lines --- src/import/importd.c | 70 ++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/src/import/importd.c b/src/import/importd.c index 417e686bb9..2e5c1c2642 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -488,11 +488,13 @@ static int transfer_start(Transfer *t) { t->stdin_fd = safe_close(t->stdin_fd); - r = sd_event_add_child(t->manager->event, &t->pid_event_source, t->pid, WEXITED, transfer_on_pid, t); + r = sd_event_add_child(t->manager->event, &t->pid_event_source, + t->pid, WEXITED, transfer_on_pid, t); if (r < 0) return r; - r = sd_event_add_io(t->manager->event, &t->log_event_source, t->log_fd, EPOLLIN, transfer_on_log, t); + r = sd_event_add_io(t->manager->event, &t->log_event_source, + t->log_fd, EPOLLIN, transfer_on_log, t); if (r < 0) return r; @@ -657,7 +659,8 @@ static int manager_new(Manager **ret) { if (r < 0) return r; - r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_on_notify, m); + r = sd_event_add_io(m->event, &m->notify_event_source, + m->notify_fd, EPOLLIN, manager_on_notify, m); if (r < 0) return r; @@ -718,13 +721,15 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_ return -EINVAL; if (!machine_name_is_valid(local)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Local name %s is invalid", local); r = setup_machine_directory(error); if (r < 0) return r; - type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW; + type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? + TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW; r = transfer_new(m, &t); if (r < 0) @@ -786,7 +791,8 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e return r; if (!machine_name_is_valid(local)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Local name %s is invalid", local); r = setup_machine_directory(error); if (r < 0) @@ -850,7 +856,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_ return r; if (!machine_name_is_valid(local)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Local name %s is invalid", local); if (fstat(fd, &st) < 0) return -errno; @@ -858,7 +865,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_ if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode)) return -EINVAL; - type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW; + type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? + TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW; r = transfer_new(m, &t); if (r < 0) @@ -922,28 +930,33 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er return r; if (!http_url_is_valid(remote)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "URL %s is invalid", remote); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "URL %s is invalid", remote); if (isempty(local)) local = NULL; else if (!machine_name_is_valid(local)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Local name %s is invalid", local); if (isempty(verify)) v = IMPORT_VERIFY_SIGNATURE; else v = import_verify_from_string(verify); if (v < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown verification mode %s", verify); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Unknown verification mode %s", verify); r = setup_machine_directory(error); if (r < 0) return r; - type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? TRANSFER_PULL_TAR : TRANSFER_PULL_RAW; + type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? + TRANSFER_PULL_TAR : TRANSFER_PULL_RAW; if (manager_find(m, type, remote)) - return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, "Transfer for %s already in progress.", remote); + return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, + "Transfer for %s already in progress.", remote); r = transfer_new(m, &t); if (r < 0) @@ -1230,7 +1243,14 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END, }; -static int transfer_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int transfer_object_find( + sd_bus *bus, + const char *path, + const char *interface, + void *userdata, + void **found, + sd_bus_error *error) { + Manager *m = userdata; Transfer *t; const char *p; @@ -1259,7 +1279,13 @@ static int transfer_object_find(sd_bus *bus, const char *path, const char *inter return 1; } -static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int transfer_node_enumerator( + sd_bus *bus, + const char *path, + void *userdata, + char ***nodes, + sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; Manager *m = userdata; Transfer *t; @@ -1289,15 +1315,23 @@ static int manager_add_bus_objects(Manager *m) { assert(m); - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/import1", "org.freedesktop.import1.Manager", manager_vtable, m); + r = sd_bus_add_object_vtable(m->bus, NULL, + "/org/freedesktop/import1", + "org.freedesktop.import1.Manager", + manager_vtable, m); if (r < 0) return log_error_errno(r, "Failed to register object: %m"); - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/import1/transfer", "org.freedesktop.import1.Transfer", transfer_vtable, transfer_object_find, m); + r = sd_bus_add_fallback_vtable(m->bus, NULL, + "/org/freedesktop/import1/transfer", + "org.freedesktop.import1.Transfer", + transfer_vtable, transfer_object_find, m); if (r < 0) return log_error_errno(r, "Failed to register object: %m"); - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/import1/transfer", transfer_node_enumerator, m); + r = sd_bus_add_node_enumerator(m->bus, NULL, + "/org/freedesktop/import1/transfer", + transfer_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add transfer enumerator: %m"); From 53f7f7fcf274e837ba49edc2213b191ef997d560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 10:19:11 +0200 Subject: [PATCH 05/30] util-lib: add stub parser for --help, --version --- src/shared/meson.build | 2 + src/shared/service-util.c | 77 +++++++++++++++++++++++++++++++++++++++ src/shared/service-util.h | 7 ++++ 3 files changed, 86 insertions(+) create mode 100644 src/shared/service-util.c create mode 100644 src/shared/service-util.h diff --git a/src/shared/meson.build b/src/shared/meson.build index e608ea8a1d..32626490d7 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -184,6 +184,8 @@ shared_sources = files(''' securebits-util.h serialize.c serialize.h + service-util.c + service-util.h sleep-config.c sleep-config.h socket-netlink.c diff --git a/src/shared/service-util.c b/src/shared/service-util.c new file mode 100644 index 0000000000..7fea74d2d9 --- /dev/null +++ b/src/shared/service-util.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include + +#include "alloc-util.h" +#include "pretty-print.h" +#include "service-util.h" +#include "terminal-util.h" +#include "util.h" + +static int help(const char *program_path, const char *service, const char *description) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man(service, "8", &link); + if (r < 0) + return log_oom(); + + printf("%s [OPTIONS...]\n\n" + "%s%s%s\n\n" + "This program takes no positional arguments.\n\n" + "%sOptions%s:\n" + " -h --help Show this help\n" + " --version Show package version\n" + "\nSee the %s for details.\n" + , program_path + , ansi_highlight(), description, ansi_normal() + , ansi_underline(), ansi_normal() + , link + ); + + return 0; /* No further action */ +} + +int service_parse_argv( + const char *service, + const char *description, + int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + {} + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + switch(c) { + + case 'h': + return help(argv[0], service, description); + + case ARG_VERSION: + return version(); + + case '?': + return -EINVAL; + + default: + assert_not_reached("Unknown option code."); + } + + if (optind < argc) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "This program takes no arguments."); + + return 1; /* Further action */ +} diff --git a/src/shared/service-util.h b/src/shared/service-util.h new file mode 100644 index 0000000000..f4868184f4 --- /dev/null +++ b/src/shared/service-util.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +int service_parse_argv( + const char *service, + const char *description, + int argc, char *argv[]); From 7ae473268c092cbe8235462c0aea923d9ce36901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 28 Apr 2020 11:06:20 +0200 Subject: [PATCH 06/30] manager: add highlighting to --help Also change the summary line to a bit more concise. --- src/core/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/main.c b/src/core/main.c index 49879d8e37..a2a1ca3a41 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1033,7 +1033,9 @@ static int help(void) { return log_oom(); printf("%s [OPTIONS...]\n\n" - "Starts up and maintains the system or user services.\n\n" + "%sStarts and monitors system and user services.%s\n\n" + "This program takes no positional arguments.\n\n" + "%sOptions%s:\n" " -h --help Show this help\n" " --version Show version\n" " --test Determine initial transaction, dump it and exit\n" @@ -1058,6 +1060,8 @@ static int help(void) { " --default-standard-error= Set default standard error output for services\n" "\nSee the %s for details.\n" , program_invocation_short_name + , ansi_highlight(), ansi_normal() + , ansi_underline(), ansi_normal() , link ); From fc021a5bbf1b00a3ac21845f3102f1a6379a9357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 10:19:46 +0200 Subject: [PATCH 07/30] logind,importd,hostnamed,localed,timedated,machined,resolved: add option parsing stubs --help and --version are implemented in the usual style. help() prints full path, since the program is not expected to be in $PATH. --- src/hostname/hostnamed.c | 12 +++++++----- src/import/importd.c | 12 +++++++----- src/locale/localed.c | 10 +++++++--- src/login/logind.c | 12 +++++++----- src/machine/machined.c | 12 +++++++----- src/resolve/resolved.c | 8 ++++++-- src/timedate/timedated.c | 10 +++++++--- 7 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index ad6577c37e..b2b5299b32 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -26,6 +26,7 @@ #include "parse-util.h" #include "path-util.h" #include "selinux-util.h" +#include "service-util.h" #include "signal-util.h" #include "strv.h" #include "user-util.h" @@ -780,14 +781,15 @@ static int run(int argc, char *argv[]) { log_setup_service(); + r = service_parse_argv("systemd-hostnamed.service", + "Manage the system hostname and related metadata.", + argc, argv); + if (r <= 0) + return r; + umask(0022); mac_selinux_init(); - if (argc != 1) { - log_error("This program takes no arguments."); - return -EINVAL; - } - assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); r = sd_event_default(&event); diff --git a/src/import/importd.c b/src/import/importd.c index 2e5c1c2642..ea16c9bec4 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -22,6 +22,7 @@ #include "path-util.h" #include "process-util.h" #include "signal-util.h" +#include "service-util.h" #include "socket-util.h" #include "stat-util.h" #include "string-table.h" @@ -1374,12 +1375,13 @@ static int run(int argc, char *argv[]) { log_setup_service(); - umask(0022); + r = service_parse_argv("systemd-importd.service", + "VM and container image import and export service.", + argc, argv); + if (r <= 0) + return r; - if (argc != 1) { - log_error("This program takes no arguments."); - return -EINVAL; - } + umask(0022); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0); diff --git a/src/locale/localed.c b/src/locale/localed.c index 7315d93a98..a0fcadcc91 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -25,6 +25,7 @@ #include "missing_capability.h" #include "path-util.h" #include "selinux-util.h" +#include "service-util.h" #include "signal-util.h" #include "string-util.h" #include "strv.h" @@ -754,12 +755,15 @@ static int run(int argc, char *argv[]) { log_setup_service(); + r = service_parse_argv("systemd-localed.service", + "Manage system locale settings and key mappings.", + argc, argv); + if (r <= 0) + return r; + umask(0022); mac_selinux_init(); - if (argc != 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments."); - assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); r = sd_event_default(&event); diff --git a/src/login/logind.c b/src/login/logind.c index 75958189ac..4678b22bea 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -27,6 +27,7 @@ #include "parse-util.h" #include "process-util.h" #include "selinux-util.h" +#include "service-util.h" #include "signal-util.h" #include "strv.h" #include "terminal-util.h" @@ -1201,12 +1202,13 @@ static int run(int argc, char *argv[]) { log_set_facility(LOG_AUTH); log_setup_service(); - umask(0022); + r = service_parse_argv("systemd-logind.service", + "Manager for user logins and devices and privileged operations.", + argc, argv); + if (r <= 0) + return r; - if (argc != 1) { - log_error("This program takes no arguments."); - return -EINVAL; - } + umask(0022); r = mac_selinux_init(); if (r < 0) diff --git a/src/machine/machined.c b/src/machine/machined.c index a93bfc42be..191031e2aa 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -22,6 +22,7 @@ #include "machined.h" #include "main-func.h" #include "process-util.h" +#include "service-util.h" #include "signal-util.h" #include "special.h" @@ -357,12 +358,13 @@ static int run(int argc, char *argv[]) { log_set_facility(LOG_AUTH); log_setup_service(); - umask(0022); + r = service_parse_argv("systemd-machined.service", + "Manage registrations of local VMs and containers.", + argc, argv); + if (r <= 0) + return r; - if (argc != 1) { - log_error("This program takes no arguments."); - return -EINVAL; - } + umask(0022); /* Always create the directories people can create inotify watches in. Note that some applications might check * for the existence of /run/systemd/machines/ to determine whether machined is available, so please always diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index 27848cccae..73da508d7a 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -15,6 +15,7 @@ #include "resolved-manager.h" #include "resolved-resolv-conf.h" #include "selinux-util.h" +#include "service-util.h" #include "signal-util.h" #include "user-util.h" @@ -25,8 +26,11 @@ static int run(int argc, char *argv[]) { log_setup_service(); - if (argc != 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments."); + r = service_parse_argv("systemd-resolved.service", + "Provide name resolution with caching using DNS, mDNS, LLMNR.", + argc, argv); + if (r <= 0) + return r; umask(0022); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 8e15cd4f06..6dac0bafff 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -28,6 +28,7 @@ #include "missing_capability.h" #include "path-util.h" #include "selinux-util.h" +#include "service-util.h" #include "signal-util.h" #include "string-util.h" #include "strv.h" @@ -1126,10 +1127,13 @@ static int run(int argc, char *argv[]) { log_setup_service(); - umask(0022); + r = service_parse_argv("systemd-timedated.service", + "Manage the system clock and timezone and NTP enablement.", + argc, argv); + if (r <= 0) + return r; - if (argc != 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments."); + umask(0022); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); From 6a7e98aacada79e273ddcad7335a7be7c2add801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 15 Apr 2020 17:21:23 +0200 Subject: [PATCH 08/30] sd-bus: add helper struct for interface definitions The idea is to have a static table that defines the dbus API. The vtable is defined right next to the interface name and path because they are logically connected. --- src/shared/bus-log-control-api.c | 19 ++++--------- src/shared/bus-log-control-api.h | 7 ++++- src/shared/bus-util.c | 49 ++++++++++++++++++++++++++++++++ src/shared/bus-util.h | 29 +++++++++++++++++-- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/src/shared/bus-log-control-api.c b/src/shared/bus-log-control-api.c index ffc52c7774..a1d0d17291 100644 --- a/src/shared/bus-log-control-api.c +++ b/src/shared/bus-log-control-api.c @@ -107,17 +107,8 @@ static const sd_bus_vtable log_control_vtable[] = { SD_BUS_VTABLE_END, }; -int bus_log_control_api_register(sd_bus *bus) { - int r; - - r = sd_bus_add_object_vtable( - bus, - NULL, - "/org/freedesktop/LogControl1", - "org.freedesktop.LogControl1", - log_control_vtable, NULL); - if (r < 0) - return log_error_errno(r, "Failed to register service API object: %m"); - - return 0; -} +const BusObjectImplementation log_control_object = { + "/org/freedesktop/LogControl1", + "org.freedesktop.LogControl1", + .vtables = BUS_VTABLES(log_control_vtable), +}; diff --git a/src/shared/bus-log-control-api.h b/src/shared/bus-log-control-api.h index a6fb2757c5..b1d00b38bc 100644 --- a/src/shared/bus-log-control-api.h +++ b/src/shared/bus-log-control-api.h @@ -2,7 +2,12 @@ #include "sd-bus.h" -int bus_log_control_api_register(sd_bus *bus); +#include "bus-util.h" + +extern const BusObjectImplementation log_control_object; +static inline int bus_log_control_api_register(sd_bus *bus) { + return bus_add_implementation(bus, &log_control_object, NULL); +} int bus_property_get_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); int bus_property_set_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 81683e5afe..30d62d5fc7 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1549,3 +1549,52 @@ 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); + } + + 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; +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index fd1820ca7e..a985523cd0 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -23,11 +23,32 @@ typedef enum BusTransport { } BusTransport; typedef struct BusLocator { - const char *destination; - const char *path; - const char *interface; + const char *destination; + const char *path; + const char *interface; } BusLocator; +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); struct bus_properties_map { @@ -199,3 +220,5 @@ 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); From a3b7cf5013e4c3cbe0824b14463e17ef26956f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 10:02:00 +0200 Subject: [PATCH 09/30] importd: convert to the new scheme --- src/import/importd.c | 167 +++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 84 deletions(-) diff --git a/src/import/importd.c b/src/import/importd.c index ea16c9bec4..398b2964b0 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -8,6 +8,7 @@ #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-log-control-api.h" +#include "bus-util.h" #include "bus-polkit.h" #include "def.h" #include "fd-util.h" @@ -1117,6 +1118,73 @@ static int property_get_progress( static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, transfer_type, TransferType); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_verify, import_verify, ImportVerify); +static int transfer_object_find( + sd_bus *bus, + const char *path, + const char *interface, + void *userdata, + void **found, + sd_bus_error *error) { + + Manager *m = userdata; + Transfer *t; + const char *p; + uint32_t id; + int r; + + assert(bus); + assert(path); + assert(interface); + assert(found); + assert(m); + + p = startswith(path, "/org/freedesktop/import1/transfer/_"); + if (!p) + return 0; + + r = safe_atou32(p, &id); + if (r < 0 || id == 0) + return 0; + + t = hashmap_get(m->transfers, UINT32_TO_PTR(id)); + if (!t) + return 0; + + *found = t; + return 1; +} + +static int transfer_node_enumerator( + sd_bus *bus, + const char *path, + void *userdata, + char ***nodes, + sd_bus_error *error) { + + _cleanup_strv_free_ char **l = NULL; + Manager *m = userdata; + Transfer *t; + unsigned k = 0; + Iterator i; + + l = new0(char*, hashmap_size(m->transfers) + 1); + if (!l) + return -ENOMEM; + + HASHMAP_FOREACH(t, m->transfers, i) { + + l[k] = strdup(t->object_path); + if (!l[k]) + return -ENOMEM; + + k++; + } + + *nodes = TAKE_PTR(l); + + return 1; +} + static const sd_bus_vtable transfer_vtable[] = { SD_BUS_VTABLE_START(0), @@ -1138,6 +1206,13 @@ static const sd_bus_vtable transfer_vtable[] = { SD_BUS_VTABLE_END, }; +static const BusObjectImplementation transfer_object = { + "/org/freedesktop/import1/transfer", + "org.freedesktop.import1.Transfer", + .fallback_vtables = BUS_FALLBACK_VTABLES({transfer_vtable, transfer_object_find}), + .node_enumerator = transfer_node_enumerator, +}; + static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_START(0), @@ -1244,97 +1319,21 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END, }; -static int transfer_object_find( - sd_bus *bus, - const char *path, - const char *interface, - void *userdata, - void **found, - sd_bus_error *error) { - - Manager *m = userdata; - Transfer *t; - const char *p; - uint32_t id; - int r; - - assert(bus); - assert(path); - assert(interface); - assert(found); - assert(m); - - p = startswith(path, "/org/freedesktop/import1/transfer/_"); - if (!p) - return 0; - - r = safe_atou32(p, &id); - if (r < 0 || id == 0) - return 0; - - t = hashmap_get(m->transfers, UINT32_TO_PTR(id)); - if (!t) - return 0; - - *found = t; - return 1; -} - -static int transfer_node_enumerator( - sd_bus *bus, - const char *path, - void *userdata, - char ***nodes, - sd_bus_error *error) { - - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - Transfer *t; - unsigned k = 0; - Iterator i; - - l = new0(char*, hashmap_size(m->transfers) + 1); - if (!l) - return -ENOMEM; - - HASHMAP_FOREACH(t, m->transfers, i) { - - l[k] = strdup(t->object_path); - if (!l[k]) - return -ENOMEM; - - k++; - } - - *nodes = TAKE_PTR(l); - - return 1; -} +static const BusObjectImplementation manager_object = { + "/org/freedesktop/import1", + "org.freedesktop.import1.Manager", + .vtables = BUS_VTABLES(manager_vtable), + .children = BUS_IMPLEMENTATIONS(&transfer_object), +}; static int manager_add_bus_objects(Manager *m) { int r; assert(m); - r = sd_bus_add_object_vtable(m->bus, NULL, - "/org/freedesktop/import1", - "org.freedesktop.import1.Manager", - manager_vtable, m); + r = bus_add_implementation(m->bus, &manager_object, m); if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, - "/org/freedesktop/import1/transfer", - "org.freedesktop.import1.Transfer", - transfer_vtable, transfer_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, - "/org/freedesktop/import1/transfer", - transfer_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add transfer enumerator: %m"); + return r; r = bus_log_control_api_register(m->bus); if (r < 0) From c2b178d3cacad52eadc30ecc349160bc02d32a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 01:00:07 +0200 Subject: [PATCH 10/30] logind: convert to the new scheme --- src/login/logind-dbus.c | 11 +- src/login/logind-dbus.h | 3 + src/login/logind-seat-dbus.c | 79 ++++----- src/login/logind-seat-dbus.h | 5 +- src/login/logind-session-dbus.c | 279 ++++++++++++++++---------------- src/login/logind-session-dbus.h | 5 +- src/login/logind-user-dbus.c | 69 ++++---- src/login/logind-user-dbus.h | 5 +- src/login/logind.c | 32 +--- src/login/logind.h | 2 - 10 files changed, 247 insertions(+), 243 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 136ccf1dd9..47fc53167e 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -3322,7 +3322,7 @@ fail: return r; } -const sd_bus_vtable manager_vtable[] = { +static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0), @@ -3754,6 +3754,15 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END }; +const BusObjectImplementation manager_object = { + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + .vtables = BUS_VTABLES(manager_vtable), + .children = BUS_IMPLEMENTATIONS(&seat_object, + &session_object, + &user_object), +}; + static int session_jobs_reply(Session *s, uint32_t jid, const char *unit, const char *result) { assert(s); assert(unit); diff --git a/src/login/logind-dbus.h b/src/login/logind-dbus.h index 6c73a9654f..6a3ee82f1c 100644 --- a/src/login/logind-dbus.h +++ b/src/login/logind-dbus.h @@ -3,6 +3,7 @@ #include "sd-bus.h" +#include "bus-util.h" #include "logind.h" #include "logind-session.h" #include "logind-user.h" @@ -29,3 +30,5 @@ int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *err int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error); int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *error); int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *error); + +extern const BusObjectImplementation manager_object; diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c index 7e811e9745..e72f265185 100644 --- a/src/login/logind-seat-dbus.c +++ b/src/login/logind-seat-dbus.c @@ -291,41 +291,7 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd return sd_bus_reply_method_return(message, NULL); } -const sd_bus_vtable seat_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), - SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0), - SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - - SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_METHOD_WITH_NAMES("ActivateSession", - "s", - SD_BUS_PARAM(session_id), - NULL,, - method_activate_session, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("SwitchTo", - "u", - SD_BUS_PARAM(vtnr), - NULL,, - method_switch_to, - SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_VTABLE_END -}; - -int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *e = NULL; sd_bus_message *message; Manager *m = userdata; @@ -373,7 +339,7 @@ char *seat_bus_path(Seat *s) { return strjoin("/org/freedesktop/login1/seat/", t); } -int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; sd_bus_message *message; Manager *m = userdata; @@ -478,3 +444,44 @@ int seat_send_changed(Seat *s, const char *properties, ...) { return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Seat", l); } + +static const sd_bus_vtable seat_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0), + SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_METHOD_WITH_NAMES("ActivateSession", + "s", + SD_BUS_PARAM(session_id), + NULL,, + method_activate_session, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SwitchTo", + "u", + SD_BUS_PARAM(vtnr), + NULL,, + method_switch_to, + SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation seat_object = { + "/org/freedesktop/login1/seat", + "org.freedesktop.login1.Seat", + .fallback_vtables = BUS_FALLBACK_VTABLES({seat_vtable, seat_object_find}), + .node_enumerator = seat_node_enumerator, +}; diff --git a/src/login/logind-seat-dbus.h b/src/login/logind-seat-dbus.h index 2590f64922..5fc857584e 100644 --- a/src/login/logind-seat-dbus.h +++ b/src/login/logind-seat-dbus.h @@ -4,11 +4,10 @@ #include "sd-bus.h" #include "logind-seat.h" +#include "bus-util.h" -extern const sd_bus_vtable seat_vtable[]; +extern const BusObjectImplementation seat_object; -int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); char *seat_bus_path(Seat *s); int seat_send_signal(Seat *s, bool new_seat); diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 9a8dbc87bc..3857f4ab7d 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -581,141 +581,7 @@ static int method_set_brightness(sd_bus_message *message, void *userdata, sd_bus return 1; } -const sd_bus_vtable session_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - - SD_BUS_METHOD("Terminate", - NULL, - NULL, - bus_session_method_terminate, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Activate", - NULL, - NULL, - bus_session_method_activate, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Lock", - NULL, - NULL, - bus_session_method_lock, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Unlock", - NULL, - NULL, - bus_session_method_lock, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("SetIdleHint", - "b", - SD_BUS_PARAM(idle), - NULL,, - method_set_idle_hint, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("SetLockedHint", - "b", - SD_BUS_PARAM(locked), - NULL,, - method_set_locked_hint, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("Kill", - "si", - SD_BUS_PARAM(who) - SD_BUS_PARAM(signal_number), - NULL,, - bus_session_method_kill, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("TakeControl", - "b", - SD_BUS_PARAM(force), - NULL,, - method_take_control, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("ReleaseControl", - NULL, - NULL, - method_release_control, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("SetType", - "s", - SD_BUS_PARAM(type), - NULL,, - method_set_type, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("TakeDevice", - "uu", - SD_BUS_PARAM(major) - SD_BUS_PARAM(minor), - "hb", - SD_BUS_PARAM(fd) - SD_BUS_PARAM(inactive), - method_take_device, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("ReleaseDevice", - "uu", - SD_BUS_PARAM(major) - SD_BUS_PARAM(minor), - NULL,, - method_release_device, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete", - "uu", - SD_BUS_PARAM(major) - SD_BUS_PARAM(minor), - NULL,, - method_pause_device_complete, - SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("SetBrightness", - "ssu", - SD_BUS_PARAM(subsystem) - SD_BUS_PARAM(name) - SD_BUS_PARAM(brightness), - NULL,, - method_set_brightness, - SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_SIGNAL_WITH_NAMES("PauseDevice", - "uus", - SD_BUS_PARAM(major) - SD_BUS_PARAM(minor) - SD_BUS_PARAM(type), - 0), - SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice", - "uuh", - SD_BUS_PARAM(major) - SD_BUS_PARAM(minor) - SD_BUS_PARAM(fd), - 0), - SD_BUS_SIGNAL("Lock", NULL, 0), - SD_BUS_SIGNAL("Unlock", NULL, 0), - - SD_BUS_VTABLE_END -}; - -int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *e = NULL; sd_bus_message *message; Manager *m = userdata; @@ -763,7 +629,7 @@ char *session_bus_path(Session *s) { return strjoin("/org/freedesktop/login1/session/", t); } -int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; sd_bus_message *message; Manager *m = userdata; @@ -964,3 +830,144 @@ int session_send_create_reply(Session *s, sd_bus_error *error) { (uint32_t) s->vtnr, false); } + +static const sd_bus_vtable session_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + SD_BUS_METHOD("Terminate", + NULL, + NULL, + bus_session_method_terminate, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Activate", + NULL, + NULL, + bus_session_method_activate, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Lock", + NULL, + NULL, + bus_session_method_lock, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Unlock", + NULL, + NULL, + bus_session_method_lock, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SetIdleHint", + "b", + SD_BUS_PARAM(idle), + NULL,, + method_set_idle_hint, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SetLockedHint", + "b", + SD_BUS_PARAM(locked), + NULL,, + method_set_locked_hint, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("Kill", + "si", + SD_BUS_PARAM(who) + SD_BUS_PARAM(signal_number), + NULL,, + bus_session_method_kill, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("TakeControl", + "b", + SD_BUS_PARAM(force), + NULL,, + method_take_control, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReleaseControl", + NULL, + NULL, + method_release_control, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SetType", + "s", + SD_BUS_PARAM(type), + NULL,, + method_set_type, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("TakeDevice", + "uu", + SD_BUS_PARAM(major) + SD_BUS_PARAM(minor), + "hb", + SD_BUS_PARAM(fd) + SD_BUS_PARAM(inactive), + method_take_device, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("ReleaseDevice", + "uu", + SD_BUS_PARAM(major) + SD_BUS_PARAM(minor), + NULL,, + method_release_device, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete", + "uu", + SD_BUS_PARAM(major) + SD_BUS_PARAM(minor), + NULL,, + method_pause_device_complete, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SetBrightness", + "ssu", + SD_BUS_PARAM(subsystem) + SD_BUS_PARAM(name) + SD_BUS_PARAM(brightness), + NULL,, + method_set_brightness, + SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_SIGNAL_WITH_NAMES("PauseDevice", + "uus", + SD_BUS_PARAM(major) + SD_BUS_PARAM(minor) + SD_BUS_PARAM(type), + 0), + SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice", + "uuh", + SD_BUS_PARAM(major) + SD_BUS_PARAM(minor) + SD_BUS_PARAM(fd), + 0), + SD_BUS_SIGNAL("Lock", NULL, 0), + SD_BUS_SIGNAL("Unlock", NULL, 0), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation session_object = { + "/org/freedesktop/login1/session", + "org.freedesktop.login1.Session", + .fallback_vtables = BUS_FALLBACK_VTABLES({session_vtable, session_object_find}), + .node_enumerator = session_node_enumerator, +}; diff --git a/src/login/logind-session-dbus.h b/src/login/logind-session-dbus.h index 9d2315cc60..6df96e06b2 100644 --- a/src/login/logind-session-dbus.h +++ b/src/login/logind-session-dbus.h @@ -5,9 +5,8 @@ #include "logind-session.h" -extern const sd_bus_vtable session_vtable[]; -int session_node_enumerator(sd_bus *bus, const char *path,void *userdata, char ***nodes, sd_bus_error *error); -int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +extern const BusObjectImplementation session_object; + char *session_bus_path(Session *s); int session_send_signal(Session *s, bool new_session); diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index f247567935..63c77cab39 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -258,36 +258,7 @@ int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * return sd_bus_reply_method_return(message, NULL); } -const sd_bus_vtable user_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0), - SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0), - SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0), - - SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD_WITH_NAMES("Kill", - "i", - SD_BUS_PARAM(signal_number), - NULL,, - bus_user_method_kill, - SD_BUS_VTABLE_UNPRIVILEGED), - - SD_BUS_VTABLE_END -}; - -int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { Manager *m = userdata; uid_t uid; User *user; @@ -342,7 +313,7 @@ char *user_bus_path(User *u) { return s; } -int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; sd_bus_message *message; Manager *m = userdata; @@ -391,6 +362,42 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** return 1; } +static const sd_bus_vtable user_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0), + SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0), + SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0), + + SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("Kill", + "i", + SD_BUS_PARAM(signal_number), + NULL,, + bus_user_method_kill, + SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation user_object = { + "/org/freedesktop/login1/user", + "org.freedesktop.login1.User", + .fallback_vtables = BUS_FALLBACK_VTABLES({user_vtable, user_object_find}), + .node_enumerator = user_node_enumerator, +}; + int user_send_signal(User *u, bool new_user) { _cleanup_free_ char *p = NULL; diff --git a/src/login/logind-user-dbus.h b/src/login/logind-user-dbus.h index acfcb981cf..b3f990c5af 100644 --- a/src/login/logind-user-dbus.h +++ b/src/login/logind-user-dbus.h @@ -5,9 +5,8 @@ #include "logind-user.h" -extern const sd_bus_vtable user_vtable[]; -int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +extern const BusObjectImplementation user_object; + char *user_bus_path(User *s); int user_send_signal(User *u, bool new_user); diff --git a/src/login/logind.c b/src/login/logind.c index 4678b22bea..1bf1f21f00 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -624,33 +624,13 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m); + r = bus_add_implementation(m->bus, &manager_object, m); if (r < 0) - return log_error_errno(r, "Failed to add manager object vtable: %m"); + return r; - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m); + r = bus_log_control_api_register(m->bus); if (r < 0) - return log_error_errno(r, "Failed to add seat object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add seat enumerator: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add session object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add session enumerator: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add user object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add user enumerator: %m"); + return r; r = sd_bus_match_signal_async( m->bus, @@ -708,10 +688,6 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to enable subscription: %m"); - r = bus_log_control_api_register(m->bus); - if (r < 0) - return r; - r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to request name: %m"); diff --git a/src/login/logind.h b/src/login/logind.h index 7e4673d27d..d3f5b28078 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -157,8 +157,6 @@ int manager_read_utmp(Manager *m); void manager_connect_utmp(Manager *m); void manager_reconnect_utmp(Manager *m); -extern const sd_bus_vtable manager_vtable[]; - /* gperf lookup function */ const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length); From 1e9bc92dba49f77ef08b5e89cb78d69a84772148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 15 Apr 2020 17:19:53 +0200 Subject: [PATCH 11/30] bus-util: add wrapper for interface introspection --- src/shared/bus-util.c | 104 ++++++++++++++++++++++++++++++++++++++++++ src/shared/bus-util.h | 4 ++ 2 files changed, 108 insertions(+) diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 30d62d5fc7..4214aa340e 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -16,6 +16,7 @@ #include "alloc-util.h" #include "bus-internal.h" +#include "bus-introspect.h" #include "bus-label.h" #include "bus-message.h" #include "bus-util.h" @@ -1598,3 +1599,106 @@ int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, voi 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; +} + +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; + + struct introspect intro = {}; + bool is_interface = 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_free_ Set *nodes = NULL; + + for (size_t i = 0; impl->children && impl->children[i]; i++) { + r = set_ensure_allocated(&nodes, &string_hash_ops); + if (r < 0) + return log_oom(); + + 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; +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index a985523cd0..7678680dae 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -222,3 +222,7 @@ int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusLocator *loc 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); From d4cc0edfced262b34be4e113bd527e651f1f0024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 28 Apr 2020 17:55:34 +0200 Subject: [PATCH 12/30] importd,logind: add --bus-introspect= option --- src/hostname/hostnamed.c | 1 + src/import/importd.c | 2 ++ src/locale/localed.c | 1 + src/login/logind.c | 2 ++ src/machine/machined.c | 1 + src/resolve/resolved.c | 1 + src/shared/service-util.c | 14 ++++++++++++-- src/shared/service-util.h | 3 +++ src/timedate/timedated.c | 1 + 9 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index b2b5299b32..535c800beb 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -783,6 +783,7 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-hostnamed.service", "Manage the system hostname and related metadata.", + NULL, argc, argv); if (r <= 0) return r; diff --git a/src/import/importd.c b/src/import/importd.c index 398b2964b0..9408edece1 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -1376,6 +1376,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-importd.service", "VM and container image import and export service.", + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; diff --git a/src/locale/localed.c b/src/locale/localed.c index a0fcadcc91..ef73448854 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -757,6 +757,7 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-localed.service", "Manage system locale settings and key mappings.", + NULL, argc, argv); if (r <= 0) return r; diff --git a/src/login/logind.c b/src/login/logind.c index 1bf1f21f00..d748e8f4b8 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1180,6 +1180,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-logind.service", "Manager for user logins and devices and privileged operations.", + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; diff --git a/src/machine/machined.c b/src/machine/machined.c index 191031e2aa..5a24f6ccc8 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -360,6 +360,7 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-machined.service", "Manage registrations of local VMs and containers.", + NULL, argc, argv); if (r <= 0) return r; diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index 73da508d7a..6f2b4c114e 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -28,6 +28,7 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-resolved.service", "Provide name resolution with caching using DNS, mDNS, LLMNR.", + NULL, argc, argv); if (r <= 0) return r; diff --git a/src/shared/service-util.c b/src/shared/service-util.c index 7fea74d2d9..c9b684fc05 100644 --- a/src/shared/service-util.c +++ b/src/shared/service-util.c @@ -9,7 +9,7 @@ #include "terminal-util.h" #include "util.h" -static int help(const char *program_path, const char *service, const char *description) { +static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) { _cleanup_free_ char *link = NULL; int r; @@ -23,6 +23,7 @@ static int help(const char *program_path, const char *service, const char *descr "%sOptions%s:\n" " -h --help Show this help\n" " --version Show package version\n" + " --bus-introspect=PATH Write D-Bus XML introspection data\n" "\nSee the %s for details.\n" , program_path , ansi_highlight(), description, ansi_normal() @@ -36,15 +37,18 @@ static int help(const char *program_path, const char *service, const char *descr int service_parse_argv( const char *service, const char *description, + const BusObjectImplementation* const* bus_objects, int argc, char *argv[]) { enum { ARG_VERSION = 0x100, + ARG_BUS_INTROSPECT, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, + { "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT }, {} }; @@ -57,11 +61,17 @@ int service_parse_argv( switch(c) { case 'h': - return help(argv[0], service, description); + return help(argv[0], service, description, bus_objects); case ARG_VERSION: return version(); + case ARG_BUS_INTROSPECT: + return bus_introspect_implementations( + stdout, + optarg, + bus_objects); + case '?': return -EINVAL; diff --git a/src/shared/service-util.h b/src/shared/service-util.h index f4868184f4..76bff61d58 100644 --- a/src/shared/service-util.h +++ b/src/shared/service-util.h @@ -1,7 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include "bus-util.h" + int service_parse_argv( const char *service, const char *description, + const BusObjectImplementation* const* bus_objects, int argc, char *argv[]); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 6dac0bafff..7f2e3019d4 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -1129,6 +1129,7 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-timedated.service", "Manage the system clock and timezone and NTP enablement.", + NULL, argc, argv); if (r <= 0) return r; From cd7e1e1a7fdf758881ec54ecd0ef60be968771e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 09:59:03 +0200 Subject: [PATCH 13/30] units: change description of systemd-logind.service "Login Service" doesn''t explain much, esp. considering that logind is actually is for logins. I think "User Login Management" is better, but not that great either. Suggestions welcome. --- units/systemd-logind.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index ed573b8f3c..0147b30e0d 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -8,7 +8,7 @@ # (at your option) any later version. [Unit] -Description=Login Service +Description=User Login Management Documentation=man:systemd-logind.service(8) man:logind.conf(5) Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat From c4b7d95c46194c744945d8ab1256adc5dd6a4951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 12:14:09 +0200 Subject: [PATCH 14/30] timedated: convert to the new scheme and add --bus-introspect --- src/timedate/timedated.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 7f2e3019d4..19e51b063a 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -14,6 +14,7 @@ #include "bus-error.h" #include "bus-log-control-api.h" #include "bus-polkit.h" +#include "bus-util.h" #include "clock-util.h" #include "conf-files.h" #include "def.h" @@ -1086,6 +1087,12 @@ static const sd_bus_vtable timedate_vtable[] = { SD_BUS_VTABLE_END, }; +const BusObjectImplementation manager_object = { + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + .vtables = BUS_VTABLES(timedate_vtable), +}; + static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; @@ -1098,9 +1105,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to get system bus connection: %m"); - r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c); + r = bus_add_implementation(bus, &manager_object, c); if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); + return r; r = bus_log_control_api_register(bus); if (r < 0) @@ -1129,7 +1136,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-timedated.service", "Manage the system clock and timezone and NTP enablement.", - NULL, + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; From 8d1280897bb63c529fdf8b3a19c09f75afbc7993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 12:45:47 +0200 Subject: [PATCH 15/30] resolved: convert to the new scheme --- src/resolve/resolved-bus.c | 28 ++---- src/resolve/resolved-bus.h | 3 + src/resolve/resolved-dnssd-bus.c | 29 +++--- src/resolve/resolved-dnssd-bus.h | 5 +- src/resolve/resolved-link-bus.c | 157 ++++++++++++++++--------------- src/resolve/resolved-link-bus.h | 5 +- src/resolve/resolved.c | 5 +- 7 files changed, 121 insertions(+), 111 deletions(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index a06e9bcf7d..529aeb8a32 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -2015,6 +2015,14 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_VTABLE_END, }; +const BusObjectImplementation manager_object = { + "/org/freedesktop/resolve1", + "org.freedesktop.resolve1.Manager", + .vtables = BUS_VTABLES(resolve_vtable), + .children = BUS_IMPLEMENTATIONS(&link_object, + &dnssd_object), +}; + static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { Manager *m = userdata; int b, r; @@ -2049,25 +2057,9 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m); + r = bus_add_implementation(m->bus, &manager_object, m); if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable, link_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register link objects: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/link", link_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to register link enumerator: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable, dnssd_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register dnssd objects: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to register dnssd enumerator: %m"); + return r; r = bus_log_control_api_register(m->bus); if (r < 0) diff --git a/src/resolve/resolved-bus.h b/src/resolve/resolved-bus.h index a499f76ad5..e69171ca70 100644 --- a/src/resolve/resolved-bus.h +++ b/src/resolve/resolved-bus.h @@ -1,8 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include "bus-util.h" #include "resolved-manager.h" +extern const BusObjectImplementation manager_object; + int manager_connect_bus(Manager *m); int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_; #define manager_send_changed(manager, ...) _manager_send_changed(manager, __VA_ARGS__, NULL) diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c index f7dcb3bfa5..84d8d879eb 100644 --- a/src/resolve/resolved-dnssd-bus.c +++ b/src/resolve/resolved-dnssd-bus.c @@ -62,16 +62,7 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_ return sd_bus_reply_method_return(message, NULL); } -const sd_bus_vtable dnssd_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_SIGNAL("Conflicted", NULL, 0), - - SD_BUS_VTABLE_END -}; - -int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *name = NULL; Manager *m = userdata; DnssdService *service; @@ -95,7 +86,7 @@ int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void return 1; } -int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; Manager *m = userdata; DnssdService *service; @@ -127,3 +118,19 @@ int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ** return 1; } + +static const sd_bus_vtable dnssd_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_SIGNAL("Conflicted", NULL, 0), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation dnssd_object = { + "/org/freedesktop/resolve1/dnssd", + "org.freedesktop.resolve1.DnssdService", + .fallback_vtables = BUS_FALLBACK_VTABLES({dnssd_vtable, dnssd_object_find}), + .node_enumerator = dnssd_node_enumerator, +}; diff --git a/src/resolve/resolved-dnssd-bus.h b/src/resolve/resolved-dnssd-bus.h index 9ee2ce17ec..8cd75642a7 100644 --- a/src/resolve/resolved-dnssd-bus.h +++ b/src/resolve/resolved-dnssd-bus.h @@ -2,9 +2,8 @@ #include "sd-bus.h" -extern const sd_bus_vtable dnssd_vtable[]; +#include "bus-util.h" -int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); +extern const BusObjectImplementation dnssd_object; int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c index a2d61f398d..4cbcc42a80 100644 --- a/src/resolve/resolved-link-bus.c +++ b/src/resolve/resolved-link-bus.c @@ -682,7 +682,82 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error return sd_bus_reply_method_return(message, NULL); } -const sd_bus_vtable link_vtable[] = { +static int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { + _cleanup_free_ char *e = NULL; + Manager *m = userdata; + Link *link; + int ifindex, r; + + assert(bus); + assert(path); + assert(interface); + assert(found); + assert(m); + + r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e); + if (r <= 0) + return 0; + + ifindex = parse_ifindex(e); + if (ifindex < 0) + return 0; + + link = hashmap_get(m->links, INT_TO_PTR(ifindex)); + if (!link) + return 0; + + *found = link; + return 1; +} + +char *link_bus_path(const Link *link) { + char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)]; + int r; + + assert(link); + + xsprintf(ifindex, "%i", link->ifindex); + + r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p); + if (r < 0) + return NULL; + + return p; +} + +static int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; + Manager *m = userdata; + Link *link; + Iterator i; + unsigned c = 0; + + assert(bus); + assert(path); + assert(m); + assert(nodes); + + l = new0(char*, hashmap_size(m->links) + 1); + if (!l) + return -ENOMEM; + + HASHMAP_FOREACH(link, m->links, i) { + char *p; + + p = link_bus_path(link); + if (!p) + return -ENOMEM; + + l[c++] = p; + } + + l[c] = NULL; + *nodes = TAKE_PTR(l); + + return 1; +} + +static const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0), @@ -751,77 +826,9 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_END }; -int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - _cleanup_free_ char *e = NULL; - Manager *m = userdata; - Link *link; - int ifindex, r; - - assert(bus); - assert(path); - assert(interface); - assert(found); - assert(m); - - r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e); - if (r <= 0) - return 0; - - ifindex = parse_ifindex(e); - if (ifindex < 0) - return 0; - - link = hashmap_get(m->links, INT_TO_PTR(ifindex)); - if (!link) - return 0; - - *found = link; - return 1; -} - -char *link_bus_path(const Link *link) { - char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)]; - int r; - - assert(link); - - xsprintf(ifindex, "%i", link->ifindex); - - r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p); - if (r < 0) - return NULL; - - return p; -} - -int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - Link *link; - Iterator i; - unsigned c = 0; - - assert(bus); - assert(path); - assert(m); - assert(nodes); - - l = new0(char*, hashmap_size(m->links) + 1); - if (!l) - return -ENOMEM; - - HASHMAP_FOREACH(link, m->links, i) { - char *p; - - p = link_bus_path(link); - if (!p) - return -ENOMEM; - - l[c++] = p; - } - - l[c] = NULL; - *nodes = TAKE_PTR(l); - - return 1; -} +const BusObjectImplementation link_object = { + "/org/freedesktop/resolve1/link", + "org.freedesktop.resolve1.Link", + .fallback_vtables = BUS_FALLBACK_VTABLES({link_vtable, link_object_find}), + .node_enumerator = link_node_enumerator, +}; diff --git a/src/resolve/resolved-link-bus.h b/src/resolve/resolved-link-bus.h index 74068a4777..c249960024 100644 --- a/src/resolve/resolved-link-bus.h +++ b/src/resolve/resolved-link-bus.h @@ -3,13 +3,12 @@ #include "sd-bus.h" +#include "bus-util.h" #include "resolved-link.h" -extern const sd_bus_vtable link_vtable[]; +extern const BusObjectImplementation link_object; -int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); char *link_bus_path(const Link *link); -int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index 6f2b4c114e..50989a6b0a 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -7,10 +7,12 @@ #include "sd-daemon.h" #include "sd-event.h" +#include "bus-log-control-api.h" #include "capability-util.h" #include "daemon-util.h" #include "main-func.h" #include "mkdir.h" +#include "resolved-bus.h" #include "resolved-conf.h" #include "resolved-manager.h" #include "resolved-resolv-conf.h" @@ -28,7 +30,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-resolved.service", "Provide name resolution with caching using DNS, mDNS, LLMNR.", - NULL, + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; From 8b4933973eada07454816853d9b7cdb48e7f306a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 12:46:23 +0200 Subject: [PATCH 16/30] bus-introspect: list the interfaces with "list" The output is not very well formatted, but it is still useful when testing this. --- src/shared/bus-util.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 4214aa340e..df701a3bfe 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1638,6 +1638,17 @@ static int bus_introspect_implementation( 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, @@ -1647,6 +1658,11 @@ int bus_introspect_implementations( _cleanup_free_ char *s = NULL; int r; + if (streq(pattern, "list")) { + list_paths(out, bus_objects); + return 0; + } + struct introspect intro = {}; bool is_interface = interface_name_is_valid(pattern); From 670139db40f0e014e8ceb76efb00f77fd738017c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 14:08:16 +0200 Subject: [PATCH 17/30] hostnamed: convert to the new scheme and add --bus-introspect --- src/hostname/hostnamed.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 535c800beb..701041c12a 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -740,6 +740,12 @@ static const sd_bus_vtable hostname_vtable[] = { SD_BUS_VTABLE_END, }; +static const BusObjectImplementation manager_object = { + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + .vtables = BUS_VTABLES(hostname_vtable), +}; + static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; @@ -752,9 +758,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to get system bus connection: %m"); - r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c); + r = bus_add_implementation(bus, &manager_object, c); if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); + return r; r = bus_log_control_api_register(bus); if (r < 0) @@ -783,7 +789,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-hostnamed.service", "Manage the system hostname and related metadata.", - NULL, + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; From 5ceceff1707ef210f932d7215cdef3f030ed5a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 14:10:33 +0200 Subject: [PATCH 18/30] localed: convert to the new scheme and add --bus-introspect --- src/locale/localed.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/locale/localed.c b/src/locale/localed.c index ef73448854..acdf79fa6b 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -710,6 +710,12 @@ static const sd_bus_vtable locale_vtable[] = { SD_BUS_VTABLE_END }; +static const BusObjectImplementation manager_object = { + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + .vtables = BUS_VTABLES(locale_vtable), +}; + static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; @@ -722,9 +728,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { if (r < 0) return log_error_errno(r, "Failed to get system bus connection: %m"); - r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c); + r = bus_add_implementation(bus, &manager_object, c); if (r < 0) - return log_error_errno(r, "Failed to register object: %m"); + return r; r = bus_log_control_api_register(bus); if (r < 0) @@ -757,7 +763,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-localed.service", "Manage system locale settings and key mappings.", - NULL, + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; From 4faa530cf633f9354c7368e6c1888c14c6516da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 14:21:46 +0200 Subject: [PATCH 19/30] machined: convert to the new scheme and add --bus-introspect --- src/machine/image-dbus.c | 59 ++++++----- src/machine/image-dbus.h | 6 +- src/machine/machine-dbus.c | 191 +++++++++++++++++++----------------- src/machine/machine-dbus.h | 5 +- src/machine/machined-dbus.c | 8 ++ src/machine/machined.c | 23 +---- src/machine/machined.h | 2 +- 7 files changed, 149 insertions(+), 145 deletions(-) diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 294ef34932..4305f49152 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -354,30 +354,6 @@ int bus_image_method_get_os_release( return bus_reply_pair_array(message, image->os_release); } -const sd_bus_vtable image_vtable[] = { - SD_BUS_VTABLE_START(0), - SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0), - SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0), - SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0), - SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0), - SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0), - SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0), - SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0), - SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0), - SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0), - SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0), - SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_VTABLE_END -}; - static int image_flush_cache(sd_event_source *s, void *userdata) { Manager *m = userdata; @@ -388,7 +364,7 @@ static int image_flush_cache(sd_event_source *s, void *userdata) { return 0; } -int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { +static int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *e = NULL; Manager *m = userdata; Image *image = NULL; @@ -462,7 +438,7 @@ char *image_bus_path(const char *name) { return strjoin("/org/freedesktop/machine1/image/", e); } -int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { +static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_hashmap_free_ Hashmap *images = NULL; _cleanup_strv_free_ char **l = NULL; Image *image; @@ -497,3 +473,34 @@ int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ** return 1; } + +const sd_bus_vtable image_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0), + SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0), + SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0), + SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0), + SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0), + SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0), + SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0), + SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0), + SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0), + SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0), + SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation image_object = { + "/org/freedesktop/machine1/image", + "org.freedesktop.machine1.Image", + .fallback_vtables = BUS_FALLBACK_VTABLES({image_vtable, image_object_find}), + .node_enumerator = image_node_enumerator, +}; diff --git a/src/machine/image-dbus.h b/src/machine/image-dbus.h index a918b77d38..43f5f34d20 100644 --- a/src/machine/image-dbus.h +++ b/src/machine/image-dbus.h @@ -1,15 +1,13 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include "bus-util.h" #include "machined.h" -extern const sd_bus_vtable image_vtable[]; +extern const BusObjectImplementation image_object; char *image_bus_path(const char *name); -int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); - int bus_image_method_remove(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index c75467cadf..1d17f220a5 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -1321,7 +1321,99 @@ int bus_machine_method_get_uid_shift(sd_bus_message *message, void *userdata, sd return sd_bus_reply_method_return(message, "u", (uint32_t) shift); } -const sd_bus_vtable machine_vtable[] = { +static int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { + Manager *m = userdata; + Machine *machine; + int r; + + assert(bus); + assert(path); + assert(interface); + assert(found); + assert(m); + + if (streq(path, "/org/freedesktop/machine1/machine/self")) { + _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); + if (r < 0) + return r; + + r = sd_bus_creds_get_pid(creds, &pid); + if (r < 0) + return r; + + r = manager_get_machine_by_pid(m, pid, &machine); + if (r <= 0) + return 0; + } else { + _cleanup_free_ char *e = NULL; + const char *p; + + p = startswith(path, "/org/freedesktop/machine1/machine/"); + if (!p) + return 0; + + e = bus_label_unescape(p); + if (!e) + return -ENOMEM; + + machine = hashmap_get(m->machines, e); + if (!machine) + return 0; + } + + *found = machine; + return 1; +} + +char *machine_bus_path(Machine *m) { + _cleanup_free_ char *e = NULL; + + assert(m); + + e = bus_label_escape(m->name); + if (!e) + return NULL; + + return strjoin("/org/freedesktop/machine1/machine/", e); +} + +static int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; + Machine *machine = NULL; + Manager *m = userdata; + Iterator i; + int r; + + assert(bus); + assert(path); + assert(nodes); + + HASHMAP_FOREACH(machine, m->machines, i) { + char *p; + + p = machine_bus_path(machine); + if (!p) + return -ENOMEM; + + r = strv_consume(&l, p); + if (r < 0) + return r; + } + + *nodes = TAKE_PTR(l); + + return 1; +} + +static const sd_bus_vtable machine_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Id", "ay", bus_property_get_id128, offsetof(Machine, id), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1423,97 +1515,12 @@ const sd_bus_vtable machine_vtable[] = { SD_BUS_VTABLE_END }; -int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - Manager *m = userdata; - Machine *machine; - int r; - - assert(bus); - assert(path); - assert(interface); - assert(found); - assert(m); - - if (streq(path, "/org/freedesktop/machine1/machine/self")) { - _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); - if (r < 0) - return r; - - r = sd_bus_creds_get_pid(creds, &pid); - if (r < 0) - return r; - - r = manager_get_machine_by_pid(m, pid, &machine); - if (r <= 0) - return 0; - } else { - _cleanup_free_ char *e = NULL; - const char *p; - - p = startswith(path, "/org/freedesktop/machine1/machine/"); - if (!p) - return 0; - - e = bus_label_unescape(p); - if (!e) - return -ENOMEM; - - machine = hashmap_get(m->machines, e); - if (!machine) - return 0; - } - - *found = machine; - return 1; -} - -char *machine_bus_path(Machine *m) { - _cleanup_free_ char *e = NULL; - - assert(m); - - e = bus_label_escape(m->name); - if (!e) - return NULL; - - return strjoin("/org/freedesktop/machine1/machine/", e); -} - -int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Machine *machine = NULL; - Manager *m = userdata; - Iterator i; - int r; - - assert(bus); - assert(path); - assert(nodes); - - HASHMAP_FOREACH(machine, m->machines, i) { - char *p; - - p = machine_bus_path(machine); - if (!p) - return -ENOMEM; - - r = strv_consume(&l, p); - if (r < 0) - return r; - } - - *nodes = TAKE_PTR(l); - - return 1; -} +const BusObjectImplementation machine_object = { + "/org/freedesktop/machine1/machine", + "org.freedesktop.machine1.Machine", + .fallback_vtables = BUS_FALLBACK_VTABLES({machine_vtable, machine_object_find}), + .node_enumerator = machine_node_enumerator, +}; int machine_send_signal(Machine *m, bool new_machine) { _cleanup_free_ char *p = NULL; diff --git a/src/machine/machine-dbus.h b/src/machine/machine-dbus.h index d9f3c59cea..7080092bcf 100644 --- a/src/machine/machine-dbus.h +++ b/src/machine/machine-dbus.h @@ -3,13 +3,12 @@ #include "sd-bus.h" +#include "bus-util.h" #include "machine.h" -extern const sd_bus_vtable machine_vtable[]; +extern const BusObjectImplementation machine_object; char *machine_bus_path(Machine *s); -int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 76d5119089..ceb3afadbd 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -1440,6 +1440,14 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END }; +const BusObjectImplementation manager_object = { + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + .vtables = BUS_VTABLES(manager_vtable), + .children = BUS_IMPLEMENTATIONS( &machine_object, + &image_object ), +}; + int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) { const char *path, *result, *unit; Manager *m = userdata; diff --git a/src/machine/machined.c b/src/machine/machined.c index 5a24f6ccc8..f2c8ff26af 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -189,25 +189,9 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m); + r = bus_add_implementation(m->bus, &manager_object, m); if (r < 0) - return log_error_errno(r, "Failed to add manager object vtable: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add machine object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add machine enumerator: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add image object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add image enumerator: %m"); + return r; r = sd_bus_match_signal_async( m->bus, @@ -360,7 +344,8 @@ static int run(int argc, char *argv[]) { r = service_parse_argv("systemd-machined.service", "Manage registrations of local VMs and containers.", - NULL, + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), argc, argv); if (r <= 0) return r; diff --git a/src/machine/machined.h b/src/machine/machined.h index 205d90f83d..0ec3fb9326 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -42,7 +42,7 @@ struct Manager { int manager_add_machine(Manager *m, const char *name, Machine **_machine); int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine); -extern const sd_bus_vtable manager_vtable[]; +extern const BusObjectImplementation manager_object; int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error); int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error); From f6e9aa9e4554004d501dac9fd4df220db7080dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 23:50:12 +0200 Subject: [PATCH 20/30] pid1: convert to the new scheme In all the other cases, I think the code was clearer with the static table. Here, not so much. And because of the existing dump code, the vtables cannot be made static and need to remain exported. I still think it's worth to do the change to have the cmdline introspection, but I'm disappointed with how this came out. --- src/core/automount.c | 1 - src/core/dbus-job.c | 52 ++++++++++ src/core/dbus-job.h | 3 +- src/core/dbus-unit.h | 1 - src/core/dbus.c | 236 +++++++++++++++++++++++++------------------ src/core/device.c | 2 - src/core/mount.c | 1 - src/core/path.c | 1 - src/core/scope.c | 1 - src/core/service.c | 1 - src/core/slice.c | 1 - src/core/socket.c | 1 - src/core/swap.c | 1 - src/core/target.c | 2 - src/core/timer.c | 1 - src/core/unit.h | 3 - 16 files changed, 189 insertions(+), 119 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index 0b3f498bfc..54711e2b7f 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -1133,7 +1133,6 @@ const UnitVTable automount_vtable = { .reset_failed = automount_reset_failed, - .bus_vtable = bus_automount_vtable, .bus_set_property = bus_automount_set_property, .shutdown = automount_shutdown, diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index 0e952c8757..404984f664 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -140,6 +140,58 @@ const sd_bus_vtable bus_job_vtable[] = { SD_BUS_VTABLE_END }; +static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { + Manager *m = userdata; + Job *j; + int r; + + assert(bus); + assert(path); + assert(interface); + assert(found); + assert(m); + + r = manager_get_job_from_dbus_path(m, path, &j); + if (r < 0) + return 0; + + *found = j; + return 1; +} + +static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; + Manager *m = userdata; + unsigned k = 0; + Iterator i; + Job *j; + + l = new0(char*, hashmap_size(m->jobs)+1); + if (!l) + return -ENOMEM; + + HASHMAP_FOREACH(j, m->jobs, i) { + l[k] = job_dbus_path(j); + if (!l[k]) + return -ENOMEM; + + k++; + } + + assert(hashmap_size(m->jobs) == k); + + *nodes = TAKE_PTR(l); + + return k; +} + +const BusObjectImplementation job_object = { + "/org/freedesktop/systemd1/job", + "org.freedesktop.systemd1.Job", + .fallback_vtables = BUS_FALLBACK_VTABLES({bus_job_vtable, bus_job_find}), + .node_enumerator = bus_job_enumerate, +}; + static int send_new_signal(sd_bus *bus, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *p = NULL; diff --git a/src/core/dbus-job.h b/src/core/dbus-job.h index 380e117fca..a840c6dfe8 100644 --- a/src/core/dbus-job.h +++ b/src/core/dbus-job.h @@ -2,11 +2,12 @@ #pragma once #include "sd-bus.h" -#include "sd-bus-vtable.h" #include "unit.h" +#include "bus-util.h" extern const sd_bus_vtable bus_job_vtable[]; +extern const BusObjectImplementation job_object; int bus_job_method_cancel(sd_bus_message *message, void *job, sd_bus_error *error); int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index 30c86ecb14..f21f236025 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -2,7 +2,6 @@ #pragma once #include "sd-bus.h" -#include "sd-bus-vtable.h" #include "unit.h" diff --git a/src/core/dbus.c b/src/core/dbus.c index 17c961edef..f9bc847d60 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -274,25 +274,6 @@ static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_er } #endif -static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - Manager *m = userdata; - Job *j; - int r; - - assert(bus); - assert(path); - assert(interface); - assert(found); - assert(m); - - r = manager_get_job_from_dbus_path(m, path, &j); - if (r < 0) - return 0; - - *found = j; - return 1; -} - static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) { Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */ int r; @@ -472,32 +453,6 @@ static int bus_kill_context_find(sd_bus *bus, const char *path, const char *inte return 1; } -static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - unsigned k = 0; - Iterator i; - Job *j; - - l = new0(char*, hashmap_size(m->jobs)+1); - if (!l) - return -ENOMEM; - - HASHMAP_FOREACH(j, m->jobs, i) { - l[k] = job_dbus_path(j); - if (!l[k]) - return -ENOMEM; - - k++; - } - - assert(hashmap_size(m->jobs) == k); - - *nodes = TAKE_PTR(l); - - return k; -} - static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; Manager *m = userdata; @@ -522,8 +477,139 @@ static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, cha return k; } +static const BusObjectImplementation unit_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Unit", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_unit_vtable, bus_unit_find }), + .node_enumerator = bus_unit_enumerate, +}; + +static const BusObjectImplementation bus_automount_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Automount", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_automount_vtable, bus_unit_interface_find }), +}; + +static const BusObjectImplementation bus_device_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Device", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_device_vtable, bus_unit_interface_find }), +}; + +static const BusObjectImplementation bus_mount_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Mount", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_mount_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }, + { bus_exec_vtable, bus_exec_context_find }, + { bus_kill_vtable, bus_kill_context_find }), +}; + +static const BusObjectImplementation bus_path_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Path", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_path_vtable, bus_unit_interface_find }), +}; + +static const BusObjectImplementation bus_scope_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Scope", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_scope_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }, + { bus_kill_vtable, bus_kill_context_find }), +}; + +static const BusObjectImplementation bus_service_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Service", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_service_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }, + { bus_exec_vtable, bus_exec_context_find }, + { bus_kill_vtable, bus_kill_context_find }), +}; + +static const BusObjectImplementation bus_slice_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Slice", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_slice_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }), +}; + +static const BusObjectImplementation bus_socket_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Socket", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_socket_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }, + { bus_exec_vtable, bus_exec_context_find }, + { bus_kill_vtable, bus_kill_context_find }), +}; + +static const BusObjectImplementation bus_swap_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Swap", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_swap_vtable, bus_unit_interface_find }, + { bus_unit_cgroup_vtable, bus_unit_cgroup_find }, + { bus_cgroup_vtable, bus_cgroup_context_find }, + { bus_exec_vtable, bus_exec_context_find }, + { bus_kill_vtable, bus_kill_context_find }), +}; + +static const BusObjectImplementation bus_target_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Target", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_target_vtable, bus_unit_interface_find }), +}; + +static const BusObjectImplementation bus_timer_object = { + "/org/freedesktop/systemd1/unit", + "org.freedesktop.systemd1.Timer", + .fallback_vtables = BUS_FALLBACK_VTABLES( + { bus_timer_vtable, bus_unit_interface_find }), +}; + +static const BusObjectImplementation bus_manager_object = { + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + .vtables = BUS_VTABLES(bus_manager_vtable), + .children = BUS_IMPLEMENTATIONS( + &job_object, + &unit_object, + &bus_automount_object, + &bus_device_object, + &bus_mount_object, + &bus_path_object, + &bus_scope_object, + &bus_service_object, + &bus_slice_object, + &bus_socket_object, + &bus_swap_object, + &bus_target_object, + &bus_timer_object), +}; + +static const BusObjectImplementation manager_log_control_object = { + "/org/freedesktop/LogControl1", + "org.freedesktop.LogControl1", + .vtables = BUS_VTABLES(bus_manager_log_control_vtable), +}; + static int bus_setup_api_vtables(Manager *m, sd_bus *bus) { - UnitType t; int r; assert(m); @@ -535,63 +621,11 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) { return log_error_errno(r, "Failed to add SELinux access filter: %m"); #endif - r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m); + r = bus_add_implementation(bus, &bus_manager_object, m); if (r < 0) - return log_error_errno(r, "Failed to register Manager vtable: %m"); + return r; - r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/LogControl1", "org.freedesktop.LogControl1", bus_manager_log_control_vtable, m); - if (r < 0) - return log_error_errno(r, "Failed to register service API vtable: %m"); - - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register Job vtable: %m"); - - r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m); - if (r < 0) - return log_error_errno(r, "Failed to add job enumerator: %m"); - - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register Unit vtable: %m"); - - r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m); - if (r < 0) - return log_error_errno(r, "Failed to add job enumerator: %m"); - - for (t = 0; t < _UNIT_TYPE_MAX; t++) { - const char *interface; - - assert_se(interface = unit_dbus_interface_from_type(t)); - - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface); - - if (unit_vtable[t]->cgroup_context_offset > 0) { - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface); - - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface); - } - - if (unit_vtable[t]->exec_context_offset > 0) { - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface); - } - - if (unit_vtable[t]->kill_context_offset > 0) { - r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m); - if (r < 0) - return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface); - } - } - - return 0; + return bus_add_implementation(bus, &manager_log_control_object, m); } static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) { diff --git a/src/core/device.c b/src/core/device.c index 8e00fd3df6..a24fea04d0 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -1081,8 +1081,6 @@ const UnitVTable device_vtable = { .active_state = device_active_state, .sub_state_to_string = device_sub_state_to_string, - .bus_vtable = bus_device_vtable, - .following = device_following, .following_set = device_following_set, diff --git a/src/core/mount.c b/src/core/mount.c index 1c4aefd734..97caf3e734 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -2110,7 +2110,6 @@ const UnitVTable mount_vtable = { .control_pid = mount_control_pid, - .bus_vtable = bus_mount_vtable, .bus_set_property = bus_mount_set_property, .bus_commit_properties = bus_mount_commit_properties, diff --git a/src/core/path.c b/src/core/path.c index cb75d778af..c7907ce4bf 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -830,6 +830,5 @@ const UnitVTable path_vtable = { .reset_failed = path_reset_failed, - .bus_vtable = bus_path_vtable, .bus_set_property = bus_path_set_property, }; diff --git a/src/core/scope.c b/src/core/scope.c index e4a536d597..42c51b0865 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -652,7 +652,6 @@ const UnitVTable scope_vtable = { .notify_cgroup_empty = scope_notify_cgroup_empty_event, - .bus_vtable = bus_scope_vtable, .bus_set_property = bus_scope_set_property, .bus_commit_properties = bus_scope_commit_properties, diff --git a/src/core/service.c b/src/core/service.c index d97270598a..b3c4ad73e5 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -4484,7 +4484,6 @@ const UnitVTable service_vtable = { .bus_name_owner_change = service_bus_name_owner_change, - .bus_vtable = bus_service_vtable, .bus_set_property = bus_service_set_property, .bus_commit_properties = bus_service_commit_properties, diff --git a/src/core/slice.c b/src/core/slice.c index 558545d310..38a2805200 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -458,7 +458,6 @@ const UnitVTable slice_vtable = { .active_state = slice_active_state, .sub_state_to_string = slice_sub_state_to_string, - .bus_vtable = bus_slice_vtable, .bus_set_property = bus_slice_set_property, .bus_commit_properties = bus_slice_commit_properties, diff --git a/src/core/socket.c b/src/core/socket.c index 4a0e3a253e..5e8f317bfc 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -3462,7 +3462,6 @@ const UnitVTable socket_vtable = { .control_pid = socket_control_pid, - .bus_vtable = bus_socket_vtable, .bus_set_property = bus_socket_set_property, .bus_commit_properties = bus_socket_commit_properties, diff --git a/src/core/swap.c b/src/core/swap.c index c5945371df..0b42236aca 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1655,7 +1655,6 @@ const UnitVTable swap_vtable = { .control_pid = swap_control_pid, - .bus_vtable = bus_swap_vtable, .bus_set_property = bus_swap_set_property, .bus_commit_properties = bus_swap_commit_properties, diff --git a/src/core/target.c b/src/core/target.c index 357ca70e09..a1d1cfc38a 100644 --- a/src/core/target.c +++ b/src/core/target.c @@ -207,8 +207,6 @@ const UnitVTable target_vtable = { .active_state = target_active_state, .sub_state_to_string = target_sub_state_to_string, - .bus_vtable = bus_target_vtable, - .status_message_formats = { .finished_start_job = { [JOB_DONE] = "Reached target %s.", diff --git a/src/core/timer.c b/src/core/timer.c index 57d979d52d..7f779fb936 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -925,6 +925,5 @@ const UnitVTable timer_vtable = { .time_change = timer_time_change, .timezone_change = timer_timezone_change, - .bus_vtable = bus_timer_vtable, .bus_set_property = bus_timer_set_property, }; diff --git a/src/core/unit.h b/src/core/unit.h index a05fd49e29..a4c342a396 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -600,9 +600,6 @@ typedef struct UnitVTable { * of this type will immediately fail. */ bool (*supported)(void); - /* The bus vtable */ - const sd_bus_vtable *bus_vtable; - /* The strings to print in status messages */ UnitStatusMessageFormats status_message_formats; From 5c08257b709fb1c4a50e8cadde1c004ad75d406a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Apr 2020 23:50:31 +0200 Subject: [PATCH 21/30] pid1: add --bus-introspect --- src/core/dbus.c | 8 ++++++++ src/core/dbus.h | 1 + src/core/main.c | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/dbus.c b/src/core/dbus.c index f9bc847d60..76bb91d0ea 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -609,6 +609,14 @@ static const BusObjectImplementation manager_log_control_object = { .vtables = BUS_VTABLES(bus_manager_log_control_vtable), }; +int bus_manager_introspect_implementations(FILE *out, const char *pattern) { + return bus_introspect_implementations( + out, + pattern, + BUS_IMPLEMENTATIONS(&bus_manager_object, + &manager_log_control_object)); +} + static int bus_setup_api_vtables(Manager *m, sd_bus *bus) { int r; diff --git a/src/core/dbus.h b/src/core/dbus.h index d5ba6537ea..812f56ea2a 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -33,3 +33,4 @@ int bus_forward_agent_released(Manager *m, const char *path); uint64_t manager_bus_n_queued_write(Manager *m); void dump_bus_properties(FILE *f); +int bus_manager_introspect_implementations(FILE *out, const char *pattern); diff --git a/src/core/main.c b/src/core/main.c index a2a1ca3a41..c9eaf70bd6 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -93,8 +93,11 @@ static enum { ACTION_TEST, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, + ACTION_BUS_INTROSPECT, } arg_action = ACTION_RUN; +static const char *arg_bus_introspect = NULL; + /* Those variables are initialized to 0 automatically, so we avoid uninitialized memory access. * Real defaults are assigned in reset_arguments() below. */ static char *arg_default_unit; @@ -729,6 +732,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION, ARG_DUMP_CONFIGURATION_ITEMS, ARG_DUMP_BUS_PROPERTIES, + ARG_BUS_INTROSPECT, ARG_DUMP_CORE, ARG_CRASH_CHVT, ARG_CRASH_SHELL, @@ -758,6 +762,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS }, { "dump-bus-properties", no_argument, NULL, ARG_DUMP_BUS_PROPERTIES }, + { "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT }, { "dump-core", optional_argument, NULL, ARG_DUMP_CORE }, { "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT }, { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL }, @@ -885,6 +890,11 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_DUMP_BUS_PROPERTIES; break; + case ARG_BUS_INTROSPECT: + arg_bus_introspect = optarg; + arg_action = ACTION_BUS_INTROSPECT; + break; + case ARG_DUMP_CORE: if (!optarg) arg_dump_core = true; @@ -1044,6 +1054,7 @@ static int help(void) { " --no-pager Do not pipe output into a pager\n" " --dump-configuration-items Dump understood unit configuration items\n" " --dump-bus-properties Dump exposed bus properties\n" + " --bus-introspect=PATH Write XML introspection data\n" " --unit=UNIT Set default unit\n" " --dump-core[=BOOL] Dump core on crash\n" " --crash-vt=NR Change to specified VT on crash\n" @@ -2615,7 +2626,7 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES)) + if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT)) (void) pager_open(arg_pager_flags); if (arg_action != ACTION_RUN) @@ -2635,6 +2646,10 @@ int main(int argc, char *argv[]) { dump_bus_properties(stdout); retval = EXIT_SUCCESS; goto finish; + } else if (arg_action == ACTION_BUS_INTROSPECT) { + r = bus_manager_introspect_implementations(stdout, arg_bus_introspect); + retval = r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; + goto finish; } assert_se(IN_SET(arg_action, ACTION_RUN, ACTION_TEST)); From c351d568c3ddf5a10231f9d5e8c9d7059292767c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 12:09:07 +0200 Subject: [PATCH 22/30] update-dbus-docs: use executables in build/ --- tools/update-dbus-docs.py | 54 +++++++++++++++------------------------ 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/tools/update-dbus-docs.py b/tools/update-dbus-docs.py index 95a22bebfa..f95faaaf22 100755 --- a/tools/update-dbus-docs.py +++ b/tools/update-dbus-docs.py @@ -3,10 +3,10 @@ import collections import sys +import os import shlex import subprocess import io -import pprint from lxml import etree PARSER = etree.XMLParser(no_network=True, @@ -19,23 +19,6 @@ PRINT_ERRORS = True class NoCommand(Exception): pass -def find_command(lines): - acc = [] - for num, line in enumerate(lines): - # skip empty leading line - if num == 0 and not line: - continue - cont = line.endswith('\\') - if cont: - line = line[:-1].rstrip() - acc.append(line if not acc else line.lstrip()) - if not cont: - break - joined = ' '.join(acc) - if not joined.startswith('$ '): - raise NoCommand - return joined[2:], lines[:num+1] + [''], lines[-1] - BORING_INTERFACES = [ 'org.freedesktop.DBus.Peer', 'org.freedesktop.DBus.Introspectable', @@ -183,31 +166,27 @@ def xml_to_text(destination, xml, *, only_interface=None): return file.getvalue(), declarations, interfaces def subst_output(document, programlisting): - try: - cmd, prefix_lines, footer = find_command(programlisting.text.splitlines()) - except NoCommand: + executable = programlisting.get('executable', None) + if executable is None: + # Not our thing return + executable = programlisting.get('executable') + node = programlisting.get('node') + interface = programlisting.get('interface') - only_interface = programlisting.get('interface', None) - - argv = shlex.split(cmd) - argv += ['--xml'] + argv = [f'{build_dir}/{executable}', f'--bus-introspect={interface}'] print(f'COMMAND: {shlex.join(argv)}') - object_idx = argv.index('--object-path') - object_path = argv[object_idx + 1] - try: out = subprocess.check_output(argv, text=True) - except subprocess.CalledProcessError: - print('command failed, ignoring', file=sys.stderr) + except FileNotFoundError: + print(f'{executable} not found, ignoring', file=sys.stderr) return xml = etree.fromstring(out, parser=PARSER) - new_text, declarations, interfaces = xml_to_text(object_path, xml, only_interface=only_interface) - - programlisting.text = '\n'.join(prefix_lines) + '\n' + new_text + footer + new_text, declarations, interfaces = xml_to_text(node, xml, only_interface=interface) + programlisting.text = '\n' + new_text + ' ' if declarations: missing = check_documented(document, declarations) @@ -291,5 +270,14 @@ def process(page): if __name__ == '__main__': pages = sys.argv[1:] + if pages[0].startswith('--build-dir='): + build_dir = pages[0].partition('=')[2] + pages = pages[1:] + else: + build_dir = 'build' + + if not os.path.exists(f'{build_dir}/systemd'): + exit(f"{build_dir}/systemd doesn't exist. Use --build-dir=.") + for page in pages: process(page) From 48f99d7c069e07671e570161aecbe109af1285e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 12:08:10 +0200 Subject: [PATCH 23/30] man: use --bus-introspect to autogenerate dbus api docs This has the advantage that the executables are always in place and we don't need any units to exist on the bus, so we can eventually hook this up into a normal build system. (Probably as a build time check.) --- man/org.freedesktop.hostname1.xml | 19 +++- man/org.freedesktop.import1.xml | 34 +++++-- man/org.freedesktop.locale1.xml | 20 +++- man/org.freedesktop.login1.xml | 151 +++++++++++++++++++++++++---- man/org.freedesktop.machine1.xml | 36 +++++-- man/org.freedesktop.resolve1.xml | 38 +++++--- man/org.freedesktop.systemd1.xml | 155 ++++++++++++++---------------- man/org.freedesktop.timedate1.xml | 20 +++- 8 files changed, 325 insertions(+), 148 deletions(-) diff --git a/man/org.freedesktop.hostname1.xml b/man/org.freedesktop.hostname1.xml index 406a6a369e..d17d9a5521 100644 --- a/man/org.freedesktop.hostname1.xml +++ b/man/org.freedesktop.hostname1.xml @@ -38,11 +38,7 @@ The service exposes the following interfaces on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.hostname1 \ - --object-path /org/freedesktop/hostname1 - + node /org/freedesktop/hostname1 { interface org.freedesktop.hostname1 { methods: @@ -349,6 +345,19 @@ node /org/freedesktop/hostname1 { the usual interface versioning guidelines. + + Examples + + + Introspect <interfacename>org.freedesktop.hostname1</interfacename> on the bus + + $ gdbus introspect --system \ + --dest org.freedesktop.hostname1 \ + --object-path /org/freedesktop/hostname1 + + + + See also diff --git a/man/org.freedesktop.import1.xml b/man/org.freedesktop.import1.xml index 4a425f1ac3..1414cc15d7 100644 --- a/man/org.freedesktop.import1.xml +++ b/man/org.freedesktop.import1.xml @@ -46,11 +46,7 @@ The service exposes the following interfaces on the Manager object on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.import1 \ - --object-path /org/freedesktop/import1 - + node /org/freedesktop/import1 { interface org.freedesktop.import1.Manager { methods: @@ -238,11 +234,7 @@ node /org/freedesktop/import1 { The Transfer Object - -$ gdbus introspect --system \ - --dest org.freedesktop.import1 \ - --object-path /org/freedesktop/import1/transfer/_1 - + node /org/freedesktop/import1/transfer/_1 { interface org.freedesktop.import1.Transfer { methods: @@ -325,6 +317,28 @@ node /org/freedesktop/import1/transfer/_1 { + + Examples + + + Introspect <interfacename>org.freedesktop.import1.Manager</interfacename> on the bus + + $ gdbus introspect --system \ + --dest org.freedesktop.import1 \ + --object-path /org/freedesktop/import1 + + + + + Introspect <interfacename>org.freedesktop.import1.Transfer</interfacename> on the bus + + $ gdbus introspect --system \ + --dest org.freedesktop.import1 \ + --object-path /org/freedesktop/import1/transfer/_1 + + + + Versioning diff --git a/man/org.freedesktop.locale1.xml b/man/org.freedesktop.locale1.xml index f15945e766..3956eaf8a7 100644 --- a/man/org.freedesktop.locale1.xml +++ b/man/org.freedesktop.locale1.xml @@ -34,11 +34,7 @@ The service exposes the following interfaces on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.locale1 \ - --object-path /org/freedesktop/locale1 - + node /org/freedesktop/locale1 { interface org.freedesktop.locale1 { methods: @@ -169,6 +165,20 @@ node /org/freedesktop/locale1 { + + Examples + + + Introspect <interfacename>org.freedesktop.locale1</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.locale1 \ + --object-path /org/freedesktop/locale1 + + + + Versioning diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index aedf5d7fc3..8de6cf513d 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -38,11 +38,7 @@ The service exposes the following interfaces on the Manager object on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.login1 \ - --object-path /org/freedesktop/login1 - + node /org/freedesktop/login1 { interface org.freedesktop.login1.Manager { methods: @@ -741,10 +737,7 @@ node /org/freedesktop/login1 { Seat Objects - -$ gdbus introspect --system --dest org.freedesktop.login1 \ - --object-path /org/freedesktop/login1/seat/seat0 - + node /org/freedesktop/login1/seat/seat0 { interface org.freedesktop.login1.Seat { methods: @@ -856,10 +849,7 @@ node /org/freedesktop/login1/seat/seat0 { User Objects - -$ gdbus introspect --system --dest org.freedesktop.login1 \ - --object-path /org/freedesktop/login1/user/_1000 - + node /org/freedesktop/login1/user/_1000 { interface org.freedesktop.login1.User { methods: @@ -1004,11 +994,8 @@ node /org/freedesktop/login1/user/_1000 { Session Objects - -$ gdbus introspect --system --dest org.freedesktop.login1 \ - --object-path /org/freedesktop/login1/session/45 - -node /org/freedesktop/login1/session/45 { + +node /org/freedesktop/login1/session/1 { interface org.freedesktop.login1.Session { methods: Terminate(); @@ -1093,6 +1080,98 @@ node /org/freedesktop/login1/session/45 { }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Methods @@ -1257,6 +1336,42 @@ node /org/freedesktop/login1/session/45 { + + Examples + + + Introspect <interfacename>org.freedesktop.login1.Manager</interfacename> on the bus + + $ gdbus introspect --system --dest org.freedesktop.login1 \ + --object-path /org/freedesktop/login1 + + + + + Introspect <interfacename>org.freedesktop.login1.Seat</interfacename> on the bus + + $ gdbus introspect --system --dest org.freedesktop.login1 \ + --object-path /org/freedesktop/login1/seat/seat0 + + + + + Introspect <interfacename>org.freedesktop.login1.User</interfacename> on the bus + + $ gdbus introspect --system --dest org.freedesktop.login1 \ + --object-path /org/freedesktop/login1/user/_1000 + + + + + Introspect <interfacename>org.freedesktop.login1.Session</interfacename> on the bus + + $ gdbus introspect --system --dest org.freedesktop.login1 \ + --object-path /org/freedesktop/login1/session/45 + + + + Versioning diff --git a/man/org.freedesktop.machine1.xml b/man/org.freedesktop.machine1.xml index bc9779c521..c18e133e7c 100644 --- a/man/org.freedesktop.machine1.xml +++ b/man/org.freedesktop.machine1.xml @@ -34,11 +34,7 @@ The service exposes the following interfaces on the Manager object on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.machine1 \ - --object-path /org/freedesktop/machine1 - + node /org/freedesktop/machine1 { interface org.freedesktop.machine1.Manager { methods: @@ -435,11 +431,7 @@ node /org/freedesktop/machine1 { Machine Objects - -$ gdbus introspect --system \ - --dest org.freedesktop.machine1 \ - --object-path /org/freedesktop/machine1/machine/rawhide - + node /org/freedesktop/machine1/machine/rawhide { interface org.freedesktop.machine1.Machine { methods: @@ -617,6 +609,30 @@ node /org/freedesktop/machine1/machine/rawhide { + + Examples + + + Introspect <interfacename>org.freedesktop.machine1.Manager</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.machine1 \ + --object-path /org/freedesktop/machine1 + + + + + Introspect <interfacename>org.freedesktop.machine1.Machine</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.machine1 \ + --object-path /org/freedesktop/machine1/machine/rawhide + + + + Versioning diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml index 912f73677c..86bd1c2a62 100644 --- a/man/org.freedesktop.resolve1.xml +++ b/man/org.freedesktop.resolve1.xml @@ -46,11 +46,7 @@ The service exposes the following interfaces on the Manager object on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.resolve1 \ - --object-path /org/freedesktop/resolve1 - + node /org/freedesktop/resolve1 { interface org.freedesktop.resolve1.Manager { methods: @@ -551,12 +547,8 @@ node /org/freedesktop/resolve1 { Link Object - -$ gdbus introspect --system \ - --dest org.freedesktop.resolve1 \ - --object-path /org/freedesktop/resolve1/link/_34 - -node /org/freedesktop/resolve1/link/_34 { + +node /org/freedesktop/resolve1/link/_1 { interface org.freedesktop.resolve1.Link { methods: SetDNS(in a(iay) addresses); @@ -790,6 +782,30 @@ node /org/freedesktop/resolve1/link/_34 { + + Examples + + + Introspect <interfacename>org.freedesktop.resolve1.Manager</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.resolve1 \ + --object-path /org/freedesktop/resolve1 + + + + + Introspect <interfacename>org.freedesktop.resolve1.Link</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.resolve1 \ + --object-path /org/freedesktop/resolve1/link/_11 + + + + Versioning diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index da5541be90..741fd3d481 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -57,11 +57,7 @@ The main entry point object is available on the fixed /org/freedesktop/systemd1 object path: - -$ gdbus introspect --system \ - --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1 - + node /org/freedesktop/systemd1 { interface org.freedesktop.systemd1.Manager { methods: @@ -1484,10 +1480,7 @@ node /org/freedesktop/systemd1 { Unit Objects - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice - + node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { interface org.freedesktop.systemd1.Unit { methods: @@ -1674,7 +1667,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Introspectable { ... }; interface org.freedesktop.DBus.Properties { ... }; - interface org.freedesktop.systemd1.Service { ... }; }; @@ -1746,12 +1738,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - - - @@ -2139,10 +2127,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { org.freedesktop.systemd1.Service interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice - + node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { interface org.freedesktop.systemd1.Service { methods: @@ -3135,14 +3120,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - + + @@ -3746,10 +3731,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { Socket Unit Objects - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket - + node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { interface org.freedesktop.systemd1.Socket { methods: @@ -4777,14 +4759,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { - - + + @@ -5340,10 +5322,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { Target Unit Objects - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/basic_2etarget - + node /org/freedesktop/systemd1/unit/basic_2etarget { interface org.freedesktop.systemd1.Target { }; @@ -5364,11 +5343,8 @@ node /org/freedesktop/systemd1/unit/basic_2etarget { All device unit objects implement the org.freedesktop.systemd1.Device interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice - -node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice { + +node /org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice { interface org.freedesktop.systemd1.Device { properties: readonly s SysFSPath = '...'; @@ -5382,14 +5358,14 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice { - - + + @@ -5411,10 +5387,7 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice { interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/home_2emount - + node /org/freedesktop/systemd1/unit/home_2emount { interface org.freedesktop.systemd1.Mount { methods: @@ -6291,14 +6264,14 @@ node /org/freedesktop/systemd1/unit/home_2emount { - - + + @@ -6773,10 +6746,7 @@ node /org/freedesktop/systemd1/unit/home_2emount { org.freedesktop.systemd1.Automount interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount - + node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount { interface org.freedesktop.systemd1.Automount { properties: @@ -6803,14 +6773,14 @@ node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount - - + + @@ -6841,10 +6811,7 @@ node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer - + node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer { interface org.freedesktop.systemd1.Timer { properties: @@ -6901,14 +6868,14 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer { - - + + @@ -6980,10 +6947,7 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer { interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap - + node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { interface org.freedesktop.systemd1.Swap { methods: @@ -7836,14 +7800,14 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { - - + + @@ -8306,10 +8270,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { Path Unit Objects - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/cups_2epath - + node /org/freedesktop/systemd1/unit/cups_2epath { interface org.freedesktop.systemd1.Path { properties: @@ -8336,14 +8297,14 @@ node /org/freedesktop/systemd1/unit/cups_2epath { - - + + @@ -8382,10 +8343,7 @@ node /org/freedesktop/systemd1/unit/cups_2epath { interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/system_2eslice - + node /org/freedesktop/systemd1/unit/system_2eslice { interface org.freedesktop.systemd1.Slice { methods: @@ -8645,14 +8603,14 @@ node /org/freedesktop/systemd1/unit/system_2eslice { - - + + @@ -8793,10 +8751,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice { interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/unit/session_2d1_2escope - + node /org/freedesktop/systemd1/unit/session_2d1_2escope { interface org.freedesktop.systemd1.Scope { methods: @@ -9097,14 +9052,14 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { - - + + @@ -9293,11 +9248,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { Job objects encapsulate scheduled or running jobs. Each unit can have none or one jobs in the execution queue. Each job is attached to exactly one unit. - -$ gdbus introspect --system --dest org.freedesktop.systemd1 \ - --object-path /org/freedesktop/systemd1/job/1292 - -node /org/freedesktop/systemd1/job/1292 { + +node /org/freedesktop/systemd1/job/666 { interface org.freedesktop.systemd1.Job { methods: Cancel(); @@ -9373,6 +9325,41 @@ node /org/freedesktop/systemd1/job/1292 { + + Examples + + + Introspect <interfacename>org.freedesktop.systemd1.Manager</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.systemd1 \ + --object-path /org/freedesktop/systemd1 + + + + + Introspect a unit on the bus + + +$ busctl introspect org.freedesktop.systemd1 \ + $(busctl call org.freedesktop.systemd1 \ + /org/freedesktop/systemd1 \ + org.freedesktop.systemd1.Manager \ + GetUnit s systemd-resolved.service | cut -d'"' -f2) + + + + + Introspect <interfacename>org.freedesktop.systemd1.Job</interfacename> on the bus + + +$ gdbus introspect --system --dest org.freedesktop.systemd1 \ + --object-path /org/freedesktop/systemd1/job/1292 + + + + Versioning diff --git a/man/org.freedesktop.timedate1.xml b/man/org.freedesktop.timedate1.xml index 3111ebbc42..325c3acfb1 100644 --- a/man/org.freedesktop.timedate1.xml +++ b/man/org.freedesktop.timedate1.xml @@ -34,11 +34,7 @@ The service exposes the following interfaces on the bus: - -$ gdbus introspect --system \ - --dest org.freedesktop.timedate1 \ - --object-path /org/freedesktop/timedate1 - + node /org/freedesktop/timedate1 { interface org.freedesktop.timedate1 { methods: @@ -180,6 +176,20 @@ node /org/freedesktop/timedate1 { + + Examples + + + Introspect <interfacename>org.freedesktop.timedate1</interfacename> on the bus + + +$ gdbus introspect --system \ + --dest org.freedesktop.timedate1 \ + --object-path /org/freedesktop/timedate1 + + + + Versioning From 38b52b691805613a7948216000dbdd40695a4dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 17:54:28 +0200 Subject: [PATCH 24/30] man: drop CanMultiSession from documention Removed in 8f8cc84ba4612e74cd1e26898c6816e6e60fc4e9. --- man/org.freedesktop.login1.xml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index 8de6cf513d..0908b2ea10 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -751,8 +751,6 @@ node /org/freedesktop/login1/seat/seat0 { readonly s Id = '...'; readonly (so) ActiveSession = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b CanMultiSession = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b CanTTY = ...; readonly b CanGraphical = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") @@ -787,8 +785,6 @@ node /org/freedesktop/login1/seat/seat0 { - - @@ -820,7 +816,7 @@ node /org/freedesktop/login1/seat/seat0 { Signals Whenever ActiveSession, Sessions, - CanGraphical, CanMultiSession and CanTTY + CanGraphical, CanTTY, or the idle state changes, PropertyChanged signals are sent out to which clients can subscribe. @@ -833,9 +829,8 @@ node /org/freedesktop/login1/seat/seat0 { ActiveSession encodes the currently active session if there is one. It is a structure consisting of the session id and the object path. - CanMultiSession encodes whether the session is multi-session capable, - CanTTY whether it is suitable for text logins, CanGraphical - whether it is suitable for graphical sessions. + CanTTY encodes whether the session is suitable for text logins, and + CanGraphical whether it is suitable for graphical sessions. The Sessions property is an array of all current sessions of this seat, each encoded in a structure consisting of the ID and the object path. From 7cb4f4145f515e2d5f858af7ff4a05513acb5a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 17:55:11 +0200 Subject: [PATCH 25/30] man: drop LogLevel from resolve1(5) Removed in 4c4520789d2bfa3fa51b38b826cac2efb5a4d252. --- man/org.freedesktop.resolve1.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml index 86bd1c2a62..7a57806ebb 100644 --- a/man/org.freedesktop.resolve1.xml +++ b/man/org.freedesktop.resolve1.xml @@ -141,9 +141,6 @@ node /org/freedesktop/resolve1 { readonly as DNSSECNegativeTrustAnchors = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DNSStubListener = '...'; - @org.freedesktop.DBus.Property.EmitsChangedSignal("false") - @org.freedesktop.systemd1.Privileged("true") - readwrite s LogLevel = '...'; }; interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Introspectable { ... }; @@ -253,8 +250,6 @@ node /org/freedesktop/resolve1 { - - From 81e06775be4d8394d0d8b1506adeee038343e4b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 20:12:03 +0200 Subject: [PATCH 26/30] meson: add man/update-dbus-docs target --- man/meson.build | 20 +++++++++++++++++++- meson.build | 7 ++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/man/meson.build b/man/meson.build index 8021adedec..c9d511b080 100644 --- a/man/meson.build +++ b/man/meson.build @@ -34,6 +34,7 @@ custom_entities_ent = configure_file( man_pages = [] html_pages = [] source_xml_files = [] +dbus_docs = [] foreach tuple : xsltproc.found() ? manpages : [] stem = tuple[0] section = tuple[1] @@ -90,7 +91,11 @@ foreach tuple : xsltproc.found() ? manpages : [] install_dir : join_paths(docdir, 'html')) html_pages += p3 - source_xml_files += files(tuple[0] + '.xml') + file = files(tuple[0] + '.xml') + source_xml_files += file + if tuple[0].startswith('org.freedesktop.') + dbus_docs += file + endif else message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition)) endif @@ -193,6 +198,19 @@ run_target( ############################################################ +if dbus_docs.length() > 0 + custom_target( + 'update-dbus-docs', + output : 'update-dbus-docs', + command : ['python3', + '@0@/tools/update-dbus-docs.py'.format(project_source_root), + '--build-dir=@0@'.format(project_build_root), + '@INPUT@'], + input : dbus_docs) +endif + +############################################################ + if git.found() custom_target( 'update-man-rules', diff --git a/meson.build b/meson.build index 6c9299e27b..c25cc1c6cf 100644 --- a/meson.build +++ b/meson.build @@ -32,8 +32,9 @@ substs.set('PROJECT_VERSION', meson.project_version(), # This is to be used instead of meson.source_root(), as the latter will return # the wrong result when systemd is being built as a meson subproject project_source_root = meson.current_source_dir() +project_build_root = meson.current_build_dir() relative_source_path = run_command('realpath', - '--relative-to=@0@'.format(meson.current_build_dir()), + '--relative-to=@0@'.format(project_build_root), project_source_root).stdout().strip() conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path) @@ -292,7 +293,7 @@ substs.set('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-loc substs.set('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_default ? 'yes' : 'no') substs.set('STATUS_UNIT_FORMAT_DEFAULT', status_unit_format_default) substs.set('HIGH_RLIMIT_NOFILE', conf.get('HIGH_RLIMIT_NOFILE')) -substs.set('BUILD_ROOT', meson.current_build_dir()) +substs.set('BUILD_ROOT', project_build_root) ##################################################################### @@ -3081,7 +3082,7 @@ custom_target( output : 'systemd-runtest.env', command : ['sh', '-c', '{ ' + 'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(project_source_root, 'test')) + - 'echo SYSTEMD_CATALOG_DIR=@0@; '.format(join_paths(meson.current_build_dir(), 'catalog')) + + 'echo SYSTEMD_CATALOG_DIR=@0@; '.format(join_paths(project_build_root, 'catalog')) + '} >@OUTPUT@'], build_by_default : true) From 1a0e562a5b367bbf01bc7532ca0f371e1dd38f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 24 Apr 2020 21:04:43 +0200 Subject: [PATCH 27/30] man: add description of org.freedesktop.LogControl1 I'm not sure if the LogTarget property is sufficiently general to be made into a property that can be generally implemented. It is very closely tied to the internal systemd logic. The other two seem fine thoough. --- man/org.freedesktop.LogControl1.xml | 106 ++++++++++++++++++++++++++++ man/rules/meson.build | 1 + man/systemd-hostnamed.service.xml | 4 +- man/systemd-importd.service.xml | 9 +-- man/systemd-localed.service.xml | 4 +- man/systemd-logind.service.xml | 4 +- man/systemd-machined.service.xml | 4 +- man/systemd-resolved.service.xml | 2 + man/systemd-timedated.service.xml | 2 + man/systemd.xml | 5 +- 10 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 man/org.freedesktop.LogControl1.xml diff --git a/man/org.freedesktop.LogControl1.xml b/man/org.freedesktop.LogControl1.xml new file mode 100644 index 0000000000..125a008347 --- /dev/null +++ b/man/org.freedesktop.LogControl1.xml @@ -0,0 +1,106 @@ + + + + + + + org.freedesktop.LogControl1 + systemd + + + + org.freedesktop.LogControl1 + 5 + + + + org.freedesktop.LogControl1 + D-Bus interface to query and set logging configuration + + + + Introduction + + org.freedesktop.LogControl1 is a generic interface that is intended + to be used by any daemon which should allow setting the log level and target over D-Bus. It is implemented + by various daemons that are part of the + systemd1 suite. + + It is assumed that those settings are global for the whole program, so a fixed object path is + used. The interface should always be available under the path + /org/freedesktop/LogControl1. + + + + Description + + The following interface is exposed: + + +node /org/freedesktop/LogControl1 { + interface org.freedesktop.LogControl1 { + properties: + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + @org.freedesktop.systemd1.Privileged("true") + readwrite s LogLevel = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + @org.freedesktop.systemd1.Privileged("true") + readwrite s LogTarget = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s SyslogIdentifier = '...'; + }; + interface org.freedesktop.DBus.Peer { ... }; + interface org.freedesktop.DBus.Introspectable { ... }; + interface org.freedesktop.DBus.Properties { ... }; +}; + + + + + + + + + + + + + + + + + + Properties + + LogLevel describes the + syslog3-style + log-level, and should be one of emerg, alert, + crit, err, warning, notice, + info, debug, in order of increasing verbosity. + + LogTarget describes the log target (mechanism). It should be one of + console (log to the console or standard output), + kmsg (log to the kernel ring buffer), + journal (log the the journal natively, see + systemd-journald.service8), + syslog (log using the + syslog3 call). + + + Those two properties are writable, so they may be set by sufficiently privileged users. + + SyslogIdentifier is a read-only property that shows the "syslog identifier". + It is a short string that identifies the program that is the source of log messages that is passed to + the syslog3 call. + + + Note: journalctl option / may + be used to filter log messages by log level, option / + may be used to by the syslog identifier, and filters like _TRANSPORT=syslog, + _TRANSPORT=journal, and _TRANSPORT=kernel may be used to filter + messages by the mechanism through which they reached systemd-journald. + + + diff --git a/man/rules/meson.build b/man/rules/meson.build index 2096222c50..cda68ef99b 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -44,6 +44,7 @@ manpages = [ ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_NSS_MYMACHINES'], ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'], ['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'], + ['org.freedesktop.LogControl1', '5', [], ''], ['org.freedesktop.hostname1', '5', [], 'ENABLE_HOSTNAMED'], ['org.freedesktop.import1', '5', [], 'ENABLE_IMPORTD'], ['org.freedesktop.locale1', '5', [], 'ENABLE_LOCALED'], diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml index 699316a09a..1aa32a61ce 100644 --- a/man/systemd-hostnamed.service.xml +++ b/man/systemd-hostnamed.service.xml @@ -56,7 +56,9 @@ is a command line client to this service. See - org.freedesktop.hostname11 + org.freedesktop.hostname15 + and + org.freedesktop.LogControl15 for a description of the D-Bus API. diff --git a/man/systemd-importd.service.xml b/man/systemd-importd.service.xml index 355e5b0b98..fa3c3a812f 100644 --- a/man/systemd-importd.service.xml +++ b/man/systemd-importd.service.xml @@ -36,10 +36,11 @@ pull-raw, pull-tar, import-raw, import-tar, export-raw, and export-tar commands. - See the - - importd D-Bus API Documentation for information about the - APIs systemd-importd provides. + See + org.freedesktop.import15 + and + org.freedesktop.LogControl15 + for a description of the D-Bus API. diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml index e5f6b78d21..49eeeffee6 100644 --- a/man/systemd-localed.service.xml +++ b/man/systemd-localed.service.xml @@ -41,7 +41,9 @@ is a command line client to this service. See - org.freedesktop.locale11 + org.freedesktop.locale15 + and + org.freedesktop.LogControl15 for a description of the D-Bus API. diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml index 12f9f7a0f6..c602b2e42f 100644 --- a/man/systemd-logind.service.xml +++ b/man/systemd-logind.service.xml @@ -79,7 +79,9 @@ such as users, sessions and seats. See - org.freedesktop.login13 + org.freedesktop.login15 + and + org.freedesktop.LogControl15 for information about the D-Bus APIs systemd-logind provides. For more information on the inhibition logic see the sd-login3 and - org.freedesktop.machine13. + org.freedesktop.machine15. + and + org.freedesktop.LogControl15 A small companion daemon diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml index 2f4efab1ff..6e1ee9f4a5 100644 --- a/man/systemd-resolved.service.xml +++ b/man/systemd-resolved.service.xml @@ -38,6 +38,8 @@ The native, fully-featured API systemd-resolved exposes on the bus, see org.freedesktop.resolve15 + and + org.freedesktop.LogControl15 for details. Usage of this API is generally recommended to clients as it is asynchronous and fully featured (for example, properly returns DNSSEC validation status and interface scope for addresses as necessary for supporting link-local networking). diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml index b722b33115..93cfdf5118 100644 --- a/man/systemd-timedated.service.xml +++ b/man/systemd-timedated.service.xml @@ -55,6 +55,8 @@ See org.freedesktop.timedate15 + and + org.freedesktop.LogControl15 for information about the D-Bus API. diff --git a/man/systemd.xml b/man/systemd.xml index 4e08ff6254..11954a78da 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -281,7 +281,10 @@ systemd.generator7. The D-Bus API of systemd is described in - org.freedesktop.systemd15. + org.freedesktop.systemd15 + and + org.freedesktop.LogControl15. + Systems which invoke systemd in a container or initrd environment should implement the Container Interface or Date: Sun, 3 May 2020 10:05:06 +0200 Subject: [PATCH 28/30] homed: convert to the new scheme and add --bus-introspect --- src/home/homed-home-bus.c | 130 +++++++++++++++---- src/home/homed-home-bus.h | 6 +- src/home/homed-manager-bus.c | 233 ++++++++++++++++++++++++++++++----- src/home/homed-manager-bus.h | 4 +- src/home/homed-manager.c | 18 +-- src/home/homed.c | 14 ++- 6 files changed, 322 insertions(+), 83 deletions(-) diff --git a/src/home/homed-home-bus.c b/src/home/homed-home-bus.c index 6b4fa58a6f..af2ddce330 100644 --- a/src/home/homed-home-bus.c +++ b/src/home/homed-home-bus.c @@ -712,38 +712,13 @@ int bus_home_method_release( /* We map a uid_t as uint32_t bus property, let's ensure this is safe. */ assert_cc(sizeof(uid_t) == sizeof(uint32_t)); -const sd_bus_vtable home_vtable[] = { - SD_BUS_VTABLE_START(0), - SD_BUS_PROPERTY("UserName", "s", NULL, offsetof(Home, user_name), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Home, uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("UnixRecord", "(suusss)", property_get_unix_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0), - SD_BUS_PROPERTY("UserRecord", "(sb)", property_get_user_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Activate", "s", NULL, bus_home_method_activate, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0), - SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Realize", "s", NULL, bus_home_method_realize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("Fixate", "s", NULL, bus_home_method_fixate, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Authenticate", "s", NULL, bus_home_method_authenticate, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Update", "s", NULL, bus_home_method_update, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Resize", "ts", NULL, bus_home_method_resize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("ChangePassword", "ss", NULL, bus_home_method_change_password, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0), - SD_BUS_METHOD("Unlock", "s", NULL, bus_home_method_unlock, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Acquire", "sb", "h", bus_home_method_acquire, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("Ref", "b", "h", bus_home_method_ref, 0), - SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0), - SD_BUS_VTABLE_END -}; - int bus_home_path(Home *h, char **ret) { assert(ret); return sd_bus_path_encode("/org/freedesktop/home1/home", h->user_name, ret); } -int bus_home_object_find( +static int bus_home_object_find( sd_bus *bus, const char *path, const char *interface, @@ -772,7 +747,7 @@ int bus_home_object_find( return 1; } -int bus_home_node_enumerator( +static int bus_home_node_enumerator( sd_bus *bus, const char *path, void *userdata, @@ -802,6 +777,107 @@ int bus_home_node_enumerator( return 1; } +const sd_bus_vtable home_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("UserName", "s", + NULL, offsetof(Home, user_name), + SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("UID", "u", + NULL, offsetof(Home, uid), + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("UnixRecord", "(suusss)", + property_get_unix_record, 0, + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("State", "s", + property_get_state, 0, + 0), + SD_BUS_PROPERTY("UserRecord", "(sb)", + property_get_user_record, 0, + SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE), + + SD_BUS_METHOD_WITH_NAMES("Activate", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_activate, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0), + SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("Realize", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_realize, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("Fixate", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_fixate, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("Authenticate", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_authenticate, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("Update", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_update, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("Resize", + "ts", + SD_BUS_PARAM(size) + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_resize, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("ChangePassword", + "ss", + SD_BUS_PARAM(new_user_record) + SD_BUS_PARAM(old_user_record), + NULL,, + bus_home_method_change_password, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0), + SD_BUS_METHOD_WITH_NAMES("Unlock", + "s", + SD_BUS_PARAM(user_record), + NULL,, + bus_home_method_unlock, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("Acquire", + "sb", + SD_BUS_PARAM(user_record) + SD_BUS_PARAM(please_suspend), + "h", + SD_BUS_PARAM(send_fd), + bus_home_method_acquire, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("Ref", + "b", + SD_BUS_PARAM(please_suspend), + "h", + SD_BUS_PARAM(send_fd), + bus_home_method_ref, + 0), + SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0), + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation home_object = { + "/org/freedesktop/home1/home", + "org.freedesktop.home1.Home", + .fallback_vtables = BUS_FALLBACK_VTABLES({home_vtable, bus_home_object_find}), + .node_enumerator = bus_home_node_enumerator, + .manager = true, +}; + static int on_deferred_change(sd_event_source *s, void *userdata) { _cleanup_free_ char *path = NULL; Home *h = userdata; diff --git a/src/home/homed-home-bus.h b/src/home/homed-home-bus.h index 20516b1205..59b2a970b8 100644 --- a/src/home/homed-home-bus.h +++ b/src/home/homed-home-bus.h @@ -3,6 +3,7 @@ #include "sd-bus.h" +#include "bus-util.h" #include "homed-home.h" int bus_home_client_is_trusted(Home *h, sd_bus_message *message); @@ -25,12 +26,9 @@ int bus_home_method_acquire(sd_bus_message *message, void *userdata, sd_bus_erro int bus_home_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_home_method_release(sd_bus_message *message, void *userdata, sd_bus_error *error); -extern const sd_bus_vtable home_vtable[]; +extern const BusObjectImplementation home_object; int bus_home_path(Home *h, char **ret); -int bus_home_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int bus_home_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); - int bus_home_emit_change(Home *h); int bus_home_emit_remove(Home *h); diff --git a/src/home/homed-manager-bus.c b/src/home/homed-manager-bus.c index b239a71887..1b8ec0c738 100644 --- a/src/home/homed-manager-bus.c +++ b/src/home/homed-manager-bus.c @@ -600,44 +600,210 @@ static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus return sd_bus_reply_method_return(message, NULL); } -const sd_bus_vtable manager_vtable[] = { +static const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("AutoLogin", "a(sso)", property_get_auto_login, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_METHOD("GetHomeByName", "s", "usussso", method_get_home_by_name, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetHomeByUID", "u", "ssussso", method_get_home_by_uid, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_METHOD("GetUserRecordByName", "s", "sbo", method_get_user_record_by_name, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("GetUserRecordByUID", "u", "sbo", method_get_user_record_by_uid, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("ListHomes", NULL, "a(susussso)", method_list_homes, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("GetHomeByName", + "s", + SD_BUS_PARAM(user_name), + "usussso", + SD_BUS_PARAM(uid) + SD_BUS_PARAM(home_state) + SD_BUS_PARAM(gid) + SD_BUS_PARAM(real_name) + SD_BUS_PARAM(home_directory) + SD_BUS_PARAM(shell) + SD_BUS_PARAM(bus_path), + method_get_home_by_name, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("GetHomeByUID", + "u", + SD_BUS_PARAM(uid), + "ssussso", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(home_state) + SD_BUS_PARAM(gid) + SD_BUS_PARAM(real_name) + SD_BUS_PARAM(home_directory) + SD_BUS_PARAM(shell) + SD_BUS_PARAM(bus_path), + method_get_home_by_uid, + SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("GetUserRecordByName", + "s", + SD_BUS_PARAM(user_name), + "sbo", + SD_BUS_PARAM(user_record) + SD_BUS_PARAM(incomplete) + SD_BUS_PARAM(bus_path), + method_get_user_record_by_name, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("GetUserRecordByUID", + "u", + SD_BUS_PARAM(uid), + "sbo", + SD_BUS_PARAM(user_record) + SD_BUS_PARAM(incomplete) + SD_BUS_PARAM(bus_path), + method_get_user_record_by_uid, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("ListHomes", + NULL,, + "a(susussso)", + SD_BUS_PARAM(home_areas), + method_list_homes, + SD_BUS_VTABLE_UNPRIVILEGED), /* The following methods directly execute an operation on a home area, without ref-counting, queueing * or anything, and are accessible through homectl. */ - SD_BUS_METHOD("ActivateHome", "ss", NULL, method_activate_home, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("DeactivateHome", "s", NULL, method_deactivate_home, 0), - SD_BUS_METHOD("RegisterHome", "s", NULL, method_register_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Add JSON record to homed, but don't create actual $HOME */ - SD_BUS_METHOD("UnregisterHome", "s", NULL, method_unregister_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record from homed, but don't remove actual $HOME */ - SD_BUS_METHOD("CreateHome", "s", NULL, method_create_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Add JSON record, and create $HOME for it */ - SD_BUS_METHOD("RealizeHome", "ss", NULL, method_realize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Create $HOME for already registered JSON entry */ - SD_BUS_METHOD("RemoveHome", "s", NULL, method_remove_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record and remove $HOME */ - SD_BUS_METHOD("FixateHome", "ss", NULL, method_fixate_home, SD_BUS_VTABLE_SENSITIVE), /* Investigate $HOME and propagate contained JSON record into our database */ - SD_BUS_METHOD("AuthenticateHome", "ss", NULL, method_authenticate_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Just check credentials */ - SD_BUS_METHOD("UpdateHome", "s", NULL, method_update_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Update JSON record of existing user */ - SD_BUS_METHOD("ResizeHome", "sts", NULL, method_resize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("ChangePasswordHome", "sss", NULL, method_change_password_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("LockHome", "s", NULL, method_lock_home, 0), /* Prepare active home for system suspend: flush out passwords, suspend access */ - SD_BUS_METHOD("UnlockHome", "ss", NULL, method_unlock_home, SD_BUS_VTABLE_SENSITIVE), /* Make $HOME usable after system resume again */ + SD_BUS_METHOD_WITH_NAMES("ActivateHome", + "ss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record), + NULL,, + method_activate_home, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("DeactivateHome", + "s", + SD_BUS_PARAM(user_name), + NULL,, + method_deactivate_home, + 0), - /* The following methods implement ref-counted activation, and are what the PAM module calls (and - * what "homectl with" runs). In contrast to the methods above which fail if an operation is already - * being executed on a home directory, these ones will queue the request, and are thus more - * reliable. Moreover, they are a bit smarter: AcquireHome() will fixate, activate, unlock, or - * authenticate depending on the state of the home, so that the end result is always the same - * (i.e. the home directory is accessible), and we always validate the specified passwords. RefHome() - * will not authenticate, and thus only works if home is already active. */ - SD_BUS_METHOD("AcquireHome", "ssb", "h", method_acquire_home, SD_BUS_VTABLE_SENSITIVE), - SD_BUS_METHOD("RefHome", "sb", "h", method_ref_home, 0), - SD_BUS_METHOD("ReleaseHome", "s", NULL, method_release_home, 0), + /* Add the JSON record to homed, but don't create actual $HOME */ + SD_BUS_METHOD_WITH_NAMES("RegisterHome", + "s", + SD_BUS_PARAM(home_record), + NULL,, + method_register_home, + SD_BUS_VTABLE_UNPRIVILEGED), + + /* Remove the JSON record from homed, but don't remove actual $HOME */ + SD_BUS_METHOD_WITH_NAMES("UnregisterHome", + "s", + SD_BUS_PARAM(user_name), + NULL,, + method_unregister_home, + SD_BUS_VTABLE_UNPRIVILEGED), + + /* Add JSON record, and create $HOME for it */ + SD_BUS_METHOD_WITH_NAMES("CreateHome", + "s", + SD_BUS_PARAM(home_record), + NULL,, + method_create_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + /* Create $HOME for already registered JSON entry */ + SD_BUS_METHOD_WITH_NAMES("RealizeHome", + "ss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record), + NULL,, + method_realize_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + /* Remove the JSON record and remove $HOME */ + SD_BUS_METHOD_WITH_NAMES("RemoveHome", + "s", + SD_BUS_PARAM(user_name), + NULL,, + method_remove_home, + SD_BUS_VTABLE_UNPRIVILEGED), + + /* Investigate $HOME and propagate contained JSON record into our database */ + SD_BUS_METHOD_WITH_NAMES("FixateHome", + "ss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record), + NULL,, + method_fixate_home, + SD_BUS_VTABLE_SENSITIVE), + + /* Just check credentials */ + SD_BUS_METHOD_WITH_NAMES("AuthenticateHome", + "ss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record), + NULL,, + method_authenticate_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + /* Update the JSON record of existing user */ + SD_BUS_METHOD_WITH_NAMES("UpdateHome", + "s", + SD_BUS_PARAM(user_record), + NULL,, + method_update_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + SD_BUS_METHOD_WITH_NAMES("ResizeHome", + "sts", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(size) + SD_BUS_PARAM(user_record), + NULL,, + method_resize_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + SD_BUS_METHOD_WITH_NAMES("ChangePasswordHome", + "sss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(new_user_record) + SD_BUS_PARAM(old_user_record), + NULL,, + method_change_password_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + + /* Prepare active home for system suspend: flush out passwords, suspend access */ + SD_BUS_METHOD_WITH_NAMES("LockHome", + "s", + SD_BUS_PARAM(user_name), + NULL,, + method_lock_home, + 0), + + /* Make $HOME usable after system resume again */ + SD_BUS_METHOD_WITH_NAMES("UnlockHome", + "ss", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record), + NULL,, + method_unlock_home, + SD_BUS_VTABLE_SENSITIVE), + + /* The following methods implement ref-counted activation, and are what the PAM module and "homectl + * with" use. In contrast to the methods above which fail if an operation is already being executed + * on a home directory, these ones will queue the request, and are thus more reliable. Moreover, + * they are a bit smarter: AcquireHome() will fixate, activate, unlock, or authenticate depending on + * the state of the home area, so that the end result is always the same (i.e. the home directory is + * accessible), and we always validate the specified passwords. RefHome() will not authenticate, and + * thus only works if the home area is already active. */ + SD_BUS_METHOD_WITH_NAMES("AcquireHome", + "ssb", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(user_record) + SD_BUS_PARAM(please_suspend), + "h", + SD_BUS_PARAM(send_fd), + method_acquire_home, + SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_NAMES("RefHome", + "sb", + SD_BUS_PARAM(user_name) + SD_BUS_PARAM(please_suspend), + "h", + SD_BUS_PARAM(send_fd), + method_ref_home, + 0), + SD_BUS_METHOD_WITH_NAMES("ReleaseHome", + "s", + SD_BUS_PARAM(user_name), + NULL,, + method_release_home, + 0), /* An operation that acts on all homes that allow it */ SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0), @@ -645,6 +811,13 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END }; +const BusObjectImplementation manager_object = { + "/org/freedesktop/home1", + "org.freedesktop.home1.Manager", + .vtables = BUS_VTABLES(manager_vtable), + .children = BUS_IMPLEMENTATIONS(&home_object), +}; + static int on_deferred_auto_login(sd_event_source *s, void *userdata) { Manager *m = userdata; int r; diff --git a/src/home/homed-manager-bus.h b/src/home/homed-manager-bus.h index 40e1cc3d86..93bef9df8e 100644 --- a/src/home/homed-manager-bus.h +++ b/src/home/homed-manager-bus.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -#include "sd-bus.h" +#include "bus-util.h" -extern const sd_bus_vtable manager_vtable[]; +extern const BusObjectImplementation manager_object; diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index 5ce7be4fac..8ea93120d0 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -879,23 +879,7 @@ static int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/home1", "org.freedesktop.home1.Manager", manager_vtable, m); - if (r < 0) - return log_error_errno(r, "Failed to add manager object vtable: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/home1/home", "org.freedesktop.home1.Home", home_vtable, bus_home_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add image object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/home1/home", bus_home_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add image enumerator: %m"); - - r = sd_bus_add_object_manager(m->bus, NULL, "/org/freedesktop/home1/home"); - if (r < 0) - return log_error_errno(r, "Failed to add object manager: %m"); - - r = bus_log_control_api_register(m->bus); + r = bus_add_implementation(m->bus, &manager_object, m); if (r < 0) return r; diff --git a/src/home/homed.c b/src/home/homed.c index ca43558269..2fd3b65d89 100644 --- a/src/home/homed.c +++ b/src/home/homed.c @@ -3,10 +3,13 @@ #include #include +#include "bus-log-control-api.h" #include "daemon-util.h" #include "homed-manager.h" +#include "homed-manager-bus.h" #include "log.h" #include "main-func.h" +#include "service-util.h" #include "signal-util.h" static int run(int argc, char *argv[]) { @@ -16,10 +19,15 @@ static int run(int argc, char *argv[]) { log_setup_service(); - umask(0022); + r = service_parse_argv("systemd-homed.service", + "A service to create, remove, change or inspect home areas.", + BUS_IMPLEMENTATIONS(&manager_object, + &log_control_object), + argc, argv); + if (r <= 0) + return r; - if (argc != 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments."); + umask(0022); if (setenv("SYSTEMD_BYPASS_USERDB", "io.systemd.Home", 1) < 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m"); From b856b346c17919e27f264496956f894e8362e291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 3 May 2020 10:19:53 +0200 Subject: [PATCH 29/30] man: add stub for home1(5) --- man/org.freedesktop.home1.xml | 369 ++++++++++++++++++++++++++++++++++ man/rules/meson.build | 1 + 2 files changed, 370 insertions(+) create mode 100644 man/org.freedesktop.home1.xml diff --git a/man/org.freedesktop.home1.xml b/man/org.freedesktop.home1.xml new file mode 100644 index 0000000000..cb1e3a182e --- /dev/null +++ b/man/org.freedesktop.home1.xml @@ -0,0 +1,369 @@ + + + + + + + org.freedesktop.home1 + systemd + + + + org.freedesktop.home1 + 5 + + + + org.freedesktop.home1 + The D-Bus interface of systemd-homed + + + + Introduction + + + systemd-homed.service8 + is a system service which may be used to to create, remove, change or inspect home areas. This page + describes the D-Bus interface. + + + + + The Manager Object + + The service exposes the following interfaces on the Manager object on the bus: + + +node /org/freedesktop/home1 { + interface org.freedesktop.home1.Manager { + methods: + GetHomeByName(in s user_name, + out u uid, + out s home_state, + out u gid, + out s real_name, + out s home_directory, + out s shell, + out o bus_path); + GetHomeByUID(in u uid, + out s user_name, + out s home_state, + out u gid, + out s real_name, + out s home_directory, + out s shell, + out o bus_path); + GetUserRecordByName(in s user_name, + out s user_record, + out b incomplete, + out o bus_path); + GetUserRecordByUID(in u uid, + out s user_record, + out b incomplete, + out o bus_path); + ListHomes(out a(susussso) home_areas); + ActivateHome(in s user_name, + in s user_record); + DeactivateHome(in s user_name); + RegisterHome(in s home_record); + UnregisterHome(in s user_name); + CreateHome(in s home_record); + RealizeHome(in s user_name, + in s user_record); + RemoveHome(in s user_name); + FixateHome(in s user_name, + in s user_record); + AuthenticateHome(in s user_name, + in s user_record); + UpdateHome(in s user_record); + ResizeHome(in s user_name, + in t size, + in s user_record); + ChangePasswordHome(in s user_name, + in s new_user_record, + in s old_user_record); + LockHome(in s user_name); + UnlockHome(in s user_name, + in s user_record); + AcquireHome(in s user_name, + in s user_record, + in b please_suspend, + out h send_fd); + RefHome(in s user_name, + in b please_suspend, + out h send_fd); + ReleaseHome(in s user_name); + LockAllHomes(); + properties: + readonly a(sso) AutoLogin = [...]; + }; + interface org.freedesktop.DBus.Peer { ... }; + interface org.freedesktop.DBus.Introspectable { ... }; + interface org.freedesktop.DBus.Properties { ... }; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Methods + + ... + + + + Signals + + ... + + + + + The Home Object + + +node /org/freedesktop/home1/home { + interface org.freedesktop.home1.Home { + methods: + Activate(in s user_record); + Deactivate(); + Unregister(); + Realize(in s user_record); + Remove(); + Fixate(in s user_record); + Authenticate(in s user_record); + Update(in s user_record); + Resize(in t size, + in s user_record); + ChangePassword(in s new_user_record, + in s old_user_record); + Lock(); + Unlock(in s user_record); + Acquire(in s user_record, + in b please_suspend, + out h send_fd); + Ref(in b please_suspend, + out h send_fd); + Release(); + properties: + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly s UserName = '...'; + readonly u UID = ...; + readonly (suusss) UnixRecord = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s State = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates") + readonly (sb) UserRecord = ...; + }; + interface org.freedesktop.DBus.Peer { ... }; + interface org.freedesktop.DBus.Introspectable { ... }; + interface org.freedesktop.DBus.Properties { ... }; + interface org.freedesktop.DBus.ObjectManager { ... }; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Versioning + + These D-Bus interfaces follow + the usual interface versioning guidelines. + + diff --git a/man/rules/meson.build b/man/rules/meson.build index cda68ef99b..0d05508e7b 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -45,6 +45,7 @@ manpages = [ ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'], ['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'], ['org.freedesktop.LogControl1', '5', [], ''], + ['org.freedesktop.home1', '5', [], 'ENABLE_HOMED'], ['org.freedesktop.hostname1', '5', [], 'ENABLE_HOSTNAMED'], ['org.freedesktop.import1', '5', [], 'ENABLE_IMPORTD'], ['org.freedesktop.locale1', '5', [], 'ENABLE_LOCALED'], From b61cc5fdadbdaaa0071fba55117a5d07d3527bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 May 2020 23:03:36 +0200 Subject: [PATCH 30/30] man: update login1(5) for SetType() Added in db72aea4a952cdfdef51eda03408d7c4a11e7359. --- man/org.freedesktop.login1.xml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index 0908b2ea10..44ad033752 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -1003,6 +1003,7 @@ node /org/freedesktop/login1/session/1 { in i signal_number); TakeControl(in b force); ReleaseControl(); + SetType(in s type); TakeDevice(in u major, in u minor, out h fd, @@ -1058,7 +1059,6 @@ node /org/freedesktop/login1/session/1 { readonly u Leader = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly u Audit = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s Type = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s Class = '...'; @@ -1099,6 +1099,8 @@ node /org/freedesktop/login1/session/1 { + + @@ -1183,10 +1185,17 @@ node /org/freedesktop/login1/session/1 { out and replaced. Otherwise, this method fails if there is already a controller. Note that this method is limited to D-Bus users with the effective UID set to the user of the session or root. - ReleaseControl() drops control of a given session. Closing the - D-Bus connection implicitly releases control as well. See TakeControl() for more information. This - method also releases all devices for which the controller requested ownership via TakeDevice(). - + ReleaseControl() drops control of a given session. Closing the D-Bus + connection implicitly releases control as well. See TakeControl() for more + information. This method also releases all devices for which the controller requested ownership via + TakeDevice(). + + SetType() allows the type of the session to be changed dynamically. It can + only be called by session's current controller. If TakeControl() has not been + called, this method will fail. In addition, the session type will be reset to its original value once + control is released, either by calling ReleaseControl() or closing the D-Bus + connection. This should help prevent a session from entering an inconsistent state, for example if the + controller crashes. The only argument type is the new session type. TakeDevice() allows a session controller to get a file descriptor for a specific device. Pass in the major and minor numbers of the character device and