summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-03-11 15:41:32 +0100
committerTom Gundersen <teg@jklm.no>2015-03-12 12:03:50 +0100
commit6969c349df91a3cc5fc2cf559a14e32a84db969d (patch)
tree3b28ca367a971a2f111d7c55c0562537d67a4c26 /src/udev
parent090b6bc5205b924df4be3239b2f7d9c097fbb705 (diff)
udevd: improve handling of failed worker
The information in the db is stale, so it does not make sense to expose it any longer. Also, don't drop the kernel event, but simply pass it on to userspace without ammending it.
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udevd.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 9426edca2e..ac21d511bb 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -83,6 +83,7 @@ struct event {
struct udev_list_node node;
struct udev *udev;
struct udev_device *dev;
+ struct udev_device *dev_kernel;
enum event_state state;
int exitcode;
unsigned long long int delaying_seqnum;
@@ -133,6 +134,7 @@ static inline struct worker *node_to_worker(struct udev_list_node *node) {
static void event_queue_delete(struct event *event) {
udev_list_node_remove(&event->node);
udev_device_unref(event->dev);
+ udev_device_unref(event->dev_kernel);
free(event);
}
@@ -459,6 +461,8 @@ static int event_queue_insert(struct udev_device *dev) {
event->udev = udev_device_get_udev(dev);
event->dev = dev;
+ event->dev_kernel = udev_device_shallow_clone(dev);
+ udev_device_copy_properties(event->dev_kernel, dev);
event->seqnum = udev_device_get_seqnum(dev);
event->devpath = udev_device_get_devpath(dev);
event->devpath_len = strlen(event->devpath);
@@ -886,6 +890,11 @@ static void handle_signal(struct udev *udev, int signo) {
log_error("worker ["PID_FMT"] failed while handling '%s'",
pid, worker->event->devpath);
worker->event->exitcode = -32;
+ /* delete state from disk */
+ udev_device_delete_db(worker->event->dev);
+ udev_device_tag_index(worker->event->dev, NULL, false);
+ /* forward kernel event without ammending it */
+ udev_monitor_send_device(monitor, NULL, worker->event->dev_kernel);
event_queue_delete(worker->event);
/* drop reference taken for state 'running' */