[systemd-commits] 5 commits - Makefile.am src/activate src/bus-driverd src/libsystemd-bus units/.gitignore units/org.freedesktop.DBus.busname units/systemd-bus-driverd.service.in
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Dec 17 06:46:08 PST 2013
Makefile.am | 13 ++
src/activate/activate.c | 10 +-
src/bus-driverd/Makefile | 1
src/bus-driverd/bus-driverd.c | 154 ++++++++++-------------------------
src/libsystemd-bus/bus-message.c | 85 +++++++++++++++++++
src/libsystemd-bus/bus-message.h | 2
src/libsystemd-bus/busctl.c | 4
src/libsystemd-bus/sd-bus.c | 43 +++++++--
units/.gitignore | 1
units/org.freedesktop.DBus.busname | 12 ++
units/systemd-bus-driverd.service.in | 14 +++
11 files changed, 210 insertions(+), 129 deletions(-)
New commits:
commit 382aa8d036b80ef30ee5cebfbf29ea1136e26df2
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 17 15:44:05 2013 +0100
bus: make driverd code more similar to other daemons, and make it exit on idle among other things
diff --git a/src/bus-driverd/bus-driverd.c b/src/bus-driverd/bus-driverd.c
index d2b3e08..bf448cd 100644
--- a/src/bus-driverd/bus-driverd.c
+++ b/src/bus-driverd/bus-driverd.c
@@ -49,9 +49,7 @@
#include "sd-id128.h"
#include "async.h"
#include "hashmap.h"
-
-#define DBUS_PATH "/org/freedesktop/DBus"
-#define DBUS_INTERFACE "org.freedesktop.DBus"
+#include "def.h"
/*
* TODO:
@@ -61,58 +59,6 @@
* StartServiceByName
*/
-static sd_bus *driver_bus;
-
-static int help(void) {
-
- printf("%s [OPTIONS...] <bus-path>\n\n"
- "Driver to provide a org.freedesktop.DBus interface on the given kdbus node.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n",
- program_invocation_short_name);
-
- return 0;
-}
-
-static int parse_argv(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':
- help();
- return 0;
-
- case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
-
- case '?':
- return -EINVAL;
-
- default:
- assert_not_reached("Unknown option");
- }
-
- return 1;
-}
-
static int driver_name_info_error(sd_bus *bus, sd_bus_message *m, const char *name, int error_code) {
if (error_code == -ENXIO || error_code == -ENOENT)
@@ -426,19 +372,11 @@ static int driver_start_service_by_name(sd_bus *bus, sd_bus_message *m, void *us
return sd_bus_send(bus, reply, NULL);
}
-static int driver_update_env(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-
- return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_NOT_SUPPORTED,
- "UpdateActivationEnvironment is unsupported");
-}
-
-static int driver_reload_config(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-
- return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_NOT_SUPPORTED,
- "ReloadConfig is unsupported");
+static int driver_unsupported(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
}
-const sd_bus_vtable dbus_vtable[] = {
+static const sd_bus_vtable driver_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("AddMatch", "s", NULL, driver_add_match, 0),
SD_BUS_METHOD("GetConnectionSELinuxSecurityContext", "s", "ay", driver_get_security_ctx, 0),
@@ -451,92 +389,88 @@ const sd_bus_vtable dbus_vtable[] = {
SD_BUS_METHOD("ListNames", NULL, "as", driver_list_names, 0),
SD_BUS_METHOD("ListQueuedOwners", "s", "as", driver_list_queued_owners, 0),
SD_BUS_METHOD("NameHasOwner", "s", "b", driver_name_has_owner, 0),
- SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_reload_config, 0),
+ SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_unsupported, 0),
SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, 0),
SD_BUS_METHOD("RequestName", "su", "u", driver_request_name, 0),
SD_BUS_METHOD("StartServiceByName", "su", "u", driver_start_service_by_name, 0),
- SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_update_env, 0),
+ SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_unsupported, 0),
SD_BUS_SIGNAL("NameAcquired", "s", 0),
SD_BUS_SIGNAL("NameLost", "s", 0),
SD_BUS_SIGNAL("NameOwnerChanged", "sss", 0),
SD_BUS_VTABLE_END
};
-static int driver_main(const char *bus_name) {
-
- _cleanup_event_source_unref_ sd_event_source *w_accept = NULL;
- _cleanup_event_source_unref_ sd_event_source *w_root_service = NULL;
- _cleanup_event_unref_ sd_event *e = NULL;
+static int connect_bus(sd_event *event, sd_bus **_bus) {
+ _cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
- r = sd_event_new(&e);
- if (r < 0) {
- log_error("Failed to allocate event loop: %s", strerror(-r));
- return r;
- }
+ assert(event);
+ assert(_bus);
- /* set up kernel bus connection */
- r = sd_bus_new(&driver_bus);
+ r = sd_bus_default_system(&bus);
if (r < 0) {
log_error("Failed to create bus: %s", strerror(-r));
return r;
}
- r = sd_bus_set_address(driver_bus, bus_name);
+ r = sd_bus_add_object_vtable(bus, "/org/freedesktop/DBus", "org.freedesktop.DBus", driver_vtable, NULL);
if (r < 0) {
- log_error("Failed to create bus: %s", strerror(-r));
- return r;
- }
-
- r = sd_bus_start(driver_bus);
- if (r < 0) {
- log_error("Failed to start kernel bus: %s", strerror(-r));
+ log_error("Failed to add manager object vtable: %s", strerror(-r));
return r;
}
- r = sd_bus_request_name(driver_bus, DBUS_INTERFACE, 0);
+ r = sd_bus_request_name(bus, "org.freedesktop.DBus", 0);
if (r < 0) {
- log_error("Unable to request name '%s': %s\n", DBUS_INTERFACE, strerror(-r));
+ log_error("Unable to request name: %s\n", strerror(-r));
return r;
}
- r = sd_bus_add_object_vtable(driver_bus, DBUS_PATH, DBUS_INTERFACE, dbus_vtable, NULL);
- if (r < 0) {
- log_error("Failed to add manager object vtable: %s", strerror(-r));
- return r;
- }
-
- r = sd_bus_attach_event(driver_bus, e, 0);
+ r = sd_bus_attach_event(bus, event, 0);
if (r < 0) {
log_error("Error %d while adding bus to even: %s", r, strerror(-r));
return r;
}
- log_debug("Entering main loop.");
+ *_bus = bus;
+ bus = NULL;
- return sd_event_loop(e);
+ return 0;
}
int main(int argc, char *argv[]) {
- char *bus_name;
+ _cleanup_event_unref_ sd_event *event = NULL;
+ _cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
- setlocale(LC_ALL, "");
+ log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
log_open();
- r = parse_argv(argc, argv);
- if (r <= 0)
- return r;
+ if (argc != 1) {
+ log_error("This program takes no arguments.");
+ r = -EINVAL;
+ goto finish;
+ }
- if (argc <= optind) {
- help();
- return -EINVAL;
+ r = sd_event_default(&event);
+ if (r < 0) {
+ log_error("Failed to allocate event loop: %s", strerror(-r));
+ goto finish;
}
- r = asprintf(&bus_name, "kernel:path=%s", argv[optind]);
+ sd_event_set_watchdog(event, true);
+
+ r = connect_bus(event, &bus);
if (r < 0)
- return r;
+ goto finish;
+
+ r = bus_event_loop_with_idle(event, bus, "org.freedesktop.DBus", DEFAULT_EXIT_USEC);
+ if (r < 0) {
+ log_error("Failed to run event loop: %s", strerror(-r));
+ goto finish;
+ }
+
+finish:
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
- return driver_main(bus_name);
}
commit f83f897489eb5286ea52a71cfd1a66a52b3ae51f
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 17 03:55:59 2013 +0100
busctl: on kdbus the bus driver is a service like any other, hence don't skip it
diff --git a/src/libsystemd-bus/busctl.c b/src/libsystemd-bus/busctl.c
index 57bc83d..4e2e6af 100644
--- a/src/libsystemd-bus/busctl.c
+++ b/src/libsystemd-bus/busctl.c
@@ -108,10 +108,6 @@ static int list_bus_names(sd_bus *bus, char **argv) {
if (arg_no_unique && (*i)[0] == ':')
continue;
- /* Skip the bus driver */
- if (streq(*i, "org.freedesktop.DBus"))
- continue;
-
printf("%-*s", (int) max_i, *i);
r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_UNIQUE_NAME, &creds);
commit e1c433c6218b3e3bcc2621bdfa575a77017bb9ae
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 17 02:43:45 2013 +0100
bus: remarshal messages when necessary before sending
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 3f70f6f..1a461e6 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -35,6 +35,7 @@
#include "bus-type.h"
#include "bus-signature.h"
#include "bus-gvariant.h"
+#include "bus-util.h"
static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
@@ -5407,3 +5408,87 @@ _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
return m->bus;
}
+
+int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
+ _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
+ usec_t timeout;
+ int r;
+
+ assert(bus);
+ assert(m);
+ assert(*m);
+
+ switch ((*m)->header->type) {
+
+ case SD_BUS_MESSAGE_SIGNAL:
+ r = sd_bus_message_new_signal(bus, (*m)->path, (*m)->interface, (*m)->member, &n);
+ if (r < 0)
+ return r;
+
+ break;
+
+ case SD_BUS_MESSAGE_METHOD_CALL:
+ r = sd_bus_message_new_method_call(bus, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member, &n);
+ if (r < 0)
+ return r;
+
+ break;
+
+ case SD_BUS_MESSAGE_METHOD_RETURN:
+ case SD_BUS_MESSAGE_METHOD_ERROR:
+
+ n = message_new(bus, (*m)->header->type);
+ if (!n)
+ return -ENOMEM;
+
+ n->reply_serial = (*m)->reply_serial;
+ r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_serial);
+ if (r < 0)
+ return r;
+
+ if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
+ r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
+ if (r < 0)
+ return r;
+
+ n->error._need_free = -1;
+ }
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if ((*m)->destination && !n->destination) {
+ r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
+ if (r < 0)
+ return r;
+ }
+
+ if ((*m)->sender && !n->sender) {
+ r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
+ if (r < 0)
+ return r;
+ }
+
+ n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
+
+ r = sd_bus_message_copy(n, *m, true);
+ if (r < 0)
+ return r;
+
+ timeout = (*m)->timeout;
+ if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
+ timeout = BUS_DEFAULT_TIMEOUT;
+
+ r = bus_message_seal(n, (*m)->header->serial, timeout);
+ if (r < 0)
+ return r;
+
+ sd_bus_message_unref(*m);
+ *m = n;
+ n = NULL;
+
+ return 0;
+}
diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h
index 9ef92cf..a9d42c3 100644
--- a/src/libsystemd-bus/bus-message.h
+++ b/src/libsystemd-bus/bus-message.h
@@ -231,3 +231,5 @@ void bus_body_part_unmap(struct bus_body_part *part);
int bus_message_to_errno(sd_bus_message *m);
int bus_message_new_synthetic_error(sd_bus *bus, uint64_t serial, const sd_bus_error *e, sd_bus_message **m);
+
+int bus_message_remarshal(sd_bus *bus, sd_bus_message **m);
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 76a27ec..338ce06 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -1319,14 +1319,6 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
assert(b);
assert(m);
- if (b->message_version != 0 &&
- m->header->version != b->message_version)
- return -EPERM;
-
- if (b->message_endian != 0 &&
- m->header->endian != b->message_endian)
- return -EPERM;
-
if (m->sealed) {
/* If we copy the same message to multiple
* destinations, avoid using the same serial
@@ -1341,6 +1333,18 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
return bus_message_seal(m, ++b->serial, timeout);
}
+static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
+ assert(b);
+
+ /* Do packet version and endianess already match? */
+ if ((b->message_version == 0 || b->message_version == (*m)->header->version) &&
+ (b->message_endian == 0 || b->message_endian == (*m)->header->endian))
+ return 0;
+
+ /* No? Then remarshal! */
+ return bus_message_remarshal(b, m);
+}
+
int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
assert(b);
assert(m);
@@ -1452,7 +1456,8 @@ static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
}
}
-_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
+_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *serial) {
+ _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
int r;
assert_return(bus, -EINVAL);
@@ -1477,6 +1482,12 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
if (r < 0)
return r;
+ /* Remarshall if we have to. This will possible unref the
+ * message and place a replacement in m */
+ r = bus_remarshal_message(bus, &m);
+ if (r < 0)
+ return r;
+
/* If this is a reply and no reply was requested, then let's
* suppress this, if we can */
if (m->dont_send && !serial)
@@ -1567,12 +1578,13 @@ static int timeout_compare(const void *a, const void *b) {
_public_ int sd_bus_call_async(
sd_bus *bus,
- sd_bus_message *m,
+ sd_bus_message *_m,
sd_bus_message_handler_t callback,
void *userdata,
uint64_t usec,
uint64_t *serial) {
+ _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
struct reply_callback *c;
int r;
@@ -1596,6 +1608,10 @@ _public_ int sd_bus_call_async(
if (r < 0)
return r;
+ r = bus_remarshal_message(bus, &m);
+ if (r < 0)
+ return r;
+
c = new0(struct reply_callback, 1);
if (!c)
return -ENOMEM;
@@ -1674,11 +1690,12 @@ int bus_ensure_running(sd_bus *bus) {
_public_ int sd_bus_call(
sd_bus *bus,
- sd_bus_message *m,
+ sd_bus_message *_m,
uint64_t usec,
sd_bus_error *error,
sd_bus_message **reply) {
+ _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
usec_t timeout;
uint64_t serial;
unsigned i;
@@ -1702,6 +1719,10 @@ _public_ int sd_bus_call(
if (r < 0)
return r;
+ r = bus_remarshal_message(bus, &m);
+ if (r < 0)
+ return r;
+
r = sd_bus_send(bus, m, &serial);
if (r < 0)
return r;
commit 603938e0a9b5379984d7397e3cf81683c0037a53
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 17 03:14:20 2013 +0100
activate: fix error checking on epoll_ctl()
diff --git a/src/activate/activate.c b/src/activate/activate.c
index d73c16e..cf545d6 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -51,10 +51,12 @@ static int add_epoll(int epoll_fd, int fd) {
ev.data.fd = fd;
r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
- if (r < 0)
- log_error("Failed to add event on epoll fd:%d for fd:%d: %m",
- epoll_fd, fd);
- return -errno;
+ if (r < 0) {
+ log_error("Failed to add event on epoll fd:%d for fd:%d: %m", epoll_fd, fd);
+ return -errno;
+ }
+
+ return 0;
}
static int make_socket_fd(const char* address, int flags) {
commit 15e913230c652ace36abfbf2b6fed0c1f56b8711
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 17 02:43:38 2013 +0100
bus: install unit files for new driver service
diff --git a/Makefile.am b/Makefile.am
index de63054..8bef21b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3728,8 +3728,21 @@ systemd_bus_driverd_LDADD = \
rootlibexec_PROGRAMS += \
systemd-bus-driverd
+
+nodist_systemunit_DATA += \
+ units/systemd-bus-driverd.service
+
+dist_systemunit_DATA += \
+ units/org.freedesktop.DBus.busname
+
+BUSNAMES_TARGET_WANTS += \
+ org.freedesktop.DBus.busname
+
endif
+EXTRA_DIST += \
+ units/systemd-bus-driverd.service.in
+
# ------------------------------------------------------------------------------
if ENABLE_LOCALED
systemd_localed_SOURCES = \
diff --git a/src/bus-driverd/Makefile b/src/bus-driverd/Makefile
new file mode 120000
index 0000000..d0b0e8e
--- /dev/null
+++ b/src/bus-driverd/Makefile
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/units/.gitignore b/units/.gitignore
index 94876ed..76c4cb3 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -22,6 +22,7 @@
/systemd-ask-password-wall.service
/systemd-backlight at .service
/systemd-binfmt.service
+/systemd-bus-driverd.service
/systemd-bus-proxyd at .service
/systemd-fsck-root.service
/systemd-fsck at .service
diff --git a/units/org.freedesktop.DBus.busname b/units/org.freedesktop.DBus.busname
new file mode 100644
index 0000000..68c649d
--- /dev/null
+++ b/units/org.freedesktop.DBus.busname
@@ -0,0 +1,12 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Bus Driver Service Bus Name
+
+[BusName]
+Service=systemd-bus-driverd.service
diff --git a/units/systemd-bus-driverd.service.in b/units/systemd-bus-driverd.service.in
new file mode 100644
index 0000000..575bddc
--- /dev/null
+++ b/units/systemd-bus-driverd.service.in
@@ -0,0 +1,14 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Bus Driver Service
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-bus-driverd
+BusName=org.freedesktop.DBus
+WatchdogSec=1min
More information about the systemd-commits
mailing list