Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 893658 Details for
Bug 983685
lxc container with networking hangs udevadm settle on the host
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
udev-remove-seqnum-API-and-all-assumption
0001-udev-remove-seqnum-API-and-all-assumptions-about-seq.patch (text/plain), 54.78 KB, created by
Gene Czarcinski
on 2014-05-08 15:11:25 UTC
(
hide
)
Description:
udev-remove-seqnum-API-and-all-assumption
Filename:
MIME Type:
Creator:
Gene Czarcinski
Created:
2014-05-08 15:11:25 UTC
Size:
54.78 KB
patch
obsolete
>From 9ea28c55a2488e6cd4a44ac5786f12b71ad5bc9f Mon Sep 17 00:00:00 2001 >From: Kay Sievers <kay@vrfy.org> >Date: Sat, 12 Apr 2014 22:35:50 -0700 >Subject: [PATCH] udev: remove seqnum API and all assumptions about seqnums >Content-Type: text/plain; charset="utf-8" >Content-Transfer-Encoding: 8bit > >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. >--- > 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 > >diff --git a/Makefile.am b/Makefile.am >index 5d84605..0ad1729 100644 >--- a/Makefile.am >+++ b/Makefile.am >@@ -2587,8 +2587,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) \ >@@ -5169,6 +5168,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 > >diff --git a/man/udevadm.xml b/man/udevadm.xml >index 21d1443..fbfa85a 100644 >--- a/man/udevadm.xml >+++ b/man/udevadm.xml >@@ -339,21 +339,6 @@ > </listitem> > </varlistentry> > <varlistentry> >- <term><option>-s</option></term> >- <term><option>--seq-start=<replaceable>SEQNUM</replaceable></option></term> >- <listitem> >- <para>Wait only for events after the given sequence >- number.</para> >- </listitem> >- </varlistentry> >- <varlistentry> >- <term><option>-e</option></term> >- <term><option>--seq-end=<replaceable>SEQNUM</replaceable></option></term> >- <listitem> >- <para>Wait only for events before the given sequence number.</para> >- </listitem> >- </varlistentry> >- <varlistentry> > <term><option>-E</option></term> > <term><option>--exit-if-exists=<replaceable>FILE</replaceable></option></term> > <listitem> >@@ -361,13 +346,6 @@ > </listitem> > </varlistentry> > <varlistentry> >- <term><option>-q</option></term> >- <term><option>--quiet</option></term> >- <listitem> >- <para>Do not print any output, like the remaining queue entries when reaching the timeout.</para> >- </listitem> >- </varlistentry> >- <varlistentry> > <term><option>-h</option></term> > <term><option>--help</option></term> > <listitem> >diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c >index ba1b04d..3f7436b 100644 >--- a/src/libudev/libudev-monitor.c >+++ b/src/libudev/libudev-monitor.c >@@ -146,21 +146,6 @@ static bool udev_has_devtmpfs(struct udev *udev) { > 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; >@@ -184,7 +169,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c > * 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 >diff --git a/src/libudev/libudev-queue-private.c b/src/libudev/libudev-queue-private.c >deleted file mode 100644 >index d5a2b50..0000000 >--- a/src/libudev/libudev-queue-private.c >+++ /dev/null >@@ -1,406 +0,0 @@ >-/*** >- This file is part of systemd. >- >- Copyright 2008-2012 Kay Sievers <kay@vrfy.org> >- Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk> >- >- 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 <http://www.gnu.org/licenses/>. >-***/ >- >-/* >- * 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 <stdio.h> >-#include <stdlib.h> >-#include <string.h> >-#include <unistd.h> >-#include <fcntl.h> >-#include <dirent.h> >-#include <limits.h> >-#include <errno.h> >-#include <sys/stat.h> >-#include <sys/types.h> >- >-#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); >-} >diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c >index 2cb4d67..eb0e096 100644 >--- a/src/libudev/libudev-queue.c >+++ b/src/libudev/libudev-queue.c >@@ -24,8 +24,6 @@ > #include <unistd.h> > #include <errno.h> > #include <string.h> >-#include <dirent.h> >-#include <fcntl.h> > #include <limits.h> > #include <sys/stat.h> > >@@ -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_new(struct udev *udev) > 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_ref(struct udev_queue *udev_queue) > { > if (udev_queue == NULL) > return NULL; >+ > udev_queue->refcount++; > return udev_queue; > } >@@ -107,10 +102,11 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue) > { > 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_udev(struct udev_queue *udev_queue) > 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_queue_get_udev_seqnum(struct udev_queue *ud > **/ > _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_active(struct udev_queue *udev_queue) > **/ > _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_sequence_is_finished(struct udev_queue *udev_ > * @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; > } >diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h >index b9b8f13..ceb89bd 100644 >--- a/src/libudev/libudev.h >+++ b/src/libudev/libudev.h >@@ -170,14 +170,14 @@ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue); > 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 >diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h >index 40f8b77..5f09ce1 100644 >--- a/src/shared/udev-util.h >+++ b/src/shared/udev-util.h >@@ -31,7 +31,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref); > 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_queue*, udev_queue_unref); > #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) >diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c >index c233b1e..f5c8bc7 100644 >--- a/src/test/test-libudev.c >+++ b/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; > } >diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c >index 1e91ec2..74bbd3a 100644 >--- a/src/udev/udev-ctrl.c >+++ b/src/udev/udev-ctrl.c >@@ -275,7 +275,7 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int > > 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; >diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c >index 927ea2a..65fc35f 100644 >--- a/src/udev/udevadm-settle.c >+++ b/src/udev/udevadm-settle.c >@@ -41,42 +41,28 @@ > static void help(void) { > printf("Usage: udevadm settle OPTIONS\n" > " -t,--timeout=<seconds> maximum time to wait for events\n" >- " -s,--seq-start=<seqnum> first seqnum to wait for\n" >- " -e,--seq-end=<seqnum> last seqnum to wait for\n" > " -E,--exit-if-exists=<file> 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, int argc, char *argv[]) > 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, int argc, char *argv[]) > 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, int argc, char *argv[]) > 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", > }; >diff --git a/src/udev/udevd.c b/src/udev/udevd.c >index f21c227..f9ee368 100644 >--- a/src/udev/udevd.c >+++ b/src/udev/udevd.c >@@ -60,7 +60,6 @@ void udev_main_log(struct udev *udev, int priority, > } > > 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 }; >@@ -139,14 +138,9 @@ static inline struct worker *node_to_worker(struct udev_list_node *node) > 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); > } >@@ -225,7 +219,6 @@ static void worker_new(struct event *event) > 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); >@@ -449,7 +442,6 @@ static int event_queue_insert(struct udev_device *dev) > 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)); > >@@ -580,7 +572,7 @@ static void event_queue_cleanup(struct udev *udev, enum event_state match_type) > if (match_type != EVENT_UNDEF && match_type != event->state) > continue; > >- event_queue_delete(event, false); >+ event_queue_delete(event); > } > } > >@@ -605,7 +597,7 @@ static void worker_returned(int fd_worker) > /* 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) >@@ -797,7 +789,8 @@ static void handle_signal(struct udev *udev, int signo) > 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); > } >@@ -1076,14 +1069,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; >@@ -1241,12 +1227,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; > >@@ -1255,8 +1241,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; >@@ -1283,18 +1281,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 : "<idle>"); > 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; > } > } >@@ -1317,7 +1315,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)) >@@ -1390,8 +1388,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); >@@ -1406,7 +1404,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(); >-- >1.9.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 983685
: 893658