From 9e871965a02a18cca080edf0fc2cf629d7569e06 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 10 Mar 2022 19:08:04 +0900 Subject: [PATCH] sd-device-enumerator: introduce sound_device_compare() and devpath_is_late_block() helper functions --- src/libsystemd/sd-device/device-enumerator.c | 90 +++++++++++--------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 4942ee43a8..3f61ed8f88 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -223,49 +223,63 @@ int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) return 1; } -static int device_compare(sd_device * const *_a, sd_device * const *_b) { - sd_device *a = *(sd_device **)_a, *b = *(sd_device **)_b; - const char *devpath_a, *devpath_b, *sound_a; - bool delay_a, delay_b; - int r; +static int sound_device_compare(const char *devpath_a, const char *devpath_b) { + const char *sound_a, *sound_b; + size_t prefix_len; + + assert(devpath_a); + assert(devpath_b); - assert_se(sd_device_get_devpath(a, &devpath_a) >= 0); - assert_se(sd_device_get_devpath(b, &devpath_b) >= 0); + /* For sound cards the control device must be enumerated last to make sure it's the final + * device node that gets ACLs applied. Applications rely on this fact and use ACL changes on + * the control node as an indicator that the ACL change of the entire sound card completed. The + * kernel makes this guarantee when creating those devices, and hence we should too when + * enumerating them. */ sound_a = strstr(devpath_a, "/sound/card"); - if (sound_a) { - /* For sound cards the control device must be enumerated last to - * make sure it's the final device node that gets ACLs applied. - * Applications rely on this fact and use ACL changes on the - * control node as an indicator that the ACL change of the - * entire sound card completed. The kernel makes this guarantee - * when creating those devices, and hence we should too when - * enumerating them. */ - sound_a += STRLEN("/sound/card"); - sound_a = strchr(sound_a, '/'); - - if (sound_a) { - unsigned prefix_len; - - prefix_len = sound_a - devpath_a; - - if (strneq(devpath_a, devpath_b, prefix_len)) { - const char *sound_b; - - sound_b = devpath_b + prefix_len; - - r = CMP(!!startswith(sound_a, "/controlC"), - !!startswith(sound_b, "/controlC")); - if (r != 0) - return r; - } - } - } + if (!sound_a) + return 0; + + sound_a += STRLEN("/sound/card"); + sound_a = strchr(devpath_a, '/'); + if (!sound_a) + return 0; + + prefix_len = sound_a - devpath_a; + + if (!strneq(devpath_a, devpath_b, prefix_len)) + return 0; + + sound_b = devpath_b + prefix_len; + + return CMP(!!startswith(sound_a, "/controlC"), + !!startswith(sound_b, "/controlC")); +} + +static bool devpath_is_late_block(const char *devpath) { + assert(devpath); + + return strstr(devpath, "/block/md") || strstr(devpath, "/block/dm-"); +} + +static int device_compare(sd_device * const *a, sd_device * const *b) { + const char *devpath_a, *devpath_b; + int r; + + assert(a); + assert(b); + assert(*a); + assert(*b); + + assert_se(sd_device_get_devpath(*(sd_device**) a, &devpath_a) >= 0); + assert_se(sd_device_get_devpath(*(sd_device**) b, &devpath_b) >= 0); + + r = sound_device_compare(devpath_a, devpath_b); + if (r != 0) + return r; /* md and dm devices are enumerated after all other devices */ - delay_a = strstr(devpath_a, "/block/md") || strstr(devpath_a, "/block/dm-"); - delay_b = strstr(devpath_b, "/block/md") || strstr(devpath_b, "/block/dm-"); - r = CMP(delay_a, delay_b); + r = CMP(devpath_is_late_block(devpath_a), devpath_is_late_block(devpath_b)); if (r != 0) return r; -- 2.25.1