chiark / gitweb /
bus: update for kdbus changes
authorKay Sievers <kay@vrfy.org>
Thu, 30 May 2013 03:35:42 +0000 (05:35 +0200)
committerKay Sievers <kay@vrfy.org>
Thu, 30 May 2013 03:35:42 +0000 (05:35 +0200)
src/libsystemd-bus/bus-kernel.c
src/libsystemd-bus/bus-message.c
src/libsystemd-bus/kdbus.h

index 0ece1f014db6e4df12d5b61277f48726c06d8e68..ad0d5731490d2fef760be1f4e89d46dca05af079 100644 (file)
@@ -313,12 +313,7 @@ fail:
 }
 
 int bus_kernel_take_fd(sd_bus *b) {
-        uint8_t h[ALIGN8(sizeof(struct kdbus_cmd_hello)) +
-                  ALIGN8(KDBUS_ITEM_HEADER_SIZE) +
-                  ALIGN8(sizeof(struct kdbus_vec))] = {};
-
-        struct kdbus_cmd_hello *hello = (struct kdbus_cmd_hello*) h;
-
+        struct kdbus_cmd_hello hello;
         int r;
 
         assert(b);
@@ -328,41 +323,38 @@ int bus_kernel_take_fd(sd_bus *b) {
 
         b->use_memfd = 1;
 
+        zero(hello);
+        hello.size = sizeof(hello);
+        hello.conn_flags = b->hello_flags;
+        hello.pool_size = KDBUS_POOL_SIZE;
+
+        r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
+        if (r < 0)
+                return -errno;
+
         if (!b->kdbus_buffer) {
-                b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+                b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0);
                 if (b->kdbus_buffer == MAP_FAILED) {
                         b->kdbus_buffer = NULL;
                         return -errno;
                 }
         }
 
-        hello->size = sizeof(h);
-        hello->conn_flags = b->hello_flags;
-
-        hello->items[0].type = KDBUS_HELLO_POOL;
-        hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
-        hello->items[0].vec.address = (uint64_t) b->kdbus_buffer;
-        hello->items[0].vec.size = KDBUS_POOL_SIZE;
-
-        r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
-        if (r < 0)
-                return -errno;
-
         /* The higher 32bit of both flags fields are considered
          * 'incompatible flags'. Refuse them all for now. */
-        if (hello->bus_flags > 0xFFFFFFFFULL ||
-            hello->conn_flags > 0xFFFFFFFFULL)
+        if (hello.bus_flags > 0xFFFFFFFFULL ||
+            hello.conn_flags > 0xFFFFFFFFULL)
                 return -ENOTSUP;
 
-        if (hello->bloom_size != BLOOM_SIZE)
+        if (hello.bloom_size != BLOOM_SIZE)
                 return -ENOTSUP;
 
-        if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
+        if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
                 return -ENOMEM;
 
         b->is_kernel = true;
         b->bus_client = true;
-        b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
+        b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
 
         r = bus_start_running(b);
         if (r < 0)
@@ -408,12 +400,14 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
 }
 
 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
+        uint64_t off;
         struct kdbus_item *d;
 
         assert(bus);
         assert(k);
 
