diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index c9d45c2253..5579d8a8bf 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -4,7 +4,7 @@ #include "alloc-util.h" #include "def.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "escape.h" #include "fileio.h" #include "mkdir.h" @@ -156,11 +156,7 @@ static int validate_device(sd_device *device) { if (r < 0) return r; - r = device_enumerator_scan_devices(enumerate); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(enumerate, other) { + FOREACH_DEVICE(enumerate, other) { const char *other_subsystem; sd_device *other_parent; diff --git a/src/core/device.c b/src/core/device.c index c8c8472ea4..634a45592f 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -7,7 +7,6 @@ #include "bus-error.h" #include "dbus-device.h" #include "device-private.h" -#include "device-enumerator-private.h" #include "device-util.h" #include "device.h" #include "libudev-private.h" @@ -831,13 +830,7 @@ static void device_enumerate(Manager *m) { goto fail; } - r = device_enumerator_scan_devices(e); - if (r < 0) { - log_error_errno(r, "Failed to enumerate devices: %m"); - goto fail; - } - - FOREACH_DEVICE_AND_SUBSYSTEM(e, dev) { + FOREACH_DEVICE(e, dev) { const char *sysfs; if (!device_is_ready(dev)) diff --git a/src/core/umount.c b/src/core/umount.c index f1779e201e..47313da231 100644 --- a/src/core/umount.c +++ b/src/core/umount.c @@ -18,7 +18,7 @@ #include "alloc-util.h" #include "blockdev-util.h" #include "def.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "escape.h" #include "fd-util.h" #include "fstab-util.h" @@ -255,27 +255,27 @@ static int loopback_list_get(MountPoint **head) { if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { - _cleanup_free_ MountPoint *lb = NULL; + FOREACH_DEVICE(e, d) { + _cleanup_free_ char *p = NULL; const char *dn; + MountPoint *lb; if (sd_device_get_devname(d, &dn) < 0) continue; - lb = new0(MountPoint, 1); + p = strdup(dn); + if (!p) + return -ENOMEM; + + lb = new(MountPoint, 1); if (!lb) return -ENOMEM; - r = free_and_strdup(&lb->path, dn); - if (r < 0) - return r; + *lb = (MountPoint) { + .path = TAKE_PTR(p), + }; LIST_PREPEND(mount_point, *head, lb); - lb = NULL; } return 0; @@ -304,32 +304,30 @@ static int dm_list_get(MountPoint **head) { if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { - _cleanup_free_ MountPoint *m = NULL; + FOREACH_DEVICE(e, d) { + _cleanup_free_ char *p = NULL; const char *dn; + MountPoint *m; dev_t devnum; - if (sd_device_get_devnum(d, &devnum) < 0) + if (sd_device_get_devnum(d, &devnum) < 0 || + sd_device_get_devname(d, &dn) < 0) continue; - if (sd_device_get_devname(d, &dn) < 0) - continue; + p = strdup(dn); + if (!p) + return -ENOMEM; - m = new0(MountPoint, 1); + m = new(MountPoint, 1); if (!m) return -ENOMEM; - m->devnum = devnum; - r = free_and_strdup(&m->path, dn); - if (r < 0) - return r; + *m = (MountPoint) { + .path = TAKE_PTR(p), + .devnum = devnum, + }; LIST_PREPEND(mount_point, *head, m); - m = NULL; } return 0; diff --git a/src/libsystemd/sd-device/device-enumerator-private.h b/src/libsystemd/sd-device/device-enumerator-private.h index 56a953d33b..87411bfdd8 100644 --- a/src/libsystemd/sd-device/device-enumerator-private.h +++ b/src/libsystemd/sd-device/device-enumerator-private.h @@ -9,6 +9,7 @@ int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *de int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator); sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator); sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator); +sd_device **device_enumerator_get_devices(sd_device_enumerator *enumerator, size_t *ret_n_devices); #define FOREACH_DEVICE_AND_SUBSYSTEM(enumerator, device) \ for (device = device_enumerator_get_first(enumerator); \ diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index e1f60126b3..3f7ead268e 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -7,7 +7,6 @@ #include "device-util.h" #include "dirent-util.h" #include "fd-util.h" -#include "prioq.h" #include "set.h" #include "string-util.h" #include "strv.h" @@ -26,7 +25,8 @@ struct sd_device_enumerator { unsigned n_ref; DeviceEnumerationType type; - Prioq *devices; + sd_device **devices; + size_t n_devices, n_allocated, current_device_index; bool scan_uptodate; Set *match_subsystem; @@ -60,15 +60,14 @@ _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) { } static sd_device_enumerator *device_enumerator_free(sd_device_enumerator *enumerator) { - sd_device *device; + size_t i; assert(enumerator); - while ((device = prioq_pop(enumerator->devices))) - sd_device_unref(device); - - prioq_free(enumerator->devices); + for (i = 0; i < enumerator->n_devices; i++) + sd_device_unref(enumerator->devices[i]); + free(enumerator->devices); set_free_free(enumerator->match_subsystem); set_free_free(enumerator->nomatch_subsystem); hashmap_free_free_free(enumerator->match_sysattr); @@ -251,7 +250,7 @@ int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) } static int device_compare(const void *_a, const void *_b) { - sd_device *a = (sd_device *)_a, *b = (sd_device *)_b; + sd_device *a = *(sd_device **)_a, *b = *(sd_device **)_b; const char *devpath_a, *devpath_b, *sound_a; bool delay_a, delay_b; @@ -301,20 +300,13 @@ static int device_compare(const void *_a, const void *_b) { } int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) { - int r; - assert_return(enumerator, -EINVAL); assert_return(device, -EINVAL); - r = prioq_ensure_allocated(&enumerator->devices, device_compare); - if (r < 0) - return r; + if (!GREEDY_REALLOC(enumerator->devices, enumerator->n_allocated, enumerator->n_devices + 1)) + return -ENOMEM; - r = prioq_put(enumerator->devices, device, NULL); - if (r < 0) - return r; - - sd_device_ref(device); + enumerator->devices[enumerator->n_devices++] = sd_device_ref(device); return 0; } @@ -810,8 +802,8 @@ static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) { } int device_enumerator_scan_devices(sd_device_enumerator *enumerator) { - sd_device *device; int r = 0, k; + size_t i; assert(enumerator); @@ -819,8 +811,10 @@ int device_enumerator_scan_devices(sd_device_enumerator *enumerator) { enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES) return 0; - while ((device = prioq_pop(enumerator->devices))) - sd_device_unref(device); + for (i = 0; i < enumerator->n_devices; i++) + sd_device_unref(enumerator->devices[i]); + + enumerator->n_devices = 0; if (!set_isempty(enumerator->match_tag)) { k = enumerator_scan_devices_tags(enumerator); @@ -836,7 +830,10 @@ int device_enumerator_scan_devices(sd_device_enumerator *enumerator) { r = k; } + qsort(enumerator->devices, enumerator->n_devices, sizeof(sd_device *), device_compare); + enumerator->scan_uptodate = true; + enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES; return r; } @@ -850,27 +847,29 @@ _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator * if (r < 0) return NULL; - enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES; + enumerator->current_device_index = 0; - return prioq_peek(enumerator->devices); + if (enumerator->n_devices == 0) + return NULL; + + return enumerator->devices[0]; } _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) { assert_return(enumerator, NULL); if (!enumerator->scan_uptodate || - enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES) + enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES || + enumerator->current_device_index + 1 >= enumerator->n_devices) return NULL; - sd_device_unref(prioq_pop(enumerator->devices)); - - return prioq_peek(enumerator->devices); + return enumerator->devices[++enumerator->current_device_index]; } int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) { - sd_device *device; const char *subsysdir; int r = 0, k; + size_t i; assert(enumerator); @@ -878,8 +877,10 @@ int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) { enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS) return 0; - while ((device = prioq_pop(enumerator->devices))) - sd_device_unref(device); + for (i = 0; i < enumerator->n_devices; i++) + sd_device_unref(enumerator->devices[i]); + + enumerator->n_devices = 0; /* modules */ if (match_subsystem(enumerator, "module")) { @@ -913,7 +914,10 @@ int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) { } } + qsort(enumerator->devices, enumerator->n_devices, sizeof(sd_device *), device_compare); + enumerator->scan_uptodate = true; + enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS; return r; } @@ -927,33 +931,56 @@ _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerato if (r < 0) return NULL; - enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS; + enumerator->current_device_index = 0; - return prioq_peek(enumerator->devices); + if (enumerator->n_devices == 0) + return NULL; + + return enumerator->devices[0]; } _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) { assert_return(enumerator, NULL); if (!enumerator->scan_uptodate || - enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS) + enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS || + enumerator->current_device_index + 1 >= enumerator->n_devices) return NULL; - sd_device_unref(prioq_pop(enumerator->devices)); - - return prioq_peek(enumerator->devices); + return enumerator->devices[++enumerator->current_device_index]; } sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) { assert_return(enumerator, NULL); - return prioq_peek(enumerator->devices); + if (!enumerator->scan_uptodate) + return NULL; + + enumerator->current_device_index = 0; + + if (enumerator->n_devices == 0) + return NULL; + + return enumerator->devices[0]; } sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) { assert_return(enumerator, NULL); - sd_device_unref(prioq_pop(enumerator->devices)); + if (!enumerator->scan_uptodate || + enumerator->current_device_index + 1 >= enumerator->n_devices) + return NULL; - return prioq_peek(enumerator->devices); + return enumerator->devices[++enumerator->current_device_index]; +} + +sd_device **device_enumerator_get_devices(sd_device_enumerator *enumerator, size_t *ret_n_devices) { + assert(enumerator); + assert(ret_n_devices); + + if (!enumerator->scan_uptodate) + return NULL; + + *ret_n_devices = enumerator->n_devices; + return enumerator->devices; } diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c index 94b33aef7d..da197d039c 100644 --- a/src/login/logind-acl.c +++ b/src/login/logind-acl.c @@ -7,7 +7,7 @@ #include "acl-util.h" #include "alloc-util.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "dirent-util.h" #include "escape.h" #include "fd-util.h" @@ -193,11 +193,7 @@ int devnode_acl_all(const char *seat, if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { const char *node, *sn; if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn)) diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 5fc4f29127..dac240d294 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -13,7 +13,7 @@ #include "bus-util.h" #include "cgroup-util.h" #include "conf-parser.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "fd-util.h" #include "logind.h" #include "parse-util.h" @@ -571,11 +571,7 @@ static int manager_count_external_displays(Manager *m) { if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { sd_device *p; const char *status, *enabled, *dash, *nn, *i, *subsys; bool external = false; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 47cf62cb3d..5035bb5bdf 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -14,7 +14,7 @@ #include "bus-error.h" #include "bus-unit-util.h" #include "bus-util.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "dirent-util.h" #include "efivars.h" #include "escape.h" @@ -1210,11 +1210,7 @@ static int trigger_device(Manager *m, sd_device *d) { return r; } - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { _cleanup_free_ char *t = NULL; const char *p; diff --git a/src/login/logind.c b/src/login/logind.c index c487fbc698..b9ad1007ae 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -13,7 +13,7 @@ #include "bus-util.h" #include "cgroup-util.h" #include "def.h" -#include "device-enumerator-private.h" +#include "device-util.h" #include "dirent-util.h" #include "fd-util.h" #include "format-util.h" @@ -175,11 +175,7 @@ static int manager_enumerate_devices(Manager *m) { if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { int k; k = manager_process_seat_device(m, d); @@ -214,11 +210,7 @@ static int manager_enumerate_buttons(Manager *m) { if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { int k; k = manager_process_button_device(m, d); diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c index 5d2a6ad209..758f9c2c1d 100644 --- a/src/login/sysfs-show.c +++ b/src/login/sysfs-show.c @@ -127,8 +127,8 @@ static int show_sysfs_one( int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - size_t n_dev = 0, n_allocated = 0, i = 0; - sd_device *d, **dev_list = NULL; + size_t n_dev = 0, i = 0; + sd_device **dev_list; int r; if (n_columns <= 0) @@ -155,27 +155,12 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputF if (r < 0) return r; - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { - const char *syspath; + dev_list = device_enumerator_get_devices(e, &n_dev); - if (sd_device_get_syspath(d, &syspath) < 0) - continue; - - if (!GREEDY_REALLOC(dev_list, n_allocated, n_dev + 2)) - return -ENOMEM; - - dev_list[n_dev++] = sd_device_ref(d); - dev_list[n_dev] = NULL; - } - - if (n_dev > 0) + if (dev_list && n_dev > 0) show_sysfs_one(seat, dev_list, &i, n_dev, "/", prefix, n_columns, flags); else printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)"); - for (i = 0; i < n_dev; i++) - sd_device_unref(dev_list[i]); - free(dev_list); - return 0; } diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index 5ce9644861..56ded606f5 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -5,10 +5,10 @@ #include "sd-bus.h" #include "sd-device.h" -#include "device-enumerator-private.h" #include "bus-error.h" #include "bus-unit-util.h" #include "bus-util.h" +#include "device-util.h" #include "dirent-util.h" #include "escape.h" #include "fd-util.h" @@ -1420,11 +1420,7 @@ static int list_devices(void) { if (r < 0) return log_error_errno(r, "Failed to add property match: %m"); - r = device_enumerator_scan_devices(e); - if (r < 0) - return log_error_errno(r, "Failed to enumerate devices: %m"); - - FOREACH_DEVICE_AND_SUBSYSTEM(e, d) { + FOREACH_DEVICE(e, d) { struct item *j; if (!GREEDY_REALLOC0(items, n_allocated, n+1)) { diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 5e48ee7981..0429a55a9c 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -14,8 +14,8 @@ #include "copy.h" #include "crypt-util.h" #include "def.h" -#include "device-enumerator-private.h" #include "device-nodes.h" +#include "device-util.h" #include "dissect-image.h" #include "fd-util.h" #include "fileio.h" @@ -278,13 +278,9 @@ int dissect_image( if (r < 0) return r; - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - /* Count the partitions enumerated by the kernel */ n = 0; - FOREACH_DEVICE_AND_SUBSYSTEM(e, q) { + FOREACH_DEVICE(e, q) { dev_t qn; if (sd_device_get_devnum(q, &qn) < 0) @@ -350,11 +346,7 @@ int dissect_image( e = sd_device_enumerator_unref(e); } - r = device_enumerator_scan_devices(e); - if (r < 0) - return r; - - FOREACH_DEVICE_AND_SUBSYSTEM(e, q) { + FOREACH_DEVICE(e, q) { unsigned long long pflags; blkid_partition pp; const char *node;