chiark / gitweb /
core,logind,networkd: don't pick up devices from udev before they finished udev initi...
authorLennart Poettering <lennart@poettering.net>
Wed, 18 Dec 2013 02:37:26 +0000 (03:37 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 18 Dec 2013 02:37:26 +0000 (03:37 +0100)
Managers shouldn't pick up the devices the manage before udev finished
initialization, hence check explicitly for that.

src/core/device.c
src/login/logind-acl.c
src/login/logind.c
src/network/networkd-manager.c

index 4ff7c37..70fac1b 100644 (file)
@@ -303,6 +303,10 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
 
         assert(m);
 
 
         assert(m);
 
+        /* Don't pick up devices before udev finished initialization for them */
+        if (!udev_device_get_is_initialized(dev))
+                return 0;
+
         sysfs = udev_device_get_syspath(dev);
         if (!sysfs)
                 return 0;
         sysfs = udev_device_get_syspath(dev);
         if (!sysfs)
                 return 0;
index 2df2ba2..09a6f6d 100644 (file)
@@ -29,6 +29,7 @@
 #include "acl-util.h"
 #include "set.h"
 #include "logind-acl.h"
 #include "acl-util.h"
 #include "set.h"
 #include "logind-acl.h"
+#include "udev-util.h"
 
 static int flush_acl(acl_t acl) {
         acl_entry_t i;
 
 static int flush_acl(acl_t acl) {
         acl_entry_t i;
@@ -178,13 +179,13 @@ int devnode_acl_all(struct udev *udev,
                     bool del, uid_t old_uid,
                     bool add, uid_t new_uid) {
 
                     bool del, uid_t old_uid,
                     bool add, uid_t new_uid) {
 
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
-        struct udev_enumerate *e;
-        Set *nodes;
-        Iterator i;
-        char *n;
+        _cleanup_set_free_free_ Set *nodes = NULL;
         _cleanup_closedir_ DIR *dir = NULL;
         struct dirent *dent;
         _cleanup_closedir_ DIR *dir = NULL;
         struct dirent *dent;
+        Iterator i;
+        char *n;
         int r;
 
         assert(udev);
         int r;
 
         assert(udev);
@@ -194,10 +195,8 @@ int devnode_acl_all(struct udev *udev,
                 return -ENOMEM;
 
         e = udev_enumerate_new(udev);
                 return -ENOMEM;
 
         e = udev_enumerate_new(udev);
-        if (!e) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!e)
+                return -ENOMEM;
 
         if (isempty(seat))
                 seat = "seat0";
 
         if (isempty(seat))
                 seat = "seat0";
@@ -209,85 +208,79 @@ int devnode_acl_all(struct udev *udev,
          * second tag manually in our loop is a good solution. */
         r = udev_enumerate_add_match_tag(e, "uaccess");
         if (r < 0)
          * second tag manually in our loop is a good solution. */
         r = udev_enumerate_add_match_tag(e, "uaccess");
         if (r < 0)
-                goto finish;
+                return r;
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
-                goto finish;
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
-                struct udev_device *d;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 const char *node, *sn;
 
                 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                 const char *node, *sn;
 
                 d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
-                if (!d) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!d)
+                        return -ENOMEM;
+
+                if (!udev_device_get_is_initialized(d))
+                        continue;
 
                 sn = udev_device_get_property_value(d, "ID_SEAT");
                 if (isempty(sn))
                         sn = "seat0";
 
 
                 sn = udev_device_get_property_value(d, "ID_SEAT");
                 if (isempty(sn))
                         sn = "seat0";
 
-                if (!streq(seat, sn)) {
-                        udev_device_unref(d);
+                if (!streq(seat, sn))
                         continue;
                         continue;
-                }
 
                 node = udev_device_get_devnode(d);
 
                 node = udev_device_get_devnode(d);
-                if (!node) {
-                        /* In case people mistag devices with nodes, we need to ignore this */
-                        udev_device_unref(d);
+                /* In case people mistag devices with nodes, we need to ignore this */
+                if (!node)
                         continue;
                         continue;
-                }
 
                 n = strdup(node);
 
                 n = strdup(node);
-                udev_device_unref(d);
                 if (!n)
                 if (!n)
-                        goto finish;
+                        return -ENOMEM;
 
                 log_debug("Found udev node %s for seat %s", n, seat);
 
                 log_debug("Found udev node %s for seat %s", n, seat);
-                r = set_put(nodes, n);
+                r = set_consume(nodes, n);
                 if (r < 0)
                 if (r < 0)
-                        goto finish;
+                        return r;
         }
 
         /* udev exports "dead" device nodes to allow module on-demand loading,
          * these devices are not known to the kernel at this moment */
         dir = opendir("/run/udev/static_node-tags/uaccess");
         if (dir) {
         }
 
         /* udev exports "dead" device nodes to allow module on-demand loading,
          * these devices are not known to the kernel at this moment */
         dir = opendir("/run/udev/static_node-tags/uaccess");
         if (dir) {
-                FOREACH_DIRENT(dent, dir, r = -errno; goto finish) {
+                FOREACH_DIRENT(dent, dir, return -errno) {
                         _cleanup_free_ char *unescaped_devname = NULL;
 
                         unescaped_devname = cunescape(dent->d_name);
                         _cleanup_free_ char *unescaped_devname = NULL;
 
                         unescaped_devname = cunescape(dent->d_name);
-                        if (unescaped_devname == NULL) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        if (!unescaped_devname)
+                                return -ENOMEM;
 
                         n = strappend("/dev/", unescaped_devname);
 
                         n = strappend("/dev/", unescaped_devname);
-                        if (!n) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        if (!n)
+                                return -ENOMEM;
 
                         log_debug("Found static node %s for seat %s", n, seat);
 
                         log_debug("Found static node %s for seat %s", n, seat);
-                        r = set_put(nodes, n);
-                        if (r < 0 && r != -EEXIST)
-                                goto finish;
-                        else
-                                r = 0;
+                        r = set_consume(nodes, n);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
                 }
         }
 
                 }
         }
 
+        r = 0;
         SET_FOREACH(n, nodes, i) {
         SET_FOREACH(n, nodes, i) {
+                int k;
+
                 log_debug("Fixing up ACLs at %s for seat %s", n, seat);
                 log_debug("Fixing up ACLs at %s for seat %s", n, seat);
-                r = devnode_acl(n, flush, del, old_uid, add, new_uid);
+                k = devnode_acl(n, flush, del, old_uid, add, new_uid);
+                if (k < 0)
+                        r = k;
         }
 
         }
 
-finish:
-        udev_enumerate_unref(e);
-        set_free_free(nodes);
         return r;
 }
         return r;
 }
