X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fsd-bus.c;h=61dc0e56a88e7e72d5ae64d80beeb04d51e754f2;hp=9c564de76403b9c928b95e504374df9f062f738d;hb=ab9001a1e3dc6e60d0cdf53363dc5d18dcc382fd;hpb=ec202eae8e84a4c99f054f771cb832046cb8769f diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 9c564de76..61dc0e56a 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -34,6 +34,7 @@ #include "strv.h" #include "set.h" #include "missing.h" +#include "def.h" #include "sd-bus.h" #include "bus-internal.h" @@ -141,6 +142,8 @@ static void bus_free(sd_bus *b) { free(b->address); free(b->kernel); free(b->machine); + free(b->fake_label); + free(b->cgroup_root); free(b->exec_path); strv_free(b->exec_argv); @@ -374,14 +377,14 @@ static int bus_send_hello(sd_bus *bus) { r = sd_bus_message_new_method_call( bus, "org.freedesktop.DBus", - "/", + "/org/freedesktop/DBus", "org.freedesktop.DBus", "Hello", &m); if (r < 0) return r; - return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_serial); + return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_cookie); } int bus_start_running(sd_bus *bus) { @@ -1045,12 +1048,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) { if (e) r = sd_bus_set_address(b, e); else -#ifdef ENABLE_KDBUS - r = sd_bus_set_address(b, "kernel:path=/dev/kdbus/0-system/bus;unix:path=/run/dbus/system_bus_socket"); -#else - r = sd_bus_set_address(b, "unix:path=/run/dbus/system_bus_socket"); -#endif - + r = sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_PATH); if (r < 0) goto fail; @@ -1101,13 +1099,13 @@ _public_ int sd_bus_open_user(sd_bus **ret) { } #ifdef ENABLE_KDBUS - asprintf(&b->address, "kernel:path=/dev/kdbus/%lu-user/bus;unix:path=%s/bus", (unsigned long) getuid(), ee); + asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, (unsigned long) getuid(), ee); #else - b->address = strjoin("unix:path=", ee, "/bus", NULL); + asprintf(&b->address, UNIX_USER_BUS_FMT, (unsigned long) getuid()); #endif } else { #ifdef ENABLE_KDBUS - asprintf(&b->address, "kernel:path=/dev/kdbus/%lu-user/bus", (unsigned long) getuid()); + asprintf(&b->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid()); #else return -ECONNREFUSED; #endif @@ -1321,16 +1319,16 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { if (m->sealed) { /* If we copy the same message to multiple - * destinations, avoid using the same serial + * destinations, avoid using the same cookie * numbers. */ - b->serial = MAX(b->serial, BUS_MESSAGE_SERIAL(m)); + b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m)); return 0; } if (timeout == 0) timeout = BUS_DEFAULT_TIMEOUT; - return bus_message_seal(m, ++b->serial, timeout); + return bus_message_seal(m, ++b->cookie, timeout); } static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) { @@ -1360,14 +1358,33 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) { return bus_message_seal(m, 0xFFFFFFFFULL, 0); } -static int bus_write_message(sd_bus *bus, sd_bus_message *message, size_t *idx) { +static int bus_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { + int r; + assert(bus); - assert(message); + assert(m); if (bus->is_kernel) - return bus_kernel_write_message(bus, message); + r = bus_kernel_write_message(bus, m); else - return bus_socket_write_message(bus, message, idx); + r = bus_socket_write_message(bus, m, idx); + + if (r <= 0) + return r; + + if (bus->is_kernel || *idx >= BUS_MESSAGE_SIZE(m)) + log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s", + bus_message_type_to_string(m->header->type), + strna(sd_bus_message_get_sender(m)), + strna(sd_bus_message_get_destination(m)), + strna(sd_bus_message_get_path(m)), + strna(sd_bus_message_get_interface(m)), + strna(sd_bus_message_get_member(m)), + (unsigned long) BUS_MESSAGE_COOKIE(m), + (unsigned long) m->reply_cookie, + strna(m->error.message)); + + return r; } static int dispatch_wqueue(sd_bus *bus) { @@ -1456,7 +1473,7 @@ 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 *cookie) { _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); int r; @@ -1473,9 +1490,9 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *serial) { return -ENOTSUP; } - /* If the serial number isn't kept, then we know that no reply + /* If the cookie number isn't kept, then we know that no reply * is expected */ - if (!serial && !m->sealed) + if (!cookie && !m->sealed) m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED; r = bus_seal_message(bus, m, 0); @@ -1490,7 +1507,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *serial) { /* If this is a reply and no reply was requested, then let's * suppress this, if we can */ - if (m->dont_send && !serial) + if (m->dont_send && !cookie) return 1; if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) { @@ -1524,13 +1541,13 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *serial) { bus->wqueue[bus->wqueue_size ++] = sd_bus_message_ref(m); } - if (serial) - *serial = BUS_MESSAGE_SERIAL(m); + if (cookie) + *cookie = BUS_MESSAGE_COOKIE(m); return 1; } -_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *serial) { +_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) { int r; assert_return(bus, -EINVAL); @@ -1548,7 +1565,7 @@ _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destinat return r; } - return sd_bus_send(bus, m, serial); + return sd_bus_send(bus, m, cookie); } static usec_t calc_elapse(uint64_t usec) { @@ -1582,7 +1599,7 @@ _public_ int sd_bus_call_async( sd_bus_message_handler_t callback, void *userdata, uint64_t usec, - uint64_t *serial) { + uint64_t *cookie) { _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); struct reply_callback *c; @@ -1618,10 +1635,10 @@ _public_ int sd_bus_call_async( c->callback = callback; c->userdata = userdata; - c->serial = BUS_MESSAGE_SERIAL(m); + c->cookie = BUS_MESSAGE_COOKIE(m); c->timeout = calc_elapse(m->timeout); - r = hashmap_put(bus->reply_callbacks, &c->serial, c); + r = hashmap_put(bus->reply_callbacks, &c->cookie, c); if (r < 0) { free(c); return r; @@ -1631,28 +1648,28 @@ _public_ int sd_bus_call_async( r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx); if (r < 0) { c->timeout = 0; - sd_bus_call_async_cancel(bus, c->serial); + sd_bus_call_async_cancel(bus, c->cookie); return r; } } - r = sd_bus_send(bus, m, serial); + r = sd_bus_send(bus, m, cookie); if (r < 0) { - sd_bus_call_async_cancel(bus, c->serial); + sd_bus_call_async_cancel(bus, c->cookie); return r; } return r; } -_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t serial) { +_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t cookie) { struct reply_callback *c; assert_return(bus, -EINVAL); - assert_return(serial != 0, -EINVAL); + assert_return(cookie != 0, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); - c = hashmap_remove(bus->reply_callbacks, &serial); + c = hashmap_remove(bus->reply_callbacks, &cookie); if (!c) return 0; @@ -1697,7 +1714,7 @@ _public_ int sd_bus_call( _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m); usec_t timeout; - uint64_t serial; + uint64_t cookie; unsigned i; int r; @@ -1723,7 +1740,7 @@ _public_ int sd_bus_call( if (r < 0) return r; - r = sd_bus_send(bus, m, &serial); + r = sd_bus_send(bus, m, &cookie); if (r < 0) return r; @@ -1737,7 +1754,7 @@ _public_ int sd_bus_call( incoming = bus->rqueue[i]; - if (incoming->reply_serial == serial) { + if (incoming->reply_cookie == cookie) { /* Found a match! */ memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1)); @@ -1759,7 +1776,7 @@ _public_ int sd_bus_call( sd_bus_message_unref(incoming); return r; - } else if (incoming->header->serial == serial && + } else if (BUS_MESSAGE_COOKIE(incoming) == cookie && bus->unique_name && incoming->sender && streq(bus->unique_name, incoming->sender)) { @@ -1909,7 +1926,7 @@ static int process_timeout(sd_bus *bus) { r = bus_message_new_synthetic_error( bus, - c->serial, + c->cookie, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"), &m); if (r < 0) @@ -1922,7 +1939,7 @@ static int process_timeout(sd_bus *bus) { return r; assert_se(prioq_pop(bus->reply_callbacks_prioq) == c); - hashmap_remove(bus->reply_callbacks, &c->serial); + hashmap_remove(bus->reply_callbacks, &c->cookie); bus->current = m; bus->iteration_counter ++; @@ -1952,7 +1969,7 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) { m->header->type != SD_BUS_MESSAGE_METHOD_ERROR) return -EIO; - if (m->reply_serial != bus->hello_serial) + if (m->reply_cookie != bus->hello_cookie) return -EIO; return 0; @@ -1970,7 +1987,7 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) { m->header->type != SD_BUS_MESSAGE_METHOD_ERROR) return 0; - c = hashmap_remove(bus->reply_callbacks, &m->reply_serial); + c = hashmap_remove(bus->reply_callbacks, &m->reply_cookie); if (!c) return 0; @@ -2051,6 +2068,9 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) { assert(bus); assert(m); + if (bus->manual_peer_interface) + return 0; + if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL) return 0; @@ -2101,11 +2121,16 @@ static int process_message(sd_bus *bus, sd_bus_message *m) { bus->current = m; bus->iteration_counter++; - log_debug("Got message sender=%s object=%s interface=%s member=%s", + log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s", + bus_message_type_to_string(m->header->type), strna(sd_bus_message_get_sender(m)), + strna(sd_bus_message_get_destination(m)), strna(sd_bus_message_get_path(m)), strna(sd_bus_message_get_interface(m)), - strna(sd_bus_message_get_member(m))); + strna(sd_bus_message_get_member(m)), + (unsigned long) BUS_MESSAGE_COOKIE(m), + (unsigned long) m->reply_cookie, + strna(m->error.message)); r = process_hello(bus, m); if (r != 0) @@ -2171,6 +2196,12 @@ static int process_running(sd_bus *bus, sd_bus_message **ret) { if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) { + log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s", + strna(sd_bus_message_get_sender(m)), + strna(sd_bus_message_get_path(m)), + strna(sd_bus_message_get_interface(m)), + strna(sd_bus_message_get_member(m))); + r = sd_bus_reply_method_errorf( m, SD_BUS_ERROR_UNKNOWN_OBJECT, @@ -2203,7 +2234,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { /* First, fail all outstanding method calls */ r = bus_message_new_synthetic_error( bus, - c->serial, + c->cookie, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"), &m); if (r < 0) @@ -2216,7 +2247,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { if (c->timeout != 0) prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx); - hashmap_remove(bus->reply_callbacks, &c->serial); + hashmap_remove(bus->reply_callbacks, &c->cookie); bus->current = m; bus->iteration_counter++; @@ -2956,3 +2987,25 @@ _public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **re *ret = c; return 0; } + +_public_ int sd_bus_try_close(sd_bus *bus) { + int r; + + assert_return(bus, -EINVAL); + assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN); + assert_return(!bus_pid_changed(bus), -ECHILD); + assert_return(bus->is_kernel, -ENOTSUP); + + if (bus->rqueue_size > 0) + return -EBUSY; + + if (bus->wqueue_size > 0) + return -EBUSY; + + r = bus_kernel_try_close(bus); + if (r < 0) + return r; + + sd_bus_close(bus); + return 0; +}