chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bus: return ECHILD as soon as people try to reuse a bus connection across a fork()
[elogind.git]
/
src
/
libsystemd-bus
/
bus-kernel.c
diff --git
a/src/libsystemd-bus/bus-kernel.c
b/src/libsystemd-bus/bus-kernel.c
index f7759b6fb498ea9f8c9926504124b86137139b80..ede78d7befa98969f2f4c47f07d3b32c987f2507 100644
(file)
--- a/
src/libsystemd-bus/bus-kernel.c
+++ b/
src/libsystemd-bus/bus-kernel.c
@@
-45,8
+45,6
@@
#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
#define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
#define KDBUS_ITEM_SIZE(s) ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE)
-#define KDBUS_POOL_SIZE (4*1024*1024)
-
static int parse_unique_name(const char *s, uint64_t *id) {
int r;
static int parse_unique_name(const char *s, uint64_t *id) {
int r;
@@
-69,6
+67,10
@@
static void append_payload_vec(struct kdbus_item **d, const void *p, size_t sz)
*d = ALIGN8_PTR(*d);
*d = ALIGN8_PTR(*d);
+ /* Note that p can be NULL, which encodes a region full of
+ * zeroes, which is useful to optimize certain padding
+ * conditions */
+
(*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
(*d)->type = KDBUS_MSG_PAYLOAD_VEC;
(*d)->vec.address = PTR_TO_UINT64(p);
(*d)->size = offsetof(struct kdbus_item, vec) + sizeof(struct kdbus_vec);
(*d)->type = KDBUS_MSG_PAYLOAD_VEC;
(*d)->vec.address = PTR_TO_UINT64(p);
@@
-244,9
+246,12
@@
static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
m->kdbus = memalign(8, sz);
sz += ALIGN8(offsetof(struct kdbus_item, fds) + sizeof(int)*m->n_fds);
m->kdbus = memalign(8, sz);
- if (!m->kdbus)
- return -ENOMEM;
+ if (!m->kdbus) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ m->free_kdbus = true;
memset(m->kdbus, 0, sz);
m->kdbus->flags =
memset(m->kdbus, 0, sz);
m->kdbus->flags =
@@
-269,24
+274,28
@@
static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
MESSAGE_FOREACH_PART(part, i, m) {
if (part->is_zero) {
MESSAGE_FOREACH_PART(part, i, m) {
if (part->is_zero) {
+ /* If this is padding then simply send a
+ * vector with a NULL data pointer which the
+ * kernel will just pass through. This is the
+ * most efficient way to encode zeroes */
+
append_payload_vec(&d, NULL, part->size);
continue;
}
append_payload_vec(&d, NULL, part->size);
continue;
}
- if (part->memfd >= 0 && part->sealed) {
- bus_body_part_unmap(part);
+ if (part->memfd >= 0 && part->sealed && m->destination) {
+ /* Try to send a memfd, if the part is
+ * sealed and this is not a broadcast. Since we can only */
- if (!part->data) {
- append_payload_memfd(&d, part->memfd, part->size);
- continue;
- }
+ append_payload_memfd(&d, part->memfd, part->size);
+ continue;
}
}
- if (part->memfd >= 0) {
- r = bus_body_part_map(part);
- if (r < 0)
- goto fail;
- }
+ /* Otherwise let's send a vector to the actual data,
+ * for that we need to map it first. */
+ r = bus_body_part_map(part);
+ if (r < 0)
+ goto fail;
append_payload_vec(&d, part->data, part->size);
}
append_payload_vec(&d, part->data, part->size);
}
@@
-306,13
+315,10
@@
static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
assert(m->kdbus->size <= sz);
m->kdbus->size = (uint8_t*) d - (uint8_t*) m->kdbus;
assert(m->kdbus->size <= sz);
- m->free_kdbus = true;
-
return 0;
fail:
return 0;
fail:
- free(m->kdbus);
- m->kdbus = NULL;
+ m->poisoned = true;
return r;
}
return r;
}