diff options
Diffstat (limited to 'src')
59 files changed, 445 insertions, 188 deletions
diff --git a/src/basic/af-list.c b/src/basic/af-list.c index 3fac9c508b..4b291d177b 100644 --- a/src/basic/af-list.c +++ b/src/basic/af-list.c @@ -23,7 +23,7 @@ #include "af-list.h" #include "macro.h" -static const struct af_name* lookup_af(register const char *str, register unsigned int len); +static const struct af_name* lookup_af(register const char *str, register GPERF_LEN_TYPE len); #include "af-from-name.h" #include "af-to-name.h" diff --git a/src/basic/arphrd-list.c b/src/basic/arphrd-list.c index 6792d1ee3f..2d598dc66f 100644 --- a/src/basic/arphrd-list.c +++ b/src/basic/arphrd-list.c @@ -23,7 +23,7 @@ #include "arphrd-list.h" #include "macro.h" -static const struct arphrd_name* lookup_arphrd(register const char *str, register unsigned int len); +static const struct arphrd_name* lookup_arphrd(register const char *str, register GPERF_LEN_TYPE len); #include "arphrd-from-name.h" #include "arphrd-to-name.h" diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index 3e249505a5..2e5622699d 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -20,6 +20,7 @@ #include <alloca.h> #include <ctype.h> #include <errno.h> +#include <limits.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -96,7 +97,7 @@ static void normalize_chain(CalendarComponent **c) { * While we're counting the chain, also normalize `stop` * so the length of the range is a multiple of `repeat` */ - if (i->stop > i->start) + if (i->stop > i->start && i->repeat > 0) i->stop -= (i->stop - i->start) % i->repeat; } @@ -487,7 +488,7 @@ static int parse_weekdays(const char **p, CalendarSpec *c) { } } -static int parse_component_decimal(const char **p, bool usec, unsigned long *res) { +static int parse_component_decimal(const char **p, bool usec, int *res) { unsigned long value; const char *e = NULL; char *ee = NULL; @@ -502,8 +503,6 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res return -errno; if (ee == *p) return -EINVAL; - if ((unsigned long) (int) value != value) - return -ERANGE; e = ee; if (usec) { @@ -511,12 +510,10 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res return -ERANGE; value *= USEC_PER_SEC; - if (*e == '.') { - unsigned add; - /* This is the start of a range, not a fractional part */ - if (e[1] == '.') - goto finish; + /* One "." is a decimal point, but ".." is a range separator */ + if (e[0] == '.' && e[1] != '.') { + unsigned add; e++; r = parse_fractional_part_u(&e, 6, &add); @@ -529,7 +526,9 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res } } -finish: + if (value > INT_MAX) + return -ERANGE; + *p = e; *res = value; @@ -556,9 +555,8 @@ static int const_chain(int value, CalendarComponent **c) { } static int prepend_component(const char **p, bool usec, CalendarComponent **c) { - unsigned long start, stop = -1, repeat = 0; + int r, start, stop = -1, repeat = 0; CalendarComponent *cc; - int r; const char *e; assert(p); @@ -1016,8 +1014,7 @@ fail: return r; } -static int find_end_of_month(struct tm *tm, bool utc, int day) -{ +static int find_end_of_month(struct tm *tm, bool utc, int day) { struct tm t = *tm; t.tm_mon++; diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index 3e773a06f5..d68cc78d05 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -26,7 +26,7 @@ #include "parse-util.h" #include "util.h" -static const struct capability_name* lookup_capability(register const char *str, register unsigned int len); +static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len); #include "cap-from-name.h" #include "cap-to-name.h" diff --git a/src/basic/errno-list.c b/src/basic/errno-list.c index 31b66bad5e..c6a01eec8b 100644 --- a/src/basic/errno-list.c +++ b/src/basic/errno-list.c @@ -23,7 +23,7 @@ #include "macro.h" static const struct errno_name* lookup_errno(register const char *str, - register unsigned int len); + register GPERF_LEN_TYPE len); #include "errno-from-name.h" #include "errno-to-name.h" diff --git a/src/basic/missing.h b/src/basic/missing.h index dd4425697f..480462357d 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -34,6 +34,7 @@ #include <net/ethernet.h> #include <stdlib.h> #include <sys/resource.h> +#include <sys/socket.h> #include <sys/syscall.h> #include <uchar.h> #include <unistd.h> @@ -50,6 +51,23 @@ #include <linux/btrfs.h> #endif +#ifdef HAVE_LINUX_VM_SOCKETS_H +#include <linux/vm_sockets.h> +#else +#define VMADDR_CID_ANY -1U +struct sockaddr_vm { + unsigned short svm_family; + unsigned short svm_reserved1; + unsigned int svm_port; + unsigned int svm_cid; + unsigned char svm_zero[sizeof(struct sockaddr) - + sizeof(unsigned short) - + sizeof(unsigned short) - + sizeof(unsigned int) - + sizeof(unsigned int)]; +}; +#endif /* !HAVE_LINUX_VM_SOCKETS_H */ + #include "macro.h" #ifndef RLIMIT_RTTIME @@ -1163,4 +1181,8 @@ struct ethtool_link_settings { #define SOL_ALG 279 #endif +#ifndef AF_VSOCK +#define AF_VSOCK 40 +#endif + #include "missing_syscall.h" diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 4ebf106109..77f81a60ba 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -113,6 +113,30 @@ int socket_address_parse(SocketAddress *a, const char *s) { memcpy(a->sockaddr.un.sun_path+1, s+1, l); a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; + } else if (startswith(s, "vsock:")) { + /* AF_VSOCK socket in vsock:cid:port notation */ + const char *cid_start = s + strlen("vsock:"); + + e = strchr(cid_start, ':'); + if (!e) + return -EINVAL; + + r = safe_atou(e+1, &u); + if (r < 0) + return r; + + n = strndupa(cid_start, e - cid_start); + if (!isempty(n)) { + r = safe_atou(n, &a->sockaddr.vm.svm_cid); + if (r < 0) + return r; + } else + a->sockaddr.vm.svm_cid = VMADDR_CID_ANY; + + a->sockaddr.vm.svm_family = AF_VSOCK; + a->sockaddr.vm.svm_port = u; + a->size = sizeof(struct sockaddr_vm); + } else { e = strchr(s, ':'); if (e) { @@ -289,6 +313,15 @@ int socket_address_verify(const SocketAddress *a) { return 0; + case AF_VSOCK: + if (a->size != sizeof(struct sockaddr_vm)) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + default: return -EAFNOSUPPORT; } @@ -394,6 +427,15 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { break; + case AF_VSOCK: + if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid) + return false; + + if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port) + return false; + + break; + default: /* Cannot compare, so we assume the addresses are different */ return false; @@ -480,15 +522,27 @@ bool socket_address_matches_fd(const SocketAddress *a, int fd) { return socket_address_equal(a, &b); } -int sockaddr_port(const struct sockaddr *_sa) { +int sockaddr_port(const struct sockaddr *_sa, unsigned *port) { union sockaddr_union *sa = (union sockaddr_union*) _sa; assert(sa); - if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6)) - return -EAFNOSUPPORT; + switch (sa->sa.sa_family) { + case AF_INET: + *port = be16toh(sa->in.sin_port); + return 0; + + case AF_INET6: + *port = be16toh(sa->in6.sin6_port); + return 0; + + case AF_VSOCK: + *port = sa->vm.svm_port; + return 0; - return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port); + default: + return -EAFNOSUPPORT; + } } int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) { @@ -591,6 +645,18 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ break; + case AF_VSOCK: + if (include_port) + r = asprintf(&p, + "vsock:%u:%u", + sa->vm.svm_cid, + sa->vm.svm_port); + else + r = asprintf(&p, "vsock:%u", sa->vm.svm_cid); + if (r < 0) + return -ENOMEM; + break; + default: return -EOPNOTSUPP; } @@ -748,6 +814,9 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b if (a->sa.sa_family == AF_INET6) return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0; + if (a->sa.sa_family == AF_VSOCK) + return a->vm.svm_cid == b->vm.svm_cid; + return false; } diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 2ef572badb..3c42e220e5 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -30,6 +30,7 @@ #include <linux/if_packet.h> #include "macro.h" +#include "missing.h" #include "util.h" union sockaddr_union { @@ -40,6 +41,7 @@ union sockaddr_union { struct sockaddr_nl nl; struct sockaddr_storage storage; struct sockaddr_ll ll; + struct sockaddr_vm vm; }; typedef struct SocketAddress { @@ -100,7 +102,7 @@ const char* socket_address_get_path(const SocketAddress *a); bool socket_ipv6_is_supported(void); -int sockaddr_port(const struct sockaddr *_sa) _pure_; +int sockaddr_port(const struct sockaddr *_sa, unsigned *port); int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret); int getpeername_pretty(int fd, bool include_port, char **ret); diff --git a/src/basic/sparse-endian.h b/src/basic/sparse-endian.h index c913fda8c5..a3573b84a9 100644 --- a/src/basic/sparse-endian.h +++ b/src/basic/sparse-endian.h @@ -26,19 +26,19 @@ #include <stdint.h> #ifdef __CHECKER__ -#define __bitwise __attribute__((bitwise)) -#define __force __attribute__((force)) +#define __sd_bitwise __attribute__((bitwise)) +#define __sd_force __attribute__((force)) #else -#define __bitwise -#define __force +#define __sd_bitwise +#define __sd_force #endif -typedef uint16_t __bitwise le16_t; -typedef uint16_t __bitwise be16_t; -typedef uint32_t __bitwise le32_t; -typedef uint32_t __bitwise be32_t; -typedef uint64_t __bitwise le64_t; -typedef uint64_t __bitwise be64_t; +typedef uint16_t __sd_bitwise le16_t; +typedef uint16_t __sd_bitwise be16_t; +typedef uint32_t __sd_bitwise le32_t; +typedef uint32_t __sd_bitwise be32_t; +typedef uint64_t __sd_bitwise le64_t; +typedef uint64_t __sd_bitwise be64_t; #undef htobe16 #undef htole16 @@ -69,20 +69,23 @@ typedef uint64_t __bitwise be64_t; #define bswap_64_on_be(x) __bswap_64(x) #endif -static inline le16_t htole16(uint16_t value) { return (le16_t __force) bswap_16_on_be(value); } -static inline le32_t htole32(uint32_t value) { return (le32_t __force) bswap_32_on_be(value); } -static inline le64_t htole64(uint64_t value) { return (le64_t __force) bswap_64_on_be(value); } +static inline le16_t htole16(uint16_t value) { return (le16_t __sd_force) bswap_16_on_be(value); } +static inline le32_t htole32(uint32_t value) { return (le32_t __sd_force) bswap_32_on_be(value); } +static inline le64_t htole64(uint64_t value) { return (le64_t __sd_force) bswap_64_on_be(value); } -static inline be16_t htobe16(uint16_t value) { return (be16_t __force) bswap_16_on_le(value); } -static inline be32_t htobe32(uint32_t value) { return (be32_t __force) bswap_32_on_le(value); } -static inline be64_t htobe64(uint64_t value) { return (be64_t __force) bswap_64_on_le(value); } +static inline be16_t htobe16(uint16_t value) { return (be16_t __sd_force) bswap_16_on_le(value); } +static inline be32_t htobe32(uint32_t value) { return (be32_t __sd_force) bswap_32_on_le(value); } +static inline be64_t htobe64(uint64_t value) { return (be64_t __sd_force) bswap_64_on_le(value); } -static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __force)value); } -static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __force)value); } -static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __force)value); } +static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __sd_force)value); } +static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __sd_force)value); } +static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __sd_force)value); } -static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __force)value); } -static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __force)value); } -static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __force)value); } +static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __sd_force)value); } +static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __sd_force)value); } +static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __sd_force)value); } + +#undef __sd_bitwise +#undef __sd_force #endif /* SPARSE_ENDIAN_H */ diff --git a/src/basic/special.h b/src/basic/special.h index 5276bcf598..feb8e5fe21 100644 --- a/src/basic/special.h +++ b/src/basic/special.h @@ -103,6 +103,7 @@ #define SPECIAL_DBUS_SOCKET "dbus.socket" #define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket" #define SPECIAL_JOURNALD_SERVICE "systemd-journald.service" +#define SPECIAL_TMPFILES_SETUP_SERVICE "systemd-tmpfiles-setup.service" /* Magic init signals */ #define SPECIAL_KBREQUEST_TARGET "kbrequest.target" diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 938533d2e7..c619dad527 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -46,6 +46,8 @@ bool uid_is_valid(uid_t uid) { + /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.436. */ + /* Some libc APIs use UID_INVALID as special placeholder */ if (uid == (uid_t) UINT32_C(0xFFFFFFFF)) return false; @@ -519,7 +521,15 @@ bool valid_user_group_name(const char *u) { const char *i; long sz; - /* Checks if the specified name is a valid user/group name. */ + /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, + * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: + * + * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator) + * - We require that names fit into the appropriate utmp field + * - We don't allow empty user names + * + * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. + */ if (isempty(u)) return false; diff --git a/src/core/device.c b/src/core/device.c index bd481c8050..0e67c96552 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -385,7 +385,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa * on its radar. In this case the device unit is partially initialized * and includes the deps on the mount unit but at that time the "bind * mounts" flag wasn't not present. Fix this up now. */ - if (device_is_bound_by_mounts(u, dev)) + if (dev && device_is_bound_by_mounts(u, dev)) device_upgrade_mount_deps(u); /* Note that this won't dispatch the load queue, the caller diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index bbac2d84b5..fc27a07955 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -120,7 +120,7 @@ int config_parse_restrict_namespaces(const char *unit, const char *filename, uns int config_parse_bind_paths(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); /* gperf prototypes */ -const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length); extern const char load_fragment_gperf_nulstr[]; typedef enum Disabled { diff --git a/src/core/service.c b/src/core/service.c index 73a8104d17..54074ff7bc 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1292,10 +1292,10 @@ static int service_spawn( return r; } - if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) { + if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) { _cleanup_free_ char *addr = NULL; char *t; - int port; + unsigned port; r = sockaddr_pretty(&sa.sa, salen, true, false, &addr); if (r < 0) @@ -1306,9 +1306,9 @@ static int service_spawn( return -ENOMEM; our_env[n_env++] = t; - port = sockaddr_port(&sa.sa); - if (port < 0) - return port; + r = sockaddr_port(&sa.sa, &port); + if (r < 0) + return r; if (asprintf(&t, "REMOTE_PORT=%u", port) < 0) return -ENOMEM; diff --git a/src/core/socket.c b/src/core/socket.c index 0960a30039..3cae6b31bb 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -63,6 +63,7 @@ struct SocketPeer { Socket *socket; union sockaddr_union peer; + socklen_t peer_salen; }; static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { @@ -448,7 +449,7 @@ static int socket_verify(Socket *s) { return 0; if (!s->ports) { - log_unit_error(UNIT(s), "Unit lacks Listen setting. Refusing."); + log_unit_error(UNIT(s), "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing."); return -EINVAL; } @@ -484,12 +485,15 @@ static void peer_address_hash_func(const void *p, struct siphash *state) { const SocketPeer *s = p; assert(s); - assert(IN_SET(s->peer.sa.sa_family, AF_INET, AF_INET6)); if (s->peer.sa.sa_family == AF_INET) siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state); - else + else if (s->peer.sa.sa_family == AF_INET6) siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state); + else if (s->peer.sa.sa_family == AF_VSOCK) + siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state); + else + assert_not_reached("Unknown address family."); } static int peer_address_compare_func(const void *a, const void *b) { @@ -505,6 +509,12 @@ static int peer_address_compare_func(const void *a, const void *b) { return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr)); case AF_INET6: return memcmp(&x->peer.in6.sin6_addr, &y->peer.in6.sin6_addr, sizeof(x->peer.in6.sin6_addr)); + case AF_VSOCK: + if (x->peer.vm.svm_cid < y->peer.vm.svm_cid) + return -1; + if (x->peer.vm.svm_cid > y->peer.vm.svm_cid) + return 1; + return 0; } assert_not_reached("Black sheep in the family!"); } @@ -591,7 +601,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { if (r < 0) return log_error_errno(errno, "getpeername failed: %m"); - if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6)) { + if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) { *p = NULL; return 0; } @@ -607,6 +617,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { return log_oom(); remote->peer = sa.peer; + remote->peer_salen = salen; r = set_put(s->peers_by_address, remote); if (r < 0) @@ -937,6 +948,16 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) { break; } + case AF_VSOCK: + if (asprintf(&r, + "%u-%u:%u-%u:%u", + nr, + local.vm.svm_cid, local.vm.svm_port, + remote.vm.svm_cid, remote.vm.svm_port) < 0) + return -ENOMEM; + + break; + default: assert_not_reached("Unhandled socket type."); } @@ -2189,7 +2210,7 @@ static void socket_enter_running(Socket *s, int cfd) { } else if (r > 0 && p->n_ref > s->max_connections_per_source) { _cleanup_free_ char *t = NULL; - sockaddr_pretty(&p->peer.sa, FAMILY_ADDRESS_SIZE(p->peer.sa.sa_family), true, false, &t); + (void) sockaddr_pretty(&p->peer.sa, p->peer_salen, true, false, &t); log_unit_warning(UNIT(s), "Too many incoming connections (%u) from source %s, dropping connection.", diff --git a/src/core/triggers.systemd.in b/src/core/triggers.systemd.in index 0d8c303136..f8c8cbc5f9 100644 --- a/src/core/triggers.systemd.in +++ b/src/core/triggers.systemd.in @@ -27,11 +27,13 @@ -- installed, because other cases are covered by the *un scriptlets, -- so sometimes we will reload needlessly. -pid = posix.fork() -if pid == 0 then - assert(posix.exec("%{_bindir}/systemctl", "daemon-reload")) -elseif pid > 0 then - posix.wait(pid) +if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then + assert(posix.exec("%{_bindir}/systemctl", "daemon-reload")) + elseif pid > 0 then + posix.wait(pid) + end end %transfiletriggerun -p <lua> -- @systemunitdir@ /etc/systemd/system @@ -48,10 +50,12 @@ end -- file in %transfiletriggerun and execute the daemon-reload in -- the first %filetriggerpostun. -posix.mkdir("%{_localstatedir}/lib") -posix.mkdir("%{_localstatedir}/lib/rpm-state") -posix.mkdir("%{_localstatedir}/lib/rpm-state/systemd") -io.open("%{_localstatedir}/lib/rpm-state/systemd/needs-reload", "w") +if posix.access("/run/systemd/system") then + posix.mkdir("%{_localstatedir}/lib") + posix.mkdir("%{_localstatedir}/lib/rpm-state") + posix.mkdir("%{_localstatedir}/lib/rpm-state/systemd") + io.open("%{_localstatedir}/lib/rpm-state/systemd/needs-reload", "w") +end %filetriggerpostun -P 1000100 -p <lua> -- @systemunitdir@ /etc/systemd/system if posix.access("%{_localstatedir}/lib/rpm-state/systemd/needs-reload") then diff --git a/src/core/unit.c b/src/core/unit.c index 5d0b17425b..409668f6d2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -866,11 +866,15 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { return 0; if (c->private_tmp) { - r = unit_require_mounts_for(u, "/tmp"); - if (r < 0) - return r; + const char *p; + + FOREACH_STRING(p, "/tmp", "/var/tmp") { + r = unit_require_mounts_for(u, p); + if (r < 0) + return r; + } - r = unit_require_mounts_for(u, "/var/tmp"); + r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true); if (r < 0) return r; } diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index f05544f3d4..e61ef8f249 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -669,7 +669,7 @@ static int get_block_device_harder(const char *path, dev_t *dev) { /* We found a device backed by multiple other devices. We don't really support automatic * discovery on such setups, with the exception of dm-verity partitions. In this case there are - * two backing devices: the data partitoin and the hash partition. We are fine with such + * two backing devices: the data partition and the hash partition. We are fine with such * setups, however, only if both partitions are on the same physical device. Hence, let's * verify this. */ diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c index f75a6f06d2..8ad9738edf 100644 --- a/src/journal-remote/journal-gatewayd.c +++ b/src/journal-remote/journal-gatewayd.c @@ -905,7 +905,7 @@ static int parse_argv(int argc, char *argv[]) { { "key", required_argument, NULL, ARG_KEY }, { "cert", required_argument, NULL, ARG_CERT }, { "trust", required_argument, NULL, ARG_TRUST }, - { "directory", required_argument, NULL, 'D' }, + { "directory", required_argument, NULL, 'D' }, {} }; diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index de1c48f805..716e758b7c 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -179,7 +179,7 @@ void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigne void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_(3,0) _sentinel_; /* gperf lookup function */ -const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* journald_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int config_parse_storage(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/journal/sd-journal.c b/src/journal/sd-journal.c index 56257c41d4..71967a0f33 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1661,6 +1661,9 @@ static int add_search_paths(sd_journal *j) { NULSTR_FOREACH(p, search_paths) (void) add_root_directory(j, p, true); + if (!(j->flags & SD_JOURNAL_LOCAL_ONLY)) + (void) add_root_directory(j, "/var/log/journal/remote", true); + return 0; } diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index a95b9717f0..c7d9f4eea9 100644 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -34,7 +34,7 @@ dropindirs_sort() local -a files local f d i - readarray -t files < <( + readarray -t files <<<"$( for d in "$@"; do for i in "$d/"*"$suffix"; do if [[ -e "$i" ]]; then @@ -42,7 +42,7 @@ dropindirs_sort() fi done done | sort -Vu - ) + )" for f in "${files[@]}"; do for d in "$@"; do @@ -104,11 +104,11 @@ fi ret=0 -readarray -t PLUGINS < <( +readarray -t PLUGINS <<<"$( dropindirs_sort ".install" \ "/etc/kernel/install.d" \ "/usr/lib/kernel/install.d" -) +)" case $COMMAND in add) diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c index cf56c89d76..845a6b7c6c 100644 --- a/src/libsystemd-network/ndisc-router.c +++ b/src/libsystemd-network/ndisc-router.c @@ -459,6 +459,7 @@ _public_ int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, _public_ int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret) { struct nd_opt_prefix_info *pi; + uint8_t flags; int r; assert_return(rt, -EINVAL); @@ -468,7 +469,14 @@ _public_ int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret) if (r < 0) return r; - *ret = pi->nd_opt_pi_flags_reserved; + flags = pi->nd_opt_pi_flags_reserved; + + if ((flags & ND_OPT_PI_FLAG_AUTO) && (pi->nd_opt_pi_prefix_len != 64)) { + log_ndisc("Invalid prefix length, ignoring prefix for stateless autoconfiguration."); + flags &= ~ND_OPT_PI_FLAG_AUTO; + } + + *ret = flags; return 0; } diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index 574cfeac85..a9819b9db3 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -186,7 +186,7 @@ int util_replace_whitespace(const char *str, char *to, size_t len) to[j++] = str[i++]; } to[j] = '\0'; - return 0; + return j; } /* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ diff --git a/src/login/logind.h b/src/login/logind.h index 086fa1eeb5..7556ee2e48 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -182,7 +182,7 @@ int manager_unit_is_active(Manager *manager, const char *unit); int manager_job_is_active(Manager *manager, const char *path); /* gperf lookup function */ -const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int manager_set_lid_switch_ignore(Manager *m, usec_t until); diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 1891f07586..d5051007fc 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -293,7 +293,6 @@ int bus_image_method_set_limit( static int directory_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) { _cleanup_free_ char *path = NULL; - _cleanup_close_ int fd = -1; int r; assert(image); diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index efb20c3622..31a40d47c3 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -243,14 +243,16 @@ static int list_machines(int argc, char *argv[], void *userdata) { if (name[0] == '.' && !arg_all) continue; - if (!GREEDY_REALLOC(machines, n_allocated, n_machines + 1)) { + if (!GREEDY_REALLOC0(machines, n_allocated, n_machines + 1)) { r = log_oom(); goto out; } - machines[n_machines].os = NULL; - machines[n_machines].version_id = NULL; - r = call_get_os_release( + machines[n_machines].name = name; + machines[n_machines].class = class; + machines[n_machines].service = service; + + (void) call_get_os_release( bus, "GetMachineOSRelease", name, @@ -258,12 +260,6 @@ static int list_machines(int argc, char *argv[], void *userdata) { "VERSION_ID\0", &machines[n_machines].os, &machines[n_machines].version_id); - if (r < 0) - goto out; - - machines[n_machines].name = name; - machines[n_machines].class = class; - machines[n_machines].service = service; l = strlen(name); if (l > max_name) @@ -331,7 +327,7 @@ static int list_machines(int argc, char *argv[], void *userdata) { (int) max_version_id, strdash_if_empty(machines[j].version_id)); r = print_addresses(bus, machines[j].name, 0, "", prefix, arg_addrs); - if (r == -ENOSYS) + if (r == -EOPNOTSUPP) printf("-\n"); } diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index b3461e39a9..e74ae9eb9f 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -59,6 +59,7 @@ VXLAN.TOS, config_parse_unsigned, 0, VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl) VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning) VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) +VXLAN.ReduceARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss) VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 70ff947b99..37c7431213 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -175,7 +175,7 @@ NetDevKind netdev_kind_from_string(const char *d) _pure_; int config_parse_netdev_kind(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); /* gperf */ -const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length); /* Macros which append INTERFACE= to the message */ diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h index 93819626ba..1136975a5e 100644 --- a/src/network/networkd-conf.h +++ b/src/network/networkd-conf.h @@ -23,7 +23,7 @@ typedef struct Manager Manager; int manager_parse_config_file(Manager *m); -const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int config_parse_duid_type( const char *unit, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 8d6992cee8..b993d27c2f 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1338,6 +1338,58 @@ static int link_set_bridge(Link *link) { return r; } +static int link_bond_set(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + assert(link->network); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK); + if (r < 0) + return log_link_error_errno(link, r, "Could not set netlink flags: %m"); + + r = sd_netlink_message_open_container(req, IFLA_LINKINFO); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m"); + + r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond"); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + if (link->network->active_slave) { + r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m"); + } + + if (link->network->primary_slave) { + r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m"); + } + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m"); + + r = sd_netlink_message_close_container(req); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); + + r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return r; +} + static int link_lldp_save(Link *link) { _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -1992,6 +2044,12 @@ static int link_joined(Link *link) { log_link_error_errno(link, r, "Could not set bridge message: %m"); } + if (link->network->bond) { + r = link_bond_set(link); + if (r < 0) + log_link_error_errno(link, r, "Could not set bond message: %m"); + } + if (link->network->use_br_vlan && (link->network->bridge || streq_ptr("bridge", link->kind))) { r = link_set_bridge_vlan(link); diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 5097ab9d72..bc80c693d0 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -133,6 +133,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { route->family = AF_INET6; route->table = link->network->ipv6_accept_ra_route_table; + route->priority = link->network->dhcp_route_metric; route->protocol = RTPROT_RA; route->pref = preference; route->gw.in6 = gateway; @@ -254,6 +255,7 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) route->family = AF_INET6; route->table = link->network->ipv6_accept_ra_route_table; + route->priority = link->network->dhcp_route_metric; route->protocol = RTPROT_RA; route->flags = RTM_F_PREFIX; route->dst_prefixlen = prefixlen; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c9b9044a14..7b54e81fb8 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -60,10 +60,12 @@ Network.IPForward, config_parse_address_family_boolean_with Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions) Network.IPv6AcceptRA, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra) -/* legacy alias for the above */ Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra) Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits) Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit) +Network.ActiveSlave, config_parse_bool, 0, offsetof(Network, active_slave) +Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave) +Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp) Network.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp) Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) Address.Address, config_parse_address, 0, 0 diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index d13e306add..b7da9d22d4 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -167,6 +167,8 @@ struct Network { int proxy_arp; bool ipv6_accept_ra_use_dns; + bool active_slave; + bool primary_slave; DHCPUseDomains ipv6_accept_ra_use_domains; uint32_t ipv6_accept_ra_route_table; @@ -242,7 +244,7 @@ int config_parse_ntp(const char *unit, const char *filename, unsigned line, cons /* Legacy IPv4LL support */ int config_parse_ipv4ll(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); -const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length); extern const sd_bus_vtable network_vtable[]; diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h index 4bd0c642df..e9ea087191 100644 --- a/src/nspawn/nspawn-settings.h +++ b/src/nspawn/nspawn-settings.h @@ -103,7 +103,7 @@ bool settings_private_network(Settings *s); DEFINE_TRIVIAL_CLEANUP_FUNC(Settings*, settings_free); -const struct ConfigPerfItem* nspawn_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* nspawn_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int config_parse_capability(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_id128(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/nspawn/nspawn.c b/src/nspawn/nspawn.c index 6246c6d6fa..6396a69c5c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1440,12 +1440,9 @@ static int copy_devnodes(const char *dest) { } else { if (mknod(to, st.st_mode, st.st_rdev) < 0) { - /* - * This is some sort of protection too against - * recursive userns chown on shared /dev/ - */ + /* Explicitly warn the user when /dev is already populated. */ if (errno == EEXIST) - log_notice("%s/dev/ should be an empty directory", dest); + log_notice("%s/dev is pre-mounted and pre-populated. If a pre-mounted /dev is provided it needs to be an unpopulated file system.", dest); if (errno != EPERM) return log_error_errno(errno, "mknod(%s) failed: %m", to); @@ -2811,15 +2808,14 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r return 0; } -static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pid) { +static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pid, sd_event_source **notify_event_source) { int r; - sd_event_source *notify_event_source; - r = sd_event_add_io(event, ¬ify_event_source, fd, EPOLLIN, nspawn_dispatch_notify_fd, inner_child_pid); + r = sd_event_add_io(event, notify_event_source, fd, EPOLLIN, nspawn_dispatch_notify_fd, inner_child_pid); if (r < 0) return log_error_errno(r, "Failed to allocate notify event source: %m"); - (void) sd_event_source_set_description(notify_event_source, "nspawn-notify"); + (void) sd_event_source_set_description(*notify_event_source, "nspawn-notify"); return 0; } @@ -3084,6 +3080,7 @@ static int run(int master, uid_shift_socket_pair[2] = { -1, -1 }; _cleanup_close_ int notify_socket= -1; _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL; + _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; _cleanup_(pty_forward_freep) PTYForward *forward = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; @@ -3367,7 +3364,7 @@ static int run(int master, if (r < 0) return log_error_errno(r, "Failed to get default event source: %m"); - r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*pid)); + r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*pid), ¬ify_event_source); if (r < 0) return r; diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c index 895f61c462..fac37faea5 100644 --- a/src/nss-mymachines/nss-mymachines.c +++ b/src/nss-mymachines/nss-mymachines.c @@ -512,10 +512,8 @@ enum nss_status _nss_mymachines_getpwuid_r( BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); - if (!uid_is_valid(uid)) { - r = -EINVAL; - goto fail; - } + if (!uid_is_valid(uid)) + goto not_found; /* We consider all uids < 65536 host uids */ if (uid < HOST_UID_LIMIT) @@ -686,10 +684,8 @@ enum nss_status _nss_mymachines_getgrgid_r( BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); - if (!gid_is_valid(gid)) { - r = -EINVAL; - goto fail; - } + if (!gid_is_valid(gid)) + goto not_found; /* We consider all gids < 65536 host gids */ if (gid < HOST_GID_LIMIT) diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index c80972742b..fd5064c937 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -123,10 +123,10 @@ enum nss_status _nss_systemd_getpwnam_r( assert(name); assert(pwd); - if (!valid_user_group_name(name)) { - r = -EINVAL; - goto fail; - } + /* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't + * generate EINVAL here, because it isn't really out business to complain about invalid user names. */ + if (!valid_user_group_name(name)) + goto not_found; /* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */ if (streq(name, root_passwd.pw_name)) { @@ -227,10 +227,8 @@ enum nss_status _nss_systemd_getpwuid_r( BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); - if (!uid_is_valid(uid)) { - r = -EINVAL; - goto fail; - } + if (!uid_is_valid(uid)) + goto not_found; /* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */ if (uid == root_passwd.pw_uid) { @@ -329,10 +327,8 @@ enum nss_status _nss_systemd_getgrnam_r( assert(name); assert(gr); - if (!valid_user_group_name(name)) { - r = -EINVAL; - goto fail; - } + if (!valid_user_group_name(name)) + goto not_found; /* Synthesize records for root and nobody, in case they are missing form /etc/group */ if (streq(name, root_group.gr_name)) { @@ -430,10 +426,8 @@ enum nss_status _nss_systemd_getgrgid_r( BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); - if (!gid_is_valid(gid)) { - r = -EINVAL; - goto fail; - } + if (!gid_is_valid(gid)) + goto not_found; /* Synthesize records for root and nobody, in case they are missing from /etc/group */ if (gid == root_group.gr_gid) { diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c index aaf5ed62c1..d89ae28dcd 100644 --- a/src/resolve/dns-type.c +++ b/src/resolve/dns-type.c @@ -29,7 +29,7 @@ typedef const struct { } dns_type; static const struct dns_type_name * -lookup_dns_type (register const char *str, register unsigned int len); +lookup_dns_type (register const char *str, register GPERF_LEN_TYPE len); #include "dns_type-from-name.h" #include "dns_type-to-name.h" diff --git a/src/resolve/resolved-conf.h b/src/resolve/resolved-conf.h index fc425a36b2..8184d6cadf 100644 --- a/src/resolve/resolved-conf.h +++ b/src/resolve/resolved-conf.h @@ -41,7 +41,7 @@ int manager_parse_search_domains_and_warn(Manager *m, const char *string); int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char *word); int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string); -const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int config_parse_dns_servers(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_search_domains(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/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c index 40d650949d..0a284825a1 100644 --- a/src/resolve/resolved-etc-hosts.c +++ b/src/resolve/resolved-etc-hosts.c @@ -431,8 +431,8 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) { for (i = 0; i < bn->n_items; i++) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; - if ((found_a && bn->items[i]->family != AF_INET) && - (found_aaaa && bn->items[i]->family != AF_INET6)) + if ((!found_a && bn->items[i]->family == AF_INET) || + (!found_aaaa && bn->items[i]->family == AF_INET6)) continue; r = dns_resource_record_new_address(&rr, bn->items[i]->family, &bn->items[i]->address, bn->name); @@ -444,5 +444,5 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) { return r; } - return 1; + return found_a || found_aaaa; } diff --git a/src/shared/install.c b/src/shared/install.c index 474426d927..478abac8ab 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1567,18 +1567,12 @@ static int install_info_symlink_wants( if (strv_isempty(list)) return 0; - if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) { + if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance) { UnitFileInstallInfo instance = { .type = _UNIT_FILE_TYPE_INVALID, }; _cleanup_free_ char *path = NULL; - /* Don't install any symlink if there's no default - * instance configured */ - - if (!i->default_instance) - return 0; - r = unit_name_replace_instance(i->name, i->default_instance, &buf); if (r < 0) return r; @@ -1861,7 +1855,7 @@ int unit_file_unmask( _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; - _cleanup_free_ char **todo = NULL; + _cleanup_strv_free_ char **todo = NULL; size_t n_todo = 0, n_allocated = 0; const char *config_path; char **i; @@ -1899,7 +1893,11 @@ int unit_file_unmask( if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2)) return -ENOMEM; - todo[n_todo++] = *i; + todo[n_todo] = strdup(*i); + if (!todo[n_todo]) + return -ENOMEM; + + n_todo++; } strv_uniq(todo); @@ -1947,7 +1945,7 @@ int unit_file_link( unsigned *n_changes) { _cleanup_lookup_paths_free_ LookupPaths paths = {}; - _cleanup_free_ char **todo = NULL; + _cleanup_strv_free_ char **todo = NULL; size_t n_todo = 0, n_allocated = 0; const char *config_path; char **i; @@ -1996,7 +1994,11 @@ int unit_file_link( if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2)) return -ENOMEM; - todo[n_todo++] = *i; + todo[n_todo] = strdup(*i); + if (!todo[n_todo]) + return -ENOMEM; + + n_todo++; } strv_uniq(todo); diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c index a23d09967e..586ef64e72 100644 --- a/src/shared/path-lookup.c +++ b/src/shared/path-lookup.c @@ -139,7 +139,7 @@ static char** user_dirs( const char *e; _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL; _cleanup_free_ char *data_home = NULL; - _cleanup_free_ char **res = NULL; + _cleanup_strv_free_ char **res = NULL; char **tmp; int r; diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c index b810891d7d..1b99b7bc82 100644 --- a/src/socket-proxy/socket-proxyd.c +++ b/src/socket-proxy/socket-proxyd.c @@ -564,7 +564,7 @@ static void help(void) { printf("%1$s [HOST:PORT]\n" "%1$s [SOCKET]\n\n" "Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n" - " -c --max-connections= Set the maximum number of connections to be accepted\n" + " -c --connections-max= Set the maximum number of connections to be accepted\n" " -h --help Show this help\n" " --version Show package version\n", program_invocation_short_name); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index f7e85c1ade..8955d5f51f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1734,7 +1734,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha if (r < 0) return bus_log_parse_error(r); - *deps = ret; + *deps = strv_uniq(ret); ret = NULL; return 0; diff --git a/src/test/test-af-list.c b/src/test/test-af-list.c index aeaa0929b1..e2479133de 100644 --- a/src/test/test-af-list.c +++ b/src/test/test-af-list.c @@ -24,7 +24,7 @@ #include "string-util.h" #include "util.h" -static const struct af_name* lookup_af(register const char *str, register unsigned int len); +static const struct af_name* lookup_af(register const char *str, register GPERF_LEN_TYPE len); #include "af-from-name.h" #include "af-list.h" diff --git a/src/test/test-arphrd-list.c b/src/test/test-arphrd-list.c index f3989ad201..8f4f342faa 100644 --- a/src/test/test-arphrd-list.c +++ b/src/test/test-arphrd-list.c @@ -24,7 +24,7 @@ #include "string-util.h" #include "util.h" -static const struct arphrd_name* lookup_arphrd(register const char *str, register unsigned int len); +static const struct arphrd_name* lookup_arphrd(register const char *str, register GPERF_LEN_TYPE len); #include "arphrd-from-name.h" #include "arphrd-list.h" diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c index 5fd749a6a8..1f34a91b10 100644 --- a/src/test/test-calendarspec.c +++ b/src/test/test-calendarspec.c @@ -238,6 +238,8 @@ int main(int argc, char* argv[]) { assert_se(calendar_spec_from_string("*:05..10/6", &c) < 0); assert_se(calendar_spec_from_string("20/4:00", &c) < 0); assert_se(calendar_spec_from_string("00:00/60", &c) < 0); + assert_se(calendar_spec_from_string("00:00:2300", &c) < 0); + assert_se(calendar_spec_from_string("00:00:18446744073709551615", &c) < 0); test_timestamp(); test_hourly_bug_4031(); diff --git a/src/test/test-selinux.c b/src/test/test-selinux.c index 7545ad3764..b676c25913 100644 --- a/src/test/test-selinux.c +++ b/src/test/test-selinux.c @@ -56,7 +56,7 @@ static void test_loading(void) { n1 = now(CLOCK_MONOTONIC); r = mac_selinux_init(); n2 = now(CLOCK_MONOTONIC); - log_info_errno(r, "mac_selinux_init → %d (%m) %.2fs", r, (n2 - n1)/1e6); + log_info_errno(r, "mac_selinux_init → %d %.2fs (%m)", r, (n2 - n1)/1e6); } static void test_cleanup(void) { @@ -78,18 +78,18 @@ static void test_misc(const char* fname) { log_info("============ %s ==========", __func__); r = mac_selinux_get_our_label(&label); - log_info_errno(r, "mac_selinux_get_our_label → %d (%m), \"%s\"", + log_info_errno(r, "mac_selinux_get_our_label → %d, \"%s\" (%m)", r, strnull(label)); r = mac_selinux_get_create_label_from_exe(fname, &label2); - log_info_errno(r, "mac_selinux_create_label_from_exe → %d (%m), \"%s\"", + log_info_errno(r, "mac_selinux_create_label_from_exe → %d, \"%s\" (%m)", r, strnull(label2)); fd = socket(AF_INET, SOCK_DGRAM, 0); assert_se(fd >= 0); r = mac_selinux_get_child_mls_label(fd, fname, label2, &label3); - log_info_errno(r, "mac_selinux_get_child_mls_label → %d (%m), \"%s\"", + log_info_errno(r, "mac_selinux_get_child_mls_label → %d, \"%s\" (%m)", r, strnull(label3)); } diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 1f853a7f16..d80613dc84 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -92,6 +92,14 @@ static void test_socket_address_parse(void) { assert_se(socket_address_parse(&a, "@abstract") >= 0); assert_se(a.sockaddr.sa.sa_family == AF_UNIX); + + assert_se(socket_address_parse(&a, "vsock::1234") >= 0); + assert_se(a.sockaddr.sa.sa_family == AF_VSOCK); + assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); + assert_se(a.sockaddr.sa.sa_family == AF_VSOCK); + assert_se(socket_address_parse(&a, "vsock:2:1234x") < 0); + assert_se(socket_address_parse(&a, "vsock:2x:1234") < 0); + assert_se(socket_address_parse(&a, "vsock:2") < 0); } static void test_socket_address_parse_netlink(void) { @@ -145,6 +153,14 @@ static void test_socket_address_equal(void) { assert_se(socket_address_parse_netlink(&a, "firewall") >= 0); assert_se(socket_address_parse_netlink(&b, "firewall") >= 0); assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); + assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0); + assert_se(socket_address_equal(&a, &b)); + assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0); + assert_se(!socket_address_equal(&a, &b)); + assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0); + assert_se(!socket_address_equal(&a, &b)); } static void test_socket_address_get_path(void) { @@ -161,6 +177,9 @@ static void test_socket_address_get_path(void) { assert_se(socket_address_parse(&a, "/foo/bar") >= 0); assert_se(streq(socket_address_get_path(&a), "/foo/bar")); + + assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); + assert_se(!socket_address_get_path(&a)); } static void test_socket_address_is(void) { @@ -408,11 +427,18 @@ static void test_sockaddr_equal(void) { .in6.sin6_port = 0, .in6.sin6_addr = IN6ADDR_ANY_INIT, }; + union sockaddr_union e = { + .vm.svm_family = AF_VSOCK, + .vm.svm_port = 0, + .vm.svm_cid = VMADDR_CID_ANY, + }; assert_se(sockaddr_equal(&a, &a)); assert_se(sockaddr_equal(&a, &b)); assert_se(sockaddr_equal(&d, &d)); + assert_se(sockaddr_equal(&e, &e)); assert_se(!sockaddr_equal(&a, &c)); assert_se(!sockaddr_equal(&b, &c)); + assert_se(!sockaddr_equal(&a, &e)); } static void test_sockaddr_un_len(void) { diff --git a/src/timesync/timesyncd-conf.h b/src/timesync/timesyncd-conf.h index cba0724b1b..0280697e9c 100644 --- a/src/timesync/timesyncd-conf.h +++ b/src/timesync/timesyncd-conf.h @@ -22,7 +22,7 @@ #include "conf-parser.h" #include "timesyncd-manager.h" -const struct ConfigPerfItem* timesyncd_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* timesyncd_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int manager_parse_server_string(Manager *m, ServerType type, const char *string); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 79f75e165b..f4ce9791fb 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -649,7 +649,7 @@ static int path_set_perms(Item *i, const char *path) { else { log_debug("chmod \"%s\" to mode %o", path, m); if (chmod(fn, m) < 0) - return log_error_errno(errno, "chmod(%s) failed: %m", path); + return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, fn); } } @@ -662,7 +662,7 @@ static int path_set_perms(Item *i, const char *path) { if (chown(fn, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID) < 0) - return log_error_errno(errno, "chown(%s) failed: %m", path); + return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn); } } diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index a99060d943..5a25cec6fd 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -94,7 +94,7 @@ const char *mac_policy_to_string(MACPolicy p) _const_; MACPolicy mac_policy_from_string(const char *p) _pure_; /* gperf lookup function */ -const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, unsigned length); +const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length); int config_parse_mac_policy(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_name_policy(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/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 59b9804dc4..51f364bf94 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -323,6 +323,9 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) && (test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel))) udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1"); + if (test_bit(EV_SW, bitmask_ev)) + udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1"); + } devnode = udev_device_get_devnode(dev); diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c index aa10beafb0..09024116f2 100644 --- a/src/udev/udev-builtin-keyboard.c +++ b/src/udev/udev-builtin-keyboard.c @@ -29,7 +29,7 @@ #include "string-util.h" #include "udev.h" -static const struct key *keyboard_lookup_key(const char *str, unsigned len); +static const struct key *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len); #include "keyboard-keys-from-name.h" static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) { diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 304a28777b..be7c7367ff 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -73,7 +73,9 @@ void udev_event_unref(struct udev_event *event) { free(event); } -size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) { +size_t udev_event_apply_format(struct udev_event *event, + const char *src, char *dest, size_t size, + bool replace_whitespace) { struct udev_device *dev = event->dev; enum subst_type { SUBST_UNKNOWN, @@ -130,8 +132,10 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char * for (;;) { enum subst_type type = SUBST_UNKNOWN; - char attrbuf[UTIL_PATH_SIZE]; - char *attr = NULL; + char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE]; + char *attr = NULL, *_s; + size_t _l; + bool replws = replace_whitespace; while (from[0] != '\0') { if (from[0] == '$') { @@ -200,6 +204,19 @@ subst: attr = NULL; } + /* result subst handles space as field separator */ + if (type == SUBST_RESULT) + replws = false; + + if (replws) { + /* store dest string ptr and remaining len */ + _s = s; + _l = l; + /* temporarily use sbuf */ + s = &sbuf; + l = UTIL_PATH_SIZE; + } + switch (type) { case SUBST_DEVPATH: l = strpcpy(&s, l, udev_device_get_devpath(dev)); @@ -380,6 +397,20 @@ subst: log_error("unknown substitution type=%i", type); break; } + + /* replace whitespace in sbuf and copy to dest */ + if (replws) { + size_t tmplen = UTIL_PATH_SIZE - l; + + /* restore s and l to dest string values */ + s = _s; + l = _l; + + /* copy ws-replaced value to s */ + tmplen = util_replace_whitespace(sbuf, s, MIN(tmplen, l)); + l -= tmplen; + s += tmplen; + } } out: @@ -927,7 +958,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_ const char *cmd = udev_list_entry_get_name(list_entry); enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry); - udev_event_apply_format(event, cmd, command, sizeof(command)); + udev_event_apply_format(event, cmd, command, sizeof(command), false); if (builtin_cmd < UDEV_BUILTIN_MAX) udev_builtin_run(event->dev, builtin_cmd, command, false); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index b0238220e4..4d07b8fce0 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1676,7 +1676,7 @@ static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct name = rules_str(rules, cur->key.attr_off); switch (cur->key.attrsubst) { case SB_FORMAT: - udev_event_apply_format(event, name, nbuf, sizeof(nbuf)); + udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false); name = nbuf; /* fall through */ case SB_NONE: @@ -1838,7 +1838,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, _cleanup_free_ char *value = NULL; size_t len; - udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false); sysctl_normalize(filename); if (sysctl_read(filename, &value) < 0) goto nomatch; @@ -1916,7 +1916,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, struct stat statbuf; int match; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false); if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) { if (filename[0] != '/') { char tmp[UTIL_PATH_SIZE]; @@ -1942,7 +1942,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char result[UTIL_LINE_SIZE]; event->program_result = mfree(event->program_result); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program), false); log_debug("PROGRAM '%s' %s:%u", program, rules_str(rules, rule->rule.filename_off), @@ -1969,7 +1969,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_FILE: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); if (import_file_into_properties(event->dev, import) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -1978,7 +1978,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_PROG: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); log_debug("IMPORT '%s' %s:%u", import, rules_str(rules, rule->rule.filename_off), @@ -2009,7 +2009,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, event->builtin_run |= (1 << cur->key.builtin_cmd); } - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command), false); log_debug("IMPORT builtin '%s' %s:%u", udev_builtin_name(cur->key.builtin_cmd), rules_str(rules, rule->rule.filename_off), @@ -2077,7 +2077,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_PARENT: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); if (import_parent_into_properties(event->dev, import) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -2115,7 +2115,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->owner_final = true; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner), false); event->owner_set = true; r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL); if (r < 0) { @@ -2141,7 +2141,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->group_final = true; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group), false); event->group_set = true; r = get_group_creds(&gr, &event->gid); if (r < 0) { @@ -2165,7 +2165,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, if (event->mode_final) break; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str), false); mode = strtol(mode_str, &endptr, 8); if (endptr[0] != '\0') { log_error("ignoring invalid mode '%s'", mode_str); @@ -2222,7 +2222,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, const char *name, *label; name = rules_str(rules, cur->key.attr_off); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str), false); if (label_str[0] != '\0') label = label_str; else @@ -2256,10 +2256,10 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char temp[UTIL_NAME_SIZE]; /* append value separated by space */ - udev_event_apply_format(event, value, temp, sizeof(temp)); + udev_event_apply_format(event, value, temp, sizeof(temp), false); strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL); } else - udev_event_apply_format(event, value, value_new, sizeof(value_new)); + udev_event_apply_format(event, value, value_new, sizeof(value_new), false); udev_device_add_property(event->dev, name, value_new); break; @@ -2268,7 +2268,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char tag[UTIL_PATH_SIZE]; const char *p; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag), false); if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) udev_device_cleanup_tags_list(event->dev); for (p = tag; *p != '\0'; p++) { @@ -2296,7 +2296,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->name_final = true; - udev_event_apply_format(event, name, name_str, sizeof(name_str)); + udev_event_apply_format(event, name, name_str, sizeof(name_str), false); if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { count = util_replace_chars(name_str, "/"); if (count > 0) @@ -2336,7 +2336,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, udev_device_cleanup_devlinks_list(event->dev); /* allow multiple symlinks separated by spaces */ - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp), esc != ESCAPE_NONE); if (esc == ESCAPE_UNSET) count = util_replace_chars(temp, "/ "); else if (esc == ESCAPE_REPLACE) @@ -2376,7 +2376,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL); attr_subst_subdir(attr, sizeof(attr)); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); log_debug("ATTR '%s' writing '%s' %s:%u", attr, value, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2392,9 +2392,9 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char value[UTIL_NAME_SIZE]; int r; - udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false); sysctl_normalize(filename); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); r = sysctl_write(filename, value); diff --git a/src/udev/udev.h b/src/udev/udev.h index 8433e8d9f2..c0cb7eae84 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -80,7 +80,9 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules); /* udev-event.c */ struct udev_event *udev_event_new(struct udev_device *dev); void udev_event_unref(struct udev_event *event); -size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size); +size_t udev_event_apply_format(struct udev_event *event, + const char *src, char *dest, size_t size, + bool replace_whitespace); int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string, char *result, size_t maxsize, int read_value); int udev_event_spawn(struct udev_event *event, diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 702dbe5282..07b667f131 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -144,7 +144,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) { udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { char program[UTIL_PATH_SIZE]; - udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program)); + udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false); printf("run: '%s'\n", program); } out: |