1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

Merge remote-tracking branch 'origin/master'

This commit is contained in:
Lennart Poettering 2014-08-18 18:12:55 +02:00
commit 630a4d9ea7
20 changed files with 177 additions and 522 deletions

View File

@ -860,6 +860,8 @@ libsystemd_shared_la_SOURCES = \
src/shared/copy.h \
src/shared/base-filesystem.c \
src/shared/base-filesystem.h \
src/shared/memfd.c \
src/shared/memfd.h \
src/shared/nss-util.h
nodist_libsystemd_shared_la_SOURCES = \
@ -2382,7 +2384,6 @@ libsystemd_internal_la_SOURCES = \
src/systemd/sd-bus.h \
src/systemd/sd-bus-protocol.h \
src/systemd/sd-bus-vtable.h \
src/systemd/sd-memfd.h \
src/systemd/sd-utf8.h \
src/systemd/sd-event.h \
src/systemd/sd-rtnl.h \
@ -2432,7 +2433,6 @@ libsystemd_internal_la_SOURCES = \
src/libsystemd/sd-bus/bus-slot.h \
src/libsystemd/sd-bus/bus-protocol.h \
src/libsystemd/sd-bus/kdbus.h \
src/libsystemd/sd-bus/sd-memfd.c \
src/libsystemd/sd-utf8/sd-utf8.c \
src/libsystemd/sd-event/sd-event.c \
src/libsystemd/sd-event/event-util.h \
@ -2550,7 +2550,6 @@ pkginclude_HEADERS += \
src/systemd/sd-bus.h \
src/systemd/sd-bus-protocol.h \
src/systemd/sd-bus-vtable.h \
src/systemd/sd-memfd.h \
src/systemd/sd-utf8.h \
src/systemd/sd-event.h \
src/systemd/sd-rtnl.h \
@ -2571,7 +2570,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,13 +2723,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
test_bus_zero_copy_SOURCES = \
src/libsystemd/sd-bus/test-bus-zero-copy.c

View File

@ -68,7 +68,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<funcdef>int sd_bus_message_append_array_memfd</funcdef>
<paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
<paramdef>char <parameter>type</parameter></paramdef>
<paramdef>sd_memfd *<parameter>memfd</parameter></paramdef>
<paramdef>int <parameter>memfd</parameter></paramdef>
</funcprototype>
<funcprototype>

View File

@ -58,7 +58,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<funcprototype>
<funcdef>int sd_bus_message_append_string_memfd</funcdef>
<paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
<paramdef>sd_memfd *<parameter>memfd</parameter></paramdef>
<paramdef>int <parameter>memfd</parameter></paramdef>
</funcprototype>
<funcprototype>

View File

@ -177,7 +177,9 @@
<para>The maximum transmission unit in bytes to
set for the device. The usual suffixes K, M, G,
are supported and are understood to the base of
1024.</para>
1024. This key is not currently suported for
<literal>tun</literal> or <literal>tap</literal> devices.
</para>
</listitem>
</varlistentry>
<varlistentry>
@ -187,6 +189,7 @@
If none is given, one is generated based on
the interface name and the
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
This key is not currently suported for <literal>tun</literal> or <literal>tap</literal> devices.
</para>
</listitem>
</varlistentry>

View File

@ -359,20 +359,6 @@ global:
sd_bus_track_first;
sd_bus_track_next;
/* sd-memfd */
sd_memfd_new;
sd_memfd_new_and_map;
sd_memfd_free;
sd_memfd_get_fd;
sd_memfd_get_file;
sd_memfd_dup_fd;
sd_memfd_map;
sd_memfd_set_sealed;
sd_memfd_get_sealed;
sd_memfd_get_size;
sd_memfd_set_size;
sd_memfd_get_name;
/* sd-event */
sd_event_default;
sd_event_new;

View File

@ -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

View File

@ -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, 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 {

View File

@ -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;
@ -2527,7 +2527,7 @@ _public_ int sd_bus_message_append_array_iovec(
_public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
char type,
sd_memfd *memfd) {
int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
ssize_t align, sz;
@ -2537,7 +2537,7 @@ _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
if (!m)
return -EINVAL;
if (!memfd)
if (memfd < 0)
return -EINVAL;
if (m->sealed)
return -EPERM;
@ -2546,15 +2546,15 @@ _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 = memfd_set_sealed(memfd);
if (r < 0)
return r;
copy_fd = sd_memfd_dup_fd(memfd);
copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
r = sd_memfd_get_size(memfd, &size);
r = memfd_get_size(memfd, &size);
if (r < 0)
return r;
@ -2593,7 +2593,7 @@ _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
return sd_bus_message_close_container(m);
}
_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
struct bus_container *c;
@ -2602,19 +2602,19 @@ _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *mem
int r;
assert_return(m, -EINVAL);
assert_return(memfd, -EINVAL);
assert_return(memfd >= 0, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(!m->poisoned, -ESTALE);
r = sd_memfd_set_sealed(memfd, true);
r = memfd_set_sealed(memfd);
if (r < 0)
return r;
copy_fd = sd_memfd_dup_fd(memfd);
copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
r = sd_memfd_get_size(memfd, &size);
r = memfd_get_size(memfd, &size);
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;
}
}

