summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/c-rbtree.c5
-rw-r--r--src/basic/copy.c63
-rw-r--r--src/basic/log.h1
-rw-r--r--src/basic/macro.h6
-rw-r--r--src/basic/missing.h216
-rw-r--r--src/basic/missing_syscall.h310
-rw-r--r--src/basic/selinux-util.c12
-rw-r--r--src/basic/time-util.c7
-rw-r--r--src/core/execute.c16
-rw-r--r--src/core/job.c26
-rw-r--r--src/core/load-fragment.c14
-rw-r--r--src/core/main.c13
-rw-r--r--src/core/selinux-setup.c2
-rw-r--r--src/core/transaction.c9
-rw-r--r--src/libsystemd-network/dhcp-identifier.c2
-rw-r--r--src/libsystemd-network/dhcp-identifier.h41
-rw-r--r--src/libsystemd-network/dhcp6-protocol.h7
-rw-r--r--src/libsystemd-network/network-internal.c28
-rw-r--r--src/libsystemd-network/network-internal.h4
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c48
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c49
-rw-r--r--src/libsystemd-network/sd-lldp.c17
-rw-r--r--src/login/70-uaccess.rules3
-rw-r--r--src/network/networkd-conf.c133
-rw-r--r--src/network/networkd-conf.h32
-rw-r--r--src/network/networkd-dhcp4.c8
-rw-r--r--src/network/networkd-dhcp6.c10
-rw-r--r--src/network/networkd-gperf.gperf18
-rw-r--r--src/network/networkd-link.c18
-rw-r--r--src/network/networkd-manager.c2
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.h2
-rw-r--r--src/network/networkd.c5
-rw-r--r--src/network/networkd.h5
-rw-r--r--src/nspawn/nspawn-cgroup.c4
-rw-r--r--src/nspawn/nspawn.c7
-rw-r--r--src/systemd/sd-dhcp-client.h4
-rw-r--r--src/systemd/sd-dhcp6-client.h7
-rw-r--r--src/test/test-copy.c61
-rw-r--r--src/test/test-env-util.c (renamed from src/test/test-env-replace.c)30
-rw-r--r--src/test/test-execute.c84
41 files changed, 655 insertions, 675 deletions
diff --git a/src/basic/c-rbtree.c b/src/basic/c-rbtree.c
index 914d7e5229..cf5a7242df 100644
--- a/src/basic/c-rbtree.c
+++ b/src/basic/c-rbtree.c
@@ -195,11 +195,6 @@ static inline void c_rbnode_set_parent_and_color(CRBNode *n, CRBNode *p, unsigne
n->__parent_and_color = (CRBNode*)((unsigned long)p | c);
}
-/* same as c_rbnode_set_parent_and_color(), but keeps the current parent */
-static inline void c_rbnode_set_color(CRBNode *n, unsigned long c) {
- c_rbnode_set_parent_and_color(n, c_rbnode_parent(n), c);
-}
-
/* same as c_rbnode_set_parent_and_color(), but keeps the current color */
static inline void c_rbnode_set_parent(CRBNode *n, CRBNode *p) {
c_rbnode_set_parent_and_color(n, p, c_rbnode_color(n));
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 519b412941..41dc8ca79a 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -40,17 +40,38 @@
#include "fs-util.h"
#include "io-util.h"
#include "macro.h"
+#include "missing.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "umask-util.h"
#include "xattr-util.h"
-#define COPY_BUFFER_SIZE (16*1024)
+#define COPY_BUFFER_SIZE (16*1024u)
+
+static ssize_t try_copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+ static int have = -1;
+ ssize_t r;
+
+ if (have == false)
+ return -ENOSYS;
+
+ r = copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
+ if (_unlikely_(have < 0))
+ have = r >= 0 || errno != ENOSYS;
+ if (r >= 0)
+ return r;
+ else
+ return -errno;
+}
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
- bool try_sendfile = true, try_splice = true;
+ bool try_cfr = true, try_sendfile = true, try_splice = true;
int r;
+ size_t m = SSIZE_MAX; /* that the maximum that sendfile and c_f_r accept */
assert(fdf >= 0);
assert(fdt >= 0);
@@ -67,11 +88,9 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
}
for (;;) {
- size_t m = COPY_BUFFER_SIZE;
ssize_t n;
if (max_bytes != (uint64_t) -1) {
-
if (max_bytes <= 0)
return 1; /* return > 0 if we hit the max_bytes limit */
@@ -79,44 +98,59 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
m = (size_t) max_bytes;
}
+ /* First try copy_file_range(), unless we already tried */
+ if (try_cfr) {
+ n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u);
+ if (n < 0) {
+ if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV))
+ return n;
+
+ try_cfr = false;
+ /* use fallback below */
+ } else if (n == 0) /* EOF */
+ break;
+ else
+ /* Success! */
+ goto next;
+ }
+
/* First try sendfile(), unless we already tried */
if (try_sendfile) {
-
n = sendfile(fdt, fdf, NULL, m);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_sendfile = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
- /* The try splice, unless we already tried */
+ /* Then try splice, unless we already tried */
if (try_splice) {
n = splice(fdf, NULL, fdt, NULL, m, 0);
if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
+ if (!IN_SET(errno, EINVAL, ENOSYS))
return -errno;
try_splice = false;
/* use fallback below */
} else if (n == 0) /* EOF */
break;
- else if (n > 0)
+ else
/* Success! */
goto next;
}
/* As a fallback just copy bits by hand */
{
- uint8_t buf[m];
+ uint8_t buf[MIN(m, COPY_BUFFER_SIZE)];
- n = read(fdf, buf, m);
+ n = read(fdf, buf, sizeof buf);
if (n < 0)
return -errno;
if (n == 0) /* EOF */
@@ -132,6 +166,11 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
+ /* sendfile accepts at most SSIZE_MAX-offset bytes to copy,
+ * so reduce our maximum by the amount we already copied,
+ * but don't go below our copy buffer size, unless we are
+ * close the the limit of bytes we are allowed to copy. */
+ m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
}
return 0; /* return 0 if we hit EOF earlier than the size limit */
diff --git a/src/basic/log.h b/src/basic/log.h
index f9fb1742a1..b6356228d9 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -246,5 +246,4 @@ int log_syntax_internal(
log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \
"String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
} \
- -EINVAL; \
})
diff --git a/src/basic/macro.h b/src/basic/macro.h
index b36a95675a..e41aa4260f 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -27,7 +27,11 @@
#include <sys/types.h>
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
-#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#ifdef __clang__
+# define _alloc_(...)
+#else
+# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
+#endif
#define _sentinel_ __attribute__ ((sentinel))
#define _unused_ __attribute__ ((unused))
#define _destructor_ __attribute__ ((destructor))
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 417604aa64..034e334e66 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -135,84 +135,6 @@
#define SOL_SCTP 132
#endif
-#if !HAVE_DECL_PIVOT_ROOT
-static inline int pivot_root(const char *new_root, const char *put_old) {
- return syscall(SYS_pivot_root, new_root, put_old);
-}
-#endif
-
-#ifndef __NR_memfd_create
-# if defined __x86_64__
-# define __NR_memfd_create 319
-# elif defined __arm__
-# define __NR_memfd_create 385
-# elif defined __aarch64__
-# define __NR_memfd_create 279
-# elif defined __s390__
-# define __NR_memfd_create 350
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_memfd_create 4354
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_memfd_create 6318
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_memfd_create 5314
-# endif
-# elif defined __i386__
-# define __NR_memfd_create 356
-# else
-# warning "__NR_memfd_create unknown for your architecture"
-# define __NR_memfd_create 0xffffffff
-# endif
-#endif
-
-#if !HAVE_DECL_MEMFD_CREATE
-static inline int memfd_create(const char *name, unsigned int flags) {
- return syscall(__NR_memfd_create, name, flags);
-}
-#endif
-
-#ifndef __NR_getrandom
-# if defined __x86_64__
-# define __NR_getrandom 318
-# elif defined(__i386__)
-# define __NR_getrandom 355
-# elif defined(__arm__)
-# define __NR_getrandom 384
-# elif defined(__aarch64__)
-# define __NR_getrandom 278
-# elif defined(__ia64__)
-# define __NR_getrandom 1339
-# elif defined(__m68k__)
-# define __NR_getrandom 352
-# elif defined(__s390x__)
-# define __NR_getrandom 349
-# elif defined(__powerpc__)
-# define __NR_getrandom 359
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_getrandom 4353
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_getrandom 6317
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_getrandom 5313
-# endif
-# else
-# warning "__NR_getrandom unknown for your architecture"
-# define __NR_getrandom 0xffffffff
-# endif
-#endif
-
-#if !HAVE_DECL_GETRANDOM
-static inline int getrandom(void *buffer, size_t count, unsigned flags) {
- return syscall(__NR_getrandom, buffer, count, flags);
-}
-#endif
-
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK 0x0001
#endif
@@ -527,12 +449,6 @@ struct btrfs_ioctl_quota_ctl_args {
#define MS_PRIVATE (1 << 18)
#endif
-#if !HAVE_DECL_GETTID
-static inline pid_t gettid(void) {
- return (pid_t) syscall(SYS_gettid);
-}
-#endif
-
#ifndef SCM_SECURITY
#define SCM_SECURITY 0x03
#endif
@@ -561,32 +477,6 @@ static inline pid_t gettid(void) {
#define MAX_HANDLE_SZ 128
#endif
-#ifndef __NR_name_to_handle_at
-# if defined(__x86_64__)
-# define __NR_name_to_handle_at 303
-# elif defined(__i386__)
-# define __NR_name_to_handle_at 341
-# elif defined(__arm__)
-# define __NR_name_to_handle_at 370
-# elif defined(__powerpc__)
-# define __NR_name_to_handle_at 345
-# else
-# error "__NR_name_to_handle_at is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_NAME_TO_HANDLE_AT
-struct file_handle {
- unsigned int handle_bytes;
- int handle_type;
- unsigned char f_handle[0];
-};
-
-static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
- return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
-}
-#endif
-
#ifndef HAVE_SECURE_GETENV
# ifdef HAVE___SECURE_GETENV
# define secure_getenv __secure_getenv
@@ -635,22 +525,6 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle
#endif
-#ifndef __NR_setns
-# if defined(__x86_64__)
-# define __NR_setns 308
-# elif defined(__i386__)
-# define __NR_setns 346
-# else
-# error "__NR_setns is not defined"
-# endif
-#endif
-
-#if !HAVE_DECL_SETNS
-static inline int setns(int fd, int nstype) {
- return syscall(__NR_setns, fd, nstype);
-}
-#endif
-
#if !HAVE_DECL_LO_FLAGS_PARTSCAN
#define LO_FLAGS_PARTSCAN 8
#endif
@@ -1018,69 +892,10 @@ static inline int setns(int fd, int nstype) {
#define CAP_AUDIT_READ 37
#endif
-static inline int raw_clone(unsigned long flags, void *child_stack) {
-#if defined(__s390__) || defined(__CRIS__)
- /* On s390 and cris the order of the first and second arguments
- * of the raw clone() system call is reversed. */
- return (int) syscall(__NR_clone, child_stack, flags);
-#else
- return (int) syscall(__NR_clone, flags, child_stack);
-#endif
-}
-
-static inline pid_t raw_getpid(void) {
-#if defined(__alpha__)
- return (pid_t) syscall(__NR_getxpid);
-#else
- return (pid_t) syscall(__NR_getpid);
-#endif
-}
-
-#if !HAVE_DECL_RENAMEAT2
-
-#ifndef __NR_renameat2
-# if defined __x86_64__
-# define __NR_renameat2 316
-# elif defined __arm__
-# define __NR_renameat2 382
-# elif defined _MIPS_SIM
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-# define __NR_renameat2 4351
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR_renameat2 6315
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-# define __NR_renameat2 5311
-# endif
-# elif defined __i386__
-# define __NR_renameat2 353
-# else
-# warning "__NR_renameat2 unknown for your architecture"
-# define __NR_renameat2 0xffffffff
-# endif
-#endif
-
-static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
- return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
-}
-#endif
-
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
-#if !HAVE_DECL_KCMP
-static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
-#if defined(__NR_kcmp)
- return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KCMP_FILE
#define KCMP_FILE 0
#endif
@@ -1097,35 +912,6 @@ static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, uns
typedef int32_t key_serial_t;
#endif
-#if !HAVE_DECL_KEYCTL
-static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
-#if defined(__NR_keyctl)
- return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
-#if defined (__NR_add_key)
- return syscall(__NR_add_key, type, description, payload, plen, ringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
-#if defined (__NR_request_key)
- return syscall(__NR_request_key, type, description, callout_info, destringid);
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
-
#ifndef KEYCTL_READ
#define KEYCTL_READ 11
#endif
@@ -1177,3 +963,5 @@ static inline key_serial_t request_key(const char *type, const char *description
#endif
#endif
+
+#include "missing_syscall.h"
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
new file mode 100644
index 0000000000..d502d3b9ca
--- /dev/null
+++ b/src/basic/missing_syscall.h
@@ -0,0 +1,310 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ 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/>.
+***/
+
+/* Missing glibc definitions to access certain kernel APIs */
+
+#if !HAVE_DECL_PIVOT_ROOT
+static inline int pivot_root(const char *new_root, const char *put_old) {
+ return syscall(SYS_pivot_root, new_root, put_old);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_MEMFD_CREATE
+# ifndef __NR_memfd_create
+# if defined __x86_64__
+# define __NR_memfd_create 319
+# elif defined __arm__
+# define __NR_memfd_create 385
+# elif defined __aarch64__
+# define __NR_memfd_create 279
+# elif defined __s390__
+# define __NR_memfd_create 350
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_memfd_create 4354
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_memfd_create 6318
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_memfd_create 5314
+# endif
+# elif defined __i386__
+# define __NR_memfd_create 356
+# else
+# warning "__NR_memfd_create unknown for your architecture"
+# endif
+# endif
+
+static inline int memfd_create(const char *name, unsigned int flags) {
+# ifdef __NR_memfd_create
+ return syscall(__NR_memfd_create, name, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETRANDOM
+# ifndef __NR_getrandom
+# if defined __x86_64__
+# define __NR_getrandom 318
+# elif defined(__i386__)
+# define __NR_getrandom 355
+# elif defined(__arm__)
+# define __NR_getrandom 384
+# elif defined(__aarch64__)
+# define __NR_getrandom 278
+# elif defined(__ia64__)
+# define __NR_getrandom 1339
+# elif defined(__m68k__)
+# define __NR_getrandom 352
+# elif defined(__s390x__)
+# define __NR_getrandom 349
+# elif defined(__powerpc__)
+# define __NR_getrandom 359
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_getrandom 4353
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_getrandom 6317
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_getrandom 5313
+# endif
+# else
+# warning "__NR_getrandom unknown for your architecture"
+# endif
+# endif
+
+static inline int getrandom(void *buffer, size_t count, unsigned flags) {
+# ifdef __NR_getrandom
+ return syscall(__NR_getrandom, buffer, count, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_GETTID
+static inline pid_t gettid(void) {
+ return (pid_t) syscall(SYS_gettid);
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_NAME_TO_HANDLE_AT
+# ifndef __NR_name_to_handle_at
+# if defined(__x86_64__)
+# define __NR_name_to_handle_at 303
+# elif defined(__i386__)
+# define __NR_name_to_handle_at 341
+# elif defined(__arm__)
+# define __NR_name_to_handle_at 370
+# elif defined(__powerpc__)
+# define __NR_name_to_handle_at 345
+# else
+# error "__NR_name_to_handle_at is not defined"
+# endif
+# endif
+
+struct file_handle {
+ unsigned int handle_bytes;
+ int handle_type;
+ unsigned char f_handle[0];
+};
+
+static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) {
+# ifdef __NR_name_to_handle_at
+ return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_SETNS
+# ifndef __NR_setns
+# if defined(__x86_64__)
+# define __NR_setns 308
+# elif defined(__i386__)
+# define __NR_setns 346
+# else
+# error "__NR_setns is not defined"
+# endif
+# endif
+
+static inline int setns(int fd, int nstype) {
+# ifdef __NR_setns
+ return syscall(__NR_setns, fd, nstype);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+static inline int raw_clone(unsigned long flags, void *child_stack) {
+#if defined(__s390__) || defined(__CRIS__)
+ /* On s390 and cris the order of the first and second arguments
+ * of the raw clone() system call is reversed. */
+ return (int) syscall(__NR_clone, child_stack, flags);
+#else
+ return (int) syscall(__NR_clone, flags, child_stack);
+#endif
+}
+
+/* ======================================================================= */
+
+static inline pid_t raw_getpid(void) {
+#if defined(__alpha__)
+ return (pid_t) syscall(__NR_getxpid);
+#else
+ return (pid_t) syscall(__NR_getpid);
+#endif
+}
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_RENAMEAT2
+# ifndef __NR_renameat2
+# if defined __x86_64__
+# define __NR_renameat2 316
+# elif defined __arm__
+# define __NR_renameat2 382
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_renameat2 4351
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_renameat2 6315
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_renameat2 5311
+# endif
+# elif defined __i386__
+# define __NR_renameat2 353
+# else
+# warning "__NR_renameat2 unknown for your architecture"
+# endif
+# endif
+
+static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
+# ifdef __NR_renameat2
+ return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KCMP
+static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
+# ifdef __NR_kcmp
+ return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_KEYCTL
+static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) {
+# ifdef __NR_keyctl
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
+# ifdef __NR_add_key
+ return syscall(__NR_add_key, type, description, payload, plen, ringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+
+static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) {
+# ifdef __NR_request_key
+ return syscall(__NR_request_key, type, description, callout_info, destringid);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
+
+/* ======================================================================= */
+
+#if !HAVE_DECL_COPY_FILE_RANGE
+# ifndef __NR_copy_file_range
+# if defined(__x86_64__)
+# define __NR_copy_file_range 326
+# elif defined(__i386__)
+# define __NR_copy_file_range 377
+# elif defined __s390__
+# define __NR_copy_file_range 375
+# elif defined __arm__
+# define __NR_copy_file_range 391
+# elif defined __aarch64__
+# define __NR_copy_file_range 285
+# else
+# warning "__NR_copy_file_range not defined for your architecture"
+# endif
+# endif
+
+static inline ssize_t copy_file_range(int fd_in, loff_t *off_in,
+ int fd_out, loff_t *off_out,
+ size_t len,
+ unsigned int flags) {
+# ifdef __NR_copy_file_range
+ return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
+# else
+ errno = ENOSYS;
+ return -1;
+# endif
+}
+#endif
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index 5e6181f662..10c2f39369 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -152,7 +152,7 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
return 0;
if (r >= 0) {
- r = lsetfilecon(path, fcon);
+ r = lsetfilecon_raw(path, fcon);
/* If the FS doesn't support labels, then exit without warning */
if (r < 0 && errno == EOPNOTSUPP)
@@ -262,7 +262,7 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
if (r < 0)
return -errno;
- r = getpeercon(socket_fd, &peercon);
+ r = getpeercon_raw(socket_fd, &peercon);
if (r < 0)
return -errno;
@@ -371,7 +371,7 @@ void mac_selinux_create_file_clear(void) {
if (!mac_selinux_use())
return;
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
#endif
}
@@ -402,7 +402,7 @@ void mac_selinux_create_socket_clear(void) {
if (!mac_selinux_use())
return;
- setsockcreatecon(NULL);
+ setsockcreatecon_raw(NULL);
#endif
}
@@ -461,7 +461,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
return -errno;
} else {
- if (setfscreatecon(fcon) < 0) {
+ if (setfscreatecon_raw(fcon) < 0) {
log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
if (security_getenforce() > 0)
return -errno;
@@ -472,7 +472,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
if (context_changed)
- setfscreatecon(NULL);
+ setfscreatecon_raw(NULL);
return r;
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index 7ca764abeb..c16460a198 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -47,12 +47,15 @@ static clockid_t map_clock_id(clockid_t c) {
/* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will
* fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is
* when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on
- * those archs. */
+ * those archs.
+ *
+ * Also, older kernels don't support CLOCK_BOOTTIME: fall back to CLOCK_MONOTONIC. */
switch (c) {
+ case CLOCK_BOOTTIME:
case CLOCK_BOOTTIME_ALARM:
- return CLOCK_BOOTTIME;
+ return clock_boottime_or_monotonic ();
case CLOCK_REALTIME_ALARM:
return CLOCK_REALTIME;
diff --git a/src/core/execute.c b/src/core/execute.c
index 517c2fb45b..ac2ac39892 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -24,6 +24,7 @@
#include <poll.h>
#include <signal.h>
#include <string.h>
+#include <sys/capability.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/socket.h>
@@ -1824,6 +1825,11 @@ static int exec_child(
if (params->apply_permissions) {
+ bool use_address_families = context->address_families_whitelist ||
+ !set_isempty(context->address_families);
+ bool use_syscall_filter = context->syscall_whitelist ||
+ !set_isempty(context->syscall_filter) ||
+ !set_isempty(context->syscall_archs);
int secure_bits = context->secure_bits;
for (i = 0; i < _RLIMIT_MAX; i++) {
@@ -1890,15 +1896,15 @@ static int exec_child(
return -errno;
}
- if (context->no_new_privileges)
+ if (context->no_new_privileges ||
+ (!have_effective_cap(CAP_SYS_ADMIN) && (use_address_families || use_syscall_filter)))
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
*exit_status = EXIT_NO_NEW_PRIVILEGES;
return -errno;
}
#ifdef HAVE_SECCOMP
- if (context->address_families_whitelist ||
- !set_isempty(context->address_families)) {
+ if (use_address_families) {
r = apply_address_families(context);
if (r < 0) {
*exit_status = EXIT_ADDRESS_FAMILIES;
@@ -1906,9 +1912,7 @@ static int exec_child(
}
}
- if (context->syscall_whitelist ||
- !set_isempty(context->syscall_filter) ||
- !set_isempty(context->syscall_archs)) {
+ if (use_syscall_filter) {
r = apply_seccomp(context);
if (r < 0) {
*exit_status = EXIT_SECCOMP;
diff --git a/src/core/job.c b/src/core/job.c
index 012cf72d1f..719cb0a3e5 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -690,17 +690,20 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR
}
static void job_print_status_message(Unit *u, JobType t, JobResult result) {
- static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
- [JOB_DONE] = ANSI_GREEN " OK " ANSI_NORMAL,
- [JOB_TIMEOUT] = ANSI_HIGHLIGHT_RED " TIME " ANSI_NORMAL,
- [JOB_FAILED] = ANSI_HIGHLIGHT_RED "FAILED" ANSI_NORMAL,
- [JOB_DEPENDENCY] = ANSI_HIGHLIGHT_YELLOW "DEPEND" ANSI_NORMAL,
- [JOB_SKIPPED] = ANSI_HIGHLIGHT " INFO " ANSI_NORMAL,
- [JOB_ASSERT] = ANSI_HIGHLIGHT_YELLOW "ASSERT" ANSI_NORMAL,
- [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW "UNSUPP" ANSI_NORMAL,
+ static struct {
+ const char *color, *word;
+ } const statuses[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = {ANSI_GREEN, " OK "},
+ [JOB_TIMEOUT] = {ANSI_HIGHLIGHT_RED, " TIME "},
+ [JOB_FAILED] = {ANSI_HIGHLIGHT_RED, "FAILED"},
+ [JOB_DEPENDENCY] = {ANSI_HIGHLIGHT_YELLOW, "DEPEND"},
+ [JOB_SKIPPED] = {ANSI_HIGHLIGHT, " INFO "},
+ [JOB_ASSERT] = {ANSI_HIGHLIGHT_YELLOW, "ASSERT"},
+ [JOB_UNSUPPORTED] = {ANSI_HIGHLIGHT_YELLOW, "UNSUPP"},
};
const char *format;
+ const char *status;
assert(u);
assert(t >= 0);
@@ -714,11 +717,16 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
if (!format)
return;
+ if (log_get_show_color())
+ status = strjoina(statuses[result].color, statuses[result].word, ANSI_NORMAL);
+ else
+ status = statuses[result].word;
+
if (result != JOB_DONE)
manager_flip_auto_status(u->manager, true);
DISABLE_WARNING_FORMAT_NONLITERAL;
- unit_status_printf(u, job_result_status_table[result], format);
+ unit_status_printf(u, status, format);
REENABLE_WARNING;
if (t == JOB_START && result == JOB_FAILED) {
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index e1bfdccbca..d078924c5b 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -3507,7 +3507,19 @@ static int merge_by_names(Unit **u, Set *names, const char *id) {
* ours? Then let's try it the other way
* round */
- other = manager_get_unit((*u)->manager, k);
+ /* If the symlink name we are looking at is unit template, then
+ we must search for instance of this template */
+ if (unit_name_is_valid(k, UNIT_NAME_TEMPLATE)) {
+ _cleanup_free_ char *instance = NULL;
+
+ r = unit_name_replace_instance(k, (*u)->instance, &instance);
+ if (r < 0)
+ return r;
+
+ other = manager_get_unit((*u)->manager, instance);
+ } else
+ other = manager_get_unit((*u)->manager, k);
+
free(k);
if (other) {
diff --git a/src/core/main.c b/src/core/main.c
index 1783b9c7af..78701805ea 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1218,10 +1218,15 @@ static int status_welcome(void) {
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read os-release file: %m");
- return status_printf(NULL, false, false,
- "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
- isempty(ansi_color) ? "1" : ansi_color,
- isempty(pretty_name) ? "Linux" : pretty_name);
+ if (log_get_show_color())
+ return status_printf(NULL, false, false,
+ "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+ isempty(ansi_color) ? "1" : ansi_color,
+ isempty(pretty_name) ? "Linux" : pretty_name);
+ else
+ return status_printf(NULL, false, false,
+ "\nWelcome to %s!\n",
+ isempty(pretty_name) ? "Linux" : pretty_name);
}
static int write_container_id(void) {
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
index 9a115a4387..4072df58e6 100644
--- a/src/core/selinux-setup.c
+++ b/src/core/selinux-setup.c
@@ -88,7 +88,7 @@ int mac_selinux_setup(bool *loaded_policy) {
log_open();
log_error("Failed to compute init label, ignoring.");
} else {
- r = setcon(label);
+ r = setcon_raw(label);
log_open();
if (r < 0)
diff --git a/src/core/transaction.c b/src/core/transaction.c
index b28fc76785..c894001cf9 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -391,6 +391,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
if (delete) {
+ const char *status;
/* logging for j not k here here to provide consistent narrative */
log_unit_warning(j->unit,
"Breaking ordering cycle by deleting job %s/%s",
@@ -399,7 +400,13 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
"Job %s/%s deleted to break ordering cycle starting with %s/%s",
delete->unit->id, job_type_to_string(delete->type),
j->unit->id, job_type_to_string(j->type));
- unit_status_printf(delete->unit, ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL,
+
+ if (log_get_show_color())
+ status = ANSI_HIGHLIGHT_RED " SKIP " ANSI_NORMAL;
+ else
+ status = " SKIP ";
+
+ unit_status_printf(delete->unit, status,
"Ordering cycle found, skipping %s");
transaction_delete_unit(tr, delete->unit);
return -EAGAIN;
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 1bef368852..1d9ec7be82 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -43,7 +43,7 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
if (r < 0)
return r;
- unaligned_write_be16(&duid->type, DHCP_DUID_TYPE_EN);
+ unaligned_write_be16(&duid->type, DHCP6_DUID_EN);
unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
*len = sizeof(duid->type) + sizeof(duid->en);
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index cb953cb416..93f06f5938 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -25,23 +25,13 @@
#include "sparse-endian.h"
#include "unaligned.h"
-typedef enum DHCPDUIDType {
- DHCP_DUID_TYPE_RAW = 0,
- DHCP_DUID_TYPE_LLT = 1,
- DHCP_DUID_TYPE_EN = 2,
- DHCP_DUID_TYPE_LL = 3,
- DHCP_DUID_TYPE_UUID = 4,
- _DHCP_DUID_TYPE_MAX,
- _DHCP_DUID_TYPE_INVALID = -1,
-} DHCPDUIDType;
-
/* RFC 3315 section 9.1:
* A DUID can be no more than 128 octets long (not including the type code).
*/
#define MAX_DUID_LEN 128
struct duid {
- be16_t type;
+ uint16_t type;
union {
struct {
/* DHCP6_DUID_LLT */
@@ -71,32 +61,3 @@ struct duid {
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
-
-static inline int dhcp_validate_duid_len(be16_t duid_type, size_t duid_len) {
- struct duid d;
-
- assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
-
- switch (be16toh(duid_type)) {
- case DHCP_DUID_TYPE_LLT:
- if (duid_len <= sizeof(d.llt))
- return -EINVAL;
- break;
- case DHCP_DUID_TYPE_EN:
- if (duid_len != sizeof(d.en))
- return -EINVAL;
- break;
- case DHCP_DUID_TYPE_LL:
- if (duid_len <= sizeof(d.ll))
- return -EINVAL;
- break;
- case DHCP_DUID_TYPE_UUID:
- if (duid_len != sizeof(d.uuid))
- return -EINVAL;
- break;
- default:
- /* accept unknown type in order to be forward compatible */
- break;
- }
- return 0;
-}
diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h
index 2487c470ab..ee4bdfb07f 100644
--- a/src/libsystemd-network/dhcp6-protocol.h
+++ b/src/libsystemd-network/dhcp6-protocol.h
@@ -62,6 +62,13 @@ enum {
#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC
#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC
+enum {
+ DHCP6_DUID_LLT = 1,
+ DHCP6_DUID_EN = 2,
+ DHCP6_DUID_LL = 3,
+ DHCP6_DUID_UUID = 4,
+};
+
enum DHCP6State {
DHCP6_STATE_STOPPED = 0,
DHCP6_STATE_INFORMATION_REQUEST = 1,
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 7c21f42591..cb7252bbeb 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -335,34 +335,6 @@ int config_parse_hwaddr(const char *unit,
return 0;
}
-int config_parse_iaid_value(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
- uint32_t iaid_value;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if ((r = safe_atou32(rvalue, &iaid_value)) < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue);
- return r;
- }
-
- *((be32_t *)data) = htobe32(iaid_value);
-
- return 0;
-}
-
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index d8b551e8ce..c8a531ab0f 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -62,10 +62,6 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_iaid_value(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index b108e35386..1188b31500 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -82,7 +82,7 @@ struct sd_dhcp_client {
} _packed_ ll;
struct {
/* 255: Node-specific (RFC 4361) */
- be32_t iaid;
+ uint32_t iaid;
struct duid duid;
} _packed_ ns;
struct {
@@ -298,51 +298,6 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
return 0;
}
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, be32_t iaid,
- size_t duid_len, struct duid *duid) {
- DHCP_CLIENT_DONT_DESTROY(client);
- int r;
- assert_return(client, -EINVAL);
- zero(client->client_id);
-
- client->client_id.type = 255;
-
- /* If IAID is not configured, generate it. */
- if (iaid == 0) {
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr,
- client->mac_addr_len,
- &client->client_id.ns.iaid);
- if (r < 0)
- return r;
- } else
- client->client_id.ns.iaid = iaid;
-
- /* If DUID is not configured, generate DUID-EN. */
- if (duid_len == 0) {
- r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid,
- &duid_len);
- if (r < 0)
- return r;
- } else {
- r = dhcp_validate_duid_len(client->client_id.type,
- duid_len - sizeof(client->client_id.type));
- if (r < 0)
- return r;
- memcpy(&client->client_id.ns.duid, duid, duid_len);
- }
-
- client->client_id_len = sizeof(client->client_id.type) + duid_len +
- sizeof(client->client_id.ns.iaid);
-
- if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
- log_dhcp_client(client, "Configured IAID+DUID, restarting.");
- client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
- sd_dhcp_client_start(client);
- }
-
- return 0;
-}
-
int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
const char *hostname) {
char *new_hostname = NULL;
@@ -514,6 +469,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
if (client->arp_type == ARPHRD_ETHER)
memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
+ /* If no client identifier exists, construct an RFC 4361-compliant one */
if (client->client_id_len == 0) {
size_t duid_len;
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 7cecba120c..af4709d788 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -180,30 +180,41 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, size_t duid_len,
- struct duid *duid) {
- int r;
+int sd_dhcp6_client_set_duid(
+ sd_dhcp6_client *client,
+ uint16_t type,
+ uint8_t *duid, size_t duid_len) {
assert_return(client, -EINVAL);
- assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+ assert_return(duid, -EINVAL);
+ assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
- if (duid_len > 0) {
- r = dhcp_validate_duid_len(duid->type,
- duid_len - sizeof(duid->type));
- if (r < 0)
- return r;
+ assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
- memcpy(&client->duid, duid, duid_len);
- client->duid_len = duid_len;
+ switch (type) {
+ case DHCP6_DUID_LLT:
+ if (duid_len <= sizeof(client->duid.llt))
+ return -EINVAL;
+ break;
+ case DHCP6_DUID_EN:
+ if (duid_len != sizeof(client->duid.en))
+ return -EINVAL;
+ break;
+ case DHCP6_DUID_LL:
+ if (duid_len <= sizeof(client->duid.ll))
+ return -EINVAL;
+ break;
+ case DHCP6_DUID_UUID:
+ if (duid_len != sizeof(client->duid.uuid))
+ return -EINVAL;
+ break;
+ default:
+ /* accept unknown type in order to be forward compatible */
+ break;
}
- return 0;
-}
-
-int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, be32_t iaid) {
- assert_return(client, -EINVAL);
- assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
-
- client->ia_na.id = iaid;
+ client->duid.type = htobe16(type);
+ memcpy(&client->duid.raw.data, duid, duid_len);
+ client->duid_len = duid_len + sizeof(client->duid.type);
return 0;
}
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index d0743cf3e2..9d4587c80e 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -112,6 +112,8 @@ static bool lldp_keep_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
return true;
}
+static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor);
+
static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
_cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *old = NULL;
bool keep;
@@ -136,7 +138,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
if (lldp_neighbor_equal(n, old)) {
/* Is this equal, then restart the TTL counter, but don't do anyting else. */
- lldp_neighbor_start_ttl(old);
+ lldp_start_timer(lldp, old);
lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
return 0;
}
@@ -162,7 +164,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
n->lldp = lldp;
- lldp_neighbor_start_ttl(n);
+ lldp_start_timer(lldp, n);
lldp_callback(lldp, old ? SD_LLDP_EVENT_UPDATED : SD_LLDP_EVENT_ADDED, n);
return 1;
@@ -368,8 +370,6 @@ static int neighbor_compare_func(const void *a, const void *b) {
return lldp_neighbor_id_hash_ops.compare(&(*x)->id, &(*y)->id);
}
-static int lldp_start_timer(sd_lldp *lldp);
-
static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
sd_lldp *lldp = userdata;
int r, q;
@@ -378,19 +378,22 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) {
if (r < 0)
return log_lldp_errno(r, "Failed to make space: %m");
- q = lldp_start_timer(lldp);
+ q = lldp_start_timer(lldp, NULL);
if (q < 0)
return log_lldp_errno(q, "Failed to restart timer: %m");
return 0;
}
-static int lldp_start_timer(sd_lldp *lldp) {
+static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
sd_lldp_neighbor *n;
int r;
assert(lldp);
+ if (neighbor)
+ lldp_neighbor_start_ttl(neighbor);
+
n = prioq_peek(lldp->neighbor_by_expiry);
if (!n) {
@@ -440,7 +443,7 @@ _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
if (!l)
return -ENOMEM;
- r = lldp_start_timer(lldp);
+ r = lldp_start_timer(lldp, NULL);
if (r < 0) {
free(l);
return r;
diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules
index 50dcd2e275..886c5bfcdf 100644
--- a/src/login/70-uaccess.rules
+++ b/src/login/70-uaccess.rules
@@ -42,8 +42,9 @@ SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", TAG+="uaccess"
SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="uaccess"
SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="uaccess"
-# DRI video devices
+# DRI and frame buffer video devices
SUBSYSTEM=="drm", KERNEL=="card*|renderD*", TAG+="uaccess"
+SUBSYSTEM=="graphics", KERNEL=="fb*", TAG+="uaccess"
# KVM
SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess"
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
deleted file mode 100644
index 4bc92b8171..0000000000
--- a/src/network/networkd-conf.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Tom Gundersen <teg@jklm.no>
-
- 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 <ctype.h>
-
-#include "conf-parser.h"
-#include "def.h"
-#include "dhcp-identifier.h"
-#include "networkd-conf.h"
-#include "string-table.h"
-
-int manager_parse_config_file(Manager *m) {
- assert(m);
-
- return config_parse_many(PKGSYSCONFDIR "/networkd.conf",
- CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
- "DUID\0",
- config_item_perf_lookup, networkd_gperf_lookup,
- false, m);
-}
-
-static const char* const dhcp_duid_type_table[_DHCP_DUID_TYPE_MAX] = {
- [DHCP_DUID_TYPE_RAW] = "raw",
- [DHCP_DUID_TYPE_LLT] = "link-layer-time",
- [DHCP_DUID_TYPE_EN] = "vendor",
- [DHCP_DUID_TYPE_LL] = "link-layer",
- [DHCP_DUID_TYPE_UUID] = "uuid"
-};
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_duid_type, DHCPDUIDType);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_duid_type, dhcp_duid_type, DHCPDUIDType, "Failed to parse DHCP DUID type");
-
-int config_parse_dhcp_duid_raw(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
- int r;
- long byte;
- char *cbyte, *pnext;
- const char *pduid = (const char *)rvalue;
- size_t count = 0, duid_len = 0;
- Manager *m = userdata;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(m);
- assert(m->dhcp_duid_type != _DHCP_DUID_TYPE_INVALID);
-
- switch (m->dhcp_duid_type) {
- case DHCP_DUID_TYPE_LLT:
- /* RawData contains DUID-LLT link-layer address (offset 6) */
- duid_len = 6;
- break;
- case DHCP_DUID_TYPE_EN:
- /* RawData contains DUID-EN identifier (offset 4) */
- duid_len = 4;
- break;
- case DHCP_DUID_TYPE_LL:
- /* RawData contains DUID-LL link-layer address (offset 2) */
- duid_len = 2;
- break;
- case DHCP_DUID_TYPE_UUID:
- /* RawData specifies UUID (offset 0) - fall thru */
- case DHCP_DUID_TYPE_RAW:
- /* First two bytes of RawData is DUID Type - fall thru */
- default:
- break;
- }
-
- if (m->dhcp_duid_type != DHCP_DUID_TYPE_RAW)
- m->dhcp_duid.type = htobe16(m->dhcp_duid_type);
-
- /* RawData contains DUID in format " NN:NN:NN... " */
- while (true) {
- r = extract_first_word(&pduid, &cbyte, ":", 0);
- if (r < 0) {
- log_error("Failed to read DUID.");
- return -EINVAL;
- }
- if (r == 0)
- break;
- if (duid_len >= MAX_DUID_LEN) {
- log_error("DUID length exceeds maximum length.");
- return -EINVAL;
- }
-
- errno = 0;
- byte = strtol(cbyte, &pnext, 16);
- if ((errno == ERANGE && (byte == LONG_MAX || byte == LONG_MIN))
- || (errno != 0 && byte == 0) || (cbyte == pnext)) {
- log_error("Invalid DUID byte: %s.", cbyte);
- return -EINVAL;
- }
-
- /* If DHCP_DUID_TYPE_RAW, first two bytes holds DUID Type */
- if ((m->dhcp_duid_type == DHCP_DUID_TYPE_RAW) && (count < 2)) {
- m->dhcp_duid.type |= (byte << (8 * count));
- count++;
- continue;
- }
-
- m->dhcp_duid.raw.data[duid_len++] = byte;
- }
-
- m->dhcp_duid_len = sizeof(m->dhcp_duid.type) + duid_len;
-
- return 0;
-}
diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h
deleted file mode 100644
index 6d9ce010e3..0000000000
--- a/src/network/networkd-conf.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Tom Gundersen <teg@jklm.no>
-
- 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 "networkd.h"
-
-
-int manager_parse_config_file(Manager *m);
-
-const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, unsigned length);
-
-int config_parse_dhcp_duid_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_dhcp_duid_raw(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 3bbb21295c..68998eabf2 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -625,13 +625,7 @@ int dhcp4_configure(Link *link) {
switch (link->network->dhcp_client_identifier) {
case DHCP_CLIENT_ID_DUID:
- /* If configured, apply user specified DUID and/or IAID */
- r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
- link->network->iaid_value,
- link->manager->dhcp_duid_len,
- &link->manager->dhcp_duid);
- if (r < 0)
- return r;
+ /* Library defaults to this. */
break;
case DHCP_CLIENT_ID_MAC:
r = sd_dhcp_client_set_client_id(link->dhcp_client,
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 9f59cb3f8a..5f7a005c36 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -230,16 +230,6 @@ int dhcp6_configure(Link *link) {
if (r < 0)
goto error;
- r = sd_dhcp6_client_set_iaid(client, link->network->iaid_value);
- if (r < 0)
- goto error;
-
- r = sd_dhcp6_client_set_duid(client,
- link->manager->dhcp_duid_len,
- &link->manager->dhcp_duid);
- if (r < 0)
- goto error;
-
r = sd_dhcp6_client_set_index(client, link->ifindex);
if (r < 0)
goto error;
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
deleted file mode 100644
index 3ef4155476..0000000000
--- a/src/network/networkd-gperf.gperf
+++ /dev/null
@@ -1,18 +0,0 @@
-%{
-#include <stddef.h>
-#include "conf-parser.h"
-#include "networkd-conf.h"
-%}
-struct ConfigPerfItem;
-%null_strings
-%language=ANSI-C
-%define slot-name section_and_lvalue
-%define hash-function-name networkd_gperf_hash
-%define lookup-function-name networkd_gperf_lookup
-%readonly-tables
-%omit-struct-type
-%struct-type
-%includes
-%%
-DUID.Type, config_parse_dhcp_duid_type, 0, offsetof(Manager, dhcp_duid_type)
-DUID.RawData, config_parse_dhcp_duid_raw, 0, offsetof(Manager, dhcp_duid)
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 67b04560cd..ff4bd76554 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2781,13 +2781,6 @@ int link_update(Link *link, sd_netlink_message *m) {
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
-
- r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
- link->network->iaid_value,
- link->manager->dhcp_duid_len,
- &link->manager->dhcp_duid);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
}
if (link->dhcp6_client) {
@@ -2797,17 +2790,6 @@ int link_update(Link *link, sd_netlink_message *m) {
ARPHRD_ETHER);
if (r < 0)
return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
-
- r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
- link->network->iaid_value);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
-
- r = sd_dhcp6_client_set_duid(link->dhcp6_client,
- link->manager->dhcp_duid_len,
- &link->manager->dhcp_duid);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
}
}
}
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 8d443f7b0f..b8cb7f875d 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -1037,8 +1037,6 @@ int manager_new(Manager **ret) {
if (r < 0)
return r;
- m->dhcp_duid_type = _DHCP_DUID_TYPE_INVALID;
-
*ret = m;
m = NULL;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 7a9a136d5b..a5d1714293 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -26,7 +26,6 @@ Match.KernelCommandLine, config_parse_net_condition,
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu)
-Link.IAIDValue, config_parse_iaid_value, 0, offsetof(Network, iaid_value)
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge)
Network.Bond, config_parse_netdev, 0, offsetof(Network, bond)
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index c5530cdfba..4a13e2b574 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -30,7 +30,6 @@ typedef struct Network Network;
#include "networkd-route.h"
#include "networkd-util.h"
#include "networkd.h"
-#include "sparse-endian.h"
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
@@ -145,7 +144,6 @@ struct Network {
struct ether_addr *mac;
unsigned mtu;
- be32_t iaid_value;
LLDPMode lldp_mode; /* LLDP reception */
bool lldp_emit; /* LLDP transmission */
diff --git a/src/network/networkd.c b/src/network/networkd.c
index c8f81a2ca6..3a2615e6fd 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -21,7 +21,6 @@
#include "capability-util.h"
#include "networkd.h"
-#include "networkd-conf.h"
#include "signal-util.h"
#include "user-util.h"
@@ -90,10 +89,6 @@ int main(int argc, char *argv[]) {
goto out;
}
- r = manager_parse_config_file(m);
- if (r < 0)
- log_warning_errno(r, "Failed to parse configuration file: %m");
-
r = manager_load_config(m);
if (r < 0) {
log_error_errno(r, "Could not load configuration files: %m");
diff --git a/src/network/networkd.h b/src/network/networkd.h
index d815f30610..6bdd8302a0 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -35,7 +35,6 @@ typedef struct Manager Manager;
#include "networkd-link.h"
#include "networkd-network.h"
#include "networkd-util.h"
-#include "dhcp-identifier.h"
struct Manager {
sd_netlink *rtnl;
@@ -62,10 +61,6 @@ struct Manager {
LIST_HEAD(AddressPool, address_pools);
usec_t network_dirs_ts_usec;
-
- DHCPDUIDType dhcp_duid_type;
- size_t dhcp_duid_len;
- struct duid dhcp_duid;
};
extern const char* const network_dirs[];
diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c
index 1db5ba7116..9f9a4759d1 100644
--- a/src/nspawn/nspawn-cgroup.c
+++ b/src/nspawn/nspawn-cgroup.c
@@ -73,7 +73,7 @@ int sync_cgroup(pid_t pid, bool unified_requested) {
unified = cg_unified();
if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierachy is used: %m");
+ return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
if ((unified > 0) == unified_requested)
return 0;
@@ -135,7 +135,7 @@ int create_subcgroup(pid_t pid, bool unified_requested) {
unified = cg_unified();
if (unified < 0)
- return log_error_errno(unified, "Failed to determine whether the unified hierachy is used: %m");
+ return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
if (unified == 0)
return 0;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index be07625a03..eb89916b7e 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -977,6 +977,13 @@ static int verify_arguments(void) {
return -EINVAL;
}
+#ifndef HAVE_LIBIPTC
+ if (arg_expose_ports) {
+ log_error("--port= is not supported, compiled without libiptc support.");
+ return -EOPNOTSUPP;
+ }
+#endif
+
if (arg_start_mode == START_BOOT && arg_kill_signal <= 0)
arg_kill_signal = SIGRTMIN+3;
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 7873cb1e04..ef45370505 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -27,7 +27,6 @@
#include "sd-dhcp-lease.h"
#include "sd-event.h"
-#include "sparse-endian.h"
#include "_sd-common.h"
@@ -83,7 +82,6 @@ enum {
SD_DHCP_OPTION_END = 255,
};
-struct duid;
typedef struct sd_dhcp_client sd_dhcp_client;
typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event,
@@ -100,8 +98,6 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type);
int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
const uint8_t *data, size_t data_len);
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, be32_t iaid,
- size_t duid_len, struct duid *duid);
int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
const uint8_t **data, size_t *data_len);
int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
index ebdd017628..1bedc941aa 100644
--- a/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/sd-dhcp6-client.h
@@ -26,7 +26,6 @@
#include "sd-dhcp6-lease.h"
#include "sd-event.h"
-#include "sparse-endian.h"
#include "_sd-common.h"
@@ -75,7 +74,6 @@ enum {
/* option codes 144-65535 are unassigned */
};
-struct duid;
typedef struct sd_dhcp6_client sd_dhcp6_client;
typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event,
@@ -87,9 +85,8 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, size_t duid_len,
- struct duid *duid);
-int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, be32_t iaid);
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
+ size_t duid_len);
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index ad57cb0202..cb437754b4 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -24,6 +24,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
+#include "log.h"
#include "macro.h"
#include "mkdir.h"
#include "path-util.h"
@@ -39,6 +40,8 @@ static void test_copy_file(void) {
size_t sz = 0;
int fd;
+ log_info("%s", __func__);
+
fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
close(fd);
@@ -66,6 +69,8 @@ static void test_copy_file_fd(void) {
char text[] = "boohoo\nfoo\n\tbar\n";
char buf[64] = {0};
+ log_info("%s", __func__);
+
in_fd = mkostemp_safe(in_fn, O_RDWR);
assert_se(in_fd >= 0);
out_fd = mkostemp_safe(out_fn, O_RDWR);
@@ -91,6 +96,8 @@ static void test_copy_tree(void) {
"link2", "dir1/file");
char **p, **link;
+ log_info("%s", __func__);
+
(void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
(void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -173,11 +180,65 @@ static void test_copy_bytes(void) {
assert_se(r == -EBADF);
}
+static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint64_t max_bytes) {
+ char fn2[] = "/tmp/test-copy-file-XXXXXX";
+ char fn3[] = "/tmp/test-copy-file-XXXXXX";
+ _cleanup_close_ int fd = -1, fd2 = -1, fd3 = -1;
+ int r;
+ struct stat buf, buf2, buf3;
+
+ log_info("%s try_reflink=%s max_bytes=%" PRIu64, __func__, yes_no(try_reflink), max_bytes);
+
+ fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+ assert_se(fd >= 0);
+
+ fd2 = mkostemp_safe(fn2, O_RDWR);
+ assert_se(fd2 >= 0);
+
+ fd3 = mkostemp_safe(fn3, O_WRONLY);
+ assert_se(fd3 >= 0);
+
+ r = copy_bytes(fd, fd2, max_bytes, try_reflink);
+ if (max_bytes == (uint64_t) -1)
+ assert_se(r == 0);
+ else
+ assert_se(IN_SET(r, 0, 1));
+
+ assert_se(lseek(fd2, 0, SEEK_SET) == 0);
+
+ r = copy_bytes(fd2, fd3, max_bytes, try_reflink);
+ if (max_bytes == (uint64_t) -1)
+ assert_se(r == 0);
+ else
+ /* We cannot distinguish between the input being exactly max_bytes
+ * or longer than max_bytes (without trying to read one more byte,
+ * or calling stat, or FION_READ, etc, and we don't want to do any
+ * of that). So we expect "truncation" since we know that file we
+ * are copying is exactly max_bytes bytes. */
+ assert_se(r == 1);
+
+ assert_se(fstat(fd, &buf) == 0);
+ assert_se(fstat(fd2, &buf2) == 0);
+ assert_se(fstat(fd3, &buf3) == 0);
+
+ assert_se((uint64_t) buf2.st_size == MIN((uint64_t) buf.st_size, max_bytes));
+ assert_se(buf3.st_size == buf2.st_size);
+
+ unlink(fn2);
+ unlink(fn3);
+}
+
int main(int argc, char *argv[]) {
test_copy_file();
test_copy_file_fd();
test_copy_tree();
test_copy_bytes();
+ test_copy_bytes_regular_file(argv[0], false, (uint64_t) -1);
+ test_copy_bytes_regular_file(argv[0], true, (uint64_t) -1);
+ test_copy_bytes_regular_file(argv[0], false, 1000); /* smaller than copy buffer size */
+ test_copy_bytes_regular_file(argv[0], true, 1000);
+ test_copy_bytes_regular_file(argv[0], false, 32000); /* larger than copy buffer size */
+ test_copy_bytes_regular_file(argv[0], true, 32000);
return 0;
}
diff --git a/src/test/test-env-replace.c b/src/test/test-env-util.c
index 264acc6ea6..35bb62906e 100644
--- a/src/test/test-env-replace.c
+++ b/src/test/test-env-util.c
@@ -2,6 +2,7 @@
This file is part of systemd.
Copyright 2010 Lennart Poettering
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
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
@@ -177,10 +178,37 @@ static void test_env_name_is_valid(void) {
assert_se(!env_name_is_valid(NULL));
assert_se(!env_name_is_valid(""));
+ assert_se(!env_name_is_valid("xxx\a"));
+ assert_se(!env_name_is_valid("xxx\007b"));
+ assert_se(!env_name_is_valid("\007\009"));
assert_se(!env_name_is_valid("5_starting_with_a_number_is_wrong"));
assert_se(!env_name_is_valid("#¤%&?_only_numbers_letters_and_underscore_allowed"));
}
+static void test_env_value_is_valid(void) {
+ assert_se(env_value_is_valid(""));
+ assert_se(env_value_is_valid("głąb kapuściany"));
+ assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
+}
+
+static void test_env_assignment_is_valid(void) {
+ assert_se(env_assignment_is_valid("a="));
+ assert_se(env_assignment_is_valid("b=głąb kapuściany"));
+ assert_se(env_assignment_is_valid("c=\\007\\009\\011"));
+ assert_se(env_assignment_is_valid("e=printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
+
+ assert_se(!env_assignment_is_valid("="));
+ assert_se(!env_assignment_is_valid("a b="));
+ assert_se(!env_assignment_is_valid("a ="));
+ assert_se(!env_assignment_is_valid(" b="));
+ /* no dots or dashes: http://tldp.org/LDP/abs/html/gotchas.html */
+ assert_se(!env_assignment_is_valid("a.b="));
+ assert_se(!env_assignment_is_valid("a-b="));
+ assert_se(!env_assignment_is_valid("\007=głąb kapuściany"));
+ assert_se(!env_assignment_is_valid("c\009=\007\009\011"));
+ assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
+}
+
int main(int argc, char *argv[]) {
test_strv_env_delete();
test_strv_env_unset();
@@ -189,6 +217,8 @@ int main(int argc, char *argv[]) {
test_replace_env_arg();
test_env_clean();
test_env_name_is_valid();
+ test_env_value_is_valid();
+ test_env_assignment_is_valid();
return 0;
}
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 0d2e4bfc15..901cc44af6 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -130,18 +130,33 @@ static void test_exec_systemcallerrornumber(Manager *m) {
#endif
}
+static void test_exec_systemcall_system_mode_with_user(Manager *m) {
+#ifdef HAVE_SECCOMP
+ if (getpwnam("nobody"))
+ test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
+ else if (getpwnam("nfsnobody"))
+ test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
+ else
+ log_error_errno(errno, "Skipping test_exec_systemcall_system_mode_with_user, could not find nobody/nfsnobody user: %m");
+#endif
+}
+
static void test_exec_user(Manager *m) {
if (getpwnam("nobody"))
test(m, "exec-user.service", 0, CLD_EXITED);
+ else if (getpwnam("nfsnobody"))
+ test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_user, could not find nobody user: %m");
+ log_error_errno(errno, "Skipping test_exec_user, could not find nobody/nfsnobody user: %m");
}
static void test_exec_group(Manager *m) {
if (getgrnam("nobody"))
test(m, "exec-group.service", 0, CLD_EXITED);
+ else if (getgrnam("nfsnobody"))
+ test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_group, could not find nobody group: %m");
+ log_error_errno(errno, "Skipping test_exec_group, could not find nobody/nfsnobody group: %m");
}
static void test_exec_environment(Manager *m) {
@@ -204,8 +219,10 @@ static void test_exec_runtimedirectory(Manager *m) {
test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
if (getgrnam("nobody"))
test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
+ else if (getgrnam("nfsnobody"))
+ test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
else
- log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody group: %m");
+ log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody/nfsnobody group: %m");
}
static void test_exec_capabilityboundingset(Manager *m) {
@@ -234,9 +251,16 @@ static void test_exec_capabilityambientset(Manager *m) {
* in the first place for the tests. */
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
if (r >= 0 || errno != EINVAL) {
- test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
- test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
- }
+ if (getpwnam("nobody")) {
+ test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
+ test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
+ } else if (getpwnam("nfsnobody")) {
+ test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
+ test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
+ } else
+ log_error_errno(errno, "Skipping test_exec_capabilityambientset, could not find nobody/nfsnobody user: %m");
+ } else
+ log_error_errno(errno, "Skipping test_exec_capabilityambientset, the kernel does not support ambient capabilities: %m");
}
static void test_exec_privatenetwork(Manager *m) {
@@ -267,8 +291,31 @@ static void test_exec_spec_interpolation(Manager *m) {
test(m, "exec-spec-interpolation.service", 0, CLD_EXITED);
}
+static int run_tests(ManagerRunningAs running_as, test_function_t *tests) {
+ test_function_t *test = NULL;
+ Manager *m = NULL;
+ int r;
+
+ assert_se(tests);
+
+ r = manager_new(running_as, true, &m);
+ if (MANAGER_SKIP_TEST(r)) {
+ printf("Skipping test: manager_new: %s\n", strerror(-r));
+ return EXIT_TEST_SKIP;
+ }
+ assert_se(r >= 0);
+ assert_se(manager_startup(m, NULL, NULL) >= 0);
+
+ for (test = tests; test && *test; test++)
+ (*test)(m);
+
+ manager_free(m);
+
+ return 0;
+}
+
int main(int argc, char *argv[]) {
- test_function_t tests[] = {
+ test_function_t user_tests[] = {
test_exec_workingdirectory,
test_exec_personality,
test_exec_ignoresigpipe,
@@ -291,8 +338,10 @@ int main(int argc, char *argv[]) {
test_exec_spec_interpolation,
NULL,
};
- test_function_t *test = NULL;
- Manager *m = NULL;
+ test_function_t system_tests[] = {
+ test_exec_systemcall_system_mode_with_user,
+ NULL,
+ };
int r;
log_parse_environment();
@@ -317,18 +366,9 @@ int main(int argc, char *argv[]) {
assert_se(unsetenv("VAR2") == 0);
assert_se(unsetenv("VAR3") == 0);
- r = manager_new(MANAGER_USER, true, &m);
- if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
- return EXIT_TEST_SKIP;
- }
- assert_se(r >= 0);
- assert_se(manager_startup(m, NULL, NULL) >= 0);
-
- for (test = tests; test && *test; test++)
- (*test)(m);
+ r = run_tests(MANAGER_USER, user_tests);
+ if (r != 0)
+ return r;
- manager_free(m);
-
- return 0;
+ return run_tests(MANAGER_SYSTEM, system_tests);
}