[systemd-commits] Makefile.am src/libsystemd src/shared src/systemd

Daniel Mack zonque at kemper.freedesktop.org
Sun Aug 17 12:48:06 PDT 2014


 Makefile.am                            |    4 
 src/libsystemd/sd-bus/PORTING-DBUS1    |   40 -------
 src/libsystemd/sd-bus/bus-kernel.c     |   21 ---
 src/libsystemd/sd-bus/bus-message.c    |   10 -
 src/libsystemd/sd-bus/kdbus.h          |   51 ---------
 src/libsystemd/sd-bus/sd-memfd.c       |   54 +++------
 src/libsystemd/sd-bus/test-bus-memfd.c |  180 ---------------------------------
 src/shared/missing.h                   |   44 ++++++++
 src/systemd/sd-memfd.h                 |    2 
 9 files changed, 73 insertions(+), 333 deletions(-)

New commits:
commit a6082d778ee4b97ec3eb6d3266cefc024c5d60f7
Author: Daniel Mack <zonque at gmail.com>
Date:   Tue May 13 01:28:09 2014 +0200

    kdbus: switch over to generic memfd implementation (ABI+API break)

diff --git a/Makefile.am b/Makefile.am
index b95ddf2..cfa51cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2571,7 +2571,6 @@ tests += \
 	test-bus-kernel \
 	test-bus-kernel-bloom \
 	test-bus-kernel-benchmark \
-	test-bus-memfd \
 	test-bus-zero-copy \
 	test-bus-introspect \
 	test-bus-objects \
@@ -2725,9 +2724,6 @@ test_bus_kernel_benchmark_LDADD = \
 	libsystemd-internal.la \
 	libsystemd-shared.la
 
-test_bus_memfd_SOURCES = \
-	src/libsystemd/sd-bus/test-bus-memfd.c
-
 test_bus_memfd_LDADD = \
 	libsystemd-internal.la \
 	libsystemd-shared.la
diff --git a/src/libsystemd/sd-bus/PORTING-DBUS1 b/src/libsystemd/sd-bus/PORTING-DBUS1
index 6205e32..9f0a91d 100644
--- a/src/libsystemd/sd-bus/PORTING-DBUS1
+++ b/src/libsystemd/sd-bus/PORTING-DBUS1
@@ -362,46 +362,6 @@ ioctl()s are added for a single match strings.
 
 MEMFDS
 
-The "memfd" concept is used for zero-copy data transfers (see
-above). memfds are file descriptors to memory chunks of arbitrary
-sizes. If you have a memfd you can mmap() it to get access to the data
-it contains or write to it. They are comparable to file descriptors to
-unlinked files on a tmpfs, or to anonymous memory that one may refer
-to with an fd. They have one particular property: they can be
-"sealed". A memfd that is "sealed" is protected from alteration. Only
-memfds that are currently not mapped and to which a single fd refers
-may be sealed (they may also be unsealed in that case).
-
-The concept of "sealing" makes memfds useful for using them as
-transport for kdbus messages: only when the receiver knows that the
-message it has received cannot change while looking at, it can safely
-parse it without having to copy it to a safe memory area. memfds can also
-be reused in multiple messages. A sender may send the same memfd to
-multiple peers, and since it is sealed, it can be sure that the receiver
-will not be able to modify it. "Sealing" hence provides both sides of
-a transaction with the guarantee that the data stays constant and is
-reusable.
-
-memfds are a generic concept that can be used outside of the immediate
-kdbus usecase. You can send them across AF_UNIX sockets too, sealed or
-unsealed. In kdbus themselves, they can be used to send zero-copy
-payloads, but may also be sent as normal fds.
-
-memfds are allocated with the KDBUS_CMD_MEMFD_NEW ioctl. After allocation,
-simply memory map them and write to them. To set their size, use
-KDBUS_CMD_MEMFD_SIZE_SET. Note that memfds will be increased in size
-automatically if you touch previously unallocated pages. However, the
-size will only be increased in multiples of the page size in that
-case. Thus, in almost all cases, an explicit KDBUS_CMD_MEMFD_SIZE_SET
-is necessary, since it allows setting memfd sizes in finer
-granularity. To seal a memfd use the KDBUS_CMD_MEMFD_SEAL_SET ioctl
-call. It will only succeed if the caller has the only fd reference to
-the memfd open, and if the memfd is currently unmapped.
-
-If memfds are shared, keep in mind that the file pointer used by
-write/read/seek is shared too, only pread/pwrite are safe to use
-in that case.
-
 memfds may be sent across kdbus via KDBUS_ITEM_PAYLOAD_MEMFD items
 attached to messages. If this is done, the data included in the memfd
 is considered part of the payload stream of a message, and are treated
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 8b961c3..4156b90 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -1111,9 +1111,6 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al
 
         if (bus->n_memfd_cache <= 0) {
                 _cleanup_free_ char *g = NULL;
-                struct kdbus_cmd_memfd_make *cmd;
-                struct kdbus_item *item;
-                size_t l, sz;
                 int r;
 
                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
@@ -1124,26 +1121,14 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al
                 if (!g)
                         return -ENOMEM;
 
-                l = strlen(g);
-                sz = ALIGN8(offsetof(struct kdbus_cmd_memfd_make, items)) +
-                        ALIGN8(offsetof(struct kdbus_item, str)) +
-                        l + 1;
-                cmd = alloca0(sz);
-                cmd->size = sz;
-
-                item = cmd->items;
-                item->size = ALIGN8(offsetof(struct kdbus_item, str)) + l + 1;
-                item->type = KDBUS_ITEM_MEMFD_NAME;
-                memcpy(item->str, g, l + 1);
-
-                r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, cmd);
+                r = memfd_create(g, 0, MFD_ALLOW_SEALING);
                 if (r < 0)
                         return -errno;
 
                 *address = NULL;
                 *mapped = 0;
                 *allocated = 0;
