summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/cgroup-util.c9
-rw-r--r--src/basic/smack-util.c117
-rw-r--r--src/basic/smack-util.h24
-rw-r--r--src/basic/terminal-util.c36
-rw-r--r--src/basic/util.c70
-rw-r--r--src/basic/util.h3
-rw-r--r--src/bootchart/bootchart.c2
-rw-r--r--src/bus-proxyd/driver.c11
-rw-r--r--src/core/execute.c10
-rw-r--r--src/core/socket.c6
-rw-r--r--src/firstboot/firstboot.c3
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c8
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c11
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c3
-rw-r--r--src/libsystemd-network/sd-lldp.c4
-rw-r--r--src/libsystemd-network/sd-pppoe.c4
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c26
-rw-r--r--src/libsystemd/sd-event/sd-event.c9
-rw-r--r--src/login/70-power-switch.rules2
-rw-r--r--src/network/networkctl.c2
-rw-r--r--src/network/networkd-dhcp4.c2
-rw-r--r--src/resolve/resolved-dns-cache.c4
-rw-r--r--src/resolve/resolved-dns-scope.c22
-rw-r--r--src/resolve/resolved-dns-scope.h6
-rw-r--r--src/resolve/resolved-dns-server.c22
-rw-r--r--src/resolve/resolved-dns-server.h6
-rw-r--r--src/resolve/resolved-dns-transaction.c56
-rw-r--r--src/resolve/resolved-dns-transaction.h10
-rw-r--r--src/udev/udev-node.c4
-rw-r--r--src/udev/udevd.c28
30 files changed, 356 insertions, 164 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 34a3060509..6b3162a35f 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -826,14 +826,12 @@ int cg_install_release_agent(const char *controller, const char *agent) {
} else if (!streq(sc, agent))
return -EEXIST;
- free(fs);
- fs = NULL;
+ fs = mfree(fs);
r = cg_get_path(controller, NULL, "notify_on_release", &fs);
if (r < 0)
return r;
- free(contents);
- contents = NULL;
+ contents = mfree(contents);
r = read_one_line_file(fs, &contents);
if (r < 0)
return r;
@@ -865,8 +863,7 @@ int cg_uninstall_release_agent(const char *controller) {
if (r < 0)
return r;
- free(fs);
- fs = NULL;
+ fs = mfree(fs);
r = cg_get_path(controller, NULL, "release_agent", &fs);
if (r < 0)
diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c
index 047aa294f4..6d5c205117 100644
--- a/src/basic/smack-util.c
+++ b/src/basic/smack-util.c
@@ -32,109 +32,93 @@
#define SMACK_FLOOR_LABEL "_"
#define SMACK_STAR_LABEL "*"
-bool mac_smack_use(void) {
#ifdef HAVE_SMACK
+bool mac_smack_use(void) {
static int cached_use = -1;
if (cached_use < 0)
cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
return cached_use;
-#else
- return false;
-#endif
}
-int mac_smack_apply(const char *path, const char *label) {
- int r = 0;
+static const char* const smack_attr_table[_SMACK_ATTR_MAX] = {
+ [SMACK_ATTR_ACCESS] = "security.SMACK64",
+ [SMACK_ATTR_EXEC] = "security.SMACK64EXEC",
+ [SMACK_ATTR_MMAP] = "security.SMACK64MMAP",
+ [SMACK_ATTR_TRANSMUTE] = "security.SMACK64TRANSMUTE",
+ [SMACK_ATTR_IPIN] = "security.SMACK64IPIN",
+ [SMACK_ATTR_IPOUT] = "security.SMACK64IPOUT",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr);
+int mac_smack_read(const char *path, SmackAttr attr, char **label) {
assert(path);
+ assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
+ assert(label);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
- if (label)
- r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
- else
- r = lremovexattr(path, "security.SMACK64");
- if (r < 0)
- return -errno;
-#endif
-
- return r;
+ return getxattr_malloc(path, smack_attr_to_string(attr), label, true);
}
-int mac_smack_apply_fd(int fd, const char *label) {
- int r = 0;
-
+int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
assert(fd >= 0);
+ assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
+ assert(label);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
- if (label)
- r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
- else
- r = fremovexattr(fd, "security.SMACK64");
- if (r < 0)
- return -errno;
-#endif
-
- return r;
+ return fgetxattr_malloc(fd, smack_attr_to_string(attr), label);
}
-int mac_smack_apply_ip_out_fd(int fd, const char *label) {
- int r = 0;
+int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
+ int r;
- assert(fd >= 0);
+ assert(path);
+ assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
if (label)
- r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
+ r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0);
else
- r = fremovexattr(fd, "security.SMACK64IPOUT");
+ r = lremovexattr(path, smack_attr_to_string(attr));
if (r < 0)
return -errno;
-#endif
- return r;
+ return 0;
}
-int mac_smack_apply_ip_in_fd(int fd, const char *label) {
- int r = 0;
+int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
+ int r;
assert(fd >= 0);
+ assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
if (label)
- r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
+ r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0);
else
- r = fremovexattr(fd, "security.SMACK64IPIN");
+ r = fremovexattr(fd, smack_attr_to_string(attr));
if (r < 0)
return -errno;
-#endif
- return r;
+ return 0;
}
int mac_smack_apply_pid(pid_t pid, const char *label) {
-
-#ifdef HAVE_SMACK
const char *p;
-#endif
int r = 0;
assert(label);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
@@ -142,21 +126,16 @@ int mac_smack_apply_pid(pid_t pid, const char *label) {
r = write_string_file(p, label, 0);
if (r < 0)
return r;
-#endif
return r;
}
int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
-
-#ifdef HAVE_SMACK
struct stat st;
-#endif
int r = 0;
assert(path);
-#ifdef HAVE_SMACK
if (!mac_smack_use())
return 0;
@@ -202,7 +181,37 @@ int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
}
-#endif
return r;
}
+
+
+#else
+bool mac_smack_use(void) {
+ return false;
+}
+
+int mac_smack_read(const char *path, SmackAttr attr, char **label) {
+ return -EOPNOTSUPP;
+}
+
+int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
+ return -EOPNOTSUPP;
+}
+
+int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
+ return 0;
+}
+
+int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
+ return 0;
+}
+
+int mac_smack_apply_pid(pid_t pid, const char *label) {
+ return 0;
+}
+
+int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
+ return 0;
+}
+#endif
diff --git a/src/basic/smack-util.h b/src/basic/smack-util.h
index 50f55b1f4b..1052cecf4c 100644
--- a/src/basic/smack-util.h
+++ b/src/basic/smack-util.h
@@ -25,12 +25,28 @@
#include <stdbool.h>
+#include "macro.h"
+
+typedef enum SmackAttr {
+ SMACK_ATTR_ACCESS = 0,
+ SMACK_ATTR_EXEC = 1,
+ SMACK_ATTR_MMAP = 2,
+ SMACK_ATTR_TRANSMUTE = 3,
+ SMACK_ATTR_IPIN = 4,
+ SMACK_ATTR_IPOUT = 5,
+ _SMACK_ATTR_MAX,
+ _SMACK_ATTR_INVALID = -1,
+} SmackAttr;
+
bool mac_smack_use(void);
int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
-int mac_smack_apply(const char *path, const char *label);
-int mac_smack_apply_fd(int fd, const char *label);
+const char* smack_attr_to_string(SmackAttr i) _const_;
+SmackAttr smack_attr_from_string(const char *s) _pure_;
+int mac_smack_read(const char *path, SmackAttr attr, char **label);
+int mac_smack_read_fd(int fd, SmackAttr attr, char **label);
+int mac_smack_apply(const char *path, SmackAttr attr, const char *label);
+int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label);
+
int mac_smack_apply_pid(pid_t pid, const char *label);
-int mac_smack_apply_ip_in_fd(int fd, const char *label);
-int mac_smack_apply_ip_out_fd(int fd, const char *label);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 042b88f222..cf55263bbf 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -44,7 +44,7 @@ static volatile unsigned cached_lines = 0;
int chvt(int vt) {
_cleanup_close_ int fd;
- fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return -errno;
@@ -230,14 +230,14 @@ int reset_terminal_fd(int fd, bool switch_to_text) {
* interfere with that. */
/* Disable exclusive mode, just in case */
- ioctl(fd, TIOCNXCL);
+ (void) ioctl(fd, TIOCNXCL);
/* Switch to text mode */
if (switch_to_text)
- ioctl(fd, KDSETMODE, KD_TEXT);
+ (void) ioctl(fd, KDSETMODE, KD_TEXT);
/* Enable console unicode mode */
- ioctl(fd, KDSKBMODE, K_UNICODE);
+ (void) ioctl(fd, KDSKBMODE, K_UNICODE);
if (tcgetattr(fd, &termios) < 0) {
r = -errno;
@@ -276,7 +276,7 @@ int reset_terminal_fd(int fd, bool switch_to_text) {
finish:
/* Just in case, flush all crap out */
- tcflush(fd, TCIOFLUSH);
+ (void) tcflush(fd, TCIOFLUSH);
return r;
}
@@ -284,7 +284,11 @@ finish:
int reset_terminal(const char *name) {
_cleanup_close_ int fd = -1;
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ /* We open the terminal with O_NONBLOCK here, to ensure we
+ * don't block on carrier if this is a terminal with carrier
+ * configured. */
+
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return fd;
@@ -304,7 +308,8 @@ int open_terminal(const char *name, int mode) {
* https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
*/
- assert(!(mode & O_CREAT));
+ if (mode & O_CREAT)
+ return -EINVAL;
for (;;) {
fd = open(name, mode, 0);
@@ -413,9 +418,8 @@ int acquire_terminal(
if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
r = 0;
- if (r < 0 && (force || fail || r != -EPERM)) {
+ if (r < 0 && (force || fail || r != -EPERM))
goto fail;
- }
if (r >= 0)
break;
@@ -499,7 +503,7 @@ int release_terminal(void) {
struct sigaction sa_old;
int r = 0;
- fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
+ fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return -errno;
@@ -527,7 +531,7 @@ int terminal_vhangup_fd(int fd) {
int terminal_vhangup(const char *name) {
_cleanup_close_ int fd;
- fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return fd;
@@ -574,7 +578,7 @@ int vt_disallocate(const char *name) {
return -EINVAL;
/* Try to deallocate */
- fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
if (fd < 0)
return fd;
@@ -612,16 +616,16 @@ void warn_melody(void) {
/* Yeah, this is synchronous. Kinda sucks. But well... */
- ioctl(fd, KIOCSOUND, (int)(1193180/440));
+ (void) ioctl(fd, KIOCSOUND, (int)(1193180/440));
usleep(125*USEC_PER_MSEC);
- ioctl(fd, KIOCSOUND, (int)(1193180/220));
+ (void) ioctl(fd, KIOCSOUND, (int)(1193180/220));
usleep(125*USEC_PER_MSEC);
- ioctl(fd, KIOCSOUND, (int)(1193180/220));
+ (void) ioctl(fd, KIOCSOUND, (int)(1193180/220));
usleep(125*USEC_PER_MSEC);
- ioctl(fd, KIOCSOUND, 0);
+ (void) ioctl(fd, KIOCSOUND, 0);
}
int make_console_stdio(void) {
diff --git a/src/basic/util.c b/src/basic/util.c
index a968e2156d..af58dc3766 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -6603,3 +6603,73 @@ int reset_uid_gid(void) {
return 0;
}
+
+int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
+ char *v;
+ size_t l;
+ ssize_t n;
+
+ assert(path);
+ assert(name);
+ assert(value);
+
+ for (l = 100; ; l = (size_t) n + 1) {
+ v = new0(char, l);
+ if (!v)
+ return -ENOMEM;
+
+ if (allow_symlink)
+ n = lgetxattr(path, name, v, l);
+ else
+ n = getxattr(path, name, v, l);
+
+ if (n >= 0 && (size_t) n < l) {
+ *value = v;
+ return n;
+ }
+
+ free(v);
+
+ if (n < 0 && errno != ERANGE)
+ return -errno;
+
+ if (allow_symlink)
+ n = lgetxattr(path, name, NULL, 0);
+ else
+ n = getxattr(path, name, NULL, 0);
+ if (n < 0)
+ return -errno;
+ }
+}
+
+int fgetxattr_malloc(int fd, const char *name, char **value) {
+ char *v;
+ size_t l;
+ ssize_t n;
+
+ assert(fd >= 0);
+ assert(name);
+ assert(value);
+
+ for (l = 100; ; l = (size_t) n + 1) {
+ v = new0(char, l);
+ if (!v)
+ return -ENOMEM;
+
+ n = fgetxattr(fd, name, v, l);
+
+ if (n >= 0 && (size_t) n < l) {
+ *value = v;
+ return n;
+ }
+
+ free(v);
+
+ if (n < 0 && errno != ERANGE)
+ return -errno;
+
+ n = fgetxattr(fd, name, NULL, 0);
+ if (n < 0)
+ return -errno;
+ }
+}
diff --git a/src/basic/util.h b/src/basic/util.h
index 88c44273d4..0a0fba9012 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -919,3 +919,6 @@ int parse_mode(const char *s, mode_t *ret);
int mount_move_root(const char *path);
int reset_uid_gid(void);
+
+int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
+int fgetxattr_malloc(int fd, const char *name, char **value);
diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c
index 1625d51fa8..322cec84a9 100644
--- a/src/bootchart/bootchart.c
+++ b/src/bootchart/bootchart.c
@@ -367,7 +367,7 @@ int main(int argc, char *argv[]) {
struct timespec n;
double uptime;
- clock_gettime(CLOCK_BOOTTIME, &n);
+ clock_gettime(clock_boottime_or_monotonic(), &n);
uptime = (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));
log_start = gettime_ns();
diff --git a/src/bus-proxyd/driver.c b/src/bus-proxyd/driver.c
index 951f515808..fa4aee691a 100644
--- a/src/bus-proxyd/driver.c
+++ b/src/bus-proxyd/driver.c
@@ -35,6 +35,7 @@
#include "driver.h"
#include "proxy.h"
#include "synthesize.h"
+#include "env-util.h"
static int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
_cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
@@ -694,9 +695,13 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m,
if (!s)
return synthetic_reply_method_errno(m, -ENOMEM, NULL);
- r = strv_extend(&args, s);
- if (r < 0)
- return synthetic_reply_method_errno(m, r, NULL);
+ if (!env_assignment_is_valid(s)) {
+ log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s);
+ } else {
+ r = strv_extend(&args, s);
+ if (r < 0)
+ return synthetic_reply_method_errno(m, r, NULL);
+ }
r = sd_bus_message_exit_container(m);
if (r < 0)
diff --git a/src/core/execute.c b/src/core/execute.c
index 21721dc240..f14ae4d8a6 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1719,7 +1719,15 @@ static int exec_child(
}
#ifdef SMACK_DEFAULT_PROCESS_LABEL
else {
- r = mac_smack_apply_pid(0, SMACK_DEFAULT_PROCESS_LABEL);
+ _cleanup_free_ char *exec_label = NULL;
+
+ r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label);
+ if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) {
+ *exit_status = EXIT_SMACK_PROCESS_LABEL;
+ return r;
+ }
+
+ r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL);
if (r < 0) {
*exit_status = EXIT_SMACK_PROCESS_LABEL;
return r;
diff --git a/src/core/socket.c b/src/core/socket.c
index 87631f8753..a387057473 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -923,13 +923,13 @@ static void socket_apply_socket_options(Socket *s, int fd) {
log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m");
if (s->smack_ip_in) {
- r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in);
+ r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in);
if (r < 0)
log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_in_fd: %m");
}
if (s->smack_ip_out) {
- r = mac_smack_apply_ip_out_fd(fd, s->smack_ip_out);
+ r = mac_smack_apply_fd(fd, SMACK_ATTR_IPOUT, s->smack_ip_out);
if (r < 0)
log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_out_fd: %m");
}
@@ -946,7 +946,7 @@ static void socket_apply_fifo_options(Socket *s, int fd) {
log_unit_warning_errno(UNIT(s), errno, "F_SETPIPE_SZ: %m");
if (s->smack) {
- r = mac_smack_apply_fd(fd, s->smack);
+ r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack);
if (r < 0)
log_unit_error_errno(UNIT(s), r, "mac_smack_apply_fd: %m");
}
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 05f1ae2646..c526a85b05 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -763,8 +763,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_ROOT_PASSWORD_FILE:
- free(arg_root_password);
- arg_root_password = NULL;
+ arg_root_password = mfree(arg_root_password);
r = read_one_line_file(optarg, &arg_root_password);
if (r < 0)
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index cc5e032344..a0af256dee 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -796,8 +796,12 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
r = sd_event_now(server->event,
clock_boottime_or_monotonic(),
&time_now);
- if (r < 0)
- time_now = now(clock_boottime_or_monotonic());
+ if (r < 0) {
+ if (!existing_lease)
+ dhcp_lease_free(lease);
+ return r;
+ }
+
lease->expiration = req->lifetime * USEC_PER_SEC + time_now;
r = server_send_ack(server, req, address);
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 85162dc555..e2f5862851 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -975,14 +975,9 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
client->retransmit_time = 0;
client->retransmit_count = 0;
- if (client->state == DHCP6_STATE_STOPPED) {
- time_now = now(clock_boottime_or_monotonic());
- } else {
- r = sd_event_now(client->event, clock_boottime_or_monotonic(),
- &time_now);
- if (r < 0)
- return r;
- }
+ r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ return r;
switch (state) {
case DHCP6_STATE_STOPPED:
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index 9e04db96bb..0cb77ccf71 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -187,8 +187,7 @@ static void ipv4ll_set_next_wakeup(sd_ipv4ll *ll, int sec, int random_sec) {
if (random_sec)
next_timeout += random_u32() % (random_sec * USEC_PER_SEC);
- if (sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) < 0)
- time_now = now(clock_boottime_or_monotonic());
+ assert_se(sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) >= 0);
ll->next_wakeup = time_now + next_timeout;
ll->next_wakeup_valid = 1;
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index 034163eb9e..574e04b541 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -392,7 +392,7 @@ static void lldp_mib_delete_objects(sd_lldp *lldp) {
break;
if (t <= 0)
- t = now(CLOCK_BOOTTIME);
+ t = now(clock_boottime_or_monotonic());
if (p->until > t)
break;
@@ -490,7 +490,7 @@ int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) {
free(s);
s = k;
- time = now(CLOCK_BOOTTIME);
+ time = now(clock_boottime_or_monotonic());
/* Don't write expired packets */
if (time - p->until <= 0)
diff --git a/src/libsystemd-network/sd-pppoe.c b/src/libsystemd-network/sd-pppoe.c
index 1de8a5e8bf..ff064f563f 100644
--- a/src/libsystemd-network/sd-pppoe.c
+++ b/src/libsystemd-network/sd-pppoe.c
@@ -346,9 +346,7 @@ static int pppoe_arm_timeout(sd_pppoe *ppp) {
assert(ppp);
r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
- if (r == -ENODATA)
- next_timeout = now(clock_boottime_or_monotonic());
- else if (r < 0)
+ if (r < 0)
return r;
next_timeout += 500 * USEC_PER_MSEC;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 767df40e81..0f075907d5 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -73,13 +73,9 @@ static void bus_close_fds(sd_bus *b) {
detach_io_events(b);
- if (b->input_fd >= 0)
- safe_close(b->input_fd);
-
- if (b->output_fd >= 0 && b->output_fd != b->input_fd)
+ if (b->input_fd != b->output_fd)
safe_close(b->output_fd);
-
- b->input_fd = b->output_fd = -1;
+ b->output_fd = b->input_fd = safe_close(b->input_fd);
}
static void bus_reset_queues(sd_bus *b) {
@@ -88,15 +84,13 @@ static void bus_reset_queues(sd_bus *b) {
while (b->rqueue_size > 0)
sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
- free(b->rqueue);
- b->rqueue = NULL;
+ b->rqueue = mfree(b->rqueue);
b->rqueue_allocated = 0;
while (b->wqueue_size > 0)
sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
- free(b->wqueue);
- b->wqueue = NULL;
+ b->wqueue = mfree(b->wqueue);
b->wqueue_allocated = 0;
}
@@ -908,15 +902,11 @@ static void bus_reset_parsed_address(sd_bus *b) {
zero(b->sockaddr);
b->sockaddr_size = 0;
- strv_free(b->exec_argv);
- free(b->exec_path);
- b->exec_path = NULL;
- b->exec_argv = NULL;
+ b->exec_argv = strv_free(b->exec_argv);
+ b->exec_path = mfree(b->exec_path);
b->server_id = SD_ID128_NULL;
- free(b->kernel);
- b->kernel = NULL;
- free(b->machine);
- b->machine = NULL;
+ b->kernel = mfree(b->kernel);
+ b->machine = mfree(b->machine);
b->nspid = 0;
}
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 76964aa0cc..754fb7614e 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -2572,9 +2572,12 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
assert_return(usec, -EINVAL);
assert_return(!event_pid_changed(e), -ECHILD);
- /* If we haven't run yet, just get the actual time */
- if (!dual_timestamp_is_set(&e->timestamp))
- return -ENODATA;
+ if (!dual_timestamp_is_set(&e->timestamp)) {
+ /* Implicitly fall back to now() if we never ran
+ * before and thus have no cached time. */
+ *usec = now(clock);
+ return 1;
+ }
switch (clock) {
diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules
index 695d246370..71f9fe6c72 100644
--- a/src/login/70-power-switch.rules
+++ b/src/login/70-power-switch.rules
@@ -11,5 +11,7 @@ SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="twl4030_pwrbutton", TAG+="power-switch"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="tps65217_pwr_but", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", \
+ SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", ATTRS{keys}=="116", TAG+="power-switch"
LABEL="power_switch_end"
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 9d6c453dbc..6c36a4ecfa 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -976,7 +976,7 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
return log_warning_errno(r < 0 ? r : ERANGE,
"Failed to parse TTL \"%s\": %m", b);
- time = now(CLOCK_BOOTTIME);
+ time = now(clock_boottime_or_monotonic());
if (x < time)
continue;
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 4aa301b112..5454bdd97b 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -468,7 +468,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
}
if (link->network->dhcp_hostname) {
- const char *hostname;
+ const char *hostname = NULL;
if (!link->network->hostname)
r = sd_dhcp_lease_get_hostname(lease, &hostname);
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index be52891681..9ffaf4b19f 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -152,7 +152,7 @@ void dns_cache_prune(DnsCache *c) {
break;
if (t <= 0)
- t = now(CLOCK_BOOTTIME);
+ t = now(clock_boottime_or_monotonic());
if (i->until > t)
break;
@@ -406,7 +406,7 @@ int dns_cache_put(
dns_cache_make_space(c, answer->n_rrs + q->n_keys);
if (timestamp <= 0)
- timestamp = now(CLOCK_BOOTTIME);
+ timestamp = now(clock_boottime_or_monotonic());
/* Second, add in positive entries for all contained RRs */
for (i = 0; i < MIN(max_rrs, answer->n_rrs); i++) {
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 4bc4157028..b8414da87e 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -34,6 +34,10 @@
#define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
#define MULTICAST_RATELIMIT_BURST 1000
+/* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
+#define MULTICAST_RESEND_TIMEOUT_MIN_USEC (100 * USEC_PER_MSEC)
+#define MULTICAST_RESEND_TIMEOUT_MAX_USEC (1 * USEC_PER_SEC)
+
int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
DnsScope *s;
@@ -48,6 +52,7 @@ int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int
s->link = l;
s->protocol = protocol;
s->family = family;
+ s->resend_timeout = MULTICAST_RESEND_TIMEOUT_MIN_USEC;
LIST_PREPEND(scopes, m->dns_scopes, s);
@@ -125,6 +130,23 @@ void dns_scope_next_dns_server(DnsScope *s) {
manager_next_dns_server(s->manager);
}
+void dns_scope_packet_received(DnsScope *s, usec_t rtt) {
+ assert(s);
+
+ if (rtt > s->max_rtt) {
+ s->max_rtt = rtt;
+ s->resend_timeout = MIN(MAX(MULTICAST_RESEND_TIMEOUT_MIN_USEC, s->max_rtt * 2),
+ MULTICAST_RESEND_TIMEOUT_MAX_USEC);
+ }
+}
+
+void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
+ assert(s);
+
+ if (s->resend_timeout <= usec)
+ s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
+}
+
int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) {
union in_addr_union addr;
int ifindex = 0, r;
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index 29479ad550..b2dac86b44 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -57,6 +57,9 @@ struct DnsScope {
RateLimit ratelimit;
+ usec_t resend_timeout;
+ usec_t max_rtt;
+
LIST_HEAD(DnsTransaction, transactions);
LIST_FIELDS(DnsScope, scopes);
@@ -65,6 +68,9 @@ struct DnsScope {
int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol p, int family);
DnsScope* dns_scope_free(DnsScope *s);
+void dns_scope_packet_received(DnsScope *s, usec_t rtt);
+void dns_scope_packet_lost(DnsScope *s, usec_t usec);
+
int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p);
int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port, DnsServer **server);
int dns_scope_udp_dns_socket(DnsScope *s, DnsServer **server);
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 92e48ae442..2ff5b192df 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -23,6 +23,10 @@
#include "resolved-dns-server.h"
+/* After how much time to repeat classic DNS requests */
+#define DNS_TIMEOUT_MIN_USEC (500 * USEC_PER_MSEC)
+#define DNS_TIMEOUT_MAX_USEC (5 * USEC_PER_SEC)
+
int dns_server_new(
Manager *m,
DnsServer **ret,
@@ -45,6 +49,7 @@ int dns_server_new(
s->type = type;
s->family = family;
s->address = *in_addr;
+ s->resend_timeout = DNS_TIMEOUT_MIN_USEC;
if (type == DNS_SERVER_LINK) {
LIST_FIND_TAIL(servers, l->dns_servers, tail);
@@ -115,6 +120,23 @@ DnsServer* dns_server_unref(DnsServer *s) {
return NULL;
}
+void dns_server_packet_received(DnsServer *s, usec_t rtt) {
+ assert(s);
+
+ if (rtt > s->max_rtt) {
+ s->max_rtt = rtt;
+ s->resend_timeout = MIN(MAX(DNS_TIMEOUT_MIN_USEC, s->max_rtt * 2),
+ DNS_TIMEOUT_MAX_USEC);
+ }
+}
+
+void dns_server_packet_lost(DnsServer *s, usec_t usec) {
+ assert(s);
+
+ if (s->resend_timeout <= usec)
+ s->resend_timeout = MIN(s->resend_timeout * 2, DNS_TIMEOUT_MAX_USEC);
+}
+
static unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
const DnsServer *s = p;
uint64_t u;
diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
index 06059e8829..10111fd6bd 100644
--- a/src/resolve/resolved-dns-server.h
+++ b/src/resolve/resolved-dns-server.h
@@ -46,6 +46,9 @@ struct DnsServer {
int family;
union in_addr_union address;
+ usec_t resend_timeout;
+ usec_t max_rtt;
+
bool marked:1;
LIST_FIELDS(DnsServer, servers);
@@ -62,6 +65,9 @@ int dns_server_new(
DnsServer* dns_server_ref(DnsServer *s);
DnsServer* dns_server_unref(DnsServer *s);
+void dns_server_packet_received(DnsServer *s, usec_t rtt);
+void dns_server_packet_lost(DnsServer *s, usec_t usec);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsServer*, dns_server_unref);
extern const struct hash_ops dns_server_hash_ops;
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 8a93b265c6..53779f3372 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -319,11 +319,14 @@ static void dns_transaction_next_dns_server(DnsTransaction *t) {
}
void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
+ usec_t ts;
int r;
assert(t);
assert(p);
assert(t->state == DNS_TRANSACTION_PENDING);
+ assert(t->scope);
+ assert(t->scope->manager);
/* Note that this call might invalidate the query. Callers
* should hence not attempt to access the query or transaction
@@ -369,6 +372,24 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
}
}
+ assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
+
+ switch (t->scope->protocol) {
+ case DNS_PROTOCOL_DNS:
+ assert(t->server);
+
+ dns_server_packet_received(t->server, ts - t->start_usec);
+
+ break;
+ case DNS_PROTOCOL_LLMNR:
+ case DNS_PROTOCOL_MDNS:
+ dns_scope_packet_received(t->scope, ts - t->start_usec);
+
+ break;
+ default:
+ assert_not_reached("Invalid DNS protocol.");
+ }
+
if (DNS_PACKET_TC(p)) {
/* Response was truncated, let's try again with good old TCP */
r = dns_transaction_open_tcp(t);
@@ -434,9 +455,9 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use
return r;
if (dns_packet_validate_reply(p) > 0 &&
- DNS_PACKET_ID(p) == t->id) {
+ DNS_PACKET_ID(p) == t->id)
dns_transaction_process_reply(t, p);
- } else
+ else
log_debug("Invalid DNS packet.");
return 0;
@@ -481,6 +502,12 @@ static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdat
/* Timeout reached? Try again, with a new server */
dns_transaction_next_dns_server(t);
+ /* ... and possibly increased timeout */
+ if (t->server)
+ dns_server_packet_lost(t->server, usec - t->start_usec);
+ else
+ dns_scope_packet_lost(t->scope, usec - t->start_usec);
+
r = dns_transaction_go(t);
if (r < 0)
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
@@ -528,8 +555,26 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
return 0;
}
+static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
+ assert(t);
+ assert(t->scope);
+
+ switch (t->scope->protocol) {
+ case DNS_PROTOCOL_DNS:
+ assert(t->server);
+
+ return t->server->resend_timeout;
+ case DNS_PROTOCOL_LLMNR:
+ case DNS_PROTOCOL_MDNS:
+ return t->scope->resend_timeout;
+ default:
+ assert_not_reached("Invalid DNS protocol.");
+ }
+}
+
int dns_transaction_go(DnsTransaction *t) {
bool had_stream;
+ usec_t ts;
int r;
assert(t);
@@ -555,7 +600,10 @@ int dns_transaction_go(DnsTransaction *t) {
return 0;
}
+ assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
+
t->n_attempts++;
+ t->start_usec = ts;
t->received = dns_packet_unref(t->received);
t->cached = dns_answer_unref(t->cached);
t->cached_rcode = 0;
@@ -600,7 +648,7 @@ int dns_transaction_go(DnsTransaction *t) {
t->scope->manager->event,
&t->timeout_event_source,
clock_boottime_or_monotonic(),
- now(clock_boottime_or_monotonic()) + jitter,
+ ts + jitter,
LLMNR_JITTER_INTERVAL_USEC,
on_transaction_timeout, t);
if (r < 0)
@@ -660,7 +708,7 @@ int dns_transaction_go(DnsTransaction *t) {
t->scope->manager->event,
&t->timeout_event_source,
clock_boottime_or_monotonic(),
- now(clock_boottime_or_monotonic()) + TRANSACTION_TIMEOUT_USEC(t->scope->protocol), 0,
+ ts + transaction_get_resend_timeout(t), 0,
on_transaction_timeout, t);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index a8f4267bc8..d8a5647609 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -58,6 +58,7 @@ struct DnsTransaction {
DnsAnswer *cached;
int cached_rcode;
+ usec_t start_usec;
sd_event_source *timeout_event_source;
unsigned n_attempts;
@@ -95,20 +96,13 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
-/* After how much time to repeat classic DNS requests */
-#define DNS_TRANSACTION_TIMEOUT_USEC (5 * USEC_PER_SEC)
-
-/* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
-#define LLMNR_TRANSACTION_TIMEOUT_USEC (1 * USEC_PER_SEC)
-
/* LLMNR Jitter interval, see RFC 4795 Section 7 */
#define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
/* Maximum attempts to send DNS requests, across all DNS servers */
-#define DNS_TRANSACTION_ATTEMPTS_MAX 8
+#define DNS_TRANSACTION_ATTEMPTS_MAX 16
/* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
#define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
-#define TRANSACTION_TIMEOUT_USEC(p) (p == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_TIMEOUT_USEC : DNS_TRANSACTION_TIMEOUT_USEC)
#define TRANSACTION_ATTEMPTS_MAX(p) (p == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index d824172b89..e730fb45f1 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -309,7 +309,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
} else if (streq(name, "smack")) {
smack = true;
- r = mac_smack_apply(devnode, label);
+ r = mac_smack_apply(devnode, SMACK_ATTR_ACCESS, label);
if (r < 0)
log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label);
else
@@ -323,7 +323,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
if (!selinux)
mac_selinux_fix(devnode, true, false);
if (!smack)
- mac_smack_apply(devnode, NULL);
+ mac_smack_apply(devnode, SMACK_ATTR_ACCESS, NULL);
}
/* always update timestamp when we re-use the node, like on media change events */
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index d0b8bad48e..28ac44fb8e 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -261,7 +261,6 @@ static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *use
static void worker_attach_event(struct worker *worker, struct event *event) {
sd_event *e;
uint64_t usec;
- int r;
assert(worker);
assert(worker->manager);
@@ -276,9 +275,7 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
e = worker->manager->event;
- r = sd_event_now(e, clock_boottime_or_monotonic(), &usec);
- if (r < 0)
- return;
+ assert_se(sd_event_now(e, clock_boottime_or_monotonic(), &usec) >= 0);
(void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
@@ -749,9 +746,7 @@ static void manager_exit(Manager *manager) {
event_queue_cleanup(manager, EVENT_QUEUED);
manager_kill_workers(manager);
- r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
- if (r < 0)
- return;
+ assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
@@ -780,7 +775,6 @@ static void manager_reload(Manager *manager) {
static void event_queue_start(Manager *manager) {
struct udev_list_node *loop;
usec_t usec;
- int r;
assert(manager);
@@ -788,17 +782,15 @@ static void event_queue_start(Manager *manager) {
manager->exit || manager->stop_exec_queue)
return;
- r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
- if (r >= 0) {
- /* check for changed config, every 3 seconds at most */
- if (manager->last_usec == 0 ||
- (usec - manager->last_usec) > 3 * USEC_PER_SEC) {
- if (udev_rules_check_timestamp(manager->rules) ||
- udev_builtin_validate(manager->udev))
- manager_reload(manager);
+ assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ /* check for changed config, every 3 seconds at most */
+ if (manager->last_usec == 0 ||
+ (usec - manager->last_usec) > 3 * USEC_PER_SEC) {
+ if (udev_rules_check_timestamp(manager->rules) ||
+ udev_builtin_validate(manager->udev))
+ manager_reload(manager);
- manager->last_usec = usec;
- }
+ manager->last_usec = usec;
}
udev_builtin_init(manager->udev);