Bug Summary

File:build-scan/../src/udev/udevd.c
Warning:line 979, column 33
Potential leak of memory pointed to by 'key'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name udevd.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-udevd.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -D LOG_REALM=LOG_REALM_UDEV -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/udev/udevd.c
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright © 2004 Chris Friesen <chris_friesen@sympatico.ca>
4 * Copyright © 2009 Canonical Ltd.
5 * Copyright © 2009 Scott James Remnant <scott@netsplit.com>
6 *
7 */
8
9#include <errno(*__errno_location ()).h>
10#include <fcntl.h>
11#include <getopt.h>
12#include <signal.h>
13#include <stdbool.h>
14#include <stddef.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <sys/epoll.h>
19#include <sys/file.h>
20#include <sys/inotify.h>
21#include <sys/ioctl.h>
22#include <sys/mount.h>
23#include <sys/prctl.h>
24#include <sys/signalfd.h>
25#include <sys/socket.h>
26#include <sys/stat.h>
27#include <sys/time.h>
28#include <sys/wait.h>
29#include <unistd.h>
30
31#include "sd-daemon.h"
32#include "sd-event.h"
33
34#include "alloc-util.h"
35#include "cgroup-util.h"
36#include "cpu-set-util.h"
37#include "dev-setup.h"
38#include "fd-util.h"
39#include "fileio.h"
40#include "format-util.h"
41#include "fs-util.h"
42#include "hashmap.h"
43#include "io-util.h"
44#include "list.h"
45#include "netlink-util.h"
46#include "parse-util.h"
47#include "proc-cmdline.h"
48#include "process-util.h"
49#include "selinux-util.h"
50#include "signal-util.h"
51#include "socket-util.h"
52#include "string-util.h"
53#include "terminal-util.h"
54#include "udev-util.h"
55#include "udev.h"
56#include "user-util.h"
57
58static bool_Bool arg_debug = false0;
59static int arg_daemonize = false0;
60static int arg_resolve_names = 1;
61static unsigned arg_children_max;
62static int arg_exec_delay;
63static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC((usec_t) 1000000ULL);
64static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC((usec_t) 1000000ULL) / 3;
65
66typedef struct Manager {
67 struct udev *udev;
68 sd_event *event;
69 Hashmap *workers;
70 LIST_HEAD(struct event, events)struct event *events;
71 const char *cgroup;
72 pid_t pid; /* the process that originally allocated the manager object */
73
74 struct udev_rules *rules;
75 struct udev_list properties;
76
77 struct udev_monitor *monitor;
78 struct udev_ctrl *ctrl;
79 struct udev_ctrl_connection *ctrl_conn_blocking;
80 int fd_inotify;
81 int worker_watch[2];
82
83 sd_event_source *ctrl_event;
84 sd_event_source *uevent_event;
85 sd_event_source *inotify_event;
86
87 usec_t last_usec;
88
89 bool_Bool stop_exec_queue:1;
90 bool_Bool exit:1;
91} Manager;
92
93enum event_state {
94 EVENT_UNDEF,
95 EVENT_QUEUED,
96 EVENT_RUNNING,
97};
98
99struct event {
100 LIST_FIELDS(struct event, event)struct event *event_next, *event_prev;
101 Manager *manager;
102 struct udev *udev;
103 struct udev_device *dev;
104 struct udev_device *dev_kernel;
105 struct worker *worker;
106 enum event_state state;
107 unsigned long long int delaying_seqnum;
108 unsigned long long int seqnum;
109 const char *devpath;
110 size_t devpath_len;
111 const char *devpath_old;
112 dev_t devnum;
113 int ifindex;
114 bool_Bool is_block;
115 sd_event_source *timeout_warning;
116 sd_event_source *timeout;
117};
118
119static void event_queue_cleanup(Manager *manager, enum event_state type);
120
121enum worker_state {
122 WORKER_UNDEF,
123 WORKER_RUNNING,
124 WORKER_IDLE,
125 WORKER_KILLED,
126};
127
128struct worker {
129 Manager *manager;
130 int refcount;
131 pid_t pid;
132 struct udev_monitor *monitor;
133 enum worker_state state;
134 struct event *event;
135};
136
137/* passed from worker to main process */
138struct worker_message {
139};
140
141static void event_free(struct event *event) {
142 int r;
143
144 if (!event)
145 return;
146 assert(event->manager)do { if ((__builtin_expect(!!(!(event->manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event->manager"), "../src/udev/udevd.c"
, 146, __PRETTY_FUNCTION__); } while (0)
;
147
148 LIST_REMOVE(event, event->manager->events, event)do { typeof(*(event->manager->events)) **_head = &(
event->manager->events), *_item = (event); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("_item"
), "../src/udev/udevd.c", 148, __PRETTY_FUNCTION__); } while (
0); if (_item->event_next) _item->event_next->event_prev
= _item->event_prev; if (_item->event_prev) _item->
event_prev->event_next = _item->event_next; else { do {
if ((__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("*_head == _item"), "../src/udev/udevd.c", 148
, __PRETTY_FUNCTION__); } while (0); *_head = _item->event_next
; } _item->event_next = _item->event_prev = ((void*)0);
} while (0)
;
149 udev_device_unref(event->dev);
150 udev_device_unref(event->dev_kernel);
151
152 sd_event_source_unref(event->timeout_warning);
153 sd_event_source_unref(event->timeout);
154
155 if (event->worker)
156 event->worker->event = NULL((void*)0);
157
158 if (LIST_IS_EMPTY(event->manager->events)(!(event->manager->events))) {
159 /* only clean up the queue from the process that created it */
160 if (event->manager->pid == getpid_cached()) {
161 r = unlink("/run/udev/queue");
162 if (r < 0)
163 log_warning_errno(errno, "could not unlink /run/udev/queue: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 163, __func__, "could not unlink /run/udev/queue: %m"
) : -abs(_e); })
;
164 }
165 }
166
167 free(event);
168}
169
170static void worker_free(struct worker *worker) {
171 if (!worker)
172 return;
173
174 assert(worker->manager)do { if ((__builtin_expect(!!(!(worker->manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("worker->manager"), "../src/udev/udevd.c"
, 174, __PRETTY_FUNCTION__); } while (0)
;
175
176 hashmap_remove(worker->manager->workers, PID_TO_PTR(worker->pid));
177 udev_monitor_unref(worker->monitor);
178 event_free(worker->event);
179
180 free(worker);
181}
182
183static void manager_workers_free(Manager *manager) {
184 struct worker *worker;
185 Iterator i;
186
187 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 187, __PRETTY_FUNCTION__
); } while (0)
;
188
189 HASHMAP_FOREACH(worker, manager->workers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((manager->workers
), &(i), (void**)&(worker), ((void*)0)); )
190 worker_free(worker);
191
192 manager->workers = hashmap_free(manager->workers);
193}
194
195static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor *worker_monitor, pid_t pid) {
196 _cleanup_free___attribute__((cleanup(freep))) struct worker *worker = NULL((void*)0);
197 int r;
198
199 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("ret"), "../src/udev/udevd.c", 199, __PRETTY_FUNCTION__
); } while (0)
;
200 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 200, __PRETTY_FUNCTION__
); } while (0)
;
201 assert(worker_monitor)do { if ((__builtin_expect(!!(!(worker_monitor)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("worker_monitor"), "../src/udev/udevd.c", 201
, __PRETTY_FUNCTION__); } while (0)
;
202 assert(pid > 1)do { if ((__builtin_expect(!!(!(pid > 1)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("pid > 1"), "../src/udev/udevd.c", 202, __PRETTY_FUNCTION__
); } while (0)
;
203
204 worker = new0(struct worker, 1)((struct worker*) calloc((1), sizeof(struct worker)));
205 if (!worker)
206 return -ENOMEM12;
207
208 worker->refcount = 1;
209 worker->manager = manager;
210 /* close monitor, but keep address around */
211 udev_monitor_disconnect(worker_monitor);
212 worker->monitor = udev_monitor_ref(worker_monitor);
213 worker->pid = pid;
214
215 r = hashmap_ensure_allocated(&manager->workers, NULL)internal_hashmap_ensure_allocated(&manager->workers, (
(void*)0) )
;
216 if (r < 0)
217 return r;
218
219 r = hashmap_put(manager->workers, PID_TO_PTR(pid), worker);
220 if (r < 0)
221 return r;
222
223 *ret = TAKE_PTR(worker)({ typeof(worker) _ptr_ = (worker); (worker) = ((void*)0); _ptr_
; })
;
224
225 return 0;
226}
227
228static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
229 struct event *event = userdata;
230
231 assert(event)do { if ((__builtin_expect(!!(!(event)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event"), "../src/udev/udevd.c", 231, __PRETTY_FUNCTION__
); } while (0)
;
232 assert(event->worker)do { if ((__builtin_expect(!!(!(event->worker)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event->worker"), "../src/udev/udevd.c",
232, __PRETTY_FUNCTION__); } while (0)
;
233
234 kill_and_sigcont(event->worker->pid, SIGKILL9);
235 event->worker->state = WORKER_KILLED;
236
237 log_error("seq %llu '%s' killed", udev_device_get_seqnum(event->dev), event->devpath)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 237, __func__, "seq %llu '%s' killed"
, udev_device_get_seqnum(event->dev), event->devpath) :
-abs(_e); })
;
238
239 return 1;
240}
241
242static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) {
243 struct event *event = userdata;
244
245 assert(event)do { if ((__builtin_expect(!!(!(event)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event"), "../src/udev/udevd.c", 245, __PRETTY_FUNCTION__
); } while (0)
;
246
247 log_warning("seq %llu '%s' is taking a long time", udev_device_get_seqnum(event->dev), event->devpath)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 247, __func__, "seq %llu '%s' is taking a long time"
, udev_device_get_seqnum(event->dev), event->devpath) :
-abs(_e); })
;
248
249 return 1;
250}
251
252static void worker_attach_event(struct worker *worker, struct event *event) {
253 sd_event *e;
254 uint64_t usec;
255
256 assert(worker)do { if ((__builtin_expect(!!(!(worker)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("worker"), "../src/udev/udevd.c", 256, __PRETTY_FUNCTION__
); } while (0)
;
257 assert(worker->manager)do { if ((__builtin_expect(!!(!(worker->manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("worker->manager"), "../src/udev/udevd.c"
, 257, __PRETTY_FUNCTION__); } while (0)
;
258 assert(event)do { if ((__builtin_expect(!!(!(event)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event"), "../src/udev/udevd.c", 258, __PRETTY_FUNCTION__
); } while (0)
;
259 assert(!event->worker)do { if ((__builtin_expect(!!(!(!event->worker)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("!event->worker"), "../src/udev/udevd.c"
, 259, __PRETTY_FUNCTION__); } while (0)
;
260 assert(!worker->event)do { if ((__builtin_expect(!!(!(!worker->event)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("!worker->event"), "../src/udev/udevd.c"
, 260, __PRETTY_FUNCTION__); } while (0)
;
261
262 worker->state = WORKER_RUNNING;
263 worker->event = event;
264 event->state = EVENT_RUNNING;
265 event->worker = worker;
266
267 e = worker->manager->event;
268
269 assert_se(sd_event_now(e, CLOCK_MONOTONIC, &usec) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(e, 1, &usec)
>= 0)),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("sd_event_now(e, CLOCK_MONOTONIC, &usec) >= 0"
), "../src/udev/udevd.c", 269, __PRETTY_FUNCTION__); } while (
0)
;
270
271 (void) sd_event_add_time(e, &event->timeout_warning, CLOCK_MONOTONIC1,
272 usec + arg_event_timeout_warn_usec, USEC_PER_SEC((usec_t) 1000000ULL), on_event_timeout_warning, event);
273
274 (void) sd_event_add_time(e, &event->timeout, CLOCK_MONOTONIC1,
275 usec + arg_event_timeout_usec, USEC_PER_SEC((usec_t) 1000000ULL), on_event_timeout, event);
276}
277
278static void manager_free(Manager *manager) {
279 if (!manager)
280 return;
281
282 udev_builtin_exit(manager->udev);
283
284 sd_event_source_unref(manager->ctrl_event);
285 sd_event_source_unref(manager->uevent_event);
286 sd_event_source_unref(manager->inotify_event);
287
288 udev_unref(manager->udev);
289 sd_event_unref(manager->event);
290 manager_workers_free(manager);
291 event_queue_cleanup(manager, EVENT_UNDEF);
292
293 udev_monitor_unref(manager->monitor);
294 udev_ctrl_unref(manager->ctrl);
295 udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
296
297 udev_list_cleanup(&manager->properties);
298 udev_rules_unref(manager->rules);
299
300 safe_close(manager->fd_inotify);
301 safe_close_pair(manager->worker_watch);
302
303 free(manager);
304}
305
306DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free)static inline void manager_freep(Manager* *p) { if (*p) manager_free
(*p); }
;
307
308static int worker_send_message(int fd) {
309 struct worker_message message = {};
310
311 return loop_write(fd, &message, sizeof(message), false0);
312}
313
314static bool_Bool shall_lock_device(struct udev_device *dev) {
315 const char *sysname;
316
317 if (!streq_ptr("block", udev_device_get_subsystem(dev)))
318 return false0;
319
320 sysname = udev_device_get_sysname(dev);
321 return !startswith(sysname, "dm-") &&
322 !startswith(sysname, "md") &&
323 !startswith(sysname, "drbd");
324}
325
326static void worker_spawn(Manager *manager, struct event *event) {
327 struct udev *udev = event->udev;
328 _cleanup_(udev_monitor_unrefp)__attribute__((cleanup(udev_monitor_unrefp))) struct udev_monitor *worker_monitor = NULL((void*)0);
329 pid_t pid;
330 int r = 0;
331
332 /* listen for new events */
333 worker_monitor = udev_monitor_new_from_netlink(udev, NULL((void*)0));
334 if (worker_monitor == NULL((void*)0))
335 return;
336 /* allow the main daemon netlink address to send devices to the worker */
337 udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
338 r = udev_monitor_enable_receiving(worker_monitor);
339 if (r < 0)
340 log_error_errno(r, "worker: could not enable receiving of device: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 340, __func__, "worker: could not enable receiving of device: %m"
) : -abs(_e); })
;
341
342 pid = fork();
343 switch (pid) {
344 case 0: {
345 struct udev_device *dev = NULL((void*)0);
346 _cleanup_(sd_netlink_unrefp)__attribute__((cleanup(sd_netlink_unrefp))) sd_netlink *rtnl = NULL((void*)0);
347 int fd_monitor;
348 _cleanup_close___attribute__((cleanup(closep))) int fd_signal = -1, fd_ep = -1;
349 struct epoll_event ep_signal = { .events = EPOLLINEPOLLIN };
350 struct epoll_event ep_monitor = { .events = EPOLLINEPOLLIN };
351 sigset_t mask;
352
353 /* take initial device from queue */
354 dev = TAKE_PTR(event->dev)({ typeof(event->dev) _ptr_ = (event->dev); (event->
dev) = ((void*)0); _ptr_; })
;
355
356 unsetenv("NOTIFY_SOCKET");
357
358 manager_workers_free(manager);
359 event_queue_cleanup(manager, EVENT_UNDEF);
360
361 manager->monitor = udev_monitor_unref(manager->monitor);
362 manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
363 manager->ctrl = udev_ctrl_unref(manager->ctrl);
364 manager->worker_watch[READ_END0] = safe_close(manager->worker_watch[READ_END0]);
365
366 manager->ctrl_event = sd_event_source_unref(manager->ctrl_event);
367 manager->uevent_event = sd_event_source_unref(manager->uevent_event);
368 manager->inotify_event = sd_event_source_unref(manager->inotify_event);
369
370 manager->event = sd_event_unref(manager->event);
371
372 sigfillset(&mask);
373 fd_signal = signalfd(-1, &mask, SFD_NONBLOCKSFD_NONBLOCK|SFD_CLOEXECSFD_CLOEXEC);
374 if (fd_signal < 0) {
375 r = log_error_errno(errno, "error creating signalfd %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 375, __func__, "error creating signalfd %m"
) : -abs(_e); })
;
376 goto out;
377 }
378 ep_signal.data.fd = fd_signal;
379
380 fd_monitor = udev_monitor_get_fd(worker_monitor);
381 ep_monitor.data.fd = fd_monitor;
382
383 fd_ep = epoll_create1(EPOLL_CLOEXECEPOLL_CLOEXEC);
384 if (fd_ep < 0) {
385 r = log_error_errno(errno, "error creating epoll fd: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 385, __func__, "error creating epoll fd: %m"
) : -abs(_e); })
;
386 goto out;
387 }
388
389 if (epoll_ctl(fd_ep, EPOLL_CTL_ADD1, fd_signal, &ep_signal) < 0 ||
390 epoll_ctl(fd_ep, EPOLL_CTL_ADD1, fd_monitor, &ep_monitor) < 0) {
391 r = log_error_errno(errno, "fail to add fds to epoll: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 391, __func__, "fail to add fds to epoll: %m"
) : -abs(_e); })
;
392 goto out;
393 }
394
395 /* Request TERM signal if parent exits.
396 Ignore error, not much we can do in that case. */
397 (void) prctl(PR_SET_PDEATHSIG1, SIGTERM15);
398
399 /* Reset OOM score, we only protect the main daemon. */
400 write_string_file("/proc/self/oom_score_adj", "0", 0);
401
402 for (;;) {
403 struct udev_event *udev_event;
404 int fd_lock = -1;
405
406 assert(dev)do { if ((__builtin_expect(!!(!(dev)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("dev"), "../src/udev/udevd.c", 406, __PRETTY_FUNCTION__
); } while (0)
;
407
408 log_debug("seq %llu running", udev_device_get_seqnum(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 408, __func__, "seq %llu running", udev_device_get_seqnum
(dev)) : -abs(_e); })
;
409 udev_event = udev_event_new(dev);
410 if (udev_event == NULL((void*)0)) {
411 r = -ENOMEM12;
412 goto out;
413 }
414
415 if (arg_exec_delay > 0)
416 udev_event->exec_delay = arg_exec_delay;
417
418 /*
419 * Take a shared lock on the device node; this establishes
420 * a concept of device "ownership" to serialize device
421 * access. External processes holding an exclusive lock will
422 * cause udev to skip the event handling; in the case udev
423 * acquired the lock, the external process can block until
424 * udev has finished its event handling.
425 */
426 if (!streq_ptr(udev_device_get_action(dev), "remove") &&
427 shall_lock_device(dev)) {
428 struct udev_device *d = dev;
429
430 if (streq_ptr("partition", udev_device_get_devtype(d)))
431 d = udev_device_get_parent(d);
432
433 if (d) {
434 fd_lock = open(udev_device_get_devnode(d), O_RDONLY00|O_CLOEXEC02000000|O_NOFOLLOW0400000|O_NONBLOCK04000);
435 if (fd_lock >= 0 && flock(fd_lock, LOCK_SH1|LOCK_NB4) < 0) {
436 log_debug_errno(errno, "Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d))({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 436, __func__, "Unable to flock(%s), skipping event handling: %m"
, udev_device_get_devnode(d)) : -abs(_e); })
;
437 fd_lock = safe_close(fd_lock);
438 goto skip;
439 }
440 }
441 }
442
443 /* needed for renaming netifs */
444 udev_event->rtnl = rtnl;
445
446 /* apply rules, create node, symlinks */
447 udev_event_execute_rules(udev_event,
448 arg_event_timeout_usec, arg_event_timeout_warn_usec,
449 &manager->properties,
450 manager->rules);
451
452 udev_event_execute_run(udev_event,
453 arg_event_timeout_usec, arg_event_timeout_warn_usec);
454
455 if (udev_event->rtnl)
456 /* in case rtnl was initialized */
457 rtnl = sd_netlink_ref(udev_event->rtnl);
458
459 /* apply/restore inotify watch */
460 if (udev_event->inotify_watch) {
461 udev_watch_begin(udev, dev);
462 udev_device_update_db(dev);
463 }
464
465 safe_close(fd_lock);
466
467 /* send processed event back to libudev listeners */
468 udev_monitor_send_device(worker_monitor, NULL((void*)0), dev);
469
470skip:
471 log_debug("seq %llu processed", udev_device_get_seqnum(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 471, __func__, "seq %llu processed",
udev_device_get_seqnum(dev)) : -abs(_e); })
;
472
473 /* send udevd the result of the event execution */
474 r = worker_send_message(manager->worker_watch[WRITE_END1]);
475 if (r < 0)
476 log_error_errno(r, "failed to send result of seq %llu to main daemon: %m",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 477, __func__, "failed to send result of seq %llu to main daemon: %m"
, udev_device_get_seqnum(dev)) : -abs(_e); })
477 udev_device_get_seqnum(dev))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 477, __func__, "failed to send result of seq %llu to main daemon: %m"
, udev_device_get_seqnum(dev)) : -abs(_e); })
;
478
479 udev_device_unref(dev);
480 dev = NULL((void*)0);
481
482 udev_event_unref(udev_event);
483
484 /* wait for more device messages from main udevd, or term signal */
485 while (dev == NULL((void*)0)) {
486 struct epoll_event ev[4];
487 int fdcount;
488 int i;
489
490 fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(ev), typeof(&*(ev))), sizeof(ev)/sizeof((ev)[0]),
((void)0)))
, -1);
491 if (fdcount < 0) {
492 if (errno(*__errno_location ()) == EINTR4)
493 continue;
494 r = log_error_errno(errno, "failed to poll: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 494, __func__, "failed to poll: %m"
) : -abs(_e); })
;
495 goto out;
496 }
497
498 for (i = 0; i < fdcount; i++) {
499 if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLINEPOLLIN) {
500 dev = udev_monitor_receive_device(worker_monitor);
501 break;
502 } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLINEPOLLIN) {
503 struct signalfd_siginfo fdsi;
504 ssize_t size;
505
506 size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
507 if (size != sizeof(struct signalfd_siginfo))
508 continue;
509 switch (fdsi.ssi_signo) {
510 case SIGTERM15:
511 goto out;
512 }
513 }
514 }
515 }
516 }
517out:
518 udev_device_unref(dev);
519 manager_free(manager);
520 log_close();
521 _exit(r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0);
522 }
523 case -1:
524 event->state = EVENT_QUEUED;
525 log_error_errno(errno, "fork of child failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 525, __func__, "fork of child failed: %m"
) : -abs(_e); })
;
526 break;
527 default:
528 {
529 struct worker *worker;
530
531 r = worker_new(&worker, manager, worker_monitor, pid);
532 if (r < 0)
533 return;
534
535 worker_attach_event(worker, event);
536
537 log_debug("seq %llu forked new worker ["PID_FMT"]", udev_device_get_seqnum(event->dev), pid)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 537, __func__, "seq %llu forked new worker ["
"%" "i""]", udev_device_get_seqnum(event->dev), pid) : -abs
(_e); })
;
538 break;
539 }
540 }
541}
542
543static void event_run(Manager *manager, struct event *event) {
544 struct worker *worker;
545 Iterator i;
546
547 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 547, __PRETTY_FUNCTION__
); } while (0)
;
548 assert(event)do { if ((__builtin_expect(!!(!(event)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("event"), "../src/udev/udevd.c", 548, __PRETTY_FUNCTION__
); } while (0)
;
549
550 HASHMAP_FOREACH(worker, manager->workers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((manager->workers
), &(i), (void**)&(worker), ((void*)0)); )
{
551 ssize_t count;
552
553 if (worker->state != WORKER_IDLE)
554 continue;
555
556 count = udev_monitor_send_device(manager->monitor, worker->monitor, event->dev);
557 if (count < 0) {
558 log_error_errno(errno, "worker ["PID_FMT"] did not accept message %zi (%m), kill it",({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 559, __func__, "worker ["
"%" "i""] did not accept message %zi (%m), kill it", worker->
pid, count) : -abs(_e); })
559 worker->pid, count)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 559, __func__, "worker ["
"%" "i""] did not accept message %zi (%m), kill it", worker->
pid, count) : -abs(_e); })
;
560 kill(worker->pid, SIGKILL9);
561 worker->state = WORKER_KILLED;
562 continue;
563 }
564 worker_attach_event(worker, event);
565 return;
566 }
567
568 if (hashmap_size(manager->workers) >= arg_children_max) {
569 if (arg_children_max > 1)
570 log_debug("maximum number (%i) of children reached", hashmap_size(manager->workers))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 570, __func__, "maximum number (%i) of children reached"
, hashmap_size(manager->workers)) : -abs(_e); })
;
571 return;
572 }
573
574 /* start new worker and pass initial device */
575 worker_spawn(manager, event);
576}
577
578static int event_queue_insert(Manager *manager, struct udev_device *dev) {
579 struct event *event;
580 int r;
581
582 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 582, __PRETTY_FUNCTION__
); } while (0)
;
583 assert(dev)do { if ((__builtin_expect(!!(!(dev)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("dev"), "../src/udev/udevd.c", 583, __PRETTY_FUNCTION__
); } while (0)
;
584
585 /* only one process can add events to the queue */
586 if (manager->pid == 0)
587 manager->pid = getpid_cached();
588
589 assert(manager->pid == getpid_cached())do { if ((__builtin_expect(!!(!(manager->pid == getpid_cached
())),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("manager->pid == getpid_cached()"
), "../src/udev/udevd.c", 589, __PRETTY_FUNCTION__); } while (
0)
;
590
591 event = new0(struct event, 1)((struct event*) calloc((1), sizeof(struct event)));
592 if (!event)
593 return -ENOMEM12;
594
595 event->udev = udev_device_get_udev(dev);
596 event->manager = manager;
597 event->dev = dev;
598 event->dev_kernel = udev_device_shallow_clone(dev);
599 udev_device_copy_properties(event->dev_kernel, dev);
600 event->seqnum = udev_device_get_seqnum(dev);
601 event->devpath = udev_device_get_devpath(dev);
602 event->devpath_len = strlen(event->devpath);
603 event->devpath_old = udev_device_get_devpath_old(dev);
604 event->devnum = udev_device_get_devnum(dev);
605 event->is_block = streq("block", udev_device_get_subsystem(dev))(strcmp(("block"),(udev_device_get_subsystem(dev))) == 0);
606 event->ifindex = udev_device_get_ifindex(dev);
607
608 log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev),({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 609, __func__, "seq %llu queued, '%s' '%s'"
, udev_device_get_seqnum(dev), udev_device_get_action(dev), udev_device_get_subsystem
(dev)) : -abs(_e); })
609 udev_device_get_action(dev), udev_device_get_subsystem(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 609, __func__, "seq %llu queued, '%s' '%s'"
, udev_device_get_seqnum(dev), udev_device_get_action(dev), udev_device_get_subsystem
(dev)) : -abs(_e); })
;
610
611 event->state = EVENT_QUEUED;
612
613 if (LIST_IS_EMPTY(manager->events)(!(manager->events))) {
614 r = touch("/run/udev/queue");
615 if (r < 0)
616 log_warning_errno(r, "could not touch /run/udev/queue: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 616, __func__, "could not touch /run/udev/queue: %m"
) : -abs(_e); })
;
617 }
618
619 LIST_APPEND(event, manager->events, event)do { typeof(*(manager->events)) *_tail; do { typeof(*(manager
->events)) *_item = (manager->events); if (!_item) (_tail
) = ((void*)0); else { while (_item->event_next) _item = _item
->event_next; (_tail) = _item; } } while (0); do { typeof(
*(manager->events)) **_head = &(manager->events), *
_a = (_tail), *_b = (event); do { if ((__builtin_expect(!!(!(
_b)),0))) log_assert_failed_realm(LOG_REALM_UDEV, ("_b"), "../src/udev/udevd.c"
, 619, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
event_next = *_head)) _b->event_next->event_prev = _b; _b
->event_prev = ((void*)0); *_head = _b; } else { if ((_b->
event_next = _a->event_next)) _b->event_next->event_prev
= _b; _b->event_prev = _a; _a->event_next = _b; } } while
(0); } while (0)
;
620
621 return 0;
622}
623
624static void manager_kill_workers(Manager *manager) {
625 struct worker *worker;
626 Iterator i;
627
628 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 628, __PRETTY_FUNCTION__
); } while (0)
;
629
630 HASHMAP_FOREACH(worker, manager->workers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((manager->workers
), &(i), (void**)&(worker), ((void*)0)); )
{
631 if (worker->state == WORKER_KILLED)
632 continue;
633
634 worker->state = WORKER_KILLED;
635 kill(worker->pid, SIGTERM15);
636 }
637}
638
639/* lookup event for identical, parent, child device */
640static bool_Bool is_devpath_busy(Manager *manager, struct event *event) {
641 struct event *loop_event;
642 size_t common;
643
644 /* check if queue contains events we depend on */
645 LIST_FOREACH(event, loop_event, manager->events)for ((loop_event) = (manager->events); (loop_event); (loop_event
) = (loop_event)->event_next)
{
646 /* we already found a later event, earlier cannot block us, no need to check again */
647 if (loop_event->seqnum < event->delaying_seqnum)
648 continue;
649
650 /* event we checked earlier still exists, no need to check again */
651 if (loop_event->seqnum == event->delaying_seqnum)
652 return true1;
653
654 /* found ourself, no later event can block us */
655 if (loop_event->seqnum >= event->seqnum)
656 break;
657
658 /* check major/minor */
659 if (major(event->devnum)gnu_dev_major (event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
660 return true1;
661
662 /* check network device ifindex */
663 if (event->ifindex != 0 && event->ifindex == loop_event->ifindex)
664 return true1;
665
666 /* check our old name */
667 if (event->devpath_old != NULL((void*)0) && streq(loop_event->devpath, event->devpath_old)(strcmp((loop_event->devpath),(event->devpath_old)) == 0
)
) {
668 event->delaying_seqnum = loop_event->seqnum;
669 return true1;
670 }
671
672 /* compare devpath */
673 common = MIN(loop_event->devpath_len, event->devpath_len)__extension__ ({ const typeof((loop_event->devpath_len)) __unique_prefix_A29
= ((loop_event->devpath_len)); const typeof((event->devpath_len
)) __unique_prefix_B30 = ((event->devpath_len)); __unique_prefix_A29
< __unique_prefix_B30 ? __unique_prefix_A29 : __unique_prefix_B30
; })
;
674
675 /* one devpath is contained in the other? */
676 if (memcmp(loop_event->devpath, event->devpath, common) != 0)
677 continue;
678
679 /* identical device event found */
680 if (loop_event->devpath_len == event->devpath_len) {
681 /* devices names might have changed/swapped in the meantime */
682 if (major(event->devnum)gnu_dev_major (event->devnum) != 0 && (event->devnum != loop_event->devnum || event->is_block != loop_event->is_block))
683 continue;
684 if (event->ifindex != 0 && event->ifindex != loop_event->ifindex)
685 continue;
686 event->delaying_seqnum = loop_event->seqnum;
687 return true1;
688 }
689
690 /* parent device event found */
691 if (event->devpath[common] == '/') {
692 event->delaying_seqnum = loop_event->seqnum;
693 return true1;
694 }
695
696 /* child device event found */
697 if (loop_event->devpath[common] == '/') {
698 event->delaying_seqnum = loop_event->seqnum;
699 return true1;
700 }
701
702 /* no matching device */
703 continue;
704 }
705
706 return false0;
707}
708
709static int on_exit_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
710 Manager *manager = userdata;
711
712 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 712, __PRETTY_FUNCTION__
); } while (0)
;
713
714 log_error_errno(ETIMEDOUT, "giving up waiting for workers to finish")({ int _level = ((3)), _e = ((110)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 714, __func__, "giving up waiting for workers to finish"
) : -abs(_e); })
;
715
716 sd_event_exit(manager->event, -ETIMEDOUT110);
717
718 return 1;
719}
720
721static void manager_exit(Manager *manager) {
722 uint64_t usec;
723 int r;
724
725 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 725, __PRETTY_FUNCTION__
); } while (0)
;
726
727 manager->exit = true1;
728
729 sd_notify(false0,
730 "STOPPING=1\n"
731 "STATUS=Starting shutdown...");
732
733 /* close sources of new events and discard buffered events */
734 manager->ctrl_event = sd_event_source_unref(manager->ctrl_event);
735 manager->ctrl = udev_ctrl_unref(manager->ctrl);
736
737 manager->inotify_event = sd_event_source_unref(manager->inotify_event);
738 manager->fd_inotify = safe_close(manager->fd_inotify);
739
740 manager->uevent_event = sd_event_source_unref(manager->uevent_event);
741 manager->monitor = udev_monitor_unref(manager->monitor);
742
743 /* discard queued events and kill workers */
744 event_queue_cleanup(manager, EVENT_QUEUED);
745 manager_kill_workers(manager);
746
747 assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(manager->event
, 1, &usec) >= 0)),0))) log_assert_failed_realm(LOG_REALM_UDEV
, ("sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0"
), "../src/udev/udevd.c", 747, __PRETTY_FUNCTION__); } while (
0)
;
748
749 r = sd_event_add_time(manager->event, NULL((void*)0), CLOCK_MONOTONIC1,
750 usec + 30 * USEC_PER_SEC((usec_t) 1000000ULL), USEC_PER_SEC((usec_t) 1000000ULL), on_exit_timeout, manager);
751 if (r < 0)
752 return;
753}
754
755/* reload requested, HUP signal received, rules changed, builtin changed */
756static void manager_reload(Manager *manager) {
757
758 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 758, __PRETTY_FUNCTION__
); } while (0)
;
759
760 sd_notify(false0,
761 "RELOADING=1\n"
762 "STATUS=Flushing configuration...");
763
764 manager_kill_workers(manager);
765 manager->rules = udev_rules_unref(manager->rules);
766 udev_builtin_exit(manager->udev);
767
768 sd_notifyf(false0,
769 "READY=1\n"
770 "STATUS=Processing with %u children at max", arg_children_max);
771}
772
773static void event_queue_start(Manager *manager) {
774 struct event *event;
775 usec_t usec;
776
777 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 777, __PRETTY_FUNCTION__
); } while (0)
;
778
779 if (LIST_IS_EMPTY(manager->events)(!(manager->events)) ||
780 manager->exit || manager->stop_exec_queue)
781 return;
782
783 assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0)do { if ((__builtin_expect(!!(!(sd_event_now(manager->event
, 1, &usec) >= 0)),0))) log_assert_failed_realm(LOG_REALM_UDEV
, ("sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0"
), "../src/udev/udevd.c", 783, __PRETTY_FUNCTION__); } while (
0)
;
784 /* check for changed config, every 3 seconds at most */
785 if (manager->last_usec == 0 ||
786 (usec - manager->last_usec) > 3 * USEC_PER_SEC((usec_t) 1000000ULL)) {
787 if (udev_rules_check_timestamp(manager->rules) ||
788 udev_builtin_validate(manager->udev))
789 manager_reload(manager);
790
791 manager->last_usec = usec;
792 }
793
794 udev_builtin_init(manager->udev);
795
796 if (!manager->rules) {
797 manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
798 if (!manager->rules)
799 return;
800 }
801
802 LIST_FOREACH(event,event,manager->events)for ((event) = (manager->events); (event); (event) = (event
)->event_next)
{
803 if (event->state != EVENT_QUEUED)
804 continue;
805
806 /* do not start event if parent or child event is still running */
807 if (is_devpath_busy(manager, event))
808 continue;
809
810 event_run(manager, event);
811 }
812}
813
814static void event_queue_cleanup(Manager *manager, enum event_state match_type) {
815 struct event *event, *tmp;
816
817 LIST_FOREACH_SAFE(event, event, tmp, manager->events)for ((event) = (manager->events); (event) && (((tmp
) = (event)->event_next), 1); (event) = (tmp))
{
818 if (match_type != EVENT_UNDEF && match_type != event->state)
819 continue;
820
821 event_free(event);
822 }
823}
824
825static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
826 Manager *manager = userdata;
827
828 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 828, __PRETTY_FUNCTION__
); } while (0)
;
829
830 for (;;) {
831 struct worker_message msg;
832 struct iovec iovec = {
833 .iov_base = &msg,
834 .iov_len = sizeof(msg),
835 };
836 union {
837 struct cmsghdr cmsghdr;
838 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))((((sizeof(struct ucred)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
];
839 } control = {};
840 struct msghdr msghdr = {
841 .msg_iov = &iovec,
842 .msg_iovlen = 1,
843 .msg_control = &control,
844 .msg_controllen = sizeof(control),
845 };
846 struct cmsghdr *cmsg;
847 ssize_t size;
848 struct ucred *ucred = NULL((void*)0);
849 struct worker *worker;
850
851 size = recvmsg(fd, &msghdr, MSG_DONTWAITMSG_DONTWAIT);
852 if (size < 0) {
853 if (errno(*__errno_location ()) == EINTR4)
854 continue;
855 else if (errno(*__errno_location ()) == EAGAIN11)
856 /* nothing more to read */
857 break;
858
859 return log_error_errno(errno, "failed to receive message: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 859, __func__, "failed to receive message: %m"
) : -abs(_e); })
;
860 } else if (size != sizeof(struct worker_message)) {
861 log_warning_errno(EIO, "ignoring worker message with invalid size %zi bytes", size)({ int _level = ((4)), _e = ((5)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 861, __func__, "ignoring worker message with invalid size %zi bytes"
, size) : -abs(_e); })
;
862 continue;
863 }
864
865 CMSG_FOREACH(cmsg, &msghdr)for ((cmsg) = ((size_t) (&msghdr)->msg_controllen >=
sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msghdr)->
msg_control : (struct cmsghdr *) 0); (cmsg); (cmsg) = __cmsg_nxthdr
((&msghdr), (cmsg)))
{
866 if (cmsg->cmsg_level == SOL_SOCKET1 &&
867 cmsg->cmsg_type == SCM_CREDENTIALSSCM_CREDENTIALS &&
868 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(struct ucred)))
)
869 ucred = (struct ucred*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data);
870 }
871
872 if (!ucred || ucred->pid <= 0) {
873 log_warning_errno(EIO, "ignoring worker message without valid PID")({ int _level = ((4)), _e = ((5)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 873, __func__, "ignoring worker message without valid PID"
) : -abs(_e); })
;
874 continue;
875 }
876
877 /* lookup worker who sent the signal */
878 worker = hashmap_get(manager->workers, PID_TO_PTR(ucred->pid));
879 if (!worker) {
880 log_debug("worker ["PID_FMT"] returned, but is no longer tracked", ucred->pid)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 880, __func__, "worker [""%" "i""] returned, but is no longer tracked"
, ucred->pid) : -abs(_e); })
;
881 continue;
882 }
883
884 if (worker->state != WORKER_KILLED)
885 worker->state = WORKER_IDLE;
886
887 /* worker returned */
888 event_free(worker->event);
889 }
890
891 /* we have free workers, try to schedule events */
892 event_queue_start(manager);
893
894 return 1;
895}
896
897static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
898 Manager *manager = userdata;
899 struct udev_device *dev;
900 int r;
901
902 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 902, __PRETTY_FUNCTION__
); } while (0)
;
903
904 dev = udev_monitor_receive_device(manager->monitor);
905 if (dev) {
906 udev_device_ensure_usec_initialized(dev, NULL((void*)0));
907 r = event_queue_insert(manager, dev);
908 if (r < 0)
909 udev_device_unref(dev);
910 else
911 /* we have fresh events, try to schedule them */
912 event_queue_start(manager);
913 }
914
915 return 1;
916}
917
918/* receive the udevd message from userspace */
919static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
920 Manager *manager = userdata;
921 _cleanup_(udev_ctrl_connection_unrefp)__attribute__((cleanup(udev_ctrl_connection_unrefp))) struct udev_ctrl_connection *ctrl_conn = NULL((void*)0);
922 _cleanup_(udev_ctrl_msg_unrefp)__attribute__((cleanup(udev_ctrl_msg_unrefp))) struct udev_ctrl_msg *ctrl_msg = NULL((void*)0);
923 const char *str;
924 int i;
925
926 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 926, __PRETTY_FUNCTION__
); } while (0)
;
1
Assuming 'manager' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
927
928 ctrl_conn = udev_ctrl_get_connection(manager->ctrl);
929 if (!ctrl_conn)
4
Assuming 'ctrl_conn' is non-null
5
Taking false branch
930 return 1;
931
932 ctrl_msg = udev_ctrl_receive_msg(ctrl_conn);
933 if (!ctrl_msg)
6
Assuming 'ctrl_msg' is non-null
7
Taking false branch
934 return 1;
935
936 i = udev_ctrl_get_set_log_level(ctrl_msg);
937 if (i >= 0) {
8
Assuming 'i' is < 0
9
Taking false branch
938 log_debug("udevd message (SET_LOG_LEVEL) received, log_priority=%i", i)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 938, __func__, "udevd message (SET_LOG_LEVEL) received, log_priority=%i"
, i) : -abs(_e); })
;
939 log_set_max_level(i)log_set_max_level_realm(LOG_REALM_UDEV, (i));
940 manager_kill_workers(manager);
941 }
942
943 if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
10
Assuming the condition is false
11
Taking false branch
944 log_debug("udevd message (STOP_EXEC_QUEUE) received")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 944, __func__, "udevd message (STOP_EXEC_QUEUE) received"
) : -abs(_e); })
;
945 manager->stop_exec_queue = true1;
946 }
947
948 if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
12
Assuming the condition is false
13
Taking false branch
949 log_debug("udevd message (START_EXEC_QUEUE) received")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 949, __func__, "udevd message (START_EXEC_QUEUE) received"
) : -abs(_e); })
;
950 manager->stop_exec_queue = false0;
951 event_queue_start(manager);
952 }
953
954 if (udev_ctrl_get_reload(ctrl_msg) > 0) {
14
Assuming the condition is false
15
Taking false branch
955 log_debug("udevd message (RELOAD) received")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 955, __func__, "udevd message (RELOAD) received"
) : -abs(_e); })
;
956 manager_reload(manager);
957 }
958
959 str = udev_ctrl_get_set_env(ctrl_msg);
960 if (str != NULL((void*)0)) {
16
Assuming 'str' is not equal to NULL
17
Taking true branch
961 _cleanup_free___attribute__((cleanup(freep))) char *key = NULL((void*)0);
962
963 key = strdup(str);
18
Memory is allocated
964 if (key) {
19
Assuming 'key' is non-null
20
Taking true branch
965 char *val;
966
967 val = strchr(key, '=');
968 if (val != NULL((void*)0)) {
21
Assuming 'val' is equal to NULL
22
Taking false branch
969 val[0] = '\0';
970 val = &val[1];
971 if (val[0] == '\0') {
972 log_debug("udevd message (ENV) received, unset '%s'", key)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 972, __func__, "udevd message (ENV) received, unset '%s'"
, key) : -abs(_e); })
;
973 udev_list_entry_add(&manager->properties, key, NULL((void*)0));
974 } else {
975 log_debug("udevd message (ENV) received, set '%s=%s'", key, val)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 975, __func__, "udevd message (ENV) received, set '%s=%s'"
, key, val) : -abs(_e); })
;
976 udev_list_entry_add(&manager->properties, key, val);
977 }
978 } else
979 log_error("wrong key format '%s'", key)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 979, __func__, "wrong key format '%s'"
, key) : -abs(_e); })
;
23
Assuming the condition is false
24
'?' condition is false
25
Potential leak of memory pointed to by 'key'
980 }
981 manager_kill_workers(manager);
982 }
983
984 i = udev_ctrl_get_set_children_max(ctrl_msg);
985 if (i >= 0) {
986 log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i", i)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 986, __func__, "udevd message (SET_MAX_CHILDREN) received, children_max=%i"
, i) : -abs(_e); })
;
987 arg_children_max = i;
988
989 (void) sd_notifyf(false0,
990 "READY=1\n"
991 "STATUS=Processing with %u children at max", arg_children_max);
992 }
993
994 if (udev_ctrl_get_ping(ctrl_msg) > 0)
995 log_debug("udevd message (SYNC) received")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 995, __func__, "udevd message (SYNC) received"
) : -abs(_e); })
;
996
997 if (udev_ctrl_get_exit(ctrl_msg) > 0) {
998 log_debug("udevd message (EXIT) received")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 998, __func__, "udevd message (EXIT) received"
) : -abs(_e); })
;
999 manager_exit(manager);
1000 /* keep reference to block the client until we exit
1001 TODO: deal with several blocking exit requests */
1002 manager->ctrl_conn_blocking = udev_ctrl_connection_ref(ctrl_conn);
1003 }
1004
1005 return 1;
1006}
1007
1008static int synthesize_change(struct udev_device *dev) {
1009 char filename[UTIL_PATH_SIZE1024];
1010 int r;
1011
1012 if (streq_ptr("block", udev_device_get_subsystem(dev)) &&
1013 streq_ptr("disk", udev_device_get_devtype(dev)) &&
1014 !startswith(udev_device_get_sysname(dev), "dm-")) {
1015 bool_Bool part_table_read = false0;
1016 bool_Bool has_partitions = false0;
1017 int fd;
1018 struct udev *udev = udev_device_get_udev(dev);
1019 _cleanup_(udev_enumerate_unrefp)__attribute__((cleanup(udev_enumerate_unrefp))) struct udev_enumerate *e = NULL((void*)0);
1020 struct udev_list_entry *item;
1021
1022 /*
1023 * Try to re-read the partition table. This only succeeds if
1024 * none of the devices is busy. The kernel returns 0 if no
1025 * partition table is found, and we will not get an event for
1026 * the disk.
1027 */
1028 fd = open(udev_device_get_devnode(dev), O_RDONLY00|O_CLOEXEC02000000|O_NOFOLLOW0400000|O_NONBLOCK04000);
1029 if (fd >= 0) {
1030 r = flock(fd, LOCK_EX2|LOCK_NB4);
1031 if (r >= 0)
1032 r = ioctl(fd, BLKRRPART(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8))
| (((95)) << 0) | ((0) << ((0 +8)+8)))
, 0);
1033
1034 close(fd);
1035 if (r >= 0)
1036 part_table_read = true1;
1037 }
1038
1039 /* search for partitions */
1040 e = udev_enumerate_new(udev);
1041 if (!e)
1042 return -ENOMEM12;
1043
1044 r = udev_enumerate_add_match_parent(e, dev);
1045 if (r < 0)
1046 return r;
1047
1048 r = udev_enumerate_add_match_subsystem(e, "block");
1049 if (r < 0)
1050 return r;
1051
1052 r = udev_enumerate_scan_devices(e);
1053 if (r < 0)
1054 return r;
1055
1056 udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e))for (item = udev_enumerate_get_list_entry(e); item != ((void*
)0); item = udev_list_entry_get_next(item))
{
1057 _cleanup_(udev_device_unrefp)__attribute__((cleanup(udev_device_unrefp))) struct udev_device *d = NULL((void*)0);
1058
1059 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
1060 if (!d)
1061 continue;
1062
1063 if (!streq_ptr("partition", udev_device_get_devtype(d)))
1064 continue;
1065
1066 has_partitions = true1;
1067 break;
1068 }
1069
1070 /*
1071 * We have partitions and re-read the table, the kernel already sent
1072 * out a "change" event for the disk, and "remove/add" for all
1073 * partitions.
1074 */
1075 if (part_table_read && has_partitions)
1076 return 0;
1077
1078 /*
1079 * We have partitions but re-reading the partition table did not
1080 * work, synthesize "change" for the disk and all partitions.
1081 */
1082 log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1082, __func__, "device %s closed, synthesising 'change'"
, udev_device_get_devnode(dev)) : -abs(_e); })
;
1083 strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL((void*)0));
1084 write_string_file(filename, "change", WRITE_STRING_FILE_CREATE);
1085
1086 udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e))for (item = udev_enumerate_get_list_entry(e); item != ((void*
)0); item = udev_list_entry_get_next(item))
{
1087 _cleanup_(udev_device_unrefp)__attribute__((cleanup(udev_device_unrefp))) struct udev_device *d = NULL((void*)0);
1088
1089 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
1090 if (!d)
1091 continue;
1092
1093 if (!streq_ptr("partition", udev_device_get_devtype(d)))
1094 continue;
1095
1096 log_debug("device %s closed, synthesising partition '%s' 'change'",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1097, __func__, "device %s closed, synthesising partition '%s' 'change'"
, udev_device_get_devnode(dev), udev_device_get_devnode(d)) :
-abs(_e); })
1097 udev_device_get_devnode(dev), udev_device_get_devnode(d))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1097, __func__, "device %s closed, synthesising partition '%s' 'change'"
, udev_device_get_devnode(dev), udev_device_get_devnode(d)) :
-abs(_e); })
;
1098 strscpyl(filename, sizeof(filename), udev_device_get_syspath(d), "/uevent", NULL((void*)0));
1099 write_string_file(filename, "change", WRITE_STRING_FILE_CREATE);
1100 }
1101
1102 return 0;
1103 }
1104
1105 log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1105, __func__, "device %s closed, synthesising 'change'"
, udev_device_get_devnode(dev)) : -abs(_e); })
;
1106 strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL((void*)0));
1107 write_string_file(filename, "change", WRITE_STRING_FILE_CREATE);
1108
1109 return 0;
1110}
1111
1112static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1113 Manager *manager = userdata;
1114 union inotify_event_buffer buffer;
1115 struct inotify_event *e;
1116 ssize_t l;
1117
1118 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 1118, __PRETTY_FUNCTION__
); } while (0)
;
1119
1120 l = read(fd, &buffer, sizeof(buffer));
1121 if (l < 0) {
1122 if (IN_SET(errno, EAGAIN, EINTR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){11, 4})/sizeof(int)]; switch((*__errno_location
())) { case 11: case 4: _found = 1; break; default: break; }
_found; })
)
1123 return 1;
1124
1125 return log_error_errno(errno, "Failed to read inotify fd: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1125, __func__, "Failed to read inotify fd: %m"
) : -abs(_e); })
;
1126 }
1127
1128 FOREACH_INOTIFY_EVENT(e, buffer, l)for ((e) = &buffer.ev; (uint8_t*) (e) < (uint8_t*) (buffer
.raw) + (l); (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof
(struct inotify_event) + (e)->len))
{
1129 _cleanup_(udev_device_unrefp)__attribute__((cleanup(udev_device_unrefp))) struct udev_device *dev = NULL((void*)0);
1130
1131 dev = udev_watch_lookup(manager->udev, e->wd);
1132 if (!dev)
1133 continue;
1134
1135 log_debug("inotify event: %x for %s", e->mask, udev_device_get_devnode(dev))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1135, __func__, "inotify event: %x for %s"
, e->mask, udev_device_get_devnode(dev)) : -abs(_e); })
;
1136 if (e->mask & IN_CLOSE_WRITE0x00000008) {
1137 synthesize_change(dev);
1138
1139 /* settle might be waiting on us to determine the queue
1140 * state. If we just handled an inotify event, we might have
1141 * generated a "change" event, but we won't have queued up
1142 * the resultant uevent yet. Do that.
1143 */
1144 on_uevent(NULL((void*)0), -1, 0, manager);
1145 } else if (e->mask & IN_IGNORED0x00008000)
1146 udev_watch_end(manager->udev, dev);
1147 }
1148
1149 return 1;
1150}
1151
1152static int on_sigterm(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1153 Manager *manager = userdata;
1154
1155 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 1155, __PRETTY_FUNCTION__
); } while (0)
;
1156
1157 manager_exit(manager);
1158
1159 return 1;
1160}
1161
1162static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1163 Manager *manager = userdata;
1164
1165 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 1165, __PRETTY_FUNCTION__
); } while (0)
;
1166
1167 manager_reload(manager);
1168
1169 return 1;
1170}
1171
1172static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1173 Manager *manager = userdata;
1174
1175 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 1175, __PRETTY_FUNCTION__
); } while (0)
;
1176
1177 for (;;) {
1178 pid_t pid;
1179 int status;
1180 struct worker *worker;
1181
1182 pid = waitpid(-1, &status, WNOHANG1);
1183 if (pid <= 0)
1184 break;
1185
1186 worker = hashmap_get(manager->workers, PID_TO_PTR(pid));
1187 if (!worker) {
1188 log_warning("worker ["PID_FMT"] is unknown, ignoring", pid)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1188, __func__, "worker [""%" "i""] is unknown, ignoring"
, pid) : -abs(_e); })
;
1189 continue;
1190 }
1191
1192 if (WIFEXITED(status)(((status) & 0x7f) == 0)) {
1193 if (WEXITSTATUS(status)(((status) & 0xff00) >> 8) == 0)
1194 log_debug("worker ["PID_FMT"] exited", pid)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1194, __func__, "worker [""%" "i""] exited"
, pid) : -abs(_e); })
;
1195 else
1196 log_warning("worker ["PID_FMT"] exited with return code %i", pid, WEXITSTATUS(status))({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1196, __func__, "worker [""%" "i""] exited with return code %i"
, pid, (((status) & 0xff00) >> 8)) : -abs(_e); })
;
1197 } else if (WIFSIGNALED(status)(((signed char) (((status) & 0x7f) + 1) >> 1) > 0
)
) {
1198 log_warning("worker ["PID_FMT"] terminated by signal %i (%s)", pid, WTERMSIG(status), signal_to_string(WTERMSIG(status)))({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1198, __func__, "worker [""%" "i""] terminated by signal %i (%s)"
, pid, ((status) & 0x7f), signal_to_string(((status) &
0x7f))) : -abs(_e); })
;
1199 } else if (WIFSTOPPED(status)(((status) & 0xff) == 0x7f)) {
1200 log_info("worker ["PID_FMT"] stopped", pid)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1200, __func__, "worker [""%" "i""] stopped"
, pid) : -abs(_e); })
;
1201 continue;
1202 } else if (WIFCONTINUED(status)((status) == 0xffff)) {
1203 log_info("worker ["PID_FMT"] continued", pid)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1203, __func__, "worker [""%" "i""] continued"
, pid) : -abs(_e); })
;
1204 continue;
1205 } else
1206 log_warning("worker ["PID_FMT"] exit with status 0x%04x", pid, status)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1206, __func__, "worker [""%" "i""] exit with status 0x%04x"
, pid, status) : -abs(_e); })
;
1207
1208 if (!WIFEXITED(status)(((status) & 0x7f) == 0) || WEXITSTATUS(status)(((status) & 0xff00) >> 8) != 0) {
1209 if (worker->event) {
1210 log_error("worker ["PID_FMT"] failed while handling '%s'", pid, worker->event->devpath)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1210, __func__, "worker [""%" "i""] failed while handling '%s'"
, pid, worker->event->devpath) : -abs(_e); })
;
1211 /* delete state from disk */
1212 udev_device_delete_db(worker->event->dev);
1213 udev_device_tag_index(worker->event->dev, NULL((void*)0), false0);
1214 /* forward kernel event without amending it */
1215 udev_monitor_send_device(manager->monitor, NULL((void*)0), worker->event->dev_kernel);
1216 }
1217 }
1218
1219 worker_free(worker);
1220 }
1221
1222 /* we can start new workers, try to schedule events */
1223 event_queue_start(manager);
1224
1225 return 1;
1226}
1227
1228static int on_post(sd_event_source *s, void *userdata) {
1229 Manager *manager = userdata;
1230 int r;
1231
1232 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("manager"), "../src/udev/udevd.c", 1232, __PRETTY_FUNCTION__
); } while (0)
;
1233
1234 if (LIST_IS_EMPTY(manager->events)(!(manager->events))) {
1235 /* no pending events */
1236 if (!hashmap_isempty(manager->workers)) {
1237 /* there are idle workers */
1238 log_debug("cleanup idle workers")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1238, __func__, "cleanup idle workers"
) : -abs(_e); })
;
1239 manager_kill_workers(manager);
1240 } else {
1241 /* we are idle */
1242 if (manager->exit) {
1243 r = sd_event_exit(manager->event, 0);
1244 if (r < 0)
1245 return r;
1246 } else if (manager->cgroup)
1247 /* cleanup possible left-over processes in our cgroup */
1248 cg_kill(SYSTEMD_CGROUP_CONTROLLER"_systemd", manager->cgroup, SIGKILL9, CGROUP_IGNORE_SELF, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1249 }
1250 }
1251
1252 return 1;
1253}
1254
1255static int listen_fds(int *rctrl, int *rnetlink) {
1256 _cleanup_(udev_unrefp)__attribute__((cleanup(udev_unrefp))) struct udev *udev = NULL((void*)0);
1257 int ctrl_fd = -1, netlink_fd = -1;
1258 int fd, n, r;
1259
1260 assert(rctrl)do { if ((__builtin_expect(!!(!(rctrl)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("rctrl"), "../src/udev/udevd.c", 1260, __PRETTY_FUNCTION__
); } while (0)
;
1261 assert(rnetlink)do { if ((__builtin_expect(!!(!(rnetlink)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("rnetlink"), "../src/udev/udevd.c", 1261, __PRETTY_FUNCTION__
); } while (0)
;
1262
1263 n = sd_listen_fds(true1);
1264 if (n < 0)
1265 return n;
1266
1267 for (fd = SD_LISTEN_FDS_START3; fd < n + SD_LISTEN_FDS_START3; fd++) {
1268 if (sd_is_socket(fd, AF_LOCAL1, SOCK_SEQPACKETSOCK_SEQPACKET, -1)) {
1269 if (ctrl_fd >= 0)
1270 return -EINVAL22;
1271 ctrl_fd = fd;
1272 continue;
1273 }
1274
1275 if (sd_is_socket(fd, AF_NETLINK16, SOCK_RAWSOCK_RAW, -1)) {
1276 if (netlink_fd >= 0)
1277 return -EINVAL22;
1278 netlink_fd = fd;
1279 continue;
1280 }
1281
1282 return -EINVAL22;
1283 }
1284
1285 if (ctrl_fd < 0) {
1286 _cleanup_(udev_ctrl_unrefp)__attribute__((cleanup(udev_ctrl_unrefp))) struct udev_ctrl *ctrl = NULL((void*)0);
1287
1288 udev = udev_new();
1289 if (!udev)
1290 return -ENOMEM12;
1291
1292 ctrl = udev_ctrl_new(udev);
1293 if (!ctrl)
1294 return log_error_errno(EINVAL, "error initializing udev control socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1294, __func__, "error initializing udev control socket"
) : -abs(_e); })
;
1295
1296 r = udev_ctrl_enable_receiving(ctrl);
1297 if (r < 0)
1298 return log_error_errno(EINVAL, "error binding udev control socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1298, __func__, "error binding udev control socket"
) : -abs(_e); })
;
1299
1300 fd = udev_ctrl_get_fd(ctrl);
1301 if (fd < 0)
1302 return log_error_errno(EIO, "could not get ctrl fd")({ int _level = ((3)), _e = ((5)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1302, __func__, "could not get ctrl fd"
) : -abs(_e); })
;
1303
1304 ctrl_fd = fcntl(fd, F_DUPFD_CLOEXEC1030, 3);
1305 if (ctrl_fd < 0)
1306 return log_error_errno(errno, "could not dup ctrl fd: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1306, __func__, "could not dup ctrl fd: %m"
) : -abs(_e); })
;
1307 }
1308
1309 if (netlink_fd < 0) {
1310 _cleanup_(udev_monitor_unrefp)__attribute__((cleanup(udev_monitor_unrefp))) struct udev_monitor *monitor = NULL((void*)0);
1311
1312 if (!udev) {
1313 udev = udev_new();
1314 if (!udev)
1315 return -ENOMEM12;
1316 }
1317
1318 monitor = udev_monitor_new_from_netlink(udev, "kernel");
1319 if (!monitor)
1320 return log_error_errno(EINVAL, "error initializing netlink socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1320, __func__, "error initializing netlink socket"
) : -abs(_e); })
;
1321
1322 (void) udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
1323
1324 r = udev_monitor_enable_receiving(monitor);
1325 if (r < 0)
1326 return log_error_errno(EINVAL, "error binding netlink socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1326, __func__, "error binding netlink socket"
) : -abs(_e); })
;
1327
1328 fd = udev_monitor_get_fd(monitor);
1329 if (fd < 0)
1330 return log_error_errno(netlink_fd, "could not get uevent fd: %m")({ int _level = ((3)), _e = ((netlink_fd)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1330, __func__, "could not get uevent fd: %m"
) : -abs(_e); })
;
1331
1332 netlink_fd = fcntl(fd, F_DUPFD_CLOEXEC1030, 3);
1333 if (netlink_fd < 0)
1334 return log_error_errno(errno, "could not dup netlink fd: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1334, __func__, "could not dup netlink fd: %m"
) : -abs(_e); })
;
1335 }
1336
1337 *rctrl = ctrl_fd;
1338 *rnetlink = netlink_fd;
1339
1340 return 0;
1341}
1342
1343/*
1344 * read the kernel command line, in case we need to get into debug mode
1345 * udev.log_priority=<level> syslog priority
1346 * udev.children_max=<number of workers> events are fully serialized if set to 1
1347 * udev.exec_delay=<number of seconds> delay execution of every executed program
1348 * udev.event_timeout=<number of seconds> seconds to wait before terminating an event
1349 */
1350static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1351 int r = 0;
1352
1353 assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("key"), "../src/udev/udevd.c", 1353, __PRETTY_FUNCTION__
); } while (0)
;
1354
1355 if (!value)
1356 return 0;
1357
1358 if (proc_cmdline_key_streq(key, "udev.log_priority")) {
1359
1360 if (proc_cmdline_value_missing(key, value))
1361 return 0;
1362
1363 r = util_log_priority(value);
1364 if (r >= 0)
1365 log_set_max_level(r)log_set_max_level_realm(LOG_REALM_UDEV, (r));
1366
1367 } else if (proc_cmdline_key_streq(key, "udev.event_timeout")) {
1368
1369 if (proc_cmdline_value_missing(key, value))
1370 return 0;
1371
1372 r = safe_atou64(value, &arg_event_timeout_usec);
1373 if (r >= 0) {
1374 arg_event_timeout_usec *= USEC_PER_SEC((usec_t) 1000000ULL);
1375 arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
1376 }
1377
1378 } else if (proc_cmdline_key_streq(key, "udev.children_max")) {
1379
1380 if (proc_cmdline_value_missing(key, value))
1381 return 0;
1382
1383 r = safe_atou(value, &arg_children_max);
1384
1385 } else if (proc_cmdline_key_streq(key, "udev.exec_delay")) {
1386
1387 if (proc_cmdline_value_missing(key, value))
1388 return 0;
1389
1390 r = safe_atoi(value, &arg_exec_delay);
1391
1392 } else if (startswith(key, "udev."))
1393 log_warning("Unknown udev kernel command line option \"%s\"", key)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1393, __func__, "Unknown udev kernel command line option \"%s\""
, key) : -abs(_e); })
;
1394
1395 if (r < 0)
1396 log_warning_errno(r, "Failed to parse \"%s=%s\", ignoring: %m", key, value)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1396, __func__, "Failed to parse \"%s=%s\", ignoring: %m"
, key, value) : -abs(_e); })
;
1397
1398 return 0;
1399}
1400
1401static void help(void) {
1402 printf("%s [OPTIONS...]\n\n"
1403 "Manages devices.\n\n"
1404 " -h --help Print this message\n"
1405 " -V --version Print version of the program\n"
1406 " -d --daemon Detach and run in the background\n"
1407 " -D --debug Enable debug output\n"
1408 " -c --children-max=INT Set maximum number of workers\n"
1409 " -e --exec-delay=SECONDS Seconds to wait before executing RUN=\n"
1410 " -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
1411 " -N --resolve-names=early|late|never\n"
1412 " When to resolve users and groups\n"
1413 , program_invocation_short_name);
1414}
1415
1416static int parse_argv(int argc, char *argv[]) {
1417 static const struct option options[] = {
1418 { "daemon", no_argument0, NULL((void*)0), 'd' },
1419 { "debug", no_argument0, NULL((void*)0), 'D' },
1420 { "children-max", required_argument1, NULL((void*)0), 'c' },
1421 { "exec-delay", required_argument1, NULL((void*)0), 'e' },
1422 { "event-timeout", required_argument1, NULL((void*)0), 't' },
1423 { "resolve-names", required_argument1, NULL((void*)0), 'N' },
1424 { "help", no_argument0, NULL((void*)0), 'h' },
1425 { "version", no_argument0, NULL((void*)0), 'V' },
1426 {}
1427 };
1428
1429 int c;
1430
1431 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("argc >= 0"), "../src/udev/udevd.c", 1431
, __PRETTY_FUNCTION__); } while (0)
;
1432 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("argv"), "../src/udev/udevd.c", 1432, __PRETTY_FUNCTION__
); } while (0)
;
1433
1434 while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL((void*)0))) >= 0) {
1435 int r;
1436
1437 switch (c) {
1438
1439 case 'd':
1440 arg_daemonize = true1;
1441 break;
1442 case 'c':
1443 r = safe_atou(optarg, &arg_children_max);
1444 if (r < 0)
1445 log_warning("Invalid --children-max ignored: %s", optarg)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1445, __func__, "Invalid --children-max ignored: %s"
, optarg) : -abs(_e); })
;
1446 break;
1447 case 'e':
1448 r = safe_atoi(optarg, &arg_exec_delay);
1449 if (r < 0)
1450 log_warning("Invalid --exec-delay ignored: %s", optarg)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1450, __func__, "Invalid --exec-delay ignored: %s"
, optarg) : -abs(_e); })
;
1451 break;
1452 case 't':
1453 r = safe_atou64(optarg, &arg_event_timeout_usec);
1454 if (r < 0)
1455 log_warning("Invalid --event-timeout ignored: %s", optarg)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1455, __func__, "Invalid --event-timeout ignored: %s"
, optarg) : -abs(_e); })
;
1456 else {
1457 arg_event_timeout_usec *= USEC_PER_SEC((usec_t) 1000000ULL);
1458 arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
1459 }
1460 break;
1461 case 'D':
1462 arg_debug = true1;
1463 break;
1464 case 'N':
1465 if (streq(optarg, "early")(strcmp((optarg),("early")) == 0)) {
1466 arg_resolve_names = 1;
1467 } else if (streq(optarg, "late")(strcmp((optarg),("late")) == 0)) {
1468 arg_resolve_names = 0;
1469 } else if (streq(optarg, "never")(strcmp((optarg),("never")) == 0)) {
1470 arg_resolve_names = -1;
1471 } else {
1472 log_error("resolve-names must be early, late or never")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1472, __func__, "resolve-names must be early, late or never"
) : -abs(_e); })
;
1473 return 0;
1474 }
1475 break;
1476 case 'h':
1477 help();
1478 return 0;
1479 case 'V':
1480 printf("%s\n", PACKAGE_VERSION"239");
1481 return 0;
1482 case '?':
1483 return -EINVAL22;
1484 default:
1485 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_UDEV, ("Unhandled option"
), "../src/udev/udevd.c", 1485, __PRETTY_FUNCTION__); } while
(0)
;
1486
1487 }
1488 }
1489
1490 return 1;
1491}
1492
1493static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cgroup) {
1494 _cleanup_(manager_freep)__attribute__((cleanup(manager_freep))) Manager *manager = NULL((void*)0);
1495 int r, fd_worker, one = 1;
1496
1497 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("ret"), "../src/udev/udevd.c", 1497, __PRETTY_FUNCTION__
); } while (0)
;
1498 assert(fd_ctrl >= 0)do { if ((__builtin_expect(!!(!(fd_ctrl >= 0)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("fd_ctrl >= 0"), "../src/udev/udevd.c", 1498
, __PRETTY_FUNCTION__); } while (0)
;
1499 assert(fd_uevent >= 0)do { if ((__builtin_expect(!!(!(fd_uevent >= 0)),0))) log_assert_failed_realm
(LOG_REALM_UDEV, ("fd_uevent >= 0"), "../src/udev/udevd.c"
, 1499, __PRETTY_FUNCTION__); } while (0)
;
1500
1501 manager = new0(Manager, 1)((Manager*) calloc((1), sizeof(Manager)));
1502 if (!manager)
1503 return log_oom()log_oom_internal(LOG_REALM_UDEV, "../src/udev/udevd.c", 1503,
__func__)
;
1504
1505 manager->fd_inotify = -1;
1506 manager->worker_watch[WRITE_END1] = -1;
1507 manager->worker_watch[READ_END0] = -1;
1508
1509 manager->udev = udev_new();
1510 if (!manager->udev)
1511 return log_error_errno(errno, "could not allocate udev context: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1511, __func__, "could not allocate udev context: %m"
) : -abs(_e); })
;
1512
1513 udev_builtin_init(manager->udev);
1514
1515 manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
1516 if (!manager->rules)
1517 return log_error_errno(ENOMEM, "error reading rules")({ int _level = ((3)), _e = ((12)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1517, __func__, "error reading rules"
) : -abs(_e); })
;
1518
1519 LIST_HEAD_INIT(manager->events)do { (manager->events) = ((void*)0); } while (0);
1520 udev_list_init(manager->udev, &manager->properties, true1);
1521
1522 manager->cgroup = cgroup;
1523
1524 manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl);
1525 if (!manager->ctrl)
1526 return log_error_errno(EINVAL, "error taking over udev control socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1526, __func__, "error taking over udev control socket"
) : -abs(_e); })
;
1527
1528 manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_uevent);
1529 if (!manager->monitor)
1530 return log_error_errno(EINVAL, "error taking over netlink socket")({ int _level = ((3)), _e = ((22)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1530, __func__, "error taking over netlink socket"
) : -abs(_e); })
;
1531
1532 /* unnamed socket from workers to the main daemon */
1533 r = socketpair(AF_LOCAL1, SOCK_DGRAMSOCK_DGRAM|SOCK_CLOEXECSOCK_CLOEXEC, 0, manager->worker_watch);
1534 if (r < 0)
1535 return log_error_errno(errno, "error creating socketpair: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1535, __func__, "error creating socketpair: %m"
) : -abs(_e); })
;
1536
1537 fd_worker = manager->worker_watch[READ_END0];
1538
1539 r = setsockopt(fd_worker, SOL_SOCKET1, SO_PASSCRED16, &one, sizeof(one));
1540 if (r < 0)
1541 return log_error_errno(errno, "could not enable SO_PASSCRED: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1541, __func__, "could not enable SO_PASSCRED: %m"
) : -abs(_e); })
;
1542
1543 manager->fd_inotify = udev_watch_init(manager->udev);
1544 if (manager->fd_inotify < 0)
1545 return log_error_errno(ENOMEM, "error initializing inotify")({ int _level = ((3)), _e = ((12)), _realm = (LOG_REALM_UDEV)
; (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1545, __func__, "error initializing inotify"
) : -abs(_e); })
;
1546
1547 udev_watch_restore(manager->udev);
1548
1549 /* block and listen to all signals on signalfd */
1550 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0)do { if ((__builtin_expect(!!(!(sigprocmask_many(0, ((void*)0
), 15, 2, 1, 17, -1) >= 0)),0))) log_assert_failed_realm(LOG_REALM_UDEV
, ("sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0"
), "../src/udev/udevd.c", 1550, __PRETTY_FUNCTION__); } while
(0)
;
1551
1552 r = sd_event_default(&manager->event);
1553 if (r < 0)
1554 return log_error_errno(r, "could not allocate event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1554, __func__, "could not allocate event loop: %m"
) : -abs(_e); })
;
1555
1556 r = sd_event_add_signal(manager->event, NULL((void*)0), SIGINT2, on_sigterm, manager);
1557 if (r < 0)
1558 return log_error_errno(r, "error creating sigint event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1558, __func__, "error creating sigint event source: %m"
) : -abs(_e); })
;
1559
1560 r = sd_event_add_signal(manager->event, NULL((void*)0), SIGTERM15, on_sigterm, manager);
1561 if (r < 0)
1562 return log_error_errno(r, "error creating sigterm event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1562, __func__, "error creating sigterm event source: %m"
) : -abs(_e); })
;
1563
1564 r = sd_event_add_signal(manager->event, NULL((void*)0), SIGHUP1, on_sighup, manager);
1565 if (r < 0)
1566 return log_error_errno(r, "error creating sighup event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1566, __func__, "error creating sighup event source: %m"
) : -abs(_e); })
;
1567
1568 r = sd_event_add_signal(manager->event, NULL((void*)0), SIGCHLD17, on_sigchld, manager);
1569 if (r < 0)
1570 return log_error_errno(r, "error creating sigchld event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1570, __func__, "error creating sigchld event source: %m"
) : -abs(_e); })
;
1571
1572 r = sd_event_set_watchdog(manager->event, true1);
1573 if (r < 0)
1574 return log_error_errno(r, "error creating watchdog event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1574, __func__, "error creating watchdog event source: %m"
) : -abs(_e); })
;
1575
1576 r = sd_event_add_io(manager->event, &manager->ctrl_event, fd_ctrl, EPOLLINEPOLLIN, on_ctrl_msg, manager);
1577 if (r < 0)
1578 return log_error_errno(r, "error creating ctrl event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1578, __func__, "error creating ctrl event source: %m"
) : -abs(_e); })
;
1579
1580 /* This needs to be after the inotify and uevent handling, to make sure
1581 * that the ping is send back after fully processing the pending uevents
1582 * (including the synthetic ones we may create due to inotify events).
1583 */
1584 r = sd_event_source_set_priority(manager->ctrl_event, SD_EVENT_PRIORITY_IDLE);
1585 if (r < 0)
1586 return log_error_errno(r, "cold not set IDLE event priority for ctrl event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1586, __func__, "cold not set IDLE event priority for ctrl event source: %m"
) : -abs(_e); })
;
1587
1588 r = sd_event_add_io(manager->event, &manager->inotify_event, manager->fd_inotify, EPOLLINEPOLLIN, on_inotify, manager);
1589 if (r < 0)
1590 return log_error_errno(r, "error creating inotify event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1590, __func__, "error creating inotify event source: %m"
) : -abs(_e); })
;
1591
1592 r = sd_event_add_io(manager->event, &manager->uevent_event, fd_uevent, EPOLLINEPOLLIN, on_uevent, manager);
1593 if (r < 0)
1594 return log_error_errno(r, "error creating uevent event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1594, __func__, "error creating uevent event source: %m"
) : -abs(_e); })
;
1595
1596 r = sd_event_add_io(manager->event, NULL((void*)0), fd_worker, EPOLLINEPOLLIN, on_worker, manager);
1597 if (r < 0)
1598 return log_error_errno(r, "error creating worker event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1598, __func__, "error creating worker event source: %m"
) : -abs(_e); })
;
1599
1600 r = sd_event_add_post(manager->event, NULL((void*)0), on_post, manager);
1601 if (r < 0)
1602 return log_error_errno(r, "error creating post event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1602, __func__, "error creating post event source: %m"
) : -abs(_e); })
;
1603
1604 *ret = TAKE_PTR(manager)({ typeof(manager) _ptr_ = (manager); (manager) = ((void*)0);
_ptr_; })
;
1605
1606 return 0;
1607}
1608
1609static int run(int fd_ctrl, int fd_uevent, const char *cgroup) {
1610 _cleanup_(manager_freep)__attribute__((cleanup(manager_freep))) Manager *manager = NULL((void*)0);
1611 int r;
1612
1613 r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
1614 if (r < 0) {
1615 r = log_error_errno(r, "failed to allocate manager object: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1615, __func__, "failed to allocate manager object: %m"
) : -abs(_e); })
;
1616 goto exit;
1617 }
1618
1619 r = udev_rules_apply_static_dev_perms(manager->rules);
1620 if (r < 0)
1621 log_error_errno(r, "failed to apply permissions on static device nodes: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1621, __func__, "failed to apply permissions on static device nodes: %m"
) : -abs(_e); })
;
1622
1623 (void) sd_notifyf(false0,
1624 "READY=1\n"
1625 "STATUS=Processing with %u children at max", arg_children_max);
1626
1627 r = sd_event_loop(manager->event);
1628 if (r < 0) {
1629 log_error_errno(r, "event loop failed: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1629, __func__, "event loop failed: %m"
) : -abs(_e); })
;
1630 goto exit;
1631 }
1632
1633 sd_event_get_exit_code(manager->event, &r);
1634
1635exit:
1636 sd_notify(false0,
1637 "STOPPING=1\n"
1638 "STATUS=Shutting down...");
1639 if (manager)
1640 udev_ctrl_cleanup(manager->ctrl);
1641 return r;
1642}
1643
1644int main(int argc, char *argv[]) {
1645 _cleanup_free___attribute__((cleanup(freep))) char *cgroup = NULL((void*)0);
1646 int fd_ctrl = -1, fd_uevent = -1;
1647 int r;
1648
1649 log_set_target(LOG_TARGET_AUTO);
1650 udev_parse_config();
1651 log_parse_environment()log_parse_environment_realm(LOG_REALM_UDEV);
1652 log_open();
1653
1654 r = parse_argv(argc, argv);
1655 if (r <= 0)
1656 goto exit;
1657
1658 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL((void*)0), PROC_CMDLINE_STRIP_RD_PREFIX);
1659 if (r < 0)
1660 log_warning_errno(r, "failed to parse kernel command line, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1660, __func__, "failed to parse kernel command line, ignoring: %m"
) : -abs(_e); })
;
1661
1662 if (arg_debug) {
1663 log_set_target(LOG_TARGET_CONSOLE);
1664 log_set_max_level(LOG_DEBUG)log_set_max_level_realm(LOG_REALM_UDEV, (7));
1665 }
1666
1667 r = must_be_root();
1668 if (r < 0)
1669 goto exit;
1670
1671 if (arg_children_max == 0) {
1672 cpu_set_t cpu_set;
1673 unsigned long mem_limit;
1674
1675 arg_children_max = 8;
1676
1677 if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) == 0)
1678 arg_children_max += CPU_COUNT(&cpu_set)__sched_cpucount (sizeof (cpu_set_t), &cpu_set) * 2;
1679
1680 mem_limit = physical_memory() / (128LU*1024*1024);
1681 arg_children_max = MAX(10U, MIN(arg_children_max, mem_limit))__extension__ ({ const typeof((10U)) __unique_prefix_A33 = ((
10U)); const typeof((__extension__ ({ const typeof((arg_children_max
)) __unique_prefix_A31 = ((arg_children_max)); const typeof((
mem_limit)) __unique_prefix_B32 = ((mem_limit)); __unique_prefix_A31
< __unique_prefix_B32 ? __unique_prefix_A31 : __unique_prefix_B32
; }))) __unique_prefix_B34 = ((__extension__ ({ const typeof(
(arg_children_max)) __unique_prefix_A31 = ((arg_children_max)
); const typeof((mem_limit)) __unique_prefix_B32 = ((mem_limit
)); __unique_prefix_A31 < __unique_prefix_B32 ? __unique_prefix_A31
: __unique_prefix_B32; }))); __unique_prefix_A33 > __unique_prefix_B34
? __unique_prefix_A33 : __unique_prefix_B34; })
;
1682
1683 log_debug("set children_max to %u", arg_children_max)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1683, __func__, "set children_max to %u"
, arg_children_max) : -abs(_e); })
;
1684 }
1685
1686 /* set umask before creating any file/directory */
1687 r = chdir("/");
1688 if (r < 0) {
1689 r = log_error_errno(errno, "could not change dir to /: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1689, __func__, "could not change dir to /: %m"
) : -abs(_e); })
;
1690 goto exit;
1691 }
1692
1693 umask(022);
1694
1695 r = mac_selinux_init();
1696 if (r < 0) {
1697 log_error_errno(r, "could not initialize labelling: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1697, __func__, "could not initialize labelling: %m"
) : -abs(_e); })
;
1698 goto exit;
1699 }
1700
1701 r = mkdir_errno_wrapper("/run/udev", 0755);
1702 if (r < 0 && r != -EEXIST17) {
1703 log_error_errno(r, "could not create /run/udev: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1703, __func__, "could not create /run/udev: %m"
) : -abs(_e); })
;
1704 goto exit;
1705 }
1706
1707 dev_setup(NULL((void*)0), UID_INVALID((uid_t) -1), GID_INVALID((gid_t) -1));
1708
1709 if (getppid() == 1) {
1710 /* get our own cgroup, we regularly kill everything udev has left behind
1711 we only do this on systemd systems, and only if we are directly spawned
1712 by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
1713 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER"_systemd", 0, &cgroup);
1714 if (r < 0) {
1715 if (IN_SET(r, -ENOENT, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-2, -123})/sizeof(int)]; switch(r) { case
-2: case -123: _found = 1; break; default: break; } _found; }
)
)
1716 log_debug_errno(r, "did not find dedicated cgroup: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1716, __func__, "did not find dedicated cgroup: %m"
) : -abs(_e); })
;
1717 else
1718 log_warning_errno(r, "failed to get cgroup: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1718, __func__, "failed to get cgroup: %m"
) : -abs(_e); })
;
1719 }
1720 }
1721
1722 r = listen_fds(&fd_ctrl, &fd_uevent);
1723 if (r < 0) {
1724 r = log_error_errno(r, "could not listen on fds: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1724, __func__, "could not listen on fds: %m"
) : -abs(_e); })
;
1725 goto exit;
1726 }
1727
1728 if (arg_daemonize) {
1729 pid_t pid;
1730
1731 log_info("starting version " PACKAGE_VERSION)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_UDEV
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/udev/udevd.c", 1731, __func__, "starting version " "239"
) : -abs(_e); })
;
1732
1733 /* connect /dev/null to stdin, stdout, stderr */
1734 if (log_get_max_level()log_get_max_level_realm(LOG_REALM_UDEV) < LOG_DEBUG7) {
1735 r = make_null_stdio();
1736 if (r < 0)
1737 log_warning_errno(r, "Failed to redirect standard streams to /dev/null: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_UDEV);
(log_get_max_level_realm(_realm) >= ((_level) & 0x07)
) ? log_internal_realm(((_realm) << 10 | (_level)), _e,
"../src/udev/udevd.c", 1737, __func__, "Failed to redirect standard streams to /dev/null: %m"
) : -abs(_e); })
;
1738 }
1739
1740 pid = fork();
1741 switch (pid) {
1742 case 0:
1743 break;
1744 case -1:
1745 r = log_error_errno(errno, "fork of daemon failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_UDEV); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/udev/udevd.c", 1745, __func__, "fork of daemon failed: %m"
) : -abs(_e); })
;
1746 goto exit;
1747 default:
1748 mac_selinux_finish();
1749 log_close();
1750 _exit(EXIT_SUCCESS0);
1751 }
1752
1753 setsid();
1754
1755 write_string_file("/proc/self/oom_score_adj", "-1000", 0);
1756 }
1757
1758 r = run(fd_ctrl, fd_uevent, cgroup);
1759
1760exit:
1761 mac_selinux_finish();
1762 log_close();
1763 return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0;
1764}