-                return cmd->fd;
+                return r;
         }
 
         c = &bus->memfd_cache[--bus->n_memfd_cache];
@@ -1195,7 +1180,7 @@ void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, si
 
         /* If overly long, let's return a bit to the OS */
         if (mapped > max_mapped) {
-                assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_mapped) >= 0);
+                assert_se(ftruncate(fd, max_mapped) >= 0);
                 assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
                 c->mapped = c->allocated = max_mapped;
         } else {
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 4768a1f..79dc471 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -1076,7 +1076,7 @@ static int part_make_space(
                         uint64_t new_allocated;
 
                         new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
-                        r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &new_allocated);
+                        r = ftruncate(part->memfd, new_allocated);
                         if (r < 0) {
                                 m->poisoned = true;
                                 return -errno;
@@ -2546,7 +2546,7 @@ _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
         if (m->poisoned)
                 return -ESTALE;
 
-        r = sd_memfd_set_sealed(memfd, true);
+        r = sd_memfd_set_sealed(memfd);
         if (r < 0)
                 return r;
 
@@ -2606,7 +2606,7 @@ _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *mem
         assert_return(!m->sealed, -EPERM);
         assert_return(!m->poisoned, -ESTALE);
 
-        r = sd_memfd_set_sealed(memfd, true);
+        r = sd_memfd_set_sealed(memfd);
         if (r < 0)
                 return r;
 
@@ -2799,11 +2799,11 @@ int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
 
                                 /* Then, sync up real memfd size */
                                 sz = part->size;
-                                if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &sz) < 0)
+                                if (ftruncate(part->memfd, sz) < 0)
                                         return -errno;
 
                                 /* Finally, try to seal */
