Merge pull request #9958 from yuwata/sd-device-enum-set

sd-device: make sd_device_enumerator_get_*_next() not destroy the list
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-09-15 18:33:18 +02:00 committed by GitHub
commit 9035119518
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 113 additions and 145 deletions

View File

@ -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;

View File

@ -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))

View File

@ -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;

View File

@ -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); \

View File

@ -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;
}

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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;