From a8368721996bda5ecfdc55cf9ed6f1c9bce11bfc Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 16 Oct 2023 15:11:29 -0500 Subject: [PATCH] device_id: accept wwids containing QEMU HARDDISK A wwid may be useful even when it contains the string "QEMU HARDDISK", so allow these to be used. --- lib/device/device_id.c | 35 ++++++++++----- test/shell/devicesfile-vpd-ids.sh | 73 +++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 11 deletions(-) diff --git a/lib/device/device_id.c b/lib/device/device_id.c index 76320d98e..fb8f7307f 100644 --- a/lib/device/device_id.c +++ b/lib/device/device_id.c @@ -629,19 +629,11 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u struct dev_wwid *dw; unsigned i; - if (idtype == DEV_ID_TYPE_SYS_WWID) { + if (idtype == DEV_ID_TYPE_SYS_WWID) dev_read_sys_wwid(cmd, dev, sysbuf, sizeof(sysbuf), NULL); - /* FIXME: enable these QEMU t10 wwids */ - - /* qemu wwid begins "t10.ATA QEMU HARDDISK ..." */ - if (strstr(sysbuf, "QEMU HARDDISK")) - sysbuf[0] = '\0'; - } - - else if (idtype == DEV_ID_TYPE_SYS_SERIAL) { + else if (idtype == DEV_ID_TYPE_SYS_SERIAL) _dev_read_sys_serial(cmd, dev, sysbuf, sizeof(sysbuf)); - } else if (idtype == DEV_ID_TYPE_MPATH_UUID) { read_sys_block(cmd, dev, "dm/uuid", sysbuf, sizeof(sysbuf)); @@ -833,6 +825,22 @@ static int _dev_has_stable_id(struct cmd_context *cmd, struct device *dev) * system_read.) */ dm_list_iterate_items(id, &dev->ids) { + /* + * An unfortunate special case to work around a previous lvm version + * where wwid's containing "QEMU HARDDISK" were ignored, which would + * generally cause the device to have IDTYPE=devname. On reboot, + * when the dev name changes, the search for a new device may use + * the search_for_devnames="auto" setting which uses this function + * to decide if a dev should be checked as the renamed device or not. + * It's not if it has a wwid, since the renamed dev we're looking for + * would be using sys_wwid if it had a wwid. Now that QEMU wwids + * are used, we still have to check devs with a QEMU wwid to see if + * it's the renamed dev. + */ + if (((id->idtype == DEV_ID_TYPE_SYS_WWID) || (id->idtype == DEV_ID_TYPE_WWID_T10)) && + id->idname && strstr(id->idname, "QEMU")) + continue; + if ((id->idtype != DEV_ID_TYPE_DEVNAME) && id->idname) return 1; } @@ -843,8 +851,13 @@ static int _dev_has_stable_id(struct cmd_context *cmd, struct device *dev) */ if ((idname = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID))) { + /* see comment above */ + if (!strstr(idname, "QEMU")) { + free((void*)idname); + return 1; + } free((void*)idname); - return 1; + return 0; } if ((idname = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_SERIAL))) { diff --git a/test/shell/devicesfile-vpd-ids.sh b/test/shell/devicesfile-vpd-ids.sh index 74dbebb18..428a933d0 100644 --- a/test/shell/devicesfile-vpd-ids.sh +++ b/test/shell/devicesfile-vpd-ids.sh @@ -16,6 +16,10 @@ SKIP_WITH_LVMPOLLD=1 . lib/inittest +aux lvmconf 'devices/global_filter = [ "a|.*|" ]' \ + 'devices/filter = [ "a|.*|" ]' + + SYS_DIR="sys" # requires trailing / to match dm aux lvmconf "devices/device_id_sysfs_dir = \"$PWD/$SYS_DIR/\"" \ @@ -499,6 +503,75 @@ grep "IDTYPE=devname" "$DF" | tee out grep "IDNAME=$DEV1" out cleanup_sysfs +# +# Test wwid containing "QEMU HARDDISK". +# These wwids were once ignored. When the qemu wwid +# was ignored, the dev would likely have used IDTYPE=devname. +# When that dev is renamed on reboot, it needs to be found +# on the device with the qemu wwid. +# The original logic behind search_for_devnames="auto" would +# have ignored any device with a wwid when searching for the +# renamed device (since devs with wwids would not use the +# devname idtype.) However, in this case, a device with the +# qemu wwid does use the devname idtype and needs to be checked, +# so it's a special case in the code to look at devs with +# any qemu wwid. +# +aux lvmconf "devices/search_for_devnames = \"auto\"" + +rm "$DF" +aux wipefs_a "$DEV1" +touch "$DF" +pvcreate "$DEV1" +vgcreate $vg1 "$DEV1" +cat "$DF" +grep "IDTYPE=devname" "$DF" | tee out +grep "IDNAME=$DEV1" out +mkdir -p "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device" +echo -n "0QEMU QEMU HARDDISK 1" > "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid" +pvs -o+uuid,deviceidtype,deviceid "$DEV1" +# Rename device, simulating reboot +sed -e "s|IDNAME=$DEV1|IDNAME=/dev/sdx|" "$DF" > tmpdf +sed -e "s|DEVNAME=$DEV1|DEVNAME=/dev/sdx|" tmpdf > "$DF" +cat "$DF" +# pvs will find PV on DEV1 and fix IDNAME +pvs -o+uuid,deviceidtype,deviceid | tee out +grep "$DEV1" out +grep "IDTYPE=devname" "$DF" | tee out +grep "IDNAME=$DEV1" out +rm "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid" +cleanup_sysfs + +# set search_for_devnames="auto" +# set wwid with QEMU HARDDISK for the disk +# add disk to system.devices, should use the wwid +# pvs should find the disk by wwid +# rename the DEVNAME field +# pvs should fix DEVNAME field + +rm "$DF" +aux wipefs_a "$DEV1" +mkdir -p "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device" +echo -n "t10.ATA QEMU HARDDISK QM00002 " > "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid" +touch "$DF" +pvcreate "$DEV1" +vgcreate $vg1 "$DEV1" +cat "$DF" +grep 'IDTYPE=sys_wwid' "$DF" | tee out +grep "QEMU_HARDDISK" out +pvs -o+uuid,deviceidtype,deviceid | tee out +grep "$DEV1" out +grep sys_wwid out +grep "QEMU_HARDDISK" out +sed -e "s|DEVNAME=$DEV1|DEVNAME=/dev/sdx|" "$DF" > tmpdf +cp tmpdf "$DF" +cat "$DF" +pvs -o+uuid,deviceidtype,deviceid "$DEV1" +grep "DEVNAME=$DEV1" "$DF" +rm "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid" +cleanup_sysfs + + # TODO: lvmdevices --adddev --deviceidtype --deviceid # This would let the user specify the second naa wwid.