-                                if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
+                                if (fcntl(part->memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE) >= 0)
                                         part->sealed = true;
                         }
         }
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index b060330..3751f9c 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -734,24 +734,6 @@ struct kdbus_cmd_match {
 } __attribute__((aligned(8)));
 
 /**
- * struct kdbus_cmd_memfd_make - create a kdbus memfd
- * @size:		The total size of the struct
- * @file_size:		The initial file size
- * @fd:			The returned file descriptor number
- * @__pad:		Padding to ensure proper alignement
- * @items:		A list of items for additional information
- *
- * This structure is used with the KDBUS_CMD_MEMFD_NEW ioctl.
- */
-struct kdbus_cmd_memfd_make {
-	__u64 size;
-	__u64 file_size;
-	int fd;
-	__u32 __pad;
-	struct kdbus_item items[0];
-} __attribute__((aligned(8)));
-
-/**
  * enum kdbus_ioctl_type - Ioctl API
  * @KDBUS_CMD_BUS_MAKE:		After opening the "control" device node, this
  *				command creates a new bus with the specified
@@ -801,32 +783,6 @@ struct kdbus_cmd_memfd_make {
  * @KDBUS_CMD_MATCH_ADD:	Install a match which broadcast messages should
  *				be delivered to the connection.
  * @KDBUS_CMD_MATCH_REMOVE:	Remove a current match for broadcast messages.
- * @KDBUS_CMD_MEMFD_NEW:	Return a new file descriptor which provides an
- *				anonymous shared memory file and which can be
- *				used to pass around larger chunks of data.
- *				Kdbus memfd files can be sealed, which allows
- *				the receiver to trust the data it has received.
- *				Kdbus memfd files expose only very limited
- *				operations, they can be mmap()ed, seek()ed,
- *				(p)read(v)() and (p)write(v)(); most other
- *				common file operations are not implemented.
- *				Special caution needs to be taken with
- *				read(v)()/write(v)() on a shared file; the
- *				underlying file position is always shared
- *				between all users of the file and race against
- *				each other, pread(v)()/pwrite(v)() avoid these
- *				issues.
- * @KDBUS_CMD_MEMFD_SIZE_GET:	Return the size of the underlying file, which
- *				changes with write().
- * @KDBUS_CMD_MEMFD_SIZE_SET:	Truncate the underlying file to the specified
- *				size.
- * @KDBUS_CMD_MEMFD_SEAL_GET:	Return the state of the file sealing.
- * @KDBUS_CMD_MEMFD_SEAL_SET:	Seal or break a seal of the file. Only files
- *				which are not shared with other processes and
- *				which are currently not mapped can be sealed.
- *				The current process needs to be the one and
- *				single owner of the file, the sealing cannot
- *				be changed as long as the file is shared.
  */
 enum kdbus_ioctl_type {
 	KDBUS_CMD_BUS_MAKE =		_IOW(KDBUS_IOCTL_MAGIC, 0x00,
@@ -866,13 +822,6 @@ enum kdbus_ioctl_type {
 					     struct kdbus_cmd_match),
 	KDBUS_CMD_MATCH_REMOVE =	_IOW(KDBUS_IOCTL_MAGIC, 0x81,
 					     struct kdbus_cmd_match),
-
-	KDBUS_CMD_MEMFD_NEW =		_IOWR(KDBUS_IOCTL_MAGIC, 0xc0,
-					      struct kdbus_cmd_memfd_make),
-	KDBUS_CMD_MEMFD_SIZE_GET =	_IOR(KDBUS_IOCTL_MAGIC, 0xc1, __u64 *),
-	KDBUS_CMD_MEMFD_SIZE_SET =	_IOW(KDBUS_IOCTL_MAGIC, 0xc2, __u64 *),
-	KDBUS_CMD_MEMFD_SEAL_GET =	_IOR(KDBUS_IOCTL_MAGIC, 0xc3, int *),
-	KDBUS_CMD_MEMFD_SEAL_SET =	_IO(KDBUS_IOCTL_MAGIC, 0xc4),
 };
 
 /*
diff --git a/src/libsystemd/sd-bus/sd-memfd.c b/src/libsystemd/sd-bus/sd-memfd.c
index fcf3e73..16d09e3 100644
--- a/src/libsystemd/sd-bus/sd-memfd.c
+++ b/src/libsystemd/sd-bus/sd-memfd.c
@@ -26,8 +26,8 @@
 #include <sys/prctl.h>
 
 #include "util.h"
-#include "kdbus.h"
 #include "bus-label.h"
+#include "missing.h"
 
 #include "sd-memfd.h"
 #include "sd-bus.h"
@@ -39,11 +39,8 @@ struct sd_memfd {
 
 _public_ int sd_memfd_new(sd_memfd **m, const char *name) {
 
-        struct kdbus_cmd_memfd_make *cmd;
-        struct kdbus_item *item;
         _cleanup_close_ int kdbus = -1;
         _cleanup_free_ char *g = NULL;
-        size_t sz, l;
         sd_memfd *n;
 
         assert_return(m, -EINVAL);
@@ -89,42 +86,28 @@ _public_ int sd_memfd_new(sd_memfd **m, const char *name) {
                 }
         }
 
-        l = strlen(name);
-        sz = ALIGN8(offsetof(struct kdbus_cmd_memfd_make, items)) +
-                ALIGN8(offsetof(struct kdbus_item, str)) +
-                l + 1;
-
-        cmd = alloca0(sz);
-        cmd->size = sz;
-
-        item = cmd->items;
-        item->size = ALIGN8(offsetof(struct kdbus_item, str)) + l + 1;
-        item->type = KDBUS_ITEM_MEMFD_NAME;
-        memcpy(item->str, name, l + 1);
-
-        if (ioctl(kdbus, KDBUS_CMD_MEMFD_NEW, cmd) < 0)
-                return -errno;
-
         n = new0(struct sd_memfd, 1);
-        if (!n) {
-                safe_close(cmd->fd);
+        if (!n)
                 return -ENOMEM;
+
+        n->fd = memfd_create(name, 0, MFD_ALLOW_SEALING);
+        if (n->fd < 0) {
+                free(n);
+                return -errno;
         }
 
-        n->fd = cmd->fd;
         *m = n;
         return 0;
 }
 
 _public_ int sd_memfd_new_from_fd(sd_memfd **m, int fd) {
         sd_memfd *n;
-        uint64_t sz;
 
         assert_return(m, -EINVAL);
         assert_return(fd >= 0, -EINVAL);
 
-        /* Check if this is a valid memfd */
-        if (ioctl(fd, KDBUS_CMD_MEMFD_SIZE_GET, &sz) < 0)
+        /* Check if this is a sealable fd */
+        if (fcntl(fd, F_GET_SEALS) < 0)
                 return -ENOTTY;
 
         n = new0(struct sd_memfd, 1);
@@ -193,7 +176,7 @@ _public_ int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p) {
         if (sealed < 0)
                 return sealed;
 
-        q = mmap(NULL, size, sealed ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, m->fd, offset);
+        q = mmap(NULL, size, sealed ? PROT_READ : PROT_READ|PROT_WRITE, MAP_PRIVATE, m->fd, offset);
         if (q == MAP_FAILED)
                 return -errno;
 
@@ -201,12 +184,12 @@ _public_ int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p) {
         return 0;
 }
 
