In a script, I wanted to look up the device node for the booted EFI partition. systemd-boot exposes this in an EFI variable but it's uppercase, so when I tried to do this, it didn't work: findfs "(< /sys/firmware/efi/vars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440)" This was very confusing to me, and I lost some time trying to figure out what was wrong before I realised that case of UUIDs was significant to findfs. Here, I've made comparisons of UUID and PARTUUID case-insensitive in libblkid, which fixes the command above. Signed-off-by: Alyssa Ross <hi@xxxxxxxxx> --- libblkid/src/evaluate.c | 12 ++++++++++++ libblkid/src/tag.c | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/libblkid/src/evaluate.c b/libblkid/src/evaluate.c index 710eac956..ceaa63cc7 100644 --- a/libblkid/src/evaluate.c +++ b/libblkid/src/evaluate.c @@ -135,6 +135,15 @@ int blkid_send_uevent(const char *devname, const char *action) return rc; } +static void ascii_downcase(char *s) +{ + while (*s) { + if ('A' <= *s && *s <= 'Z') + *s += 'a' - 'A'; + s++; + } +} + static char *evaluate_by_udev(const char *token, const char *value, int uevent) { char dev[PATH_MAX]; @@ -163,6 +172,9 @@ static char *evaluate_by_udev(const char *token, const char *value, int uevent) if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0) return NULL; + if (!strcmp(token, "UUID") || !strcmp(token, "PARTUUID")) + ascii_downcase(dev); + DBG(EVALUATE, ul_debug("expected udev link: %s", dev)); if (stat(dev, &st)) diff --git a/libblkid/src/tag.c b/libblkid/src/tag.c index 390a64864..ca81c6921 100644 --- a/libblkid/src/tag.c +++ b/libblkid/src/tag.c @@ -10,10 +10,13 @@ * %End-Header% */ -#include <unistd.h> +#include <locale.h> +#include <stdbool.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdio.h> +#include <strings.h> +#include <unistd.h> #include "blkidP.h" @@ -101,6 +104,19 @@ static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type) return head; } +static bool tag_value_matches(const char *type, const char *expected, + const char *actual) +{ + if (!strcmp(type, "UUID") || !strcmp(type, "PARTUUID")) { + locale_t posix = newlocale(0, "POSIX", 0); + bool r = !strcasecmp_l(expected, actual, posix); + freelocale(posix); + return r; + } + + return !strcmp(expected, actual); +} + /* * Set a tag on an existing device. * @@ -345,7 +361,7 @@ try_again: blkid_tag tmp = list_entry(p, struct blkid_struct_tag, bit_names); - if (!strcmp(tmp->bit_val, value) && + if (tag_value_matches(type, tmp->bit_val, value) && (tmp->bit_dev->bid_pri > pri) && !access(tmp->bit_dev->bid_name, F_OK)) { dev = tmp->bit_dev; -- 2.31.1