View File

@ -295,7 +295,6 @@ static int node_callbacks_run(
#define CAPABILITY_SHIFT(x) (((x) >> __builtin_ctzll(_SD_BUS_VTABLE_CAPABILITY_MASK)) & 0xFFFF)
static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c, sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
uint64_t cap;
int r;

View File

@ -733,24 +733,6 @@ struct kdbus_cmd_match {
struct kdbus_item items[0];
} __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
@ -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),
};
/*

View File

@ -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;
}

View File

@ -24,9 +24,9 @@
#include "util.h"
#include "log.h"
#include "memfd.h"
#include "sd-bus.h"
#include "sd-memfd.h"
#include "bus-message.h"
#include "bus-error.h"
#include "bus-kernel.h"
@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
sd_bus *a, *b;
int r, bus_ref;
sd_bus_message *m;
sd_memfd *f;
int f;
uint64_t sz;
uint32_t u32;
size_t i, l;
@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
memset(p+1, 'L', FIRST_ARRAY-2);
p[FIRST_ARRAY-1] = '>';
r = sd_memfd_new_and_map(&f, NULL, STRING_SIZE, (void**) &s);
r = memfd_new_and_map(&f, NULL, STRING_SIZE, (void**) &s);
assert_se(r >= 0);
s[0] = '<';
@ -103,16 +103,16 @@ int main(int argc, char *argv[]) {
s[STRING_SIZE-1] = 0;
munmap(s, STRING_SIZE);
r = sd_memfd_get_size(f, &sz);
r = memfd_get_size(f, &sz);
assert_se(r >= 0);
assert_se(sz == STRING_SIZE);
r = sd_bus_message_append_string_memfd(m, f);
assert_se(r >= 0);
sd_memfd_free(f);
close(f);
r = sd_memfd_new_and_map(&f, NULL, SECOND_ARRAY, (void**) &p);
r = memfd_new_and_map(&f, NULL, SECOND_ARRAY, (void**) &p);
assert_se(r >= 0);
p[0] = '<';
@ -120,14 +120,14 @@ int main(int argc, char *argv[]) {
p[SECOND_ARRAY-1] = '>';
munmap(p, SECOND_ARRAY);
r = sd_memfd_get_size(f, &sz);
r = memfd_get_size(f, &sz);
assert_se(r >= 0);
assert_se(sz == SECOND_ARRAY);
r = sd_bus_message_append_array_memfd(m, 'y', f);
assert_se(r >= 0);
sd_memfd_free(f);
close(f);
r = sd_bus_message_close_container(m);
assert_se(r >= 0);

View File

@ -779,7 +779,7 @@ _public_ int sd_event_add_io(
r = source_io_register(s, s->enabled, events);
if (r < 0) {
source_free(s);
return -errno;
return r;
}
if (ret)
@ -894,6 +894,8 @@ _public_ int sd_event_add_time(
s->userdata = userdata;
s->enabled = SD_EVENT_ONESHOT;
d->needs_rearm = true;
r = prioq_put(d->earliest, s, &s->time.earliest_index);
if (r < 0)
goto fail;
@ -902,8 +904,6 @@ _public_ int sd_event_add_time(
if (r < 0)
goto fail;
d->needs_rearm = true;
if (ret)
*ret = s;
@ -1060,7 +1060,7 @@ _public_ int sd_event_add_child(
r = event_update_signal_fd(e);
if (r < 0) {
source_free(s);
return -errno;
return r;
}
}
@ -1872,6 +1872,7 @@ static int process_timer(
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
return 0;

View File

@ -141,7 +141,7 @@ static int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) {
c++;
}
qsort(links, c, sizeof(LinkInfo), link_info_compare);
qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
*ret = links;
links = NULL;

View File

@ -172,9 +172,35 @@ static void tuntap_done(NetDev *netdev) {
t->group_name = NULL;
}
static int tuntap_verify(NetDev *netdev, const char *filename) {
TunTap *t = NULL;
assert(netdev);
if (netdev->kind == NETDEV_KIND_TUN)
t = TUN(netdev);
else
t = TAP(netdev);
assert(t);
if (netdev->mtu) {
log_warning_netdev(netdev, "MTU configured for %s, ignoring",
netdev_kind_to_string(netdev->kind));
}
if (netdev->mac) {
log_warning_netdev(netdev, "MAC configured for %s, ignoring",
netdev_kind_to_string(netdev->kind));
}
return 0;
}
const NetDevVTable tun_vtable = {
.object_size = sizeof(TunTap),
.sections = "Match\0NetDev\0Tun\0",
.config_verify = tuntap_verify,
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
@ -183,6 +209,7 @@ const NetDevVTable tun_vtable = {
const NetDevVTable tap_vtable = {
.object_size = sizeof(TunTap),
.sections = "Match\0NetDev\0Tap\0",
.config_verify = tuntap_verify,
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,

View File

@ -908,7 +908,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
}
void log_parse_environment(void) {
_cleanup_free_ char *line = NULL;
const char *e;
parse_proc_cmdline(parse_proc_cmdline_item);

View File

@ -26,31 +26,18 @@
#include <sys/prctl.h>
#include "util.h"
#include "kdbus.h"
#include "bus-label.h"
#include "missing.h"
#include "memfd.h"
#include "sd-memfd.h"
#include "sd-bus.h"
struct sd_memfd {
int fd;
FILE *f;
};
int memfd_new(int *fd, const char *name) {
_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;
int n;
assert_return(m, -EINVAL);
kdbus = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (kdbus < 0)
return -errno;
assert_return(fd, -EINVAL);
if (name) {
/* The kernel side is pretty picky about the character
@ -89,111 +76,31 @@ _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)
n = memfd_create(name, MFD_ALLOW_SEALING);
if (n < 0)
return -errno;
n = new0(struct sd_memfd, 1);
if (!n) {
safe_close(cmd->fd);
return -ENOMEM;
}
n->fd = cmd->fd;
*m = n;
*fd = 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)
return -ENOTTY;
n = new0(struct sd_memfd, 1);
if (!n)
return -ENOMEM;
n->fd = fd;
*m = n;
return 0;
}
_public_ void sd_memfd_free(sd_memfd *m) {
if (!m)
return;
if (m->f)
fclose(m->f);
else
safe_close(m->fd);
free(m);
}
_public_ int sd_memfd_get_fd(sd_memfd *m) {
assert_return(m, -EINVAL);
return m->fd;
}
_public_ int sd_memfd_get_file(sd_memfd *m, FILE **f) {
assert_return(m, -EINVAL);
assert_return(f, -EINVAL);
if (!m->f) {
m->f = fdopen(m->fd, "r+");
if (!m->f)
return -errno;
}
*f = m->f;
return 0;
}
_public_ int sd_memfd_dup_fd(sd_memfd *m) {
int fd;
assert_return(m, -EINVAL);
fd = fcntl(m->fd, F_DUPFD_CLOEXEC, 3);
if (fd < 0)
return -errno;
return fd;
}
_public_ int sd_memfd_map(sd_memfd *m, uint64_t offset, size_t size, void **p) {
int memfd_map(int fd, uint64_t offset, size_t size, void **p) {
void *q;
int sealed;
assert_return(m, -EINVAL);
assert_return(fd >= 0, -EINVAL);
assert_return(size > 0, -EINVAL);
assert_return(p, -EINVAL);
sealed = sd_memfd_get_sealed(m);
sealed = memfd_get_sealed(fd);
if (sealed < 0)
return sealed;
q = mmap(NULL, size, sealed ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, m->fd, offset);
if (sealed)
q = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, offset);
else
q = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
if (q == MAP_FAILED)
return -errno;
@ -201,89 +108,89 @@ _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) {
int memfd_set_sealed(int fd) {
int r;
assert_return(m, -EINVAL);
assert_return(fd >= 0, -EINVAL);
r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_SET, b);
r = fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE);
if (r < 0)
return -errno;
return 0;
}
_public_ int sd_memfd_get_sealed(sd_memfd *m) {
int r, b;
int memfd_get_sealed(int fd) {
int r;
assert_return(m, -EINVAL);
assert_return(fd >= 0, -EINVAL);
r = ioctl(m->fd, KDBUS_CMD_MEMFD_SEAL_GET, &b);
r = fcntl(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 memfd_get_size(int fd, uint64_t *sz) {
int r;
struct stat stat;
assert_return(m, -EINVAL);
assert_return(fd >= 0, -EINVAL);
assert_return(sz, -EINVAL);
r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_GET, sz);
r = fstat(fd, &stat);
if (r < 0)
return -errno;
*sz = stat.st_size;
return r;
}
int memfd_set_size(int fd, uint64_t sz) {
int r;
assert_return(fd >= 0, -EINVAL);
r = ftruncate(fd, sz);
if (r < 0)
return -errno;
return r;
}
_public_ int sd_memfd_set_size(sd_memfd *m, uint64_t sz) {
int memfd_new_and_map(int *fd, const char *name, size_t sz, void **p) {
_cleanup_close_ int n = -1;
int r;
assert_return(m, -EINVAL);
r = ioctl(m->fd, KDBUS_CMD_MEMFD_SIZE_SET, &sz);
if (r < 0)
return -errno;
return r;
}
_public_ int sd_memfd_new_and_map(sd_memfd **m, const char *name, size_t sz, void **p) {
sd_memfd *n;
int r;
r = sd_memfd_new(&n, name);
r = memfd_new(&n, name);
if (r < 0)
return r;
r = sd_memfd_set_size(n, sz);
if (r < 0) {
sd_memfd_free(n);
r = memfd_set_size(n, sz);
if (r < 0)
return r;
}
r = sd_memfd_map(n, 0, sz, p);
if (r < 0) {
sd_memfd_free(n);
r = memfd_map(n, 0, sz, p);
if (r < 0)
return r;
}
*m = n;
*fd = n;
n = -1;
return 0;
}
_public_ int sd_memfd_get_name(sd_memfd *m, char **name) {
int memfd_get_name(int fd, char **name) {
char path[sizeof("/proc/self/fd/") + DECIMAL_STR_MAX(int)], buf[FILENAME_MAX+1], *e;
const char *delim, *end;
_cleanup_free_ char *n = NULL;
ssize_t k;
assert_return(m, -EINVAL);
assert_return(fd >= 0, -EINVAL);
assert_return(name, -EINVAL);
sprintf(path, "/proc/self/fd/%i", m->fd);
sprintf(path, "/proc/self/fd/%i", fd);
k = readlink(path, buf, sizeof(buf));
if (k < 0)

View File

@ -1,7 +1,6 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdmemfdhfoo
#define foosdmemfdhfoo
#pragma once
/***
This file is part of systemd.
@ -25,33 +24,18 @@
#include <inttypes.h>
#include <sys/types.h>
#include <stdio.h>
#include "macro.h"
#include "util.h"
#include "_sd-common.h"
int memfd_new(int *fd, const char *name);
int memfd_new_and_map(int *fd, const char *name, size_t sz, void **p);
_SD_BEGIN_DECLARATIONS;
int memfd_map(int fd, uint64_t offset, size_t size, void **p);
typedef struct sd_memfd sd_memfd;
int memfd_set_sealed(int fd);
int memfd_get_sealed(int fd);
int sd_memfd_new(sd_memfd **m, const char *name);
int sd_memfd_new_from_fd(sd_memfd **m, int fd);
int sd_memfd_new_and_map(sd_memfd **m, const char *name, size_t sz, void **p);
int memfd_get_size(int fd, uint64_t *sz);
int memfd_set_size(int fd, uint64_t sz);
void sd_memfd_free(sd_memfd *m);
int sd_memfd_get_fd(sd_memfd *m);
int sd_memfd_dup_fd(sd_memfd *n);
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_get_sealed(sd_memfd *m);
int sd_memfd_get_size(sd_memfd *m, uint64_t *sz);
int sd_memfd_set_size(sd_memfd *m, uint64_t sz);
int sd_memfd_get_name(sd_memfd *m, char **name);
_SD_END_DECLARATIONS;
#endif
int memfd_get_name(int fd, char **name);

View File

@ -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 flags) {
return syscall(__NR_memfd_create, name, flags);
}
#endif
#ifndef BTRFS_IOCTL_MAGIC
#define BTRFS_IOCTL_MAGIC 0x94
#endif

View File

@ -28,7 +28,7 @@
#include "sd-id128.h"
#include "sd-event.h"
#include "sd-memfd.h"
#include "memfd.h"
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
@ -230,10 +230,10 @@ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p);
int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size);
int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr);
int sd_bus_message_append_array_iovec(sd_bus_message *m, char type, const struct iovec *iov, unsigned n);
int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd);
int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, int memfd);
int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s);
int sd_bus_message_append_string_iovec(sd_bus_message *m, const struct iovec *iov, unsigned n);
int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd* memfd);
int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd);
int sd_bus_message_append_strv(sd_bus_message *m, char **l);
int sd_bus_message_open_container(sd_bus_message *m, char type, const char *contents);
int sd_bus_message_close_container(sd_bus_message *m);