diff options
Diffstat (limited to 'src')
71 files changed, 1125 insertions, 666 deletions
diff --git a/src/activate/activate.c b/src/activate/activate.c index 8ac8dd8e72..a0cfc22000 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -316,19 +316,31 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) { } /* SIGCHLD handler. */ -static void sigchld_hdl(int sig, siginfo_t *t, void *data) { +static void sigchld_hdl(int sig) { PROTECT_ERRNO; - log_info("Child %d died with code %d", t->si_pid, t->si_status); + for (;;) { + siginfo_t si; + int r; - /* Wait for a dead child. */ - (void) waitpid(t->si_pid, NULL, 0); + si.si_pid = 0; + r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG); + if (r < 0) { + if (errno != ECHILD) + log_error_errno(errno, "Failed to reap children: %m"); + return; + } + if (si.si_pid == 0) + return; + + log_info("Child %d died with code %d", si.si_pid, si.si_status); + } } static int install_chld_handler(void) { static const struct sigaction act = { - .sa_flags = SA_SIGINFO, - .sa_sigaction = sigchld_hdl, + .sa_flags = SA_NOCLDSTOP, + .sa_handler = sigchld_hdl, }; int r; 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/cgroup-util.c b/src/basic/cgroup-util.c index 56c1fcaab9..5043180747 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -101,6 +101,39 @@ int cg_read_pid(FILE *f, pid_t *_pid) { return 1; } +int cg_read_event(const char *controller, const char *path, const char *event, + char **val) +{ + _cleanup_free_ char *events = NULL, *content = NULL; + char *p, *line; + int r; + + r = cg_get_path(controller, path, "cgroup.events", &events); + if (r < 0) + return r; + + r = read_full_file(events, &content, NULL); + if (r < 0) + return r; + + p = content; + while ((line = strsep(&p, "\n"))) { + char *key; + + key = strsep(&line, " "); + if (!key || !line) + return -EINVAL; + + if (strcmp(key, event)) + continue; + + *val = strdup(line); + return 0; + } + + return -ENOENT; +} + int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) { _cleanup_free_ char *fs = NULL; int r; @@ -1007,18 +1040,12 @@ int cg_is_empty_recursive(const char *controller, const char *path) { return unified; if (unified > 0) { - _cleanup_free_ char *populated = NULL, *t = NULL; + _cleanup_free_ char *t = NULL; /* On the unified hierarchy we can check empty state - * via the "cgroup.populated" attribute. */ + * via the "populated" attribute of "cgroup.events". */ - r = cg_get_path(controller, path, "cgroup.populated", &populated); - if (r < 0) - return r; - - r = read_one_line_file(populated, &t); - if (r == -ENOENT) - return 1; + r = cg_read_event(controller, path, "populated", &t); if (r < 0) return r; @@ -2129,7 +2156,7 @@ int cg_unified(void) { if (statfs("/sys/fs/cgroup/", &fs) < 0) return -errno; - if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC)) + if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) unified_cache = true; else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) unified_cache = false; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index ad1edd9cdb..4254e51e5d 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -96,6 +96,8 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); int cg_read_pid(FILE *f, pid_t *_pid); +int cg_read_event(const char *controller, const char *path, const char *event, + char **val); int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); int cg_read_subgroup(DIR *d, char **fn); 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/hostname-util.c b/src/basic/hostname-util.c index 5a7ee87a20..13c3bb6446 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -178,16 +178,16 @@ bool is_localhost(const char *hostname) { assert(hostname); /* This tries to identify local host and domain names - * described in RFC6761 plus the redhatism of .localdomain */ + * described in RFC6761 plus the redhatism of localdomain */ return strcaseeq(hostname, "localhost") || strcaseeq(hostname, "localhost.") || - strcaseeq(hostname, "localdomain.") || - strcaseeq(hostname, "localdomain") || + strcaseeq(hostname, "localhost.localdomain") || + strcaseeq(hostname, "localhost.localdomain.") || endswith_no_case(hostname, ".localhost") || endswith_no_case(hostname, ".localhost.") || - endswith_no_case(hostname, ".localdomain") || - endswith_no_case(hostname, ".localdomain."); + endswith_no_case(hostname, ".localhost.localdomain") || + endswith_no_case(hostname, ".localhost.localdomain."); } bool is_gateway_hostname(const char *hostname) { diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index cda6b2895d..eaad25e65b 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -153,6 +153,8 @@ static int add_locales_from_libdir (Set *locales) { FOREACH_DIRENT(entry, dir, return -errno) { char *z; + dirent_ensure_type(dir, entry); + if (entry->d_type != DT_DIR) continue; 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..66cd5921ad 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 @@ -515,6 +437,10 @@ struct btrfs_ioctl_quota_ctl_args { #define CGROUP_SUPER_MAGIC 0x27e0eb #endif +#ifndef CGROUP2_SUPER_MAGIC +#define CGROUP2_SUPER_MAGIC 0x63677270 +#endif + #ifndef TMPFS_MAGIC #define TMPFS_MAGIC 0x01021994 #endif @@ -527,12 +453,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 +481,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 +529,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 +896,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 +916,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 +967,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 c16460a198..7ca764abeb 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -47,15 +47,12 @@ 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. - * - * Also, older kernels don't support CLOCK_BOOTTIME: fall back to CLOCK_MONOTONIC. */ + * those archs. */ switch (c) { - case CLOCK_BOOTTIME: case CLOCK_BOOTTIME_ALARM: - return clock_boottime_or_monotonic (); + return CLOCK_BOOTTIME; case CLOCK_REALTIME_ALARM: return CLOCK_REALTIME; diff --git a/src/basic/utf8.h b/src/basic/utf8.h index 12c272d66e..f9b9c9468b 100644 --- a/src/basic/utf8.h +++ b/src/basic/utf8.h @@ -28,6 +28,7 @@ #include "missing.h" #define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd" +#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf" bool unichar_is_valid(char32_t c); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 39235a95f6..9c34928052 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -765,7 +765,7 @@ int unit_set_cgroup_path(Unit *u, const char *path) { } int unit_watch_cgroup(Unit *u) { - _cleanup_free_ char *populated = NULL; + _cleanup_free_ char *events = NULL; int r; assert(u); @@ -791,11 +791,11 @@ int unit_watch_cgroup(Unit *u) { if (r < 0) return log_oom(); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.populated", &populated); + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events", &events); if (r < 0) return log_oom(); - u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, populated, IN_MODIFY); + u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, events, IN_MODIFY); if (u->cgroup_inotify_wd < 0) { if (errno == ENOENT) /* If the directory is already 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..5557a6a942 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -645,7 +645,7 @@ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobR static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = { [JOB_DONE] = "Stopped %s.", [JOB_FAILED] = "Stopped (with error) %s.", - [JOB_TIMEOUT] = "Timed out stoppping %s.", + [JOB_TIMEOUT] = "Timed out stopping %s.", }; static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = { [JOB_DONE] = "Reloaded %s.", @@ -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..56df32426a 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) { @@ -1659,7 +1664,7 @@ int main(int argc, char *argv[]) { test_usr(); } - if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0) + if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY) watchdog_set_timeout(&arg_runtime_watchdog); if (arg_timer_slack_nsec != NSEC_INFINITY) @@ -2090,7 +2095,7 @@ finish: assert(pos < ELEMENTSOF(command_line)); - if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) { + if (arm_reboot_watchdog && arg_shutdown_watchdog > 0 && arg_shutdown_watchdog != USEC_INFINITY) { char *e; /* If we reboot let's set the shutdown diff --git a/src/core/manager.c b/src/core/manager.c index f13e933578..e739795e70 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1333,8 +1333,12 @@ int manager_load_unit_prepare( t = unit_name_to_type(name); - if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) + if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) { + if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE)) + return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is missing the instance name.", name); + return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name); + } ret = manager_get_unit(m, name); if (ret) { @@ -1631,7 +1635,9 @@ static void invoke_sigchld_event(Manager *m, Unit *u, const siginfo_t *si) { log_unit_debug(u, "Child "PID_FMT" belongs to %s", si->si_pid, u->id); unit_unwatch_pid(u, si->si_pid); - UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status); + + if (UNIT_VTABLE(u)->sigchld_event) + UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status); } static int manager_dispatch_sigchld(Manager *m) { @@ -2016,7 +2022,7 @@ int manager_loop(Manager *m) { while (m->exit_code == MANAGER_OK) { usec_t wait_usec; - if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) + if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && m->running_as == MANAGER_SYSTEM) watchdog_ping(); if (!ratelimit_test(&rl)) { @@ -2041,7 +2047,7 @@ int manager_loop(Manager *m) { continue; /* Sleep for half the watchdog time */ - if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) { + if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && m->running_as == MANAGER_SYSTEM) { wait_usec = m->runtime_watchdog / 2; if (wait_usec <= 0) wait_usec = 1; diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index de1a361cc4..32fe51c67e 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -94,7 +94,7 @@ static const MountPoint mount_table[] = { #endif { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, NULL, MNT_FATAL|MNT_IN_CONTAINER }, - { "cgroup", "/sys/fs/cgroup", "cgroup", "__DEVEL__sane_behavior", MS_NOSUID|MS_NOEXEC|MS_NODEV, + { "cgroup", "/sys/fs/cgroup", "cgroup2", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, cg_is_unified_wanted, MNT_FATAL|MNT_IN_CONTAINER }, { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER }, 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/socket.c b/src/core/socket.c index 87586c1c2e..dd515a17a5 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1341,8 +1341,12 @@ static int socket_open_fds(Socket *s) { break; case SOCKET_USB_FUNCTION: + { + _cleanup_free_ char *ep = NULL; - p->fd = usbffs_address_create(p->path); + ep = path_make_absolute("ep0", p->path); + + p->fd = usbffs_address_create(ep); if (p->fd < 0) { r = p->fd; goto rollback; @@ -1357,7 +1361,7 @@ static int socket_open_fds(Socket *s) { goto rollback; break; - + } default: assert_not_reached("Unknown port type"); } 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/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 2ef966257a..9927621ea0 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -719,8 +719,12 @@ int main(int argc, char *argv[]) { int k; k = crypt_init_by_name(&cd, argv[2]); - if (k) { - log_error_errno(k, "crypt_init() failed: %m"); + if (k == -ENODEV) { + log_info("Volume %s already inactive.", argv[2]); + r = EXIT_SUCCESS; + goto finish; + } else if (k) { + log_error_errno(k, "crypt_init_by_name() failed: %m"); goto finish; } diff --git a/src/import/import-common.c b/src/import/import-common.c index 18a30be36d..287a3382a1 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -136,7 +136,7 @@ int import_fork_tar_x(const char *path, pid_t *ret) { if (r < 0) log_error_errno(r, "Failed to drop capabilities, ignoring: %m"); - execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", NULL); + execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", "--xattrs", "--xattrs-include=*", NULL); log_error_errno(errno, "Failed to execute tar: %m"); _exit(EXIT_FAILURE); } @@ -210,7 +210,7 @@ int import_fork_tar_c(const char *path, pid_t *ret) { if (r < 0) log_error_errno(r, "Failed to drop capabilities, ignoring: %m"); - execlp("tar", "tar", "-C", path, "-c", ".", NULL); + execlp("tar", "tar", "-C", path, "-c", "--xattrs", "--xattrs-include=*", ".", NULL); log_error_errno(errno, "Failed to execute tar: %m"); _exit(EXIT_FAILURE); } diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index 1bef368852..4f7d4d8bf2 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, DUID_TYPE_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..e6486b78f8 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -25,15 +25,15 @@ #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; +typedef enum DUIDType { + DUID_TYPE_RAW = 0, + DUID_TYPE_LLT = 1, + DUID_TYPE_EN = 2, + DUID_TYPE_LL = 3, + DUID_TYPE_UUID = 4, + _DUID_TYPE_MAX, + _DUID_TYPE_INVALID = -1, +} DUIDType; /* RFC 3315 section 9.1: * A DUID can be no more than 128 octets long (not including the type code). @@ -72,29 +72,31 @@ 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) { +static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) { struct duid d; - assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL); + assert(duid_len > 0); - switch (be16toh(duid_type)) { - case DHCP_DUID_TYPE_LLT: + switch (duid_type) { + case DUID_TYPE_LLT: if (duid_len <= sizeof(d.llt)) return -EINVAL; break; - case DHCP_DUID_TYPE_EN: + case DUID_TYPE_EN: if (duid_len != sizeof(d.en)) return -EINVAL; break; - case DHCP_DUID_TYPE_LL: + case DUID_TYPE_LL: if (duid_len <= sizeof(d.ll)) return -EINVAL; break; - case DHCP_DUID_TYPE_UUID: + case DUID_TYPE_UUID: if (duid_len != sizeof(d.uuid)) return -EINVAL; break; default: + if (duid_len > sizeof(d.raw)) + return -EINVAL; /* accept unknown type in order to be forward compatible */ break; } diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c index 190c9baece..6a716430e3 100644 --- a/src/libsystemd-network/lldp-neighbor.c +++ b/src/libsystemd-network/lldp-neighbor.c @@ -24,7 +24,6 @@ #include "in-addr-util.h" #include "lldp-internal.h" #include "lldp-neighbor.h" -#include "lldp.h" #include "unaligned.h" static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) { @@ -245,7 +244,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { switch (type) { - case LLDP_TYPE_END: + case SD_LLDP_TYPE_END: if (length != 0) { log_lldp("End marker TLV not zero-sized, ignoring datagram."); return -EBADMSG; @@ -257,7 +256,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { goto end_marker; - case LLDP_TYPE_CHASSIS_ID: + case SD_LLDP_TYPE_CHASSIS_ID: if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */ log_lldp("Chassis ID field size out of range, ignoring datagram."); return -EBADMSG; @@ -274,7 +273,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { n->id.chassis_id_size = length; break; - case LLDP_TYPE_PORT_ID: + case SD_LLDP_TYPE_PORT_ID: if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */ log_lldp("Port ID field size out of range, ignoring datagram."); return -EBADMSG; @@ -291,7 +290,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { n->id.port_id_size = length; break; - case LLDP_TYPE_TTL: + case SD_LLDP_TYPE_TTL: if (length != 2) { log_lldp("TTL field has wrong size, ignoring datagram."); return -EBADMSG; @@ -306,25 +305,25 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { n->has_ttl = true; break; - case LLDP_TYPE_PORT_DESCRIPTION: + case SD_LLDP_TYPE_PORT_DESCRIPTION: r = parse_string(&n->port_description, p, length); if (r < 0) return r; break; - case LLDP_TYPE_SYSTEM_NAME: + case SD_LLDP_TYPE_SYSTEM_NAME: r = parse_string(&n->system_name, p, length); if (r < 0) return r; break; - case LLDP_TYPE_SYSTEM_DESCRIPTION: + case SD_LLDP_TYPE_SYSTEM_DESCRIPTION: r = parse_string(&n->system_description, p, length); if (r < 0) return r; break; - case LLDP_TYPE_SYSTEM_CAPABILITIES: + case SD_LLDP_TYPE_SYSTEM_CAPABILITIES: if (length != 4) log_lldp("System capabilities field has wrong size, ignoring."); else { @@ -335,7 +334,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { break; - case LLDP_TYPE_PRIVATE: + case SD_LLDP_TYPE_PRIVATE: if (length < 4) log_lldp("Found private TLV that is too short, ignoring."); @@ -479,18 +478,18 @@ _public_ int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, cons switch (*(uint8_t*) n->id.chassis_id) { - case LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT: - case LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS: - case LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT: - case LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME: - case LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED: + case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT: + case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS: + case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT: + case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME: + case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED: k = cescape_length((char*) n->id.chassis_id + 1, n->id.chassis_id_size - 1); if (!k) return -ENOMEM; goto done; - case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: + case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: r = format_mac_address(n->id.chassis_id, n->id.chassis_id_size, &k); if (r < 0) return r; @@ -499,7 +498,7 @@ _public_ int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, cons break; - case LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS: + case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS: r = format_network_address(n->id.chassis_id, n->id.chassis_id_size, &k); if (r < 0) return r; @@ -550,17 +549,17 @@ _public_ int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const c switch (*(uint8_t*) n->id.port_id) { - case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: - case LLDP_PORT_SUBTYPE_PORT_COMPONENT: - case LLDP_PORT_SUBTYPE_INTERFACE_NAME: - case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: + case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: + case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT: + case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME: + case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: k = cescape_length((char*) n->id.port_id + 1, n->id.port_id_size - 1); if (!k) return -ENOMEM; goto done; - case LLDP_PORT_SUBTYPE_MAC_ADDRESS: + case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS: r = format_mac_address(n->id.port_id, n->id.port_id_size, &k); if (r < 0) return r; @@ -569,7 +568,7 @@ _public_ int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const c break; - case LLDP_PORT_SUBTYPE_NETWORK_ADDRESS: + case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS: r = format_network_address(n->id.port_id, n->id.port_id_size, &k); if (r < 0) return r; @@ -738,7 +737,7 @@ _public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], u assert_return(oui, -EINVAL); assert_return(subtype, -EINVAL); - r = sd_lldp_neighbor_tlv_is_type(n, LLDP_TYPE_PRIVATE); + r = sd_lldp_neighbor_tlv_is_type(n, SD_LLDP_TYPE_PRIVATE); if (r < 0) return r; if (r == 0) diff --git a/src/libsystemd-network/lldp.h b/src/libsystemd-network/lldp.h deleted file mode 100644 index d61ecabcfc..0000000000 --- a/src/libsystemd-network/lldp.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -/*** - This file is part of systemd. - - Copyright (C) 2014 Tom Gundersen - Copyright (C) 2014 Susant Sahani - - 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/>. -***/ - -#define LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e } - -/* IEEE 802.3AB Clause 9: TLV Types */ -enum { - LLDP_TYPE_END = 0, - LLDP_TYPE_CHASSIS_ID = 1, - LLDP_TYPE_PORT_ID = 2, - LLDP_TYPE_TTL = 3, - LLDP_TYPE_PORT_DESCRIPTION = 4, - LLDP_TYPE_SYSTEM_NAME = 5, - LLDP_TYPE_SYSTEM_DESCRIPTION = 6, - LLDP_TYPE_SYSTEM_CAPABILITIES = 7, - LLDP_TYPE_MGMT_ADDRESS = 8, - LLDP_TYPE_PRIVATE = 127, -}; - -/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */ -enum { - LLDP_CHASSIS_SUBTYPE_RESERVED = 0, - LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1, - LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2, - LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3, - LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4, - LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5, - LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6, - LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7, -}; - -/* IEEE 802.3AB Clause 9.5.3: Port subtype */ -enum { - LLDP_PORT_SUBTYPE_RESERVED = 0, - LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1, - LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2, - LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3, - LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4, - LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5, - LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6, - LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7, -}; - -enum { - LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0, - LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1, - LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2, - LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3, - LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4, - LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5, - LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6, - LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7, - LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8, - LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9, - LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10, -}; - -#define _LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1) - -#define _LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS \ - ((uint16_t) \ - (LLDP_SYSTEM_CAPABILITIES_REPEATER| \ - LLDP_SYSTEM_CAPABILITIES_BRIDGE| \ - LLDP_SYSTEM_CAPABILITIES_WLAN_AP| \ - LLDP_SYSTEM_CAPABILITIES_ROUTER| \ - LLDP_SYSTEM_CAPABILITIES_DOCSIS| \ - LLDP_SYSTEM_CAPABILITIES_CVLAN| \ - LLDP_SYSTEM_CAPABILITIES_SVLAN| \ - LLDP_SYSTEM_CAPABILITIES_TPMR)) - - -#define LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 } -#define LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f } - -enum { - LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1, - LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2, - LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3, - LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4, - LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5, - LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6, - LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7, -}; diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 7c21f42591..0e2d757b2b 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -335,17 +335,17 @@ 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 config_parse_iaid(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; int r; assert(filename); @@ -353,12 +353,13 @@ int config_parse_iaid_value(const char *unit, assert(rvalue); assert(data); - if ((r = safe_atou32(rvalue, &iaid_value)) < 0) { + r = safe_atou32(rvalue, &iaid); + if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue); return r; } - *((be32_t *)data) = htobe32(iaid_value); + *((uint32_t *)data) = iaid; return 0; } diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index d8b551e8ce..72432774d7 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -62,9 +62,9 @@ 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 config_parse_iaid(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..287b6e26fa 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -298,8 +298,8 @@ 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) { +int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, + uint16_t duid_type, uint8_t *duid, size_t duid_len) { DHCP_CLIENT_DONT_DESTROY(client); int r; assert_return(client, -EINVAL); @@ -315,7 +315,7 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, be32_t iaid, if (r < 0) return r; } else - client->client_id.ns.iaid = iaid; + client->client_id.ns.iaid = htobe32(iaid); /* If DUID is not configured, generate DUID-EN. */ if (duid_len == 0) { @@ -324,11 +324,12 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, be32_t iaid, if (r < 0) return r; } else { - r = dhcp_validate_duid_len(client->client_id.type, - duid_len - sizeof(client->client_id.type)); + r = dhcp_validate_duid_len(client->client_id.type, duid_len); if (r < 0) return r; - memcpy(&client->client_id.ns.duid, duid, duid_len); + client->client_id.ns.duid.type = htobe16(duid_type); + memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len); + duid_len += sizeof(client->client_id.ns.duid.type); } client->client_id_len = sizeof(client->client_id.type) + duid_len + @@ -514,6 +515,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..ee4fb4fc1e 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -180,30 +180,29 @@ 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 sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type, + uint8_t *duid, size_t duid_len) { int r; assert_return(client, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); if (duid_len > 0) { - r = dhcp_validate_duid_len(duid->type, - duid_len - sizeof(duid->type)); + r = dhcp_validate_duid_len(duid_type, duid_len); if (r < 0) return r; - - memcpy(&client->duid, duid, duid_len); - client->duid_len = duid_len; + client->duid.type = htobe16(duid_type); + memcpy(&client->duid.raw.data, duid, duid_len); + client->duid_len = duid_len + sizeof(client->duid.type); } return 0; } -int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, be32_t iaid) { +int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) { assert_return(client, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - client->ia_na.id = iaid; + client->ia_na.id = htobe32(iaid); 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/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c index da4ce293bc..1aae2253c0 100644 --- a/src/libsystemd-network/test-lldp.c +++ b/src/libsystemd-network/test-lldp.c @@ -30,7 +30,6 @@ #include "alloc-util.h" #include "fd-util.h" #include "lldp-network.h" -#include "lldp.h" #include "macro.h" #include "string-util.h" @@ -127,12 +126,12 @@ static void test_receive_basic_packet(sd_event *e) { assert_se(sd_lldp_get_neighbors(lldp, &neighbors) == 1); assert_se(sd_lldp_neighbor_get_chassis_id(neighbors[0], &type, &data, &length) == 0); - assert_se(type == LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS); + assert_se(type == SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS); assert_se(length == ETH_ALEN); assert_se(!memcmp(data, "\x00\x01\x02\x03\x04\x05", ETH_ALEN)); assert_se(sd_lldp_neighbor_get_port_id(neighbors[0], &type, &data, &length) == 0); - assert_se(type == LLDP_PORT_SUBTYPE_INTERFACE_NAME); + assert_se(type == SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME); assert_se(length == 3); assert_se(strneq((char *) data, "1/3", 3)); @@ -218,23 +217,23 @@ static void test_receive_oui_packet(sd_event *e) { assert_se(sd_lldp_get_neighbors(lldp, &neighbors) == 1); assert_se(sd_lldp_neighbor_tlv_rewind(neighbors[0]) >= 0); - assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], LLDP_TYPE_CHASSIS_ID) > 0); + assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_CHASSIS_ID) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], LLDP_TYPE_PORT_ID) > 0); + assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_PORT_ID) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], LLDP_TYPE_TTL) > 0); + assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_TTL) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], LLDP_OUI_802_1, LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID) > 0); + assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], LLDP_OUI_802_1, LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID) > 0); + assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], LLDP_OUI_802_1, LLDP_OUI_802_1_SUBTYPE_VLAN_NAME) > 0); + assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], LLDP_OUI_802_1, LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID) > 0); + assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], LLDP_OUI_802_1, LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION) > 0); + assert_se(sd_lldp_neighbor_tlv_is_oui(neighbors[0], SD_LLDP_OUI_802_1, SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) > 0); - assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], LLDP_TYPE_END) > 0); + assert_se(sd_lldp_neighbor_tlv_is_type(neighbors[0], SD_LLDP_TYPE_END) > 0); assert_se(sd_lldp_neighbor_tlv_next(neighbors[0]) == 0); sd_lldp_neighbor_unref(neighbors[0]); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 8657e61cd9..e9f8970d2c 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1457,15 +1457,20 @@ static int device_properties_prepare(sd_device *device) { return r; if (device->property_devlinks_outdated) { - char *devlinks = NULL; + _cleanup_free_ char *devlinks = NULL; + size_t devlinks_allocated = 0, devlinks_len = 0; const char *devlink; - devlink = sd_device_get_devlink_first(device); - if (devlink) - devlinks = strdupa(devlink); + for (devlink = sd_device_get_devlink_first(device); devlink; devlink = sd_device_get_devlink_next(device)) { + char *e; - while ((devlink = sd_device_get_devlink_next(device))) - devlinks = strjoina(devlinks, " ", devlink); + if (!GREEDY_REALLOC(devlinks, devlinks_allocated, devlinks_len + strlen(devlink) + 2)) + return -ENOMEM; + if (devlinks_len > 0) + stpcpy(devlinks + devlinks_len++, " "); + e = stpcpy(devlinks + devlinks_len, devlink); + devlinks_len = e - devlinks; + } r = device_add_property_internal(device, "DEVLINKS", devlinks); if (r < 0) @@ -1475,17 +1480,23 @@ static int device_properties_prepare(sd_device *device) { } if (device->property_tags_outdated) { - char *tags = NULL; + _cleanup_free_ char *tags = NULL; + size_t tags_allocated = 0, tags_len = 0; const char *tag; - tag = sd_device_get_tag_first(device); - if (tag) - tags = strjoina(":", tag); + if (!GREEDY_REALLOC(tags, tags_allocated, 2)) + return -ENOMEM; + stpcpy(tags, ":"); + tags_len++; - while ((tag = sd_device_get_tag_next(device))) - tags = strjoina(tags, ":", tag); + for (tag = sd_device_get_tag_first(device); tag; tag = sd_device_get_tag_next(device)) { + char *e; - tags = strjoina(tags, ":"); + if (!GREEDY_REALLOC(tags, tags_allocated, tags_len + strlen(tag) + 1)) + return -ENOMEM; + e = stpcpy(stpcpy(tags + tags_len, tag), ":"); + tags_len = e - tags; + } r = device_add_property_internal(device, "TAGS", tags); if (r < 0) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index cde33bdf41..4865335349 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -116,11 +116,11 @@ static void print_overridden_variables(void) { if (variables[j]) { if (print_warning) { log_warning("Warning: Settings on kernel command line override system locale settings in /etc/locale.conf.\n" - " Command Line: %s=%s", locale_variable_to_string(j), variables[j]); + " Command Line: %s=%s", locale_variable_to_string(j), variables[j]); print_warning = false; } else - log_warning(" %s=%s", locale_variable_to_string(j), variables[j]); + log_warning(" %s=%s", locale_variable_to_string(j), variables[j]); } finish: for (j = 0; j < _VARIABLE_LC_MAX; j++) @@ -131,7 +131,7 @@ static void print_status_info(StatusInfo *i) { assert(i); if (strv_isempty(i->locale)) - puts(" System Locale: n/a\n"); + puts(" System Locale: n/a"); else { char **j; diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules index 694df2cfc8..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" @@ -75,4 +76,7 @@ SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess" # software-defined radio communication devices ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess" +# 3D printers, CNC machines, laser cutters, 3D scanners, etc. +ENV{ID_MAKER_TOOL}=="?*", TAG+="uaccess" + LABEL="uaccess_end" diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c index 11a91c3947..29ab00eb1f 100644 --- a/src/login/logind-utmp.c +++ b/src/login/logind-utmp.c @@ -65,7 +65,7 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) { assert(m); - if (!startswith(tty, "/dev/")) + if (!startswith(tty, "/dev/") || !m->scheduled_shutdown_tty) return true; return !streq(tty + 5, m->scheduled_shutdown_tty); diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 6ec7a911ca..b22a0f648a 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -33,7 +33,6 @@ #include "ether-addr-util.h" #include "fd-util.h" #include "hwdb-util.h" -#include "lldp.h" #include "local-addresses.h" #include "locale-util.h" #include "netlink-util.h" diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c index 4bc92b8171..8b149124b3 100644 --- a/src/network/networkd-conf.c +++ b/src/network/networkd-conf.c @@ -3,7 +3,7 @@ /*** This file is part of systemd. - Copyright 2014 Tom Gundersen <teg@jklm.no> + Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com> 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 @@ -37,17 +37,17 @@ int manager_parse_config_file(Manager *m) { 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" +static const char* const duid_type_table[_DUID_TYPE_MAX] = { + [DUID_TYPE_RAW] = "raw", + [DUID_TYPE_LLT] = "link-layer-time", + [DUID_TYPE_EN] = "vendor", + [DUID_TYPE_LL] = "link-layer", + [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"); +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType); +DEFINE_CONFIG_PARSE_ENUM(config_parse_duid_type, duid_type, DUIDType, "Failed to parse DUID type"); -int config_parse_dhcp_duid_raw( +int config_parse_duid_rawdata( const char *unit, const char *filename, unsigned line, @@ -61,39 +61,61 @@ int config_parse_dhcp_duid_raw( int r; long byte; char *cbyte, *pnext; - const char *pduid = (const char *)rvalue; - size_t count = 0, duid_len = 0; - Manager *m = userdata; + const char *pduid = rvalue; + size_t count = 0, duid_index = 0; + Manager *m; + Network *n; + DUIDType *duid_type; + uint16_t *dhcp_duid_type; + size_t *dhcp_duid_len; + uint8_t *dhcp_duid; assert(filename); assert(lvalue); assert(rvalue); - assert(m); - assert(m->dhcp_duid_type != _DHCP_DUID_TYPE_INVALID); + assert(userdata); + + if (ltype == DUID_CONFIG_SOURCE_GLOBAL) { + m = userdata; + duid_type = &m->duid_type; + dhcp_duid_type = &m->dhcp_duid_type; + dhcp_duid_len = &m->dhcp_duid_len; + dhcp_duid = m->dhcp_duid; + } else { + /* DUID_CONFIG_SOURCE_NETWORK */ + n = userdata; + duid_type = &n->duid_type; + dhcp_duid_type = &n->dhcp_duid_type; + dhcp_duid_len = &n->dhcp_duid_len; + dhcp_duid = n->dhcp_duid; + } + + if (*duid_type == _DUID_TYPE_INVALID) + *duid_type = DUID_TYPE_RAW; - switch (m->dhcp_duid_type) { - case DHCP_DUID_TYPE_LLT: + switch (*duid_type) { + case DUID_TYPE_LLT: /* RawData contains DUID-LLT link-layer address (offset 6) */ - duid_len = 6; + duid_index = 6; break; - case DHCP_DUID_TYPE_EN: + case DUID_TYPE_EN: /* RawData contains DUID-EN identifier (offset 4) */ - duid_len = 4; + duid_index = 4; break; - case DHCP_DUID_TYPE_LL: + case DUID_TYPE_LL: /* RawData contains DUID-LL link-layer address (offset 2) */ - duid_len = 2; + duid_index = 2; break; - case DHCP_DUID_TYPE_UUID: + case DUID_TYPE_UUID: /* RawData specifies UUID (offset 0) - fall thru */ - case DHCP_DUID_TYPE_RAW: + case 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); + if (*duid_type != DUID_TYPE_RAW) + *dhcp_duid_type = (uint16_t)(*duid_type); /* RawData contains DUID in format " NN:NN:NN... " */ while (true) { @@ -104,7 +126,7 @@ int config_parse_dhcp_duid_raw( } if (r == 0) break; - if (duid_len >= MAX_DUID_LEN) { + if (duid_index >= MAX_DUID_LEN) { log_error("DUID length exceeds maximum length."); return -EINVAL; } @@ -117,17 +139,17 @@ int config_parse_dhcp_duid_raw( 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)); + /* If DUID_TYPE_RAW, first two bytes hold DHCP DUID type code */ + if ((*duid_type == DUID_TYPE_RAW) && (count < 2)) { + *dhcp_duid_type |= (byte << (8 * (1 - count))); count++; continue; } - m->dhcp_duid.raw.data[duid_len++] = byte; + dhcp_duid[duid_index++] = byte; } - m->dhcp_duid_len = sizeof(m->dhcp_duid.type) + duid_len; + *dhcp_duid_len = duid_index; return 0; } diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h index 6d9ce010e3..efc370f839 100644 --- a/src/network/networkd-conf.h +++ b/src/network/networkd-conf.h @@ -5,7 +5,7 @@ /*** This file is part of systemd. - Copyright 2014 Tom Gundersen <teg@jklm.no> + Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com> 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 @@ -23,10 +23,14 @@ #include "networkd.h" +typedef enum DuidConfigSource { + DUID_CONFIG_SOURCE_GLOBAL = 0, + DUID_CONFIG_SOURCE_NETWORK, +} DuidConfigSource; 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); +int config_parse_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_duid_rawdata(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..0589ebf227 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -626,10 +626,18 @@ 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 (link->network->duid_type != _DUID_TYPE_INVALID) + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid, + link->network->dhcp_duid_type, + link->network->dhcp_duid, + link->network->dhcp_duid_len); + else + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid, + link->manager->dhcp_duid_type, + link->manager->dhcp_duid, + link->manager->dhcp_duid_len); if (r < 0) return r; break; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 9f59cb3f8a..d4b2fbfc57 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -230,13 +230,20 @@ int dhcp6_configure(Link *link) { if (r < 0) goto error; - r = sd_dhcp6_client_set_iaid(client, link->network->iaid_value); + r = sd_dhcp6_client_set_iaid(client, link->network->iaid); if (r < 0) goto error; - r = sd_dhcp6_client_set_duid(client, - link->manager->dhcp_duid_len, - &link->manager->dhcp_duid); + if (link->network->duid_type != _DUID_TYPE_INVALID) + r = sd_dhcp6_client_set_duid(client, + link->network->dhcp_duid_type, + link->network->dhcp_duid, + link->network->dhcp_duid_len); + else + r = sd_dhcp6_client_set_duid(client, + link->manager->dhcp_duid_type, + link->manager->dhcp_duid, + link->manager->dhcp_duid_len); if (r < 0) goto error; diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf index 3ef4155476..0625fb335b 100644 --- a/src/network/networkd-gperf.gperf +++ b/src/network/networkd-gperf.gperf @@ -14,5 +14,5 @@ struct ConfigPerfItem; %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) +DUID.Type, config_parse_duid_type, 0, offsetof(Manager, duid_type) +DUID.RawData, config_parse_duid_rawdata, DUID_CONFIG_SOURCE_GLOBAL, offsetof(Manager, dhcp_duid) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 67b04560cd..88b3cbe90a 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -26,7 +26,6 @@ #include "dhcp-lease-internal.h" #include "fd-util.h" #include "fileio.h" -#include "lldp.h" #include "netlink-util.h" #include "network-internal.h" #include "networkd-link.h" @@ -2234,8 +2233,8 @@ static int link_configure(Link *link) { r = sd_lldp_match_capabilities(link->lldp, link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ? - _LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS : - _LLDP_SYSTEM_CAPABILITIES_ALL); + SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS : + SD_LLDP_SYSTEM_CAPABILITIES_ALL); if (r < 0) return r; @@ -2782,10 +2781,18 @@ int link_update(Link *link, sd_netlink_message *m) { 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 (link->network->duid_type != _DUID_TYPE_INVALID) + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid, + link->network->dhcp_duid_type, + link->network->dhcp_duid, + link->network->dhcp_duid_len); + else + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid, + link->manager->dhcp_duid_type, + link->manager->dhcp_duid, + link->manager->dhcp_duid_len); if (r < 0) return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m"); } @@ -2799,13 +2806,20 @@ int link_update(Link *link, sd_netlink_message *m) { 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); + link->network->iaid); 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 (link->network->duid_type != _DUID_TYPE_INVALID) + r = sd_dhcp6_client_set_duid(link->dhcp6_client, + link->network->dhcp_duid_type, + link->network->dhcp_duid, + link->network->dhcp_duid_len); + else + r = sd_dhcp6_client_set_duid(link->dhcp6_client, + link->manager->dhcp_duid_type, + link->manager->dhcp_duid, + link->manager->dhcp_duid_len); if (r < 0) return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m"); } diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index ae8367a60e..5af2a31ea7 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -24,7 +24,6 @@ #include "fd-util.h" #include "fileio.h" #include "hostname-util.h" -#include "lldp.h" #include "networkd-lldp-tx.h" #include "random-util.h" #include "socket-util.h" @@ -128,51 +127,51 @@ static int lldp_make_packet( h = (struct ether_header*) packet; h->ether_type = htobe16(ETHERTYPE_LLDP); - memcpy(h->ether_dhost, &(struct ether_addr) { LLDP_MULTICAST_ADDR }, ETH_ALEN); + memcpy(h->ether_dhost, &(struct ether_addr) { SD_LLDP_MULTICAST_ADDR }, ETH_ALEN); memcpy(h->ether_shost, hwaddr, ETH_ALEN); p = (uint8_t*) packet + sizeof(struct ether_header); - r = lldp_write_tlv_header(&p, LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length); if (r < 0) return r; - *(p++) = LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED; + *(p++) = SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED; p = mempcpy(p, machine_id, machine_id_length); - r = lldp_write_tlv_header(&p, LLDP_TYPE_PORT_ID, 1 + ifname_length); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_ID, 1 + ifname_length); if (r < 0) return r; - *(p++) = LLDP_PORT_SUBTYPE_INTERFACE_NAME; + *(p++) = SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME; p = mempcpy(p, ifname, ifname_length); - r = lldp_write_tlv_header(&p, LLDP_TYPE_TTL, 2); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_TTL, 2); if (r < 0) return r; unaligned_write_be16(p, ttl); p += 2; if (port_description) { - r = lldp_write_tlv_header(&p, LLDP_TYPE_PORT_DESCRIPTION, port_description_length); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_DESCRIPTION, port_description_length); if (r < 0) return r; p = mempcpy(p, port_description, port_description_length); } if (hostname) { - r = lldp_write_tlv_header(&p, LLDP_TYPE_SYSTEM_NAME, hostname_length); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_NAME, hostname_length); if (r < 0) return r; p = mempcpy(p, hostname, hostname_length); } if (pretty_hostname) { - r = lldp_write_tlv_header(&p, LLDP_TYPE_SYSTEM_DESCRIPTION, pretty_hostname_length); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_DESCRIPTION, pretty_hostname_length); if (r < 0) return r; p = mempcpy(p, pretty_hostname, pretty_hostname_length); } - r = lldp_write_tlv_header(&p, LLDP_TYPE_SYSTEM_CAPABILITIES, 4); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4); if (r < 0) return r; unaligned_write_be16(p, system_capabilities); @@ -180,7 +179,7 @@ static int lldp_make_packet( unaligned_write_be16(p, enabled_capabilities); p += 2; - r = lldp_write_tlv_header(&p, LLDP_TYPE_END, 0); + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_END, 0); if (r < 0) return r; @@ -200,7 +199,7 @@ static int lldp_send_packet(int ifindex, const void *packet, size_t packet_size) .ll.sll_protocol = htobe16(ETHERTYPE_LLDP), .ll.sll_ifindex = ifindex, .ll.sll_halen = ETH_ALEN, - .ll.sll_addr = LLDP_MULTICAST_ADDR, + .ll.sll_addr = SD_LLDP_MULTICAST_ADDR, }; _cleanup_close_ int fd = -1; @@ -245,8 +244,8 @@ static int link_send_lldp(Link *link) { ttl = (usec_t) UINT16_MAX; caps = (link->network && link->network->ip_forward != ADDRESS_FAMILY_NO) ? - LLDP_SYSTEM_CAPABILITIES_ROUTER : - LLDP_SYSTEM_CAPABILITIES_STATION; + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : + SD_LLDP_SYSTEM_CAPABILITIES_STATION; r = lldp_make_packet(&link->mac, sd_id128_to_string(machine_id, machine_id_string), @@ -255,7 +254,7 @@ static int link_send_lldp(Link *link) { link->network ? link->network->description : NULL, hostname, pretty_hostname, - LLDP_SYSTEM_CAPABILITIES_STATION|LLDP_SYSTEM_CAPABILITIES_BRIDGE|LLDP_SYSTEM_CAPABILITIES_ROUTER, + SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER, caps, &packet, &packet_size); if (r < 0) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 8d443f7b0f..d355aaa19c 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1037,7 +1037,7 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->dhcp_duid_type = _DHCP_DUID_TYPE_INVALID; + m->duid_type = _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..9793938080 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -2,6 +2,7 @@ #include <stddef.h> #include "conf-parser.h" #include "networkd.h" +#include "networkd-conf.h" #include "network-internal.h" %} struct ConfigPerfItem; @@ -26,7 +27,9 @@ 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) +Link.IAID, config_parse_iaid, 0, offsetof(Network, iaid) +DUID.Type, config_parse_duid_type, 0, offsetof(Network, duid_type) +DUID.RawData, config_parse_duid_rawdata, DUID_CONFIG_SOURCE_NETWORK, offsetof(Network, dhcp_duid) 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.c b/src/network/networkd-network.c index 491b9a3efa..5946ba18dc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -131,10 +131,12 @@ static int network_load_one(Manager *manager, const char *filename) { network->ipv6_accept_ra = -1; network->ipv6_dad_transmits = -1; network->ipv6_hop_limit = -1; + network->duid_type = _DUID_TYPE_INVALID; r = config_parse(NULL, filename, file, "Match\0" "Link\0" + "DUID\0" "Network\0" "Address\0" "Route\0" diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index c5530cdfba..5400a8bc9d 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -24,13 +24,13 @@ typedef struct Network Network; +#include "dhcp-identifier.h" #include "networkd-address.h" #include "networkd-fdb.h" #include "networkd-netdev.h" #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 +145,13 @@ struct Network { struct ether_addr *mac; unsigned mtu; - be32_t iaid_value; + uint32_t iaid; + /* Value of Type in [DUID] section */ + DUIDType duid_type; + /* DUID type code - RFC 3315 */ + uint16_t dhcp_duid_type; + size_t dhcp_duid_len; + uint8_t dhcp_duid[MAX_DUID_LEN]; LLDPMode lldp_mode; /* LLDP reception */ bool lldp_emit; /* LLDP transmission */ diff --git a/src/network/networkd.h b/src/network/networkd.h index d815f30610..72a2438ac8 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -31,11 +31,11 @@ typedef struct Manager Manager; +#include "dhcp-identifier.h" #include "networkd-address-pool.h" #include "networkd-link.h" #include "networkd-network.h" #include "networkd-util.h" -#include "dhcp-identifier.h" struct Manager { sd_netlink *rtnl; @@ -63,9 +63,12 @@ struct Manager { usec_t network_dirs_ts_usec; - DHCPDUIDType dhcp_duid_type; + /* Value of Type in [DUID] section */ + DUIDType duid_type; + /* DUID type code - RFC 3315 */ + uint16_t dhcp_duid_type; size_t dhcp_duid_len; - struct duid dhcp_duid; + uint8_t dhcp_duid[MAX_DUID_LEN]; }; extern const char* const network_dirs[]; diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c index 1db5ba7116..f50f1ad6c2 100644 --- a/src/nspawn/nspawn-cgroup.c +++ b/src/nspawn/nspawn-cgroup.c @@ -55,8 +55,7 @@ int chown_cgroup(pid_t pid, uid_t uid_shift) { "cgroup.events", "cgroup.clone_children", "cgroup.controllers", - "cgroup.subtree_control", - "cgroup.populated") + "cgroup.subtree_control") if (fchownat(fd, fn, uid_shift, uid_shift, 0) < 0) log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, "Failed to chown() cgroup file %s, ignoring: %m", fn); @@ -73,7 +72,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; @@ -94,7 +93,7 @@ int sync_cgroup(pid_t pid, bool unified_requested) { if (unified) r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr"); else - r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "__DEVEL__sane_behavior"); + r = mount("cgroup", tree, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL); if (r < 0) { r = log_error_errno(errno, "Failed to mount unified hierarchy: %m"); goto finish; @@ -135,7 +134,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-mount.c b/src/nspawn/nspawn-mount.c index 70cca15278..8e2d2d543c 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -438,21 +438,22 @@ static int mount_bind(const char *dest, CustomMount *m) { r = mkdir_parents_label(where, 0755); if (r < 0) return log_error_errno(r, "Failed to make parents of %s: %m", where); + + /* Create the mount point. Any non-directory file can be + * mounted on any non-directory file (regular, fifo, socket, + * char, block). + */ + if (S_ISDIR(source_st.st_mode)) + r = mkdir_label(where, 0755); + else + r = touch(where); + if (r < 0) + return log_error_errno(r, "Failed to create mount point %s: %m", where); + } else { return log_error_errno(errno, "Failed to stat %s: %m", where); } - /* Create the mount point. Any non-directory file can be - * mounted on any non-directory file (regular, fifo, socket, - * char, block). - */ - if (S_ISDIR(source_st.st_mode)) - r = mkdir_label(where, 0755); - else - r = touch(where); - if (r < 0 && r != -EEXIST) - return log_error_errno(r, "Failed to create mount point %s: %m", where); - if (mount(m->source, where, NULL, mount_flags, mount_opts) < 0) return log_error_errno(errno, "mount(%s) failed: %m", where); @@ -750,7 +751,7 @@ static int mount_unified_cgroups(const char *dest) { return -EINVAL; } - if (mount("cgroup", p, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "__DEVEL__sane_behavior") < 0) + if (mount("cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0) return log_error_errno(errno, "Failed to mount unified cgroup hierarchy to %s: %m", p); 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/resolve/resolve-tool.c b/src/resolve/resolve-tool.c index 009cc73aec..14ee01c49d 100644 --- a/src/resolve/resolve-tool.c +++ b/src/resolve/resolve-tool.c @@ -17,7 +17,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <gcrypt.h> #include <getopt.h> #include <net/if.h> @@ -863,7 +862,7 @@ static int resolve_openpgp(sd_bus *bus, const char *address) { } domain++; - r = string_hashsum(address, domain - 1 - address, GCRY_MD_SHA224, &hashed); + r = string_hashsum_sha224(address, domain - 1 - address, &hashed); if (r < 0) return log_error_errno(r, "Hashing failed: %m"); diff --git a/src/run/run.c b/src/run/run.c index 1ed1bd96bf..f92a7f4e2e 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -878,7 +878,7 @@ static int start_transient_service( (void) sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL); if (!arg_quiet) - log_info("Running as unit %s.\nPress ^] three times within 1s to disconnect TTY.", service); + log_info("Running as unit: %s\nPress ^] three times within 1s to disconnect TTY.", service); r = pty_forward_new(event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &forward); if (r < 0) @@ -896,7 +896,7 @@ static int start_transient_service( fputc('\n', stdout); } else if (!arg_quiet) - log_info("Running as unit %s.", service); + log_info("Running as unit: %s", service); return 0; } @@ -1038,7 +1038,7 @@ static int start_transient_scope( return r; if (!arg_quiet) - log_info("Running scope as unit %s.", scope); + log_info("Running scope as unit: %s", scope); execvpe(argv[0], argv, env); @@ -1189,9 +1189,9 @@ static int start_transient_timer( if (r < 0) return r; - log_info("Running timer as unit %s.", timer); + log_info("Running timer as unit: %s", timer); if (argv[0]) - log_info("Will run service as unit %s.", service); + log_info("Will run service as unit: %s", service); return 0; } diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 0fa04da935..0caaca03c7 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1078,7 +1078,7 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_ } case SD_BUS_TYPE_UINT32: { - uint64_t u; + uint32_t u; uint32_t *p = userdata; r = sd_bus_message_read_basic(m, type, &u); @@ -2040,7 +2040,7 @@ static const struct { static void log_job_error_with_service_result(const char* service, const char *result, const char* const* extra_args) { _cleanup_free_ char *service_shell_quoted = NULL; - const char *systemctl = "systemctl", *journalctl = "journalct"; + const char *systemctl = "systemctl", *journalctl = "journalctl"; assert(service); diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index e7fe9ac21e..bd0a1f483b 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -294,7 +294,7 @@ int config_parse(const char *unit, _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; - bool section_ignored = false; + bool section_ignored = false, allow_bom = true; int r; assert(filename); @@ -314,11 +314,11 @@ int config_parse(const char *unit, fd_warn_permissions(filename, fileno(f)); - while (!feof(f)) { - char l[LINE_MAX], *p, *c = NULL, *e; + for (;;) { + char buf[LINE_MAX], *l, *p, *c = NULL, *e; bool escaped = false; - if (!fgets(l, sizeof(l), f)) { + if (!fgets(buf, sizeof buf, f)) { if (feof(f)) break; @@ -326,6 +326,11 @@ int config_parse(const char *unit, return -errno; } + l = buf; + if (allow_bom && startswith(l, UTF8_BYTE_ORDER_MARK)) + l += strlen(UTF8_BYTE_ORDER_MARK); + allow_bom = false; + truncate_nl(l); if (continuation) { diff --git a/src/shared/gcrypt-util.c b/src/shared/gcrypt-util.c index 4ff94520c3..39b544b6f0 100644 --- a/src/shared/gcrypt-util.c +++ b/src/shared/gcrypt-util.c @@ -19,10 +19,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#ifdef HAVE_GCRYPT #include <gcrypt.h> -#include "hexdecoct.h" #include "gcrypt-util.h" +#include "hexdecoct.h" void initialize_libgcrypt(bool secmem) { const char *p; @@ -67,3 +68,4 @@ int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) { *out = enc; return 0; } +#endif diff --git a/src/shared/gcrypt-util.h b/src/shared/gcrypt-util.h index c7652c22d1..cf33b3c59c 100644 --- a/src/shared/gcrypt-util.h +++ b/src/shared/gcrypt-util.h @@ -19,7 +19,21 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <errno.h> #include <stdbool.h> +#include <stddef.h> + +#ifdef HAVE_GCRYPT +#include <gcrypt.h> void initialize_libgcrypt(bool secmem); int string_hashsum(const char *s, size_t len, int md_algorithm, char **out); +#endif + +static inline int string_hashsum_sha224(const char *s, size_t len, char **out) { +#ifdef HAVE_GCRYPT + return string_hashsum(s, len, GCRY_MD_SHA224, out); +#else + return -EOPNOTSUPP; +#endif +} diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c index cf3c8ad5a3..7dae4d14fe 100644 --- a/src/shared/spawn-polkit-agent.c +++ b/src/shared/spawn-polkit-agent.c @@ -44,6 +44,10 @@ int polkit_agent_open(void) { if (agent_pid > 0) return 0; + /* Clients that run as root don't need to activate/query polkit */ + if (geteuid() == 0) + return 0; + /* We check STDIN here, not STDOUT, since this is about input, * not output */ if (!isatty(STDIN_FILENO)) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 57e62a607b..62cff3a677 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -341,6 +341,11 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) { if (arg_all) return true; + if (!strv_isempty(arg_states)) + return true; + + /* By default show all units except the ones in inactive + * state and with no pending job */ if (u->job_id > 0) return true; @@ -1892,13 +1897,13 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n) printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state); if (m->is_host) - printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n", + printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n", (int) (namelen - (sizeof(" (host)")-1)), strna(m->name), on_state, statelen, strna(m->state), off_state, on_failed, failedlen, m->n_failed_units, off_failed, jobslen, m->n_jobs); else - printf("%-*s %s%-*s%s %s%*u%s %*u\n", + printf("%-*s %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n", namelen, strna(m->name), on_state, statelen, strna(m->state), off_state, on_failed, failedlen, m->n_failed_units, off_failed, @@ -4645,8 +4650,8 @@ static int show_system_status(sd_bus *bus) { printf(" State: %s%s%s\n", on, strna(mi.state), off); - printf(" Jobs: %u queued\n", mi.n_jobs); - printf(" Failed: %u units\n", mi.n_failed_units); + printf(" Jobs: %" PRIu32 " queued\n", mi.n_jobs); + printf(" Failed: %" PRIu32 " units\n", mi.n_failed_units); printf(" Since: %s; %s\n", format_timestamp(since2, sizeof(since2), mi.timestamp), diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 7873cb1e04..374ff8774e 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,8 @@ 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_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid, + uint16_t duid_type, uint8_t *duid, size_t duid_len); 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..4604cb6382 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,9 @@ 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 duid_type, + uint8_t *duid, size_t duid_len); +int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid); 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/systemd/sd-lldp.h b/src/systemd/sd-lldp.h index f7eff58769..4f2a3b50c0 100644 --- a/src/systemd/sd-lldp.h +++ b/src/systemd/sd-lldp.h @@ -33,6 +33,87 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_lldp sd_lldp; typedef struct sd_lldp_neighbor sd_lldp_neighbor; +#define SD_LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e } + +/* IEEE 802.3AB Clause 9: TLV Types */ +enum { + SD_LLDP_TYPE_END = 0, + SD_LLDP_TYPE_CHASSIS_ID = 1, + SD_LLDP_TYPE_PORT_ID = 2, + SD_LLDP_TYPE_TTL = 3, + SD_LLDP_TYPE_PORT_DESCRIPTION = 4, + SD_LLDP_TYPE_SYSTEM_NAME = 5, + SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6, + SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7, + SD_LLDP_TYPE_MGMT_ADDRESS = 8, + SD_LLDP_TYPE_PRIVATE = 127, +}; + +/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */ +enum { + SD_LLDP_CHASSIS_SUBTYPE_RESERVED = 0, + SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1, + SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2, + SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3, + SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4, + SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5, + SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6, + SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7, +}; + +/* IEEE 802.3AB Clause 9.5.3: Port subtype */ +enum { + SD_LLDP_PORT_SUBTYPE_RESERVED = 0, + SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1, + SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2, + SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3, + SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4, + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5, + SD_LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6, + SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7, +}; + +enum { + SD_LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0, + SD_LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1, + SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2, + SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3, + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4, + SD_LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5, + SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6, + SD_LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7, + SD_LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8, + SD_LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9, + SD_LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10, +}; + +#define SD_LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1) + +#define SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS \ + ((uint16_t) \ + (SD_LLDP_SYSTEM_CAPABILITIES_REPEATER| \ + SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE| \ + SD_LLDP_SYSTEM_CAPABILITIES_WLAN_AP| \ + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER| \ + SD_LLDP_SYSTEM_CAPABILITIES_DOCSIS| \ + SD_LLDP_SYSTEM_CAPABILITIES_CVLAN| \ + SD_LLDP_SYSTEM_CAPABILITIES_SVLAN| \ + SD_LLDP_SYSTEM_CAPABILITIES_TPMR)) + + +#define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 } +#define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f } + +enum { + SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1, + SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2, + SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3, + SD_LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4, + SD_LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5, + SD_LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6, + SD_LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7, +}; + typedef enum sd_lldp_event { SD_LLDP_EVENT_ADDED = 'a', SD_LLDP_EVENT_REMOVED = 'r', 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); } diff --git a/src/test/test-udev.c b/src/test/test-udev.c index d01789fe08..64ef08652c 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -40,11 +40,11 @@ static int fake_filesystems(void) { const char *target; const char *error; } fakefss[] = { - { "test/sys", "/sys", "failed to mount test /sys" }, - { "test/dev", "/dev", "failed to mount test /dev" }, - { "test/run", "/run", "failed to mount test /run" }, - { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" }, - { "test/run", UDEVLIBEXECDIR "/rules.d","failed to mount empty " UDEVLIBEXECDIR "/rules.d" }, + { "test/tmpfs/sys", "/sys", "failed to mount test /sys" }, + { "test/dev", "/dev", "failed to mount test /dev" }, + { "test/run", "/run", "failed to mount test /run" }, + { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" }, + { "test/run", UDEVLIBEXECDIR "/rules.d","failed to mount empty " UDEVLIBEXECDIR "/rules.d" }, }; unsigned int i; int err; |