chiark / gitweb /
udevd: improve handling of failed worker
authorTom Gundersen <teg@jklm.no>
Wed, 11 Mar 2015 14:41:32 +0000 (15:41 +0100)
committerTom Gundersen <teg@jklm.no>
Thu, 12 Mar 2015 11:03:50 +0000 (12:03 +0100)
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.

src/udev/udevd.c

index 9426edca2eba93b7bee9c538bed1c657fd8b0e1b..ac21d511bb6bca4b4f9543d6b987b72b55419db0 100644 (file)
@@ -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' */