diff --git a/1022-udev-remove-seqnum-API-and-all-assumptions-about-seq.patch b/1022-udev-remove-seqnum-API-and-all-assumptions-about-seq.patch deleted file mode 100644 index db403e31..00000000 --- a/1022-udev-remove-seqnum-API-and-all-assumptions-about-seq.patch +++ /dev/null @@ -1,1443 +0,0 @@ -From 9ea28c55a2488e6cd4a44ac5786f12b71ad5bc9f Mon Sep 17 00:00:00 2001 -From: Kay Sievers -Date: Sat, 12 Apr 2014 22:35:50 -0700 -Subject: [PATCH] udev: remove seqnum API and all assumptions about seqnums - -The way the kernel namespaces have been implemented breaks assumptions -udev made regarding uevent sequence numbers. Creating devices in a -namespace "steals" uevents and its sequence numbers from the host. It -confuses the "udevadmin settle" logic, which might block until util a -timeout is reached, even when no uevent is pending. - -Remove any assumptions about sequence numbers and deprecate libudev's -API exposing these numbers; none of that can reliably be used anymore -when namespaces are involved. - -Signed-off-by: Robert Milasan ---- - Makefile.am | 6 +- - man/udevadm.xml | 22 -- - src/libudev/libudev-monitor.c | 17 +- - src/libudev/libudev-queue-private.c | 406 ------------------------------------ - src/libudev/libudev-queue.c | 302 ++------------------------- - src/libudev/libudev.h | 10 +- - src/shared/udev-util.h | 2 - - src/test/test-libudev.c | 24 --- - src/udev/udev-ctrl.c | 2 +- - src/udev/udevadm-settle.c | 131 ++---------- - src/udev/udevd.c | 59 +++--- - 11 files changed, 84 insertions(+), 897 deletions(-) - delete mode 100644 src/libudev/libudev-queue-private.c - -Index: systemd-210/Makefile.am -=================================================================== ---- systemd-210.orig/Makefile.am -+++ systemd-210/Makefile.am -@@ -2520,8 +2520,7 @@ noinst_LTLIBRARIES += \ - - libudev_internal_la_SOURCES =\ - $(libudev_la_SOURCES) \ -- src/libudev/libudev-device-private.c \ -- src/libudev/libudev-queue-private.c -+ src/libudev/libudev-device-private.c - - libudev_internal_la_CFLAGS = \ - $(AM_CFLAGS) \ -@@ -5063,6 +5062,9 @@ test_libsystemd_sym_LDADD = \ - - test_libudev_sym_SOURCES = \ - test-libudev-sym.c -+test_libudev_sym_CFLAGS = \ -+ $(AM_CFLAGS) \ -+ -Wno-deprecated-declarations - test_libudev_sym_LDADD = \ - libudev.la - -Index: systemd-210/man/udevadm.xml -=================================================================== ---- systemd-210.orig/man/udevadm.xml -+++ systemd-210/man/udevadm.xml -@@ -339,21 +339,6 @@ - - - -- -- -- -- Wait only for events after the given sequence -- number. -- -- -- -- -- -- -- Wait only for events before the given sequence number. -- -- -- - - - -@@ -361,13 +346,6 @@ - - - -- -- -- -- Do not print any output, like the remaining queue entries when reaching the timeout. -- -- -- - - - -Index: systemd-210/src/libudev/libudev-monitor.c -=================================================================== ---- systemd-210.orig/src/libudev/libudev-monitor.c -+++ systemd-210/src/libudev/libudev-monitor.c -@@ -147,21 +147,6 @@ static bool udev_has_devtmpfs(struct ude - return false; - } - --/* we consider udev running when we have running udev service */ --static bool udev_has_service(struct udev *udev) { -- struct udev_queue *queue; -- bool active; -- -- queue = udev_queue_new(udev); -- if (!queue) -- return false; -- -- active = udev_queue_get_udev_is_active(queue); -- udev_queue_unref(queue); -- -- return active; --} -- - struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) - { - struct udev_monitor *udev_monitor; -@@ -185,7 +170,7 @@ struct udev_monitor *udev_monitor_new_fr - * We do not set a netlink multicast group here, so the socket - * will not receive any messages. - */ -- if (!udev_has_service(udev) && !udev_has_devtmpfs(udev)) { -+ if (access("/run/udev/control", F_OK) < 0 && !udev_has_devtmpfs(udev)) { - udev_dbg(udev, "the udev service seems not to be active, disable the monitor\n"); - group = UDEV_MONITOR_NONE; - } else -Index: systemd-210/src/libudev/libudev-queue-private.c -=================================================================== ---- systemd-210.orig/src/libudev/libudev-queue-private.c -+++ /dev/null -@@ -1,406 +0,0 @@ --/*** -- This file is part of systemd. -- -- Copyright 2008-2012 Kay Sievers -- Copyright 2009 Alan Jenkins -- -- systemd is free software; you can redistribute it and/or modify it -- under the terms of the GNU Lesser General Public License as published by -- the Free Software Foundation; either version 2.1 of the License, or -- (at your option) any later version. -- -- systemd is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public License -- along with systemd; If not, see . --***/ -- --/* -- * DISCLAIMER - The file format mentioned here is private to udev/libudev, -- * and may be changed without notice. -- * -- * The udev event queue is exported as a binary log file. -- * Each log record consists of a sequence number followed by the device path. -- * -- * When a new event is queued, its details are appended to the log. -- * When the event finishes, a second record is appended to the log -- * with the same sequence number but a devpath len of 0. -- * -- * Example: -- * { 0x0000000000000001 } -- * { 0x0000000000000001, 0x0019, "/devices/virtual/mem/null" }, -- * { 0x0000000000000002, 0x001b, "/devices/virtual/mem/random" }, -- * { 0x0000000000000001, 0x0000 }, -- * { 0x0000000000000003, 0x0019, "/devices/virtual/mem/zero" }, -- * -- * Events 2 and 3 are still queued, but event 1 has finished. -- * -- * The queue does not grow indefinitely. It is periodically re-created -- * to remove finished events. Atomic rename() makes this transparent to readers. -- * -- * The queue file starts with a single sequence number which specifies the -- * minimum sequence number in the log that follows. Any events prior to this -- * sequence number have already finished. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "libudev.h" --#include "libudev-private.h" -- --static int rebuild_queue_file(struct udev_queue_export *udev_queue_export); -- --struct udev_queue_export { -- struct udev *udev; -- int queued_count; /* number of unfinished events exported in queue file */ -- FILE *queue_file; -- unsigned long long int seqnum_max; /* earliest sequence number in queue file */ -- unsigned long long int seqnum_min; /* latest sequence number in queue file */ -- int waste_bytes; /* queue file bytes wasted on finished events */ --}; -- --struct udev_queue_export *udev_queue_export_new(struct udev *udev) --{ -- struct udev_queue_export *udev_queue_export; -- unsigned long long int initial_seqnum; -- -- if (udev == NULL) -- return NULL; -- -- udev_queue_export = new0(struct udev_queue_export, 1); -- if (udev_queue_export == NULL) -- return NULL; -- udev_queue_export->udev = udev; -- -- initial_seqnum = udev_get_kernel_seqnum(udev); -- udev_queue_export->seqnum_min = initial_seqnum; -- udev_queue_export->seqnum_max = initial_seqnum; -- -- udev_queue_export_cleanup(udev_queue_export); -- if (rebuild_queue_file(udev_queue_export) != 0) { -- free(udev_queue_export); -- return NULL; -- } -- -- return udev_queue_export; --} -- --struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export) --{ -- if (udev_queue_export == NULL) -- return NULL; -- if (udev_queue_export->queue_file != NULL) -- fclose(udev_queue_export->queue_file); -- free(udev_queue_export); -- return NULL; --} -- --void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export) --{ -- if (udev_queue_export == NULL) -- return; -- unlink("/run/udev/queue.tmp"); -- unlink("/run/udev/queue.bin"); --} -- --static int skip_to(FILE *file, long offset) --{ -- long old_offset; -- -- /* fseek may drop buffered data, avoid it for small seeks */ -- old_offset = ftell(file); -- if (offset > old_offset && offset - old_offset <= BUFSIZ) { -- size_t skip_bytes = offset - old_offset; -- char *buf = alloca(skip_bytes); -- -- if (fread(buf, skip_bytes, 1, file) != skip_bytes) -- return -1; -- } -- -- return fseek(file, offset, SEEK_SET); --} -- --struct queue_devpaths { -- unsigned int devpaths_first; /* index of first queued event */ -- unsigned int devpaths_size; -- long devpaths[]; /* seqnum -> offset of devpath in queue file (or 0) */ --}; -- --/* -- * Returns a table mapping seqnum to devpath file offset for currently queued events. -- * devpaths[i] represents the event with seqnum = i + udev_queue_export->seqnum_min. -- */ --static struct queue_devpaths *build_index(struct udev_queue_export *udev_queue_export) --{ -- struct queue_devpaths *devpaths; -- unsigned long long int range; -- long devpath_offset; -- ssize_t devpath_len; -- unsigned long long int seqnum; -- unsigned long long int n; -- unsigned int i; -- -- /* seek to the first event in the file */ -- rewind(udev_queue_export->queue_file); -- udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum); -- -- /* allocate the table */ -- range = udev_queue_export->seqnum_min - udev_queue_export->seqnum_max; -- if (range - 1 > INT_MAX) { -- udev_err(udev_queue_export->udev, "queue file overflow\n"); -- return NULL; -- } -- devpaths = malloc0(sizeof(struct queue_devpaths) + (range + 1) * sizeof(long)); -- if (devpaths == NULL) -- return NULL; -- devpaths->devpaths_size = range + 1; -- -- /* read all records and populate the table */ -- for (;;) { -- if (udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum) < 0) -- break; -- n = seqnum - udev_queue_export->seqnum_max; -- if (n >= devpaths->devpaths_size) -- goto read_error; -- -- devpath_offset = ftell(udev_queue_export->queue_file); -- devpath_len = udev_queue_skip_devpath(udev_queue_export->queue_file); -- if (devpath_len < 0) -- goto read_error; -- -- if (devpath_len > 0) -- devpaths->devpaths[n] = devpath_offset; -- else -- devpaths->devpaths[n] = 0; -- } -- -- /* find first queued event */ -- for (i = 0; i < devpaths->devpaths_size; i++) { -- if (devpaths->devpaths[i] != 0) -- break; -- } -- devpaths->devpaths_first = i; -- -- return devpaths; -- --read_error: -- udev_err(udev_queue_export->udev, "queue file corrupted\n"); -- free(devpaths); -- return NULL; --} -- --static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) --{ -- unsigned long long int seqnum; -- struct queue_devpaths *devpaths = NULL; -- FILE *new_queue_file = NULL; -- unsigned int i; -- -- /* read old queue file */ -- if (udev_queue_export->queue_file != NULL) { -- devpaths = build_index(udev_queue_export); -- if (devpaths != NULL) -- udev_queue_export->seqnum_max += devpaths->devpaths_first; -- } -- if (devpaths == NULL) { -- udev_queue_export->queued_count = 0; -- udev_queue_export->seqnum_max = udev_queue_export->seqnum_min; -- } -- -- /* create new queue file */ -- new_queue_file = fopen("/run/udev/queue.tmp", "w+e"); -- if (new_queue_file == NULL) -- goto error; -- seqnum = udev_queue_export->seqnum_max; -- fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file); -- -- /* copy unfinished events only to the new file */ -- if (devpaths != NULL) { -- for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) { -- char devpath[UTIL_PATH_SIZE]; -- int err; -- unsigned short devpath_len; -- -- if (devpaths->devpaths[i] != 0) -- { -- skip_to(udev_queue_export->queue_file, devpaths->devpaths[i]); -- err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath)); -- devpath_len = err; -- -- fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file); -- fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file); -- fwrite(devpath, 1, devpath_len, new_queue_file); -- } -- seqnum++; -- } -- free(devpaths); -- devpaths = NULL; -- } -- fflush(new_queue_file); -- if (ferror(new_queue_file)) -- goto error; -- -- /* rename the new file on top of the old one */ -- if (rename("/run/udev/queue.tmp", "/run/udev/queue.bin") != 0) -- goto error; -- -- if (udev_queue_export->queue_file != NULL) -- fclose(udev_queue_export->queue_file); -- udev_queue_export->queue_file = new_queue_file; -- udev_queue_export->waste_bytes = 0; -- -- return 0; -- --error: -- udev_err(udev_queue_export->udev, "failed to create queue file: %m\n"); -- udev_queue_export_cleanup(udev_queue_export); -- -- if (udev_queue_export->queue_file != NULL) { -- fclose(udev_queue_export->queue_file); -- udev_queue_export->queue_file = NULL; -- } -- if (new_queue_file != NULL) -- fclose(new_queue_file); -- -- if (devpaths != NULL) -- free(devpaths); -- udev_queue_export->queued_count = 0; -- udev_queue_export->waste_bytes = 0; -- udev_queue_export->seqnum_max = udev_queue_export->seqnum_min; -- -- return -1; --} -- --static int write_queue_record(struct udev_queue_export *udev_queue_export, -- unsigned long long int seqnum, const char *devpath, size_t devpath_len) --{ -- unsigned short len; -- -- if (udev_queue_export->queue_file == NULL) -- return -1; -- -- if (fwrite(&seqnum, sizeof(unsigned long long int), 1, udev_queue_export->queue_file) != 1) -- goto write_error; -- -- len = (devpath_len < USHRT_MAX) ? devpath_len : USHRT_MAX; -- if (fwrite(&len, sizeof(unsigned short), 1, udev_queue_export->queue_file) != 1) -- goto write_error; -- if (len > 0) { -- if (fwrite(devpath, 1, len, udev_queue_export->queue_file) != len) -- goto write_error; -- } -- -- /* *must* flush output; caller may fork */ -- if (fflush(udev_queue_export->queue_file) != 0) -- goto write_error; -- -- return 0; -- --write_error: -- /* if we failed half way through writing a record to a file, -- we should not try to write any further records to it. */ -- udev_err(udev_queue_export->udev, "error writing to queue file: %m\n"); -- fclose(udev_queue_export->queue_file); -- udev_queue_export->queue_file = NULL; -- -- return -1; --} -- --enum device_state { -- DEVICE_QUEUED, -- DEVICE_FINISHED, --}; -- --static inline size_t queue_record_size(size_t devpath_len) --{ -- return sizeof(unsigned long long int) + sizeof(unsigned short int) + devpath_len; --} -- --static int update_queue(struct udev_queue_export *udev_queue_export, -- struct udev_device *udev_device, enum device_state state) --{ -- unsigned long long int seqnum = udev_device_get_seqnum(udev_device); -- const char *devpath = NULL; -- size_t devpath_len = 0; -- int bytes; -- int err; -- -- /* FINISHED records have a zero length devpath */ -- if (state == DEVICE_QUEUED) { -- devpath = udev_device_get_devpath(udev_device); -- devpath_len = strlen(devpath); -- } -- -- /* recover from an earlier failed rebuild */ -- if (udev_queue_export->queue_file == NULL) { -- if (rebuild_queue_file(udev_queue_export) != 0) -- return -1; -- } -- -- /* if we're removing the last event from the queue, that's the best time to rebuild it */ -- if (state != DEVICE_QUEUED && udev_queue_export->queued_count == 1) { -- /* we don't need to read the old queue file */ -- fclose(udev_queue_export->queue_file); -- udev_queue_export->queue_file = NULL; -- rebuild_queue_file(udev_queue_export); -- return 0; -- } -- -- /* try to rebuild the queue files before they grow larger than one page. */ -- bytes = ftell(udev_queue_export->queue_file) + queue_record_size(devpath_len); -- if ((udev_queue_export->waste_bytes > bytes / 2) && bytes > 4096) -- rebuild_queue_file(udev_queue_export); -- -- /* don't record a finished event, if we already dropped the event in a failed rebuild */ -- if (seqnum < udev_queue_export->seqnum_max) -- return 0; -- -- /* now write to the queue */ -- if (state == DEVICE_QUEUED) { -- udev_queue_export->queued_count++; -- udev_queue_export->seqnum_min = seqnum; -- } else { -- udev_queue_export->waste_bytes += queue_record_size(devpath_len) + queue_record_size(0); -- udev_queue_export->queued_count--; -- } -- err = write_queue_record(udev_queue_export, seqnum, devpath, devpath_len); -- -- /* try to handle ENOSPC */ -- if (err != 0 && udev_queue_export->queued_count == 0) { -- udev_queue_export_cleanup(udev_queue_export); -- err = rebuild_queue_file(udev_queue_export); -- } -- -- return err; --} -- --static int update(struct udev_queue_export *udev_queue_export, -- struct udev_device *udev_device, enum device_state state) --{ -- if (update_queue(udev_queue_export, udev_device, state) != 0) -- return -1; -- -- return 0; --} -- --int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device) --{ -- return update(udev_queue_export, udev_device, DEVICE_QUEUED); --} -- --int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device) --{ -- return update(udev_queue_export, udev_device, DEVICE_FINISHED); --} -Index: systemd-210/src/libudev/libudev-queue.c -=================================================================== ---- systemd-210.orig/src/libudev/libudev-queue.c -+++ systemd-210/src/libudev/libudev-queue.c -@@ -24,8 +24,6 @@ - #include - #include - #include --#include --#include - #include - #include - -@@ -36,10 +34,7 @@ - * SECTION:libudev-queue - * @short_description: access to currently active events - * -- * The udev daemon processes events asynchronously. All events which do not have -- * interdependencies run in parallel. This exports the current state of the -- * event processing queue, and the current event sequence numbers from the kernel -- * and the udev daemon. -+ * This exports the current state of the udev processing queue. - */ - - /** -@@ -50,7 +45,6 @@ - struct udev_queue { - struct udev *udev; - int refcount; -- struct udev_list queue_list; - }; - - /** -@@ -72,9 +66,9 @@ _public_ struct udev_queue *udev_queue_n - udev_queue = new0(struct udev_queue, 1); - if (udev_queue == NULL) - return NULL; -+ - udev_queue->refcount = 1; - udev_queue->udev = udev; -- udev_list_init(udev, &udev_queue->queue_list, false); - return udev_queue; - } - -@@ -90,6 +84,7 @@ _public_ struct udev_queue *udev_queue_r - { - if (udev_queue == NULL) - return NULL; -+ - udev_queue->refcount++; - return udev_queue; - } -@@ -107,10 +102,11 @@ _public_ struct udev_queue *udev_queue_u - { - if (udev_queue == NULL) - return NULL; -+ - udev_queue->refcount--; - if (udev_queue->refcount > 0) - return NULL; -- udev_list_cleanup(&udev_queue->queue_list); -+ - free(udev_queue); - return NULL; - } -@@ -130,141 +126,30 @@ _public_ struct udev *udev_queue_get_ude - return udev_queue->udev; - } - --unsigned long long int udev_get_kernel_seqnum(struct udev *udev) --{ -- unsigned long long int seqnum; -- int fd; -- char buf[32]; -- ssize_t len; -- -- fd = open("/sys/kernel/uevent_seqnum", O_RDONLY|O_CLOEXEC); -- if (fd < 0) -- return 0; -- len = read(fd, buf, sizeof(buf)); -- close(fd); -- if (len <= 2) -- return 0; -- buf[len-1] = '\0'; -- seqnum = strtoull(buf, NULL, 10); -- return seqnum; --} -- - /** - * udev_queue_get_kernel_seqnum: - * @udev_queue: udev queue context - * -- * Get the current kernel event sequence number. -+ * This function is deprecated. - * -- * Returns: the sequence number. -+ * Returns: 0. - **/ - _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) - { -- unsigned long long int seqnum; -- -- if (udev_queue == NULL) -- return -EINVAL; -- -- seqnum = udev_get_kernel_seqnum(udev_queue->udev); -- return seqnum; --} -- --int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum) --{ -- if (fread(seqnum, sizeof(unsigned long long int), 1, queue_file) != 1) -- return -1; -- - return 0; - } - --ssize_t udev_queue_skip_devpath(FILE *queue_file) --{ -- unsigned short int len; -- -- if (fread(&len, sizeof(unsigned short int), 1, queue_file) == 1) { -- char *devpath = alloca(len); -- -- /* use fread to skip, fseek might drop buffered data */ -- if (fread(devpath, 1, len, queue_file) == len) -- return len; -- } -- -- return -1; --} -- --ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size) --{ -- unsigned short int read_bytes = 0; -- unsigned short int len; -- -- if (fread(&len, sizeof(unsigned short int), 1, queue_file) != 1) -- return -1; -- -- read_bytes = (len < size - 1) ? len : size - 1; -- if (fread(devpath, 1, read_bytes, queue_file) != read_bytes) -- return -1; -- devpath[read_bytes] = '\0'; -- -- /* if devpath was too long, skip unread characters */ -- if (read_bytes != len) { -- unsigned short int skip_bytes = len - read_bytes; -- char *buf = alloca(skip_bytes); -- -- if (fread(buf, 1, skip_bytes, queue_file) != skip_bytes) -- return -1; -- } -- -- return read_bytes; --} -- --static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long int *seqnum_start) --{ -- FILE *queue_file; -- -- queue_file = fopen("/run/udev/queue.bin", "re"); -- if (queue_file == NULL) -- return NULL; -- -- if (udev_queue_read_seqnum(queue_file, seqnum_start) < 0) { -- udev_err(udev_queue->udev, "corrupt queue file\n"); -- fclose(queue_file); -- return NULL; -- } -- -- return queue_file; --} -- - /** - * udev_queue_get_udev_seqnum: - * @udev_queue: udev queue context - * -- * Get the last known udev event sequence number. -+ * This function is deprecated. - * -- * Returns: the sequence number. -+ * Returns: 0. - **/ - _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) - { -- unsigned long long int seqnum_udev; -- FILE *queue_file; -- -- queue_file = open_queue_file(udev_queue, &seqnum_udev); -- if (queue_file == NULL) -- return 0; -- -- for (;;) { -- unsigned long long int seqnum; -- ssize_t devpath_len; -- -- if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) -- break; -- devpath_len = udev_queue_skip_devpath(queue_file); -- if (devpath_len < 0) -- break; -- if (devpath_len > 0) -- seqnum_udev = seqnum; -- } -- -- fclose(queue_file); -- return seqnum_udev; -+ return 0; - } - - /** -@@ -277,15 +162,7 @@ _public_ unsigned long long int udev_que - **/ - _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) - { -- unsigned long long int seqnum_start; -- FILE *queue_file; -- -- queue_file = open_queue_file(udev_queue, &seqnum_start); -- if (queue_file == NULL) -- return 0; -- -- fclose(queue_file); -- return 1; -+ return access("/run/udev/control", F_OK) >= 0; - } - - /** -@@ -298,48 +175,7 @@ _public_ int udev_queue_get_udev_is_acti - **/ - _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) - { -- unsigned long long int seqnum_kernel; -- unsigned long long int seqnum_udev = 0; -- int queued = 0; -- int is_empty = 0; -- FILE *queue_file; -- -- if (udev_queue == NULL) -- return -EINVAL; -- queue_file = open_queue_file(udev_queue, &seqnum_udev); -- if (queue_file == NULL) -- return 1; -- -- for (;;) { -- unsigned long long int seqnum; -- ssize_t devpath_len; -- -- if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) -- break; -- devpath_len = udev_queue_skip_devpath(queue_file); -- if (devpath_len < 0) -- break; -- -- if (devpath_len > 0) { -- queued++; -- seqnum_udev = seqnum; -- } else { -- queued--; -- } -- } -- -- if (queued > 0) -- goto out; -- -- seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue); -- if (seqnum_udev < seqnum_kernel) -- goto out; -- -- is_empty = 1; -- --out: -- fclose(queue_file); -- return is_empty; -+ return access("/run/udev/queue", F_OK) >= 0; - } - - /** -@@ -348,63 +184,15 @@ out: - * @start: first event sequence number - * @end: last event sequence number - * -- * Check if udev is currently processing any events in a given sequence number range. -+ * This function is deprecated, it just returns the result of -+ * udev_queue_get_queue_is_empty(). - * -- * Returns: a flag indicating if any of the sequence numbers in the given range is currently active. -+ * Returns: a flag indicating if udev is currently handling events. - **/ - _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, - unsigned long long int start, unsigned long long int end) - { -- unsigned long long int seqnum; -- ssize_t devpath_len; -- int unfinished; -- FILE *queue_file; -- -- if (udev_queue == NULL) -- return -EINVAL; -- queue_file = open_queue_file(udev_queue, &seqnum); -- if (queue_file == NULL) -- return 1; -- if (start < seqnum) -- start = seqnum; -- if (start > end) { -- fclose(queue_file); -- return 1; -- } -- if (end - start > INT_MAX - 1) { -- fclose(queue_file); -- return -EOVERFLOW; -- } -- -- /* -- * we might start with 0, and handle the initial seqnum -- * only when we find an entry in the queue file -- **/ -- unfinished = end - start; -- -- do { -- if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) -- break; -- devpath_len = udev_queue_skip_devpath(queue_file); -- if (devpath_len < 0) -- break; -- -- /* -- * we might start with an empty or re-build queue file, where -- * the initial seqnum is not recorded as finished -- */ -- if (start == seqnum && devpath_len > 0) -- unfinished++; -- -- if (devpath_len == 0) { -- if (seqnum >= start && seqnum <= end) -- unfinished--; -- } -- } while (unfinished > 0); -- -- fclose(queue_file); -- -- return (unfinished == 0); -+ return udev_queue_get_queue_is_empty(udev_queue); - } - - /** -@@ -412,69 +200,25 @@ _public_ int udev_queue_get_seqnum_seque - * @udev_queue: udev queue context - * @seqnum: sequence number - * -- * Check if udev is currently processing a given sequence number. -+ * This function is deprecated, it just returns the result of -+ * udev_queue_get_queue_is_empty(). - * -- * Returns: a flag indicating if the given sequence number is currently active. -+ * Returns: a flag indicating if udev is currently handling events. - **/ - _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) - { -- if (!udev_queue_get_seqnum_sequence_is_finished(udev_queue, seqnum, seqnum)) -- return 0; -- -- return 1; -+ return udev_queue_get_queue_is_empty(udev_queue); - } - - /** - * udev_queue_get_queued_list_entry: - * @udev_queue: udev queue context - * -- * Get the first entry of the list of queued events. -+ * This function is deprecated. - * -- * Returns: a udev_list_entry. -+ * Returns: NULL. - **/ - _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) - { -- unsigned long long int seqnum; -- FILE *queue_file; -- -- if (udev_queue == NULL) -- return NULL; -- udev_list_cleanup(&udev_queue->queue_list); -- -- queue_file = open_queue_file(udev_queue, &seqnum); -- if (queue_file == NULL) -- return NULL; -- -- for (;;) { -- char syspath[UTIL_PATH_SIZE]; -- char *s; -- size_t l; -- ssize_t len; -- char seqnum_str[32]; -- struct udev_list_entry *list_entry; -- -- if (udev_queue_read_seqnum(queue_file, &seqnum) < 0) -- break; -- snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum); -- -- s = syspath; -- l = strpcpy(&s, sizeof(syspath), "/sys"); -- len = udev_queue_read_devpath(queue_file, s, l); -- if (len < 0) -- break; -- -- if (len > 0) { -- udev_list_entry_add(&udev_queue->queue_list, syspath, seqnum_str); -- } else { -- udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_queue->queue_list)) { -- if (streq(seqnum_str, udev_list_entry_get_value(list_entry))) { -- udev_list_entry_delete(list_entry); -- break; -- } -- } -- } -- } -- fclose(queue_file); -- -- return udev_list_get_entry(&udev_queue->queue_list); -+ return NULL; - } -Index: systemd-210/src/libudev/libudev.h -=================================================================== ---- systemd-210.orig/src/libudev/libudev.h -+++ systemd-210/src/libudev/libudev.h -@@ -170,14 +170,14 @@ struct udev_queue *udev_queue_ref(struct - struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue); - struct udev *udev_queue_get_udev(struct udev_queue *udev_queue); - struct udev_queue *udev_queue_new(struct udev *udev); --unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue); --unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue); -+unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated)); -+unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated)); - int udev_queue_get_udev_is_active(struct udev_queue *udev_queue); - int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue); --int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum); -+int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__ ((deprecated)); - int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, -- unsigned long long int start, unsigned long long int end); --struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue); -+ unsigned long long int start, unsigned long long int end) __attribute__ ((deprecated)); -+struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) __attribute__ ((deprecated)); - - /* - * udev_hwdb -Index: systemd-210/src/shared/udev-util.h -=================================================================== ---- systemd-210.orig/src/shared/udev-util.h -+++ systemd-210/src/shared/udev-util.h -@@ -31,7 +31,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ - DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref); - DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref); - DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref); --DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_queue*, udev_queue_unref); - - #define _cleanup_udev_unref_ _cleanup_(udev_unrefp) - #define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp) -@@ -40,5 +39,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ - #define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp) - #define _cleanup_udev_ctrl_unref_ _cleanup_(udev_ctrl_unrefp) - #define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp) --#define _cleanup_udev_queue_unref_ _cleanup_(udev_queue_unrefp) - #define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup) -Index: systemd-210/src/test/test-libudev.c -=================================================================== ---- systemd-210.orig/src/test/test-libudev.c -+++ systemd-210/src/test/test-libudev.c -@@ -303,38 +303,14 @@ out: - - static int test_queue(struct udev *udev) { - struct udev_queue *udev_queue; -- unsigned long long int seqnum; -- struct udev_list_entry *list_entry; - - udev_queue = udev_queue_new(udev); - if (udev_queue == NULL) - return -1; -- seqnum = udev_queue_get_kernel_seqnum(udev_queue); -- printf("seqnum kernel: %llu\n", seqnum); -- seqnum = udev_queue_get_udev_seqnum(udev_queue); -- printf("seqnum udev : %llu\n", seqnum); - - if (udev_queue_get_queue_is_empty(udev_queue)) - printf("queue is empty\n"); -- printf("get queue list\n"); -- udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) -- printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); -- printf("\n"); -- printf("get queue list again\n"); -- udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) -- printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry)); -- printf("\n"); - -- list_entry = udev_queue_get_queued_list_entry(udev_queue); -- if (list_entry != NULL) { -- printf("event [%llu] is queued\n", seqnum); -- seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10); -- if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum)) -- printf("event [%llu] is not finished\n", seqnum); -- else -- printf("event [%llu] is finished\n", seqnum); -- } -- printf("\n"); - udev_queue_unref(udev_queue); - return 0; - } -Index: systemd-210/src/udev/udev-ctrl.c -=================================================================== ---- systemd-210.orig/src/udev/udev-ctrl.c -+++ systemd-210/src/udev/udev-ctrl.c -@@ -275,7 +275,7 @@ static int ctrl_send(struct udev_ctrl *u - - pfd[0].fd = uctrl->sock; - pfd[0].events = POLLIN; -- r = poll(pfd, 1, timeout * 1000); -+ r = poll(pfd, 1, timeout * MSEC_PER_SEC); - if (r < 0) { - if (errno == EINTR) - continue; -Index: systemd-210/src/udev/udevadm-settle.c -=================================================================== ---- systemd-210.orig/src/udev/udevadm-settle.c -+++ systemd-210/src/udev/udevadm-settle.c -@@ -41,42 +41,28 @@ - static void help(void) { - printf("Usage: udevadm settle OPTIONS\n" - " -t,--timeout= maximum time to wait for events\n" -- " -s,--seq-start= first seqnum to wait for\n" -- " -e,--seq-end= last seqnum to wait for\n" - " -E,--exit-if-exists= stop waiting if file exists\n" -- " -q,--quiet do not print list after timeout\n" - " -h,--help\n\n"); - } - - static int adm_settle(struct udev *udev, int argc, char *argv[]) - { - static const struct option options[] = { -- { "seq-start", required_argument, NULL, 's' }, -- { "seq-end", required_argument, NULL, 'e' }, -+ { "seq-start", required_argument, NULL, '\0' }, /* removed */ -+ { "seq-end", required_argument, NULL, '\0' }, /* removed */ - { "timeout", required_argument, NULL, 't' }, - { "exit-if-exists", required_argument, NULL, 'E' }, -- { "quiet", no_argument, NULL, 'q' }, -+ { "quiet", no_argument, NULL, 'q' }, /* removed */ - { "help", no_argument, NULL, 'h' }, - {} - }; -- usec_t start_usec = now(CLOCK_MONOTONIC); -- usec_t start = 0; -- usec_t end = 0; -- int quiet = 0; - const char *exists = NULL; - unsigned int timeout = 120; - struct pollfd pfd[1] = { {.fd = -1}, }; -- _cleanup_udev_queue_unref_ struct udev_queue *udev_queue = NULL; - int rc = EXIT_FAILURE, c; - -- while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0) -+ while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0) { - switch (c) { -- case 's': -- start = strtoull(optarg, NULL, 0); -- break; -- case 'e': -- end = strtoull(optarg, NULL, 0); -- break; - case 't': { - int r; - -@@ -91,9 +77,6 @@ static int adm_settle(struct udev *udev, - case 'E': - exists = optarg; - break; -- case 'q': -- quiet = 1; -- break; - case 'h': - help(); - exit(EXIT_SUCCESS); -@@ -102,44 +85,13 @@ static int adm_settle(struct udev *udev, - default: - assert_not_reached("Unknown argument"); - } -+ } - - if (optind < argc) { - fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]); - exit(EXIT_FAILURE); - } - -- udev_queue = udev_queue_new(udev); -- if (udev_queue == NULL) -- exit(2); -- -- if (start > 0) { -- unsigned long long kernel_seq; -- -- kernel_seq = udev_queue_get_kernel_seqnum(udev_queue); -- -- /* unless specified, the last event is the current kernel seqnum */ -- if (end == 0) -- end = udev_queue_get_kernel_seqnum(udev_queue); -- -- if (start > end) { -- log_error("seq-start larger than seq-end, ignoring"); -- start = 0; -- end = 0; -- } -- -- if (start > kernel_seq || end > kernel_seq) { -- log_error("seq-start or seq-end larger than current kernel value, ignoring"); -- start = 0; -- end = 0; -- } -- log_debug("start=%llu end=%llu current=%llu", (unsigned long long)start, (unsigned long long)end, kernel_seq); -- } else { -- if (end > 0) { -- log_error("seq-end needs seq-start parameter, ignoring"); -- end = 0; -- } -- } -- - /* guarantee that the udev daemon isn't pre-processing */ - if (getuid() == 0) { - struct udev_ctrl *uctrl; -@@ -160,73 +112,34 @@ static int adm_settle(struct udev *udev, - pfd[0].fd = inotify_init1(IN_CLOEXEC); - if (pfd[0].fd < 0) { - log_error("inotify_init failed: %m"); -- } else { -- if (inotify_add_watch(pfd[0].fd, "/run/udev" , IN_MOVED_TO) < 0) { -- log_error("watching /run/udev failed"); -- close(pfd[0].fd); -- pfd[0].fd = -1; -- } -+ goto out; - } - -- for (;;) { -- struct stat statbuf; -+ if (inotify_add_watch(pfd[0].fd, "/run/udev/queue" , IN_DELETE) < 0) { -+ log_debug("watching /run/udev failed"); -+ goto out; -+ } - -- if (exists != NULL && stat(exists, &statbuf) == 0) { -+ for (;;) { -+ if (exists && access(exists, F_OK) >= 0) { - rc = EXIT_SUCCESS; - break; - } - -- if (start > 0) { -- /* if asked for, wait for a specific sequence of events */ -- if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) { -- rc = EXIT_SUCCESS; -- break; -- } -- } else { -- /* exit if queue is empty */ -- if (udev_queue_get_queue_is_empty(udev_queue)) { -- rc = EXIT_SUCCESS; -- break; -- } -- } -- -- if (pfd[0].fd >= 0) { -- int delay; -- -- if (exists != NULL || start > 0) -- delay = 100; -- else -- delay = 1000; -- /* wake up after delay, or immediately after the queue is rebuilt */ -- if (poll(pfd, 1, delay) > 0 && pfd[0].revents & POLLIN) { -- char buf[sizeof(struct inotify_event) + PATH_MAX]; -- -- read(pfd[0].fd, buf, sizeof(buf)); -- } -- } else { -- sleep(1); -+ /* exit if queue is empty */ -+ if (access("/run/udev/queue", F_OK) < 0) { -+ rc = EXIT_SUCCESS; -+ break; - } - -- if (timeout > 0) { -- usec_t age_usec; -+ /* wake up when "queue" file is deleted */ -+ if (poll(pfd, 1, 100) > 0 && pfd[0].revents & POLLIN) { -+ char buf[sizeof(struct inotify_event) + PATH_MAX]; - -- age_usec = now(CLOCK_MONOTONIC) - start_usec; -- if (age_usec / (1000 * 1000) >= timeout) { -- struct udev_list_entry *list_entry; -- -- if (!quiet && udev_queue_get_queued_list_entry(udev_queue) != NULL) { -- log_debug("timeout waiting for udev queue"); -- printf("\nudevadm settle - timeout of %i seconds reached, the event queue contains:\n", timeout); -- udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) -- printf(" %s (%s)\n", -- udev_list_entry_get_name(list_entry), -- udev_list_entry_get_value(list_entry)); -- } -- -- break; -- } -+ read(pfd[0].fd, buf, sizeof(buf)); - } - } -+ - out: - if (pfd[0].fd >= 0) - close(pfd[0].fd); -@@ -236,5 +149,5 @@ out: - const struct udevadm_cmd udevadm_settle = { - .name = "settle", - .cmd = adm_settle, -- .help = "wait for the event queue to finish", -+ .help = "wait for pending udev events", - }; -Index: systemd-210/src/udev/udevd.c -=================================================================== ---- systemd-210.orig/src/udev/udevd.c -+++ systemd-210/src/udev/udevd.c -@@ -61,7 +61,6 @@ void udev_main_log(struct udev *udev, in - } - - static struct udev_rules *rules; --static struct udev_queue_export *udev_queue_export; - static struct udev_ctrl *udev_ctrl; - static struct udev_monitor *monitor; - static int worker_watch[2] = { -1, -1 }; -@@ -140,14 +139,9 @@ static inline struct worker *node_to_wor - return container_of(node, struct worker, node); - } - --static void event_queue_delete(struct event *event, bool export) -+static void event_queue_delete(struct event *event) - { - udev_list_node_remove(&event->node); -- -- if (export) { -- udev_queue_export_device_finished(udev_queue_export, event->dev); -- log_debug("seq %llu done with %i", udev_device_get_seqnum(event->dev), event->exitcode); -- } - udev_device_unref(event->dev); - free(event); - } -@@ -226,7 +220,6 @@ static void worker_new(struct event *eve - free(worker); - worker_list_cleanup(udev); - event_queue_cleanup(udev, EVENT_UNDEF); -- udev_queue_export_unref(udev_queue_export); - udev_monitor_unref(monitor); - udev_ctrl_unref(udev_ctrl); - close(fd_signal); -@@ -477,7 +470,6 @@ static int event_queue_insert(struct ude - event->nodelay = true; - #endif - -- udev_queue_export_device_queued(udev_queue_export, dev); - log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev), - udev_device_get_action(dev), udev_device_get_subsystem(dev)); - -@@ -608,7 +600,7 @@ static void event_queue_cleanup(struct u - if (match_type != EVENT_UNDEF && match_type != event->state) - continue; - -- event_queue_delete(event, false); -+ event_queue_delete(event); - } - } - -@@ -633,7 +625,7 @@ static void worker_returned(int fd_worke - /* worker returned */ - if (worker->event) { - worker->event->exitcode = msg.exitcode; -- event_queue_delete(worker->event, true); -+ event_queue_delete(worker->event); - worker->event = NULL; - } - if (worker->state != WORKER_KILLED) -@@ -825,7 +817,8 @@ static void handle_signal(struct udev *u - log_error("worker [%u] failed while handling '%s'", - pid, worker->event->devpath); - worker->event->exitcode = -32; -- event_queue_delete(worker->event, true); -+ event_queue_delete(worker->event); -+ - /* drop reference taken for state 'running' */ - worker_unref(worker); - } -@@ -1104,14 +1097,7 @@ int main(int argc, char *argv[]) - goto exit; - } - -- udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024); -- -- /* create queue file before signalling 'ready', to make sure we block 'settle' */ -- udev_queue_export = udev_queue_export_new(udev); -- if (udev_queue_export == NULL) { -- log_error("error creating queue file"); -- goto exit; -- } -+ udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024); - - if (daemonize) { - pid_t pid; -@@ -1269,12 +1255,12 @@ int main(int argc, char *argv[]) - worker_kill(udev); - - /* exit after all has cleaned up */ -- if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list)) -+ if (udev_list_node_is_empty(&event_list) && children == 0) - break; - - /* timeout at exit for workers to finish */ -- timeout = 30 * 1000; -- } else if (udev_list_node_is_empty(&event_list) && !children) { -+ timeout = 30 * MSEC_PER_SEC; -+ } else if (udev_list_node_is_empty(&event_list) && children == 0) { - /* we are idle */ - timeout = -1; - -@@ -1283,8 +1269,20 @@ int main(int argc, char *argv[]) - cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL); - } else { - /* kill idle or hanging workers */ -- timeout = 3 * 1000; -+ timeout = 3 * MSEC_PER_SEC; - } -+ -+ /* tell settle that we are busy or idle */ -+ if (!udev_list_node_is_empty(&event_list)) { -+ int fd; -+ -+ fd = open("/run/udev/queue", O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444); -+ if (fd >= 0) -+ close(fd); -+ } else { -+ unlink("/run/udev/queue"); -+ } -+ - fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout); - if (fdcount < 0) - continue; -@@ -1311,18 +1309,18 @@ int main(int argc, char *argv[]) - if (worker->state != WORKER_RUNNING) - continue; - -- if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) { -+ if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * USEC_PER_SEC) { - log_error("worker [%u] %s timeout; kill it", worker->pid, - worker->event ? worker->event->devpath : ""); - kill(worker->pid, SIGKILL); - worker->state = WORKER_KILLED; -+ - /* drop reference taken for state 'running' */ - worker_unref(worker); - if (worker->event) { -- log_error("seq %llu '%s' killed", -- udev_device_get_seqnum(worker->event->dev), worker->event->devpath); -+ log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath); - worker->event->exitcode = -64; -- event_queue_delete(worker->event, true); -+ event_queue_delete(worker->event); - worker->event = NULL; - } - } -@@ -1345,7 +1343,7 @@ int main(int argc, char *argv[]) - } - - /* check for changed config, every 3 seconds at most */ -- if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * 1000 * 1000) { -+ if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * USEC_PER_SEC) { - if (udev_rules_check_timestamp(rules)) - reload = true; - if (udev_builtin_validate(udev)) -@@ -1420,8 +1418,8 @@ int main(int argc, char *argv[]) - - rc = EXIT_SUCCESS; - exit: -- udev_queue_export_cleanup(udev_queue_export); - udev_ctrl_cleanup(udev_ctrl); -+ unlink("/run/udev/queue"); - exit_daemonize: - if (fd_ep >= 0) - close(fd_ep); -@@ -1436,7 +1434,6 @@ exit_daemonize: - if (worker_watch[WRITE_END] >= 0) - close(worker_watch[WRITE_END]); - udev_monitor_unref(monitor); -- udev_queue_export_unref(udev_queue_export); - udev_ctrl_connection_unref(ctrl_conn); - udev_ctrl_unref(udev_ctrl); - label_finish();