-_public_ int sd_memfd_set_sealed(sd_memfd *m, int b) {
+_public_ int sd_memfd_set_sealed(sd_memfd *m) {
         int r;
 
         assert_return(m, -EINVAL);
 
-        r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_SET, b);
+        r = fcntl(m->fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
         if (r < 0)
                 return -errno;
 
@@ -214,27 +197,30 @@ _public_ int sd_memfd_set_sealed(sd_memfd *m, int b) {
 }
 
 _public_ int sd_memfd_get_sealed(sd_memfd *m) {
-        int r, b;
+        int r;
 
         assert_return(m, -EINVAL);
 
-        r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_GET, &b);
+        r = fcntl(m->fd, F_GET_SEALS);
         if (r < 0)
                 return -errno;
 
-        return !!b;
+        return (r & (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)) ==
+                    (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
 }
 
 _public_ int sd_memfd_get_size(sd_memfd *m, uint64_t *sz) {
         int r;
+        struct stat stat;
 
         assert_return(m, -EINVAL);
         assert_return(sz, -EINVAL);
 
-        r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_GET, sz);
+        r = fstat(m->fd, &stat);
         if (r < 0)
                 return -errno;
 
+        *sz = stat.st_size;
         return r;
 }
 
@@ -243,7 +229,7 @@ _public_ int sd_memfd_set_size(sd_memfd *m, uint64_t sz) {
 
         assert_return(m, -EINVAL);
 
-        r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
+        r = ftruncate(m->fd, sz);
         if (r < 0)
                 return -errno;
 
diff --git a/src/libsystemd/sd-bus/test-bus-memfd.c b/src/libsystemd/sd-bus/test-bus-memfd.c
deleted file mode 100644
index 3462732..0000000
--- a/src/libsystemd/sd-bus/test-bus-memfd.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Lennart Poettering
-
-  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.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/mman.h>
-#include <sys/uio.h>
-
-#include "log.h"
-#include "macro.h"
-#include "util.h"
-
-#include "sd-memfd.h"
-
-int main(int argc, char *argv[]) {
-        sd_memfd *m;
-        char *s, *name;
-        uint64_t sz;
-        int r, fd;
-        FILE *f = NULL;
-        char buf[3] = {};
-        struct iovec iov[3] = {};
-        char bufv[3][3] = {};
-
-        log_set_max_level(LOG_DEBUG);
-
-        r = sd_memfd_new(&m, NULL);
-        if (r == -ENOENT)
-                return EXIT_TEST_SKIP;
-
-        assert_se(r >= 0);
-
-        assert_se(sd_memfd_get_name(m, &name) >= 0);
-        log_info("name: %s", name);
-        free(name);
-
-        r = sd_memfd_map(m, 0, 12, (void**) &s);
-        assert_se(r >= 0);
-
-        strcpy(s, "----- world");
-
-        r = sd_memfd_set_sealed(m, 1);
-        assert_se(r == -ETXTBSY);
-
-        assert_se(write(sd_memfd_get_fd(m), "he", 2) == 2);
-        assert_se(write(sd_memfd_get_fd(m), "XXX", 3) == 3);
-        assert_se(streq(s, "heXXX world"));
-
-        /* fix "hello" */
-        assert_se(lseek(sd_memfd_get_fd(m), 2, SEEK_SET) == 2);
-        assert_se(write(sd_memfd_get_fd(m), "ll", 2) == 2);
-
-        assert_se(sd_memfd_get_file(m, &f) >= 0);
-        fputc('o', f);
-        fflush(f);
-
-        /* check content  */
-        assert_se(streq(s, "hello world"));
-
-        assert_se(munmap(s, 12) == 0);
-
-        r = sd_memfd_get_sealed(m);
-        assert_se(r == 0);
-
-        r = sd_memfd_get_size(m, &sz);
-        assert_se(r >= 0);
-        assert_se(sz = page_size());
-
-        /* truncate it */
-        r = sd_memfd_set_size(m, 6);
-        assert_se(r >= 0);
-
-        /* get back new value */
-        r = sd_memfd_get_size(m, &sz);
-        assert_se(r >= 0);
-        assert_se(sz == 6);
-
-        r = sd_memfd_set_sealed(m, 1);
-        assert_se(r >= 0);
-
-        r = sd_memfd_get_sealed(m);
-        assert_se(r == 1);
-
-        fd = sd_memfd_dup_fd(m);
-        assert_se(fd >= 0);
-
-        sd_memfd_free(m);
-
-        /* new sd_memfd, same underlying memfd */
-        r = sd_memfd_new_from_fd(&m, fd);
-        assert_se(r >= 0);
-
-        /* we did truncate it to 6 */
-        r = sd_memfd_get_size(m, &sz);
-        assert_se(r >= 0 && sz == 6);
-
-        /* map it, check content */
-        r = sd_memfd_map(m, 0, 12, (void **)&s);
-        assert_se(r >= 0);
-
-        /* we only see the truncated size */
-        assert_se(streq(s, "hello "));
-
-        /* it was already sealed */
-        r = sd_memfd_set_sealed(m, 1);
-        assert_se(r == -EALREADY);
-
-        /* we cannot break the seal, it is mapped */
-        r = sd_memfd_set_sealed(m, 0);
-        assert_se(r == -ETXTBSY);
-
-        /* unmap it; become the single owner */
-        assert_se(munmap(s, 12) == 0);
-
-        /* now we can do flip the sealing */
-        r = sd_memfd_set_sealed(m, 0);
-        assert_se(r == 0);
-        r = sd_memfd_get_sealed(m);
-        assert_se(r == 0);
-
-        r = sd_memfd_set_sealed(m, 1);
-        assert_se(r == 0);
-        r = sd_memfd_get_sealed(m);
-        assert_se(r == 1);
-
-        r = sd_memfd_set_sealed(m, 0);
-        assert_se(r == 0);
-        r = sd_memfd_get_sealed(m);
-        assert_se(r == 0);
-
-        /* seek at 2, read() 2 bytes */
-        assert_se(lseek(fd, 2, SEEK_SET) == 2);
-        assert_se(read(fd, buf, 2) == 2);
-
-        /* check content */
-        assert_se(memcmp(buf, "ll", 2) == 0);
-
-        /* writev it out*/
-        iov[0].iov_base = (char *)"ABC";
-        iov[0].iov_len = 3;
-        iov[1].iov_base = (char *)"DEF";
-        iov[1].iov_len = 3;
-        iov[2].iov_base = (char *)"GHI";
-        iov[2].iov_len = 3;
-        assert_se(pwritev(fd, iov, 3, 0) == 9);
-
-        /* readv it back */
-        iov[0].iov_base = bufv[0];
-        iov[0].iov_len = 3;
-        iov[1].iov_base = bufv[1];
-        iov[1].iov_len = 3;
-        iov[2].iov_base = bufv[2];
-        iov[2].iov_len = 3;
-        assert_se(preadv(fd, iov, 3, 0) == 9);
-
-        /* check content */
-        assert_se(memcmp(bufv[0], "ABC", 3) == 0);
-        assert_se(memcmp(bufv[1], "DEF", 3) == 0);
-        assert_se(memcmp(bufv[2], "GHI", 3) == 0);
-
-        sd_memfd_free(m);
-
-        return 0;
-}
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 195edfc..3a7e67e 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -64,6 +64,34 @@
 #define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
 #endif
 
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#endif
+
+#ifndef F_GET_SEALS
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+#endif
+
+#ifndef F_SEAL_SEAL
+#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
+#endif
+
+#ifndef F_SEAL_SHRINK
+#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
+#endif
+
+#ifndef F_SEAL_GROW
+#define F_SEAL_GROW     0x0004  /* prevent file from growing */
+#endif
+
+#ifndef F_SEAL_WRITE
+#define F_SEAL_WRITE    0x0008  /* prevent writes */
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002ULL
+#endif
+
 #ifndef IP_FREEBIND
 #define IP_FREEBIND 15
 #endif
@@ -109,6 +137,13 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
 #  ifndef __NR_fanotify_mark
 #    define __NR_fanotify_mark 301
 #  endif
+#  ifndef __NR_memfd_create
+#    define __NR_memfd_create 319
+#  endif
+#elif defined __arm__
+#  ifndef __NR_memfd_create
+#    define __NR_memfd_create 385
+#  endif
 #elif defined _MIPS_SIM
 #  if _MIPS_SIM == _MIPS_SIM_ABI32
 #    ifndef __NR_fanotify_init
@@ -139,6 +174,9 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
 #  ifndef __NR_fanotify_mark
 #    define __NR_fanotify_mark 339
 #  endif
+#  ifndef __NR_memfd_create
+#    define __NR_memfd_create 356
+#  endif
 #endif
 
 #ifndef HAVE_FANOTIFY_INIT
@@ -166,6 +204,12 @@ static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t ma
 }
 #endif
 
+#ifndef HAVE_MEMFD_CREATE
+static inline int memfd_create(const char *name, uint64_t size, uint64_t flags) {
+        return syscall(__NR_memfd_create, name, size, flags);
+}
+#endif
+
 #ifndef BTRFS_IOCTL_MAGIC
 #define BTRFS_IOCTL_MAGIC 0x94
 #endif
diff --git a/src/systemd/sd-memfd.h b/src/systemd/sd-memfd.h
index 753ed68..6de045c 100644
--- a/src/systemd/sd-memfd.h
+++ b/src/systemd/sd-memfd.h
@@ -44,7 +44,7 @@ int sd_memfd_get_file(sd_memfd *m, FILE **f);
 
 int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p);
 
-int sd_memfd_set_sealed(sd_memfd *m, int b);
+int sd_memfd_set_sealed(sd_memfd *m);
 int sd_memfd_get_sealed(sd_memfd *m);
 
 int sd_memfd_get_size(sd_memfd *m, uint64_t *sz);



More information about the systemd-commits mailing list