-        ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, k);
+        off = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
+        ioctl(bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
 
         KDBUS_ITEM_FOREACH(d, k) {
 
@@ -446,10 +440,10 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess
 
                 l = d->size - offsetof(struct kdbus_item, data);
 
-                if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
+                if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
 
                         if (!h) {
-                                h = UINT64_TO_PTR(d->vec.address);
+                                h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
 
                                 if (!bus_header_is_complete(h, d->vec.size))
                                         return -EBADMSG;
@@ -500,7 +494,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess
 
                 l = d->size - offsetof(struct kdbus_item, data);
 
-                if (d->type == KDBUS_MSG_PAYLOAD_VEC) {
+                if (d->type == KDBUS_MSG_PAYLOAD_OFF) {
                         size_t begin_body;
 
                         begin_body = BUS_MESSAGE_BODY_BEGIN(m);
@@ -516,15 +510,19 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess
                                         goto fail;
                                 }
 
+                                /* A -1 offset is NUL padding. */
+                                part->is_zero = d->vec.offset == ~0ULL;
+
                                 if (idx >= begin_body) {
-                                        part->data = UINT64_TO_PTR(d->vec.address);
+                                        if (!part->is_zero)
+                                                part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
                                         part->size = d->vec.size;
                                 } else {
-                                        part->data = d->vec.address != 0 ? (uint8_t*) UINT64_TO_PTR(d->vec.address) + (begin_body - idx) : NULL;
+                                        if (!part->is_zero)
+                                                part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
                                         part->size = d->vec.size - (begin_body - idx);
                                 }
 
-                                part->is_zero = d->vec.address == 0;
                                 part->sealed = true;
                         }
 
@@ -631,21 +629,21 @@ fail:
 }
 
 int bus_kernel_read_message(sd_bus *bus, sd_bus_message **m) {
-        uint64_t addr;
+        uint64_t off;
         struct kdbus_msg *k;
         int r;
 
         assert(bus);
         assert(m);
 
-        r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &addr);
+        r = ioctl(bus->input_fd, KDBUS_CMD_MSG_RECV, &off);
         if (r < 0) {
                 if (errno == EAGAIN)
                         return 0;
 
                 return -errno;
         }
-        k = UINT64_TO_PTR(addr);
+        k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
 
         r = bus_kernel_make_message(bus, k, m);
         if (r <= 0)
index 6f2f3e903987d7ff453d4d75a284b16a849726df..e6bf9db99adf2e380cbbe8eb08f98bb402522f78 100644 (file)
@@ -125,8 +125,12 @@ static void message_free(sd_bus_message *m) {
         if (m->free_kdbus)
                 free(m->kdbus);
 
-        if (m->release_kdbus)
-                ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
+        if (m->release_kdbus) {
+                uint64_t off;
+
+                off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
+                ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
+        }
 
         if (m->bus)
                 sd_bus_unref(m->bus);
index dfc64ffe2414e84d2ae42eaf4d81ed9a5f1724a1..3b7783e1b16874523bfe7fa3829c8b8ff43cad3c 100644 (file)
@@ -73,8 +73,11 @@ struct kdbus_timestamp {
 };
 
 struct kdbus_vec {
-       __u64 address;
        __u64 size;
+       union {
+               __u64 address;
+               __u64 offset;
+       };
 };
 
 struct kdbus_memfd {
@@ -88,6 +91,7 @@ enum {
 
        /* Filled in by userspace */
        KDBUS_MSG_PAYLOAD_VEC,          /* .data_vec, reference to memory area */
+       KDBUS_MSG_PAYLOAD_OFF,          /* .data_vec, reference to memory area */
        KDBUS_MSG_PAYLOAD_MEMFD,        /* file descriptor of a special data file */
        KDBUS_MSG_FDS,                  /* .data_fds of file descriptors */
        KDBUS_MSG_BLOOM,                /* for broadcasts, carries bloom filter blob in .data */
@@ -212,6 +216,7 @@ struct kdbus_policy_access {
        __u64 id;               /* uid, gid, 0 */
 };
 
+//FIXME: convert access to access[]
 struct kdbus_policy {
        KDBUS_PART_HEADER;
        union {
@@ -242,13 +247,6 @@ enum {
        KDBUS_HELLO_ATTACH_AUDIT        =  1 << 16,
 };
 
-/* Items to append to struct kdbus_cmd_hello */
-enum {
-       _KDBUS_HELLO_NULL,
-       KDBUS_HELLO_POOL,       /* kdbus_vec, userspace supplied pool to
-                                * place received messages */
-};
-
 struct kdbus_cmd_hello {
        __u64 size;
 
@@ -269,6 +267,7 @@ struct kdbus_cmd_hello {
        __u64 id;               /* id assigned to this connection */
        __u64 bloom_size;       /* The bloom filter size chosen by the
                                 * bus owner */
+       __u64 pool_size;        /* maximum size of pool buffer */
        struct kdbus_item items[0];
 };
 
@@ -284,7 +283,8 @@ enum {
        _KDBUS_MAKE_NULL,
        KDBUS_MAKE_NAME,
        KDBUS_MAKE_CGROUP,      /* the cgroup hierarchy ID for which to attach
-                                * cgroup membership paths * to messages. */
+                                * cgroup membership paths to messages.
+                                * FIXME: remove, use *the* hierarchy */
        KDBUS_MAKE_CRED,        /* allow translator services which connect
                                 * to the bus on behalf of somebody else,
                                 * allow specifiying the credentials of the
@@ -304,7 +304,6 @@ struct kdbus_cmd_bus_make {
                                 * KDBUS_CMD_HELLO, later */
        __u64 bloom_size;       /* size of the bloom filter for this bus */
        struct kdbus_item items[0];
-
 };
 
 struct kdbus_cmd_ep_make {
@@ -414,7 +413,7 @@ enum {
        /* kdbus ep node commands: require connected state */
        KDBUS_CMD_MSG_SEND =            _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg),
        KDBUS_CMD_MSG_RECV =            _IOWR(KDBUS_IOC_MAGIC, 0x41, __u64 *),
-       KDBUS_CMD_MSG_RELEASE =         _IOWR(KDBUS_IOC_MAGIC, 0x42, struct kdbus_msg),
+       KDBUS_CMD_MSG_RELEASE =         _IOWR(KDBUS_IOC_MAGIC, 0x42, __u64 *),
 
        KDBUS_CMD_NAME_ACQUIRE =        _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name),
        KDBUS_CMD_NAME_RELEASE =        _IOWR(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name),