test: adopt new memfd interface
authorDaniel Mack <zonque@gmail.com>
Mon, 12 May 2014 22:28:19 +0000 (00:28 +0200)
committerDaniel Mack <zonque@gmail.com>
Sun, 17 Aug 2014 19:44:30 +0000 (21:44 +0200)
test/Makefile
test/kdbus-util.c
test/kdbus-util.h
test/test-kdbus-benchmark.c
test/test-kdbus.c

index f8117c826e755c2285bf521d4329afa88dc57a60..af1564959031f284d5825d774929fc279689a6fb 100644 (file)
@@ -1,4 +1,6 @@
 CFLAGS         += -std=gnu99 -Wall -Wextra -g \
+                  -I$(KERNELDIR)/usr/include \
+                  -I$(KERNELDIR)/include/uapi \
                   -D_GNU_SOURCE \
                   -Wno-unused-parameter \
                   -Wmaybe-uninitialized \
index 90b597d315b075276f66ff3b446e88ab519313ed..a979c99dc08245511bd795483199d373631e440f 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
 #include <grp.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
+#include <linux/memfd.h>
+#include <linux/unistd.h>
+#include <linux/fcntl.h>
 
 #include "kdbus-util.h"
 #include "kdbus-enum.h"
 
+/* we can't include <fcntl.h> due to glibc header file namespace confusion ... */
+extern int fcntl (int __fd, int __cmd, ...);
+extern int open (const char *__file, int __oflag, ...);
+
 #define POOL_SIZE (16 * 1024LU * 1024LU)
 struct conn *
 kdbus_hello(const char *path, uint64_t flags,
@@ -95,7 +102,7 @@ kdbus_hello(const char *path, uint64_t flags,
                return NULL;
        }
 
-       conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
+       conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
        if (conn->buf == MAP_FAILED) {
                free(conn);
                fprintf(stderr, "--- error mmap (%m)\n");
@@ -149,6 +156,55 @@ struct conn *kdbus_hello_activator(const char *path, const char *name,
                                     KDBUS_HELLO_ACTIVATOR);
 }
 
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS     (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS     (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
+#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
+#define F_SEAL_GROW     0x0004  /* prevent file from growing */
+#define F_SEAL_WRITE    0x0008  /* prevent writes */
+#endif
+
+int sys_memfd_create(const char *name, __u64 size)
+{
+       int ret, fd;
+
+       ret = syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING);
+       if (ret < 0)
+               return ret;
+
+       fd = ret;
+
+       ret = ftruncate(fd, size);
+       if (ret < 0) {
+               close(fd);
+               return ret;
+       }
+
+       return fd;
+}
+
+int sys_memfd_seal_set(int fd)
+{
+       return fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
+}
+
+off_t sys_memfd_get_size(int fd, off_t *size)
+{
+       struct stat stat;
+       int ret;
+
+       ret = fstat(fd, &stat);
+       if (ret < 0) {
+               fprintf(stderr, "stat() failed: %m\n");
+               return ret;
+       }
+
+       *size = stat.st_size;
+       return 0;
+}
+
 int msg_send(const struct conn *conn,
             const char *name,
             uint64_t cookie,
@@ -173,25 +229,11 @@ int msg_send(const struct conn *conn,
        if (dst_id == KDBUS_DST_ID_BROADCAST)
                size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
        else {
-               struct {
-                       struct kdbus_cmd_memfd_make cmd;
-                       uint64_t size;
-                       uint64_t type;
-                       char name[16];
-               } m = {};
-
-               m.cmd.size = sizeof(m);
-               m.cmd.file_size = 1024 * 1024;
-               m.cmd.items[0].type = KDBUS_ITEM_MEMFD_NAME;
-               m.cmd.items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(m.name);
-               strcpy(m.name, "my-name-is-nice");
-               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &m);
-               if (ret < 0) {
-                       ret = -errno;
-                       fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
-                       return ret;
+               memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024);
+               if (memfd < 0) {
+                       fprintf(stderr, "failed to create memfd: %m\n");
+                       return memfd;
                }
-               memfd = m.cmd.fd;
 
                if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
                        ret = -errno;
@@ -199,7 +241,7 @@ int msg_send(const struct conn *conn,
                        return ret;
                }
 
-               ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true);
+               ret = sys_memfd_seal_set(memfd);
                if (ret < 0) {
                        ret = -errno;
                        fprintf(stderr, "memfd sealing failed: %m\n");
@@ -353,15 +395,15 @@ void msg_dump(const struct conn *conn, const struct kdbus_msg *msg)
 
                case KDBUS_ITEM_PAYLOAD_MEMFD: {
                        char *buf;
-                       uint64_t size;
+                       off_t size;
 
-                       buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
+                       buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_PRIVATE, item->memfd.fd, 0);
                        if (buf == MAP_FAILED) {
-                               printf("mmap() fd=%i failed:%m", item->memfd.fd);
+                               printf("mmap() fd=%i size=%llu failed: %m\n", item->memfd.fd, item->memfd.size);
                                break;
                        }
 
-                       if (ioctl(item->memfd.fd, KDBUS_CMD_MEMFD_SIZE_GET, &size) < 0) {
+                       if (sys_memfd_get_size(item->memfd.fd, &size) < 0) {
                                fprintf(stderr, "KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n");
                                break;
                        }
index ba94d7bdd5912d8acc89135c997ecad529717ad7..5ecab2f5a5c92f556ac95fa5d940fa9bdfae89cb 100644 (file)
@@ -36,6 +36,10 @@ struct conn {
        size_t size;
 };
 
+int sys_memfd_create(const char *name, __u64 size);
+int sys_memfd_seal_set(int fd);
+off_t sys_memfd_get_size(int fd, off_t *size);
+
 int name_list(struct conn *conn, uint64_t flags);
 int name_release(struct conn *conn, const char *name);
 int name_acquire(struct conn *conn, const char *name, uint64_t flags);
index c56e77879ca48d4311742b56ff4e7a4bb0ae15e5..493b02a98d02b92d2530684e46aa3a41dc19b454 100644 (file)
@@ -83,7 +83,6 @@ static int
 send_echo_request(struct conn *conn, uint64_t dst_id)
 {
        struct kdbus_msg *msg;
-       struct kdbus_cmd_memfd_make mfd = {};
        struct kdbus_item *item;
        uint64_t size;
        int memfd = -1;
@@ -95,20 +94,18 @@ send_echo_request(struct conn *conn, uint64_t dst_id)
        size = sizeof(struct kdbus_msg);
        size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
 
-       mfd.size = sizeof(struct kdbus_cmd_memfd_make);
-       ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &mfd);
-       if (ret < 0) {
-               fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
+       memfd = sys_memfd_create("memfd-name", 0);
+       if (memfd < 0) {
+               fprintf(stderr, "sys_memfd_create() failed: %m\n");
                return EXIT_FAILURE;
        }
-       memfd = mfd.fd;
 
        if (write(memfd, &now, sizeof(now)) != sizeof(now)) {
                fprintf(stderr, "writing to memfd failed: %m\n");
                return EXIT_FAILURE;
        }
 
-       ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true);
+       ret = sys_memfd_seal_set(memfd);
        if (ret < 0) {
                fprintf(stderr, "memfd sealing failed: %m\n");
                return EXIT_FAILURE;
@@ -177,9 +174,10 @@ handle_echo_reply(struct conn *conn)
                case KDBUS_ITEM_PAYLOAD_MEMFD: {
                        char *buf;
 
-                       buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
+                       buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_PRIVATE, item->memfd.fd, 0);
                        if (buf == MAP_FAILED) {
-                               printf("mmap() fd=%i failed: %m", item->memfd.fd);
+                               printf("mmap() fd=%i size=%llu failed: %m\n", item->memfd.fd, item->memfd.size);
+                               close(item->memfd.fd);
                                break;
                        }
 
index e4f5df50943521bb68485dd6fb242731c016f77b..2db7eb81a4ffcba4a3b8ce258ae5e40978f79793 100644 (file)
@@ -108,7 +108,7 @@ static struct kdbus_conn *make_conn(const char *buspath, uint64_t flags)
                return NULL;
        }
 
-       conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, conn->fd, 0);
+       conn->buf = mmap(NULL, POOL_SIZE, PROT_READ, MAP_PRIVATE, conn->fd, 0);
        if (conn->buf == MAP_FAILED) {
                free(conn);
                fprintf(stderr, "--- error mmap (%m)\n");
@@ -180,16 +180,12 @@ static int send_message(const struct kdbus_conn *conn,
        if (dst_id == KDBUS_DST_ID_BROADCAST)
                size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
        else {
-               struct kdbus_cmd_memfd_make mfd;
-
-               mfd.size = sizeof(struct kdbus_cmd_memfd_make);
-               ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &mfd);
-               ASSERT_RETURN(ret == 0);
-               memfd = mfd.fd;
+               memfd = sys_memfd_create("payload", 0);
+               ASSERT_RETURN(memfd >= 0);
 
                ASSERT_RETURN(write(memfd, "kdbus memfd 1234567", 19) == 19);
 
-               ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1);
+               ret = sys_memfd_seal_set(memfd);
                ASSERT_RETURN(ret == 0);
 
                size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));