Commit 8aa8d747 authored by Thomas Haller's avatar Thomas Haller

systemd: update code from upstream (2018-08-26)

This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=56663345dfb1dd3ff23cac5fbc955aba54477efa

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ \
             :/shared/nm-utils/unaligned.h | \
  xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_shared() {
    mkdir -p "./shared/nm-utils/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/env-util.c"
nm_copy_sd "src/basic/env-util.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stat-util.c"
nm_copy_sd "src/basic/stat-util.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
parent 353810cc
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
/***
Copyright © 2014 Tom Gundersen
***/
#include <endian.h> #include <endian.h>
#include <stdint.h> #include <stdint.h>
......
This diff is collapsed.
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include "macro.h"
#include "string.h"
bool env_name_is_valid(const char *e);
bool env_value_is_valid(const char *e);
bool env_assignment_is_valid(const char *e);
enum {
REPLACE_ENV_USE_ENVIRONMENT = 1u,
REPLACE_ENV_ALLOW_BRACELESS = 2u,
REPLACE_ENV_ALLOW_EXTENDED = 4u,
};
char *replace_env_n(const char *format, size_t n, char **env, unsigned flags);
char **replace_env_argv(char **argv, char **env);
static inline char *replace_env(const char *format, char **env, unsigned flags) {
return replace_env_n(format, strlen(format), env, flags);
}
bool strv_env_is_valid(char **e);
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
bool strv_env_name_is_valid(char **l);
bool strv_env_name_or_assignment_is_valid(char **l);
char **strv_env_merge(size_t n_lists, ...);
char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */
char **strv_env_set(char **x, const char *p); /* New copy ... */
char **strv_env_unset(char **l, const char *p); /* In place ... */
char **strv_env_unset_many(char **l, ...) _sentinel_;
int strv_env_replace(char ***l, char *p); /* In place ... */
char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
char *strv_env_get(char **x, const char *n) _pure_;
int getenv_bool(const char *p);
int getenv_bool_secure(const char *p);
int serialize_environment(FILE *f, char **environment);
int deserialize_environment(char ***environment, const char *line);
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
/***
Copyright © 2014 Tom Gundersen
***/
#include <errno.h> #include <errno.h>
#include <net/ethernet.h> #include <net/ethernet.h>
......
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
/***
Copyright © 2014 Tom Gundersen
***/
#include <net/ethernet.h> #include <net/ethernet.h>
#include <stdbool.h> #include <stdbool.h>
......
...@@ -78,8 +78,12 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags); ...@@ -78,8 +78,12 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags);
int fd_duplicate_data_fd(int fd); int fd_duplicate_data_fd(int fd);
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */ /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
#define ERRNO_IS_DISCONNECT(r) \ /* The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH) * See the icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, \
ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \
ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, ENONET)
/* Resource exhaustion, could be our fault or general system trouble */ /* Resource exhaustion, could be our fault or general system trouble */
#define ERRNO_IS_RESOURCE(r) \ #define ERRNO_IS_RESOURCE(r) \
......
...@@ -1225,9 +1225,13 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) { ...@@ -1225,9 +1225,13 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
const char *fn; const char *fn;
char *t; char *t;
assert(p);
assert(ret); assert(ret);
if (isempty(p))
return -EINVAL;
if (path_equal(p, "/"))
return -EINVAL;
/* /*
* Turns this: * Turns this:
* /foo/bar/waldo * /foo/bar/waldo
...@@ -1258,9 +1262,13 @@ int tempfn_random(const char *p, const char *extra, char **ret) { ...@@ -1258,9 +1262,13 @@ int tempfn_random(const char *p, const char *extra, char **ret) {
uint64_t u; uint64_t u;
unsigned i; unsigned i;
assert(p);
assert(ret); assert(ret);
if (isempty(p))
return -EINVAL;
if (path_equal(p, "/"))
return -EINVAL;
/* /*
* Turns this: * Turns this:
* /foo/bar/waldo * /foo/bar/waldo
...@@ -1319,7 +1327,10 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { ...@@ -1319,7 +1327,10 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
if (!t) if (!t)
return -ENOMEM; return -ENOMEM;
x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra); if (isempty(p))
x = stpcpy(stpcpy(t, ".#"), extra);
else
x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
u = random_u64(); u = random_u64();
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
...@@ -1404,7 +1415,8 @@ int open_tmpfile_unlinkable(const char *directory, int flags) { ...@@ -1404,7 +1415,8 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
r = tmp_dir(&directory); r = tmp_dir(&directory);
if (r < 0) if (r < 0)
return r; return r;
} } else if (isempty(directory))
return -EINVAL;
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */ /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
...@@ -1439,22 +1451,14 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { ...@@ -1439,22 +1451,14 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
* which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
* "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */ * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
{ fd = open_parent(target, O_TMPFILE|flags, 0640);
_cleanup_free_ char *dn = NULL; if (fd >= 0) {
*ret_path = NULL;
dn = dirname_malloc(target); return fd;
if (!dn)
return -ENOMEM;
fd = open(dn, O_TMPFILE|flags, 0640);
if (fd >= 0) {
*ret_path = NULL;
return fd;
}
log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
} }
log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target);
r = tempfn_random(target, NULL, &tmp); r = tempfn_random(target, NULL, &tmp);
if (r < 0) if (r < 0)
return r; return r;
......
...@@ -435,6 +435,31 @@ int mkfifo_atomic(const char *path, mode_t mode) { ...@@ -435,6 +435,31 @@ int mkfifo_atomic(const char *path, mode_t mode) {
return 0; return 0;
} }
int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) {
_cleanup_free_ char *t = NULL;
int r;
assert(path);
if (path_is_absolute(path))
return mkfifo_atomic(path, mode);
/* We're only interested in the (random) filename. */
r = tempfn_random_child("", NULL, &t);
if (r < 0)
return r;
if (mkfifoat(dirfd, t, mode) < 0)
return -errno;
if (renameat(dirfd, t, dirfd, path) < 0) {
unlink_noerrno(t);
return -errno;
}
return 0;
}
int get_files_in_directory(const char *path, char ***list) { int get_files_in_directory(const char *path, char ***list) {
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
struct dirent *de; struct dirent *de;
...@@ -670,7 +695,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, ...@@ -670,7 +695,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) { if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) {
/* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set /* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set
* and doesn't care about any of the other special features we provide either. */ * and doesn't care about any of the other special features we provide either. */
r = open(path, O_PATH|O_CLOEXEC); r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0));
if (r < 0) if (r < 0)
return -errno; return -errno;
...@@ -825,7 +850,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, ...@@ -825,7 +850,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0) fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
return -EREMOTE; return -EREMOTE;
if (S_ISLNK(st.st_mode)) { if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) {
char *joined; char *joined;
_cleanup_free_ char *destination = NULL; _cleanup_free_ char *destination = NULL;
...@@ -1156,7 +1181,7 @@ int unlinkat_deallocate(int fd, const char *name, int flags) { ...@@ -1156,7 +1181,7 @@ int unlinkat_deallocate(int fd, const char *name, int flags) {
} }
int fsync_directory_of_file(int fd) { int fsync_directory_of_file(int fd) {
_cleanup_free_ char *path = NULL, *dn = NULL; _cleanup_free_ char *path = NULL;
_cleanup_close_ int dfd = -1; _cleanup_close_ int dfd = -1;
int r; int r;
...@@ -1182,16 +1207,40 @@ int fsync_directory_of_file(int fd) { ...@@ -1182,16 +1207,40 @@ int fsync_directory_of_file(int fd) {
if (!path_is_absolute(path)) if (!path_is_absolute(path))
return -EINVAL; return -EINVAL;
dn = dirname_malloc(path); dfd = open_parent(path, O_CLOEXEC, 0);
if (!dn)
return -ENOMEM;
dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (dfd < 0) if (dfd < 0)
return -errno; return dfd;
if (fsync(dfd) < 0) if (fsync(dfd) < 0)
return -errno; return -errno;
return 0; return 0;
} }
int open_parent(const char *path, int flags, mode_t mode) {
_cleanup_free_ char *parent = NULL;
int fd;
if (isempty(path))
return -EINVAL;
if (path_equal(path, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */
return -EINVAL;
parent = dirname_malloc(path);
if (!parent)
return -ENOMEM;
/* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an
* O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */
if ((flags & O_PATH) == O_PATH)
flags |= O_DIRECTORY;
else if ((flags & O_TMPFILE) != O_TMPFILE)
flags |= O_DIRECTORY|O_RDONLY;
fd = open(parent, flags, mode);
if (fd < 0)
return -errno;
return fd;
}
...@@ -42,6 +42,7 @@ int symlink_idempotent(const char *from, const char *to); ...@@ -42,6 +42,7 @@ int symlink_idempotent(const char *from, const char *to);
int symlink_atomic(const char *from, const char *to); int symlink_atomic(const char *from, const char *to);
int mknod_atomic(const char *path, mode_t mode, dev_t dev); int mknod_atomic(const char *path, mode_t mode, dev_t dev);
int mkfifo_atomic(const char *path, mode_t mode); int mkfifo_atomic(const char *path, mode_t mode);
int mkfifoat_atomic(int dir_fd, const char *path, mode_t mode);
int get_files_in_directory(const char *path, char ***list); int get_files_in_directory(const char *path, char ***list);
...@@ -72,6 +73,7 @@ enum { ...@@ -72,6 +73,7 @@ enum {
CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */ CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */
CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */ CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */ CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */
CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */
}; };
/* How many iterations to execute before returning -ELOOP */ /* How many iterations to execute before returning -ELOOP */
...@@ -103,3 +105,5 @@ void unlink_tempfilep(char (*p)[]); ...@@ -103,3 +105,5 @@ void unlink_tempfilep(char (*p)[]);
int unlinkat_deallocate(int fd, const char *name, int flags); int unlinkat_deallocate(int fd, const char *name, int flags);
int fsync_directory_of_file(int fd); int fsync_directory_of_file(int fd);
int open_parent(const char *path, int flags, mode_t mode);
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
/***
Copyright © 2014 Michal Schmidt
***/
#include <string.h> #include <string.h>
...@@ -74,7 +71,7 @@ void trivial_hash_func(const void *p, struct siphash *state) { ...@@ -74,7 +71,7 @@ void trivial_hash_func(const void *p, struct siphash *state) {
} }
int trivial_compare_func(const void *a, const void *b) { int trivial_compare_func(const void *a, const void *b) {
return a < b ? -1 : (a > b ? 1 : 0); return CMP(a, b);
} }
const struct hash_ops trivial_hash_ops = { const struct hash_ops trivial_hash_ops = {
...@@ -90,7 +87,7 @@ int uint64_compare_func(const void *_a, const void *_b) { ...@@ -90,7 +87,7 @@ int uint64_compare_func(const void *_a, const void *_b) {
uint64_t a, b; uint64_t a, b;
a = *(const uint64_t*) _a; a = *(const uint64_t*) _a;
b = *(const uint64_t*) _b; b = *(const uint64_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0); return CMP(a, b);
} }
const struct hash_ops uint64_hash_ops = { const struct hash_ops uint64_hash_ops = {
...@@ -107,7 +104,7 @@ int devt_compare_func(const void *_a, const void *_b) { ...@@ -107,7 +104,7 @@ int devt_compare_func(const void *_a, const void *_b) {
dev_t a, b; dev_t a, b;
a = *(const dev_t*) _a; a = *(const dev_t*) _a;
b = *(const dev_t*) _b; b = *(const dev_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0); return CMP(a, b);
} }
const struct hash_ops devt_hash_ops = { const struct hash_ops devt_hash_ops = {
......
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
/***
Copyright © 2014 Michal Schmidt
***/
#include "macro.h" #include "macro.h"
#include "siphash24.h" #include "siphash24.h"
......
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
/***
Copyright © 2014 Michal Schmidt
***/
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
...@@ -9,8 +6,9 @@ ...@@ -9,8 +6,9 @@
#include <string.h> #include <string.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "hashmap.h" #include "env-util.h"
#include "fileio.h" #include "fileio.h"
#include "hashmap.h"
#include "macro.h" #include "macro.h"
#include "mempool.h" #include "mempool.h"
#include "process-util.h" #include "process-util.h"
...@@ -769,20 +767,31 @@ static void reset_direct_storage(HashmapBase *h) { ...@@ -769,20 +767,31 @@ static void reset_direct_storage(HashmapBase *h) {
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets); memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
} }
static bool use_pool(void) {
static int b = -1;
if (!is_main_thread())
return false;
if (b < 0)
b = getenv_bool("SYSTEMD_MEMPOOL") != 0;
return b;
}
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) { static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
HashmapBase *h; HashmapBase *h;
const struct hashmap_type_info *hi = &hashmap_type_info[type]; const struct hashmap_type_info *hi = &hashmap_type_info[type];
bool use_pool; bool up;
use_pool = is_main_thread(); up = use_pool();
h = use_pool ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
if (!h) if (!h)
return NULL; return NULL;
h->type = type; h->type = type;
h->from_pool = use_pool; h->from_pool = up;
h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops; h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;
if (type == HASHMAP_TYPE_ORDERED) { if (type == HASHMAP_TYPE_ORDERED) {
...@@ -860,9 +869,11 @@ static void hashmap_free_no_clear(HashmapBase *h) { ...@@ -860,9 +869,11 @@ static void hashmap_free_no_clear(HashmapBase *h) {
assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0); assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
#endif #endif
if (h->from_pool) if (h->from_pool) {
/* Ensure that the object didn't get migrated between threads. */
assert_se(is_main_thread());
mempool_free_tile(hashmap_type_info[h->type].mempool, h); mempool_free_tile(hashmap_type_info[h->type].mempool, h);
else } else
free(h); free(h);
} }
......
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
/***
Copyright © 2014 Michal Schmidt
***/
#include <limits.h> #include <limits.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
......
...@@ -571,3 +571,26 @@ int in_addr_prefix_from_string_auto( ...@@ -571,3 +571,26 @@ int in_addr_prefix_from_string_auto(
return 0; return 0;
} }
void in_addr_data_hash_func(const void *p, struct siphash *state) {
const struct in_addr_data *a = p;
siphash24_compress(&a->family, sizeof(a->family), state);
siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
}
int in_addr_data_compare_func(const void *a, const void *b) {
const struct in_addr_data *x = a, *y = b;
int r;
r = CMP(x->family, y->family);
if (r != 0)
return r;
return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
}
const struct hash_ops in_addr_data_hash_ops = {
.hash = in_addr_data_hash_func,
.compare = in_addr_data_compare_func,
};
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <stddef.h> #include <stddef.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "hash-funcs.h"
#include "macro.h" #include "macro.h"
#include "util.h" #include "util.h"
...@@ -53,3 +54,7 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) { ...@@ -53,3 +54,7 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) {
} }
#define IN_ADDR_NULL ((union in_addr_union) {}) #define IN_ADDR_NULL ((union in_addr_union) {})
void in_addr_data_hash_func(const void *p, struct siphash *state);
int in_addr_data_compare_func(const void *a, const void *b);
extern const struct hash_ops in_addr_data_hash_ops;
This diff is collapsed.
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
/***
Copyright © 2014 Michal Schmidt
***/
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
......
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
/***
Copyright © 2014 Michal Schmidt
***/
#include <stddef.h> #include <stddef.h>
struct pool; struct pool;
......
...@@ -637,6 +637,8 @@ int parse_permille_unbounded(const char *p) { ...@@ -637,6 +637,8 @@ int parse_permille_unbounded(const char *p) {
r = safe_atoi(n, &v); r = safe_atoi(n, &v);
if (r < 0)