index b7c8f71..b97ba6d 100644 (file)
@@ -182,7 +182,7 @@ void manager_free(Manager *m) {
 
 static int manager_enumerate_devices(Manager *m) {
         struct udev_list_entry *item = NULL, *first = NULL;
 
 static int manager_enumerate_devices(Manager *m) {
         struct udev_list_entry *item = NULL, *first = NULL;
-        struct udev_enumerate *e;
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         int r;
 
         assert(m);
         int r;
 
         assert(m);
@@ -191,47 +191,40 @@ static int manager_enumerate_devices(Manager *m) {
          * necessary */
 
         e = udev_enumerate_new(m->udev);
          * necessary */
 
         e = udev_enumerate_new(m->udev);
-        if (!e) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!e)
+                return -ENOMEM;
 
         r = udev_enumerate_add_match_tag(e, "master-of-seat");
         if (r < 0)
 
         r = udev_enumerate_add_match_tag(e, "master-of-seat");
         if (r < 0)
-                goto finish;
+                return r;
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
-                goto finish;
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
-                struct udev_device *d;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
-                if (!d) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!d)
+                        return -ENOMEM;
 
 
-                k = manager_process_seat_device(m, d);
-                udev_device_unref(d);
+                if (!udev_device_get_is_initialized(d))
+                        continue;
 
 
+                k = manager_process_seat_device(m, d);
                 if (k < 0)
                         r = k;
         }
 
                 if (k < 0)
                         r = k;
         }
 
-finish:
-        if (e)
-                udev_enumerate_unref(e);
-
         return r;
 }
 
 static int manager_enumerate_buttons(Manager *m) {
         return r;
 }
 
 static int manager_enumerate_buttons(Manager *m) {
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
-        struct udev_enumerate *e;
         int r;
 
         assert(m);
         int r;
 
         assert(m);
@@ -245,45 +238,38 @@ static int manager_enumerate_buttons(Manager *m) {
                 return 0;
 
         e = udev_enumerate_new(m->udev);
                 return 0;
 
         e = udev_enumerate_new(m->udev);
-        if (!e) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!e)
+                return -ENOMEM;
 
         r = udev_enumerate_add_match_subsystem(e, "input");
         if (r < 0)
 
         r = udev_enumerate_add_match_subsystem(e, "input");
         if (r < 0)
-                goto finish;
+                return r;
 
         r = udev_enumerate_add_match_tag(e, "power-switch");
         if (r < 0)
 
         r = udev_enumerate_add_match_tag(e, "power-switch");
         if (r < 0)
-                goto finish;
+                return r;
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
-                goto finish;
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
-                struct udev_device *d;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
-                if (!d) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!d)
+                        return -ENOMEM;
 
 
-                k = manager_process_button_device(m, d);
-                udev_device_unref(d);
+                if (!udev_device_get_is_initialized(d))
+                        continue;
 
 
+                k = manager_process_button_device(m, d);
                 if (k < 0)
                         r = k;
         }
 
                 if (k < 0)
                         r = k;
         }
 
-finish:
-        if (e)
-                udev_enumerate_unref(e);
-
         return r;
 }
 
         return r;
 }
 
index 724e5e5..6998562 100644 (file)
@@ -157,48 +157,41 @@ static int manager_process_link(Manager *m, struct udev_device *device) {
 }
 
 int manager_udev_enumerate_links(Manager *m) {
 }
 
 int manager_udev_enumerate_links(Manager *m) {
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
-        struct udev_enumerate *e;
         int r;
 
         assert(m);
 
         e = udev_enumerate_new(m->udev);
         int r;
 
         assert(m);
 
         e = udev_enumerate_new(m->udev);
-        if (!e) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!e)
+                return -ENOMEM;
 
         r = udev_enumerate_add_match_subsystem(e, "net");
         if (r < 0)
 
         r = udev_enumerate_add_match_subsystem(e, "net");
         if (r < 0)
-                goto finish;
+                return r;
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
-                goto finish;
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
-                struct udev_device *d;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
                 int k;
 
                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
-                if (!d) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!d)
+                        return -ENOMEM;
 
 
-                k = manager_process_link(m, d);
-                udev_device_unref(d);
+                if (!udev_device_get_is_initialized(d))
+                        continue;
 
 
+                k = manager_process_link(m, d);
                 if (k < 0)
                         r = k;
         }
 
                 if (k < 0)
                         r = k;
         }
 
-finish:
-        if (e)
-                udev_enumerate_unref(e);
-
         return r;
 }
 
         return r;
 }