Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=908555459f0abbcda6878…
Commit: 908555459f0abbcda687882439589209528e1dc0
Parent: f6f2737015746b1b6c7fbd0d297a4596c584749b
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Oct 12 14:41:58 2022 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Oct 12 15:14:59 2022 +0200
toollib: do not process just created historical LV
When executing process_each_lv_in_vg, we process live LVs first and
after that, we process any historical LVs. In case we have just removed
an LV, which also means we have just made it "historical" and so it
appears as fresh item in vg->historical_lvs list, we have to skip it
when we get to processing historical LVs inside the same process_each_lv_in_vg
call.
The simplest approach here, without introducing another LV list, is to
simply mark such historical LVs as "fresh" directly in struct
historical_logical_volume when we have just removed the original LV
and created the historical LV for it. Then, we just need to check the
flag when processing historical LVs and skip it if it is "fresh".
When we read historical LVs out of metadata, they are marked as
"not fresh" and so they can be processed as usual.
This was mainly an issue in conjuction with -S|--select use:
# lvmconfig --type diff
metadata {
record_lvs_history=1
}
(In this example, a thin pool with lvol1 thin LV and lvol2 and lvol3 snapshots.)
# lvs -H vg -o name,pool_lv,full_ancestors,full_descendants
LV Pool FAncestors FDescendants
lvol1 pool lvol2,lvol3
lvol2 pool lvol1 lvol3
lvol3 pool lvol2,lvol1
pool
# lvremove -S 'name=lvol2'
Logical volume "lvol2" successfully removed.
Historical logical volume "lvol2" successfully removed.
...here, the historical LV lvol2 should not have been removed because
we have just removed its original non-historical lvol2 and the fresh
historical lvol2 must not be included in the same processing spree.
---
WHATS_NEW | 1 +
lib/metadata/lv.h | 1 +
lib/metadata/pool_manip.c | 1 +
tools/toollib.c | 3 +++
4 files changed, 6 insertions(+)
diff --git a/WHATS_NEW b/WHATS_NEW
index e29ec7066..2942b0e53 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.03.17 -
===============================
+ Fix 'lvremove -S|--select LV' to not also remove its historical LV right away.
Fix lv_active field type to binary so --select and --binary applies properly.
Switch to use mallinfo2 and use it only with glibc.
Error out in lvm shell if using a cmd argument not supported in the shell.
diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h
index 304ee2f7d..e591a9510 100644
--- a/lib/metadata/lv.h
+++ b/lib/metadata/lv.h
@@ -93,6 +93,7 @@ struct historical_logical_volume {
struct dm_list indirect_glvs; /* list of struct generic_logical_volume */
unsigned checked:1; /* set if this historical LV has been checked for validity */
unsigned valid:1; /* historical LV is valid if there's at least one live LV among ancestors */
+ unsigned fresh:1; /* historical LV has just been created (the original LV just removed) */
};
struct generic_logical_volume {
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index a6bfc2deb..559b07ba8 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -169,6 +169,7 @@ static struct glv_list *_init_historical_glvl(struct dm_pool *mem, struct lv_seg
hlv->name = seg->lv->name;
hlv->vg = seg->lv->vg;
hlv->timestamp = seg->lv->timestamp;
+ hlv->fresh = 1;
dm_list_init(&hlv->indirect_glvs);
glvl->glv->is_historical = 1;
diff --git a/tools/toollib.c b/tools/toollib.c
index e45afb6ee..5305e811b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3450,6 +3450,9 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
goto_out;
}
+ if (glvl->glv->historical->fresh)
+ continue;
+
process_lv = process_all;
if (lvargs_supplied &&
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fc52e87f06959f542ea78…
Commit: fc52e87f06959f542ea78b75df104bc6c85fd973
Parent: 657df00c9615ea5abb6faf4c21f01f90de17b207
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Oct 11 11:28:19 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Oct 11 12:48:31 2022 -0500
tests: add comments to fsadm-renamed
to explain the what and why of the steps that are
not obvious
---
test/shell/fsadm-renamed.sh | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/test/shell/fsadm-renamed.sh b/test/shell/fsadm-renamed.sh
index 5e2e2ed78..698b143cf 100644
--- a/test/shell/fsadm-renamed.sh
+++ b/test/shell/fsadm-renamed.sh
@@ -83,29 +83,44 @@ echo "$i"
# https://github.com/systemd/systemd/pull/2017
aux udev_wait
+# mount /dev/test/lv1 on /mnt
mount "$dev_vg_lv" "$mount_dir"
aux udev_wait
+# rename lv1 to lv1_renamed, now /dev/test/lv1_renamed is mounted on /mnt,
+# but "df" and "mount" commands will still show /dev/test/lv1 mounted on /mnt.
lvrename $vg_lv $vg_lv_ren
check_mounted
# fails on renamed LV
+# lvextend -r test/lv1_renamed succeeds in extending the LV (as lv1_renamed),
+# but xfs_growfs /dev/test/lv1_renamed fails because it doesn't recognize
+# that device is mounted, because the old lv name reported as being mounted.
fail lvresize -y -L+10M -r $vg_lv_ren
# fails on unknown mountpoint (FIXME: umount)
not umount "$dev_vg_lv"
+# create a new LV with the previous name of the renamed lv
lvcreate -L300 -n $lv1 $vg
"$i" $MKFS_ARGS "$dev_vg_lv"
aux udev_wait
+# mount the new lv on a dir with a similar name as the other
+# now df will show
+# /dev/mapper/test-lv1 ... /mnt
+# /dev/mapper/test-lv1 ... /mnt $SPACE dir
mount "$dev_vg_lv" "$mount_dolar_dir"
check_mounted
+# try to resize the LV that was renamed: lvextend -r test/lv1_renamed
+# this succeeds in extending the LV (lv1_renamed), but xfs_growfs fails
+# for the same reason as above, i.e. mount doesn't show the lv1_renamed
+# device is mounted anywhere.
not lvresize -L+10M -r $vg_lv_ren
umount "$mount_dir"
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=79e67fc5e4f28d19fe4d9…
Commit: 79e67fc5e4f28d19fe4d93e6831a3a60e9760b68
Parent: 8de87e0207342b0142778ebe9c51f0d552adfab8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 31 16:05:07 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Oct 10 11:47:29 2022 -0500
device id: add new types using values from vpd_pg83
The new device_id types are: wwid_naa, wwid_eui, wwid_t10.
The new types use the specific wwid type in their name.
lvm currently gets the values for these types by reading
the device's vpd_pg83 sysfs file (this could change in the
future if better methods become available for reading the
values.)
If a device is added to the devices file using one of these
types, prior versions of lvm will not recognize the types
and will be unable to use the devices.
When adding a new device, lvm continues to first use sys_wwid
from the sysfs wwid file. If the device has no sysfs wwid file,
lvm now attempts to use one of the new types from vpd_pg83.
If a devices file entry with type sys_wwid does not match a
given device's sysfs wwid file, the sys_wwid value will also
be compared to that device's other wwids from its vpd_pg83 file.
If the kernel changes the wwid type reported from the sysfs
wwid file, e.g. from a device's t10 id to its naa id, then lvm
should still be able to match it correctly using the vpd_pg83
data which will include both ids.
---
lib/config/config_settings.h | 3 ++
lib/config/defaults.h | 2 +
lib/device/device.h | 4 ++
lib/device/device_id.c | 103 ++++++++++++++++++++++++++++++++++++++++++-
lib/device/device_id.h | 2 +
5 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index b172c7c5f..699b40bd0 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -224,6 +224,9 @@ cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADV
"Directory in which to create volume group device nodes.\n"
"Commands also accept this as a prefix on volume group names.\n")
+cfg(devices_device_id_sysfs_dir_CFG, "device_id_sysfs_dir", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_UNSUPPORTED, CFG_TYPE_STRING, DEFAULT_DEVICE_ID_SYSFS_DIR, vsn(2, 3, 17), NULL, 0, NULL,
+ "Location of sysfs for finding device ids (for testing.)\n")
+
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL, 0, NULL,
"Directories containing device nodes to use with LVM.\n")
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 3308b1ea6..571054dc4 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -332,4 +332,6 @@
#define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online"
#define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup"
+#define DEFAULT_DEVICE_ID_SYSFS_DIR "/sys/" /* trailing / to match dm_sysfs_dir() */
+
#endif /* _LVM_DEFAULTS_H */
diff --git a/lib/device/device.h b/lib/device/device.h
index 89173a840..ca46490ce 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -67,7 +67,11 @@ struct dev_ext {
#define DEV_ID_TYPE_CRYPT_UUID 6
#define DEV_ID_TYPE_LVMLV_UUID 7
#define DEV_ID_TYPE_DEVNAME 8
+#define DEV_ID_TYPE_WWID_NAA 9
+#define DEV_ID_TYPE_WWID_EUI 10
+#define DEV_ID_TYPE_WWID_T10 11
+/* Max length of WWID_NAA, WWID_EUI, WWID_T10 */
#define DEV_WWID_SIZE 128
/*
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 5481bb6b0..6383f69fb 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -188,13 +188,17 @@ static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
int binary, int *retlen)
{
char path[PATH_MAX];
+ const char *sysfs_dir;
dev_t devt = dev->dev;
dev_t prim = 0;
int ret;
+ if (!(sysfs_dir = find_config_tree_str(cmd, devices_device_id_sysfs_dir_CFG, NULL)))
+ sysfs_dir = dm_sysfs_dir();
+
retry:
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/%s",
- dm_sysfs_dir(), (int)MAJOR(devt), (int)MINOR(devt), suffix) < 0) {
+ sysfs_dir, (int)MAJOR(devt), (int)MINOR(devt), suffix) < 0) {
log_error("Failed to create sysfs path for %s", dev_name(dev));
return 0;
}
@@ -338,6 +342,26 @@ static int _wwid_type_num(char *id)
return -1;
}
+int wwid_type_to_idtype(int wwid_type)
+{
+ switch (wwid_type) {
+ case 3: return DEV_ID_TYPE_WWID_NAA;
+ case 2: return DEV_ID_TYPE_WWID_EUI;
+ case 1: return DEV_ID_TYPE_WWID_T10;
+ default: return -1;
+ }
+}
+
+int idtype_to_wwid_type(int idtype)
+{
+ switch (idtype) {
+ case DEV_ID_TYPE_WWID_NAA: return 3;
+ case DEV_ID_TYPE_WWID_EUI: return 2;
+ case DEV_ID_TYPE_WWID_T10: return 1;
+ default: return -1;
+ }
+}
+
void free_wwids(struct dm_list *ids)
{
struct dev_wwid *dw, *safe;
@@ -436,6 +460,7 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
{
char sysbuf[PATH_MAX] = { 0 };
const char *idname = NULL;
+ struct dev_wwid *dw;
int i;
if (idtype == DEV_ID_TYPE_SYS_WWID) {
@@ -485,6 +510,18 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
return idname;
}
+ else if (idtype == DEV_ID_TYPE_WWID_NAA ||
+ idtype == DEV_ID_TYPE_WWID_EUI ||
+ idtype == DEV_ID_TYPE_WWID_T10) {
+ if (!(dev->flags & DEV_ADDED_VPD_WWIDS))
+ dev_read_vpd_wwids(cmd, dev);
+ dm_list_iterate_items(dw, &dev->wwids) {
+ if (idtype_to_wwid_type(idtype) == dw->type)
+ return strdup(dw->id);
+ }
+ return NULL;
+ }
+
/* wwids are already munged if needed */
if (idtype != DEV_ID_TYPE_SYS_WWID) {
for (i = 0; i < strlen(sysbuf); i++) {
@@ -591,6 +628,12 @@ const char *idtype_to_str(uint16_t idtype)
return "md_uuid";
if (idtype == DEV_ID_TYPE_LOOP_FILE)
return "loop_file";
+ if (idtype == DEV_ID_TYPE_WWID_NAA)
+ return "wwid_naa";
+ if (idtype == DEV_ID_TYPE_WWID_EUI)
+ return "wwid_eui";
+ if (idtype == DEV_ID_TYPE_WWID_T10)
+ return "wwid_t10";
return "unknown";
}
@@ -612,6 +655,12 @@ uint16_t idtype_from_str(const char *str)
return DEV_ID_TYPE_MD_UUID;
if (!strcmp(str, "loop_file"))
return DEV_ID_TYPE_LOOP_FILE;
+ if (!strcmp(str, "wwid_naa"))
+ return DEV_ID_TYPE_WWID_NAA;
+ if (!strcmp(str, "wwid_eui"))
+ return DEV_ID_TYPE_WWID_EUI;
+ if (!strcmp(str, "wwid_t10"))
+ return DEV_ID_TYPE_WWID_T10;
return 0;
}
@@ -1202,13 +1251,26 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
/*
* No device-specific, existing, or user-specified idtypes,
- * so use first available of sys_wwid / sys_serial / devname.
+ * so use first available of sys_wwid, wwid_naa, wwid_eui,
+ * wwid_t10, sys_serial, devname.
*/
idtype = DEV_ID_TYPE_SYS_WWID;
if ((idname = device_id_system_read(cmd, dev, idtype)))
goto id_done;
+ idtype = DEV_ID_TYPE_WWID_NAA;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+
+ idtype = DEV_ID_TYPE_WWID_EUI;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+
+ idtype = DEV_ID_TYPE_WWID_T10;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+
idtype = DEV_ID_TYPE_SYS_SERIAL;
if ((idname = device_id_system_read(cmd, dev, idtype)))
goto id_done;
@@ -1731,6 +1793,43 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), idname ?: ".");
*/
+ /*
+ * Make the du match this device if the dev has a vpd_pg83 wwid
+ * that matches du->idname, even if the sysfs wwid for dev did
+ * not match the du->idname. This could happen if sysfs changes
+ * which wwid it reports (there are often multiple), or if lvm in
+ * the future selects a sys_wwid value from vpd_pg83 data rather
+ * than from the sysfs wwid.
+ *
+ * TODO: update the df entry IDTYPE somewhere?
+ */
+ if (du->idtype == DEV_ID_TYPE_SYS_WWID) {
+ struct dev_wwid *dw;
+
+ if (!(dev->flags & DEV_ADDED_VPD_WWIDS))
+ dev_read_vpd_wwids(cmd, dev);
+
+ dm_list_iterate_items(dw, &dev->wwids) {
+ if (!strcmp(dw->id, du->idname)) {
+ if (!(id = zalloc(sizeof(struct dev_id))))
+ return_0;
+ /* wwid types are 1,2,3 and idtypes are DEV_ID_TYPE_ */
+ id->idtype = wwid_type_to_idtype(dw->type);
+ id->idname = strdup(dw->id);
+ id->dev = dev;
+ dm_list_add(&dev->ids, &id->list);
+ du->dev = dev;
+ dev->id = id;
+ dev->flags |= DEV_MATCHED_USE_ID;
+ log_print("Match device_id %s %s to vpd_pg83 %s %s",
+ idtype_to_str(du->idtype), du->idname,
+ idtype_to_str(id->idtype), dev_name(dev));
+ du->idtype = id->idtype;
+ return 1;
+ }
+ }
+ }
+
return 0;
}
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 46ab33784..6962925df 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -63,6 +63,8 @@ int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
+int wwid_type_to_idtype(int wwid_type);
+int idtype_to_wwid_type(int idtype);
void free_wwids(struct dm_list *ids);
struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids);
int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev);
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8de87e0207342b0142778…
Commit: 8de87e0207342b0142778ebe9c51f0d552adfab8
Parent: 380ab3f45c48f016fcebe4105bb94b8f024bae71
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 31 15:59:28 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Oct 10 11:47:29 2022 -0500
device id: change space handling in t10 wwid
t10 wwids are now edited in the same way that multipath does,
which is replacing a series of spaces with one _. Previously
lvm replaced every space with one _. Devices file entries
with the old form will be converted to the new shorter form.
---
lib/device/device_id.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 3dd428df8..5481bb6b0 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -400,6 +400,7 @@ int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev)
int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
char *buf, int bufsize, struct dev_wwid **dw_out)
{
+ char tmpbuf[DEV_WWID_SIZE];
struct dev_wwid *dw;
int ret;
@@ -413,6 +414,15 @@ int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
if (!ret || !buf[0])
return 0;
+ /* in t10 id, replace series of spaces with one _ */
+ if (!strncmp(buf, "t10.", 4) && strchr(buf, ' ')) {
+ if (bufsize < DEV_WWID_SIZE)
+ return 0;
+ memcpy(tmpbuf, buf, DEV_WWID_SIZE);
+ memset(buf, 0, bufsize);
+ format_t10_id((const unsigned char *)tmpbuf, DEV_WWID_SIZE, (unsigned char *)buf, bufsize);
+ }
+
/* Note, if wwids are also read from vpd, this same wwid will be added again. */
if (!(dw = dev_add_wwid(buf, 0, &dev->wwids)))
@@ -475,9 +485,12 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
return idname;
}
- for (i = 0; i < strlen(sysbuf); i++) {
- if (isblank(sysbuf[i]) || isspace(sysbuf[i]) || iscntrl(sysbuf[i]))
- sysbuf[i] = '_';
+ /* wwids are already munged if needed */
+ if (idtype != DEV_ID_TYPE_SYS_WWID) {
+ for (i = 0; i < strlen(sysbuf); i++) {
+ if (isblank(sysbuf[i]) || isspace(sysbuf[i]) || iscntrl(sysbuf[i]))
+ sysbuf[i] = '_';
+ }
}
if (!sysbuf[0])
@@ -1551,6 +1564,28 @@ static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
return 0;
}
+static void _reduce_underscores(char *in, int in_len, char *out, int out_size)
+{
+ int us = 0, i, j = 0;
+
+ for (i = 0; i < in_len; i++) {
+ if (in[i] == '_')
+ us++;
+ else
+ us = 0;
+
+ if (us == 1)
+ out[j++] = '_';
+ else if (us > 1)
+ continue;
+ else
+ out[j++] = in[i];
+
+ if (j == out_size)
+ break;
+ }
+}
+
/*
* du is a devices file entry. dev is any device on the system.
* check if du is for dev by comparing the device's ids to du->idname.
@@ -1564,6 +1599,7 @@ static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct device *dev)
{
+ char du_t10[DEV_WWID_SIZE] = { 0 };
struct dev_id *id;
const char *idname;
int part;
@@ -1613,6 +1649,16 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
return 0;
}
+ /*
+ * Devices file entries with IDTYPE=sys_wwid and a T10 WWID
+ * for IDNAME were saved in the past with each space replaced
+ * by one _. Now we convert multiple spaces to a single _.
+ * So, convert a df entry with the old style to the new shorter
+ * style to compare.
+ */
+ if (du->idtype == DEV_ID_TYPE_SYS_WWID && !strncmp(du->idname, "t10", 3) && strstr(du->idname, "__"))
+ _reduce_underscores(du->idname, strlen(du->idname), du_t10, sizeof(du_t10) - 1);
+
/*
* Try to match du with ids that have already been read for the dev
* (and saved on dev->ids to avoid rereading.)
@@ -1636,6 +1682,15 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
idtype_to_str(du->idtype), du->idname, dev_name(dev));
return 1;
+ } else if ((id->idtype == DEV_ID_TYPE_SYS_WWID) && !strncmp(id->idname, "t10", 3) &&
+ du_t10[0] && !strcmp(id->idname, du_t10)) {
+ /* Compare the shorter form du t10 wwid to the dev t10 wwid. */
+ du->dev = dev;
+ dev->id = id;
+ dev->flags |= DEV_MATCHED_USE_ID;
+ log_debug("Match device_id %s %s to %s",
+ idtype_to_str(du->idtype), du->idname, dev_name(dev));
+ return 1;
} else {
/*
log_debug("Mismatch device_id %s %s to %s: idname %s",
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=380ab3f45c48f016fcebe…
Commit: 380ab3f45c48f016fcebe4105bb94b8f024bae71
Parent: 39e6c4f749e97c0efae116e1fa0dbc25451de80e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Aug 30 15:10:52 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Oct 10 11:47:29 2022 -0500
device id wwid adjustments
Move the functions handling dev wwids.
Add dev flags indicating that wwids have been read from
sysfs wwid file or sysfs vpd_pg83 file. This can be
used to avoid rereading these.
Improve filter-mpath search for a device's wwid in
/etc/multipath/wwids, to avoid unnecessary rereading
of wwids from sysfs files.
Type 8 wwids from vpd_pg83 with naa or eui names should be
saved as those types.
---
lib/device/dev-mpath.c | 156 ++++++++----------------------------
lib/device/device.h | 39 +++++----
lib/device/device_id.c | 209 ++++++++++++++++++++++++++++++++++++++-----------
lib/device/device_id.h | 6 ++
lib/device/parse_vpd.c | 26 ++++--
5 files changed, 244 insertions(+), 192 deletions(-)
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
index 2040edac3..3679e4428 100644
--- a/lib/device/dev-mpath.c
+++ b/lib/device/dev-mpath.c
@@ -601,114 +601,12 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
return is_mpath_component;
}
-static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev,
- char *idbuf, int idbufsize)
-{
- char idtmp[DEV_WWID_SIZE];
-
- if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) {
- /* the wwid file is not under device for nvme devs */
- if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize))
- return 0;
- }
- if (!idbuf[0])
- return 0;
-
- /* in t10 id, replace series of spaces with one _ like multipath */
- if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) {
- if (idbufsize < DEV_WWID_SIZE)
- return 0;
- memcpy(idtmp, idbuf, DEV_WWID_SIZE);
- memset(idbuf, 0, idbufsize);
- format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize);
- }
- return 1;
-}
-
-#define VPD_SIZE 4096
-
-static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev,
- struct dm_list *ids)
-{
- unsigned char vpd_data[VPD_SIZE] = { 0 };
- int vpd_datalen = 0;
-
- if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
- return 0;
- if (!vpd_datalen)
- return 0;
-
- /* adds dev_wwid entry to dev->wwids for each id in vpd data */
- parse_vpd_ids(vpd_data, vpd_datalen, ids);
- return 1;
-}
-
-void free_wwids(struct dm_list *ids)
-{
- struct dev_wwid *dw, *safe;
-
- dm_list_iterate_items_safe(dw, safe, ids) {
- dm_list_del(&dw->list);
- free(dw);
- }
-}
-
-static int _wwid_type_num(char *id)
-{
- if (!strncmp(id, "naa.", 4))
- return 3;
- else if (!strncmp(id, "eui.", 4))
- return 2;
- else if (!strncmp(id, "t10.", 4))
- return 1;
- else
- return -1;
-}
-
-/*
- * TODO: if each of the different wwid types (naa/eui/t10) were
- * represented by different DEV_ID_TYPE_FOO values, and used
- * as device_id types, then we could drop struct dev_wwid and
- * drop dev->wwids, and just use dev->ids for each of the
- * different wwids found in vpd_pg83. This would also require
- * the ability to handle both the original method of replacing
- * every space in the id string with _ and the new/multipath
- * format_t10_id replacing series of spaces with one _.
- */
-struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids)
-{
- struct dev_wwid *dw;
- int len;
-
- if (!id_type) {
- id_type = _wwid_type_num(id);
- if (id_type == -1)
- log_debug("unknown wwid type %s", id);
- }
-
- if (!(dw = zalloc(sizeof(struct dev_wwid))))
- return NULL;
- len = strlen(id);
- if (len >= DEV_WWID_SIZE)
- len = DEV_WWID_SIZE - 1;
- memcpy(dw->id, id, len);
- dw->type = id_type;
- dm_list_add(ids, &dw->list);
- return dw;
-}
-
-/*
- * we save ids with format: naa.<value>, eui.<value>, t10.<value>.
- * multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
- * The values are saved in wwid_hash_tab without the type prefix.
- */
-
static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
int primary_result, dev_t primary_dev)
{
char idbuf[DEV_WWID_SIZE] = { 0 };
struct dev_wwid *dw;
- char *wwid;
+ char *wwid, *full_wwid;
if (!_wwid_hash_tab)
return 0;
@@ -724,42 +622,54 @@ static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
}
/*
- * This function may be called multiple times for the same device, in
- * particular if partitioned for each partition.
+ * sysfs wwid uses format: naa.<value>, eui.<value>, t10.<value>.
+ * multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
+ *
+ * We omit the type prefix before looking up. The multipath/wwids
+ * values in the wwid_hash_tab have the initial character removed.
+ *
+ * There's no type prefix for "scsi name string" type 8 ids.
+ *
+ * First try looking up any wwids that have already been read.
*/
- if (!dm_list_empty(&dev->wwids))
- goto lookup;
+lookup:
+ dm_list_iterate_items(dw, &dev->wwids) {
+ if (dw->type == 1 || dw->type == 2 || dw->type == 3)
+ wwid = &dw->id[4];
+ else
+ wwid = dw->id;
- /*
- * Get all the ids for the device from vpd_pg83 and check if any of
- * those are in /etc/multipath/wwids. These ids should include the
- * value printed from the sysfs wwid file.
- */
- _read_sys_vpd_wwids(cmd, dev, &dev->wwids);
- if (!dm_list_empty(&dev->wwids))
- goto lookup;
+ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
+ full_wwid = dw->id;
+ goto found;
+ }
+ }
/*
- * This will read the sysfs wwid file, nvme devices in particular have
- * a wwid file but not a vpd_pg83 file.
+ * The id from sysfs wwid may not be the id used by multipath,
+ * or a device may not have a vpd_pg83 file (e.g. nvme).
*/
- if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf)))
- add_wwid(idbuf, 0, &dev->wwids);
- lookup:
- dm_list_iterate_items(dw, &dev->wwids) {
+ if (!(dev->flags & DEV_ADDED_VPD_WWIDS) && dev_read_vpd_wwids(cmd, dev))
+ goto lookup;
+
+ if (!(dev->flags & DEV_ADDED_SYS_WWID) && dev_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf), &dw)) {
if (dw->type == 1 || dw->type == 2 || dw->type == 3)
wwid = &dw->id[4];
else
wwid = dw->id;
if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
- log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id);
- return 1;
+ full_wwid = dw->id;
+ goto found;
}
}
return 0;
+
+ found:
+ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), full_wwid);
+ return 1;
}
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *holder_devno)
diff --git a/lib/device/device.h b/lib/device/device.h
index 06440f44b..89173a840 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -32,8 +32,8 @@
#define DEV_NOT_O_NOATIME 0x00000400 /* Don't use O_NOATIME */
#define DEV_IN_BCACHE 0x00000800 /* dev fd is open and used in bcache */
#define DEV_BCACHE_EXCL 0x00001000 /* bcache_fd should be open EXCL */
-/* unused 0x00002000 */
-/* unused 0x00004000 */
+#define DEV_ADDED_SYS_WWID 0x00002000 /* wwid has been added from sysfs wwid file */
+#define DEV_ADDED_VPD_WWIDS 0x00004000 /* wwids have been added from vpd_pg83 */
#define DEV_BCACHE_WRITE 0x00008000 /* bcache_fd is open with RDWR */
#define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
@@ -59,23 +59,30 @@ struct dev_ext {
void *handle;
};
+#define DEV_ID_TYPE_SYS_WWID 1
+#define DEV_ID_TYPE_SYS_SERIAL 2
+#define DEV_ID_TYPE_MPATH_UUID 3
+#define DEV_ID_TYPE_MD_UUID 4
+#define DEV_ID_TYPE_LOOP_FILE 5
+#define DEV_ID_TYPE_CRYPT_UUID 6
+#define DEV_ID_TYPE_LVMLV_UUID 7
+#define DEV_ID_TYPE_DEVNAME 8
+
#define DEV_WWID_SIZE 128
+/*
+ * A wwid read from:
+ * /sys/dev/block/%d:%d/device/wwid
+ * /sys/dev/block/%d:%d/wwid
+ * /sys/dev/block/%d:%d/device/vpd_pg83
+ */
+
struct dev_wwid {
- struct dm_list list;
- int type;
- char id[DEV_WWID_SIZE];
+ struct dm_list list; /* dev->wwids */
+ int type; /* 1,2,3 for NAA,EUI,T10 */
+ char id[DEV_WWID_SIZE]; /* includes prefix naa.,eui.,t10. */
};
-#define DEV_ID_TYPE_SYS_WWID 0x0001
-#define DEV_ID_TYPE_SYS_SERIAL 0x0002
-#define DEV_ID_TYPE_MPATH_UUID 0x0003
-#define DEV_ID_TYPE_MD_UUID 0x0004
-#define DEV_ID_TYPE_LOOP_FILE 0x0005
-#define DEV_ID_TYPE_CRYPT_UUID 0x0006
-#define DEV_ID_TYPE_LVMLV_UUID 0x0007
-#define DEV_ID_TYPE_DEVNAME 0x0008
-
/*
* A device ID of a certain type for a device.
* A struct device may have multiple dev_id structs on dev->ids.
@@ -83,7 +90,7 @@ struct dev_wwid {
*/
struct dev_id {
- struct dm_list list;
+ struct dm_list list; /* dev->ids */
struct device *dev;
uint16_t idtype; /* DEV_ID_TYPE_ */
char *idname; /* id string determined by idtype */
@@ -215,8 +222,6 @@ void dev_destroy_file(struct device *dev);
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);
-struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids);
-void free_wwids(struct dm_list *ids);
int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids);
int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes);
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index a0a626533..3dd428df8 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -168,7 +168,8 @@ void free_dus(struct dm_list *dus)
void free_did(struct dev_id *id)
{
- free(id->idname);
+ if (strlen(id->idname))
+ free(id->idname); /* idname = "" when id type doesn't exist */
free(id);
}
@@ -321,6 +322,106 @@ static int _dev_has_lvmlv_uuid(struct cmd_context *cmd, struct device *dev, cons
return 1;
}
+/*
+ * The numbers 1,2,3 for NAA,EUI,T10 are part of the standard
+ * and are used in the vpd data.
+ */
+static int _wwid_type_num(char *id)
+{
+ if (!strncmp(id, "naa.", 4))
+ return 3;
+ else if (!strncmp(id, "eui.", 4))
+ return 2;
+ else if (!strncmp(id, "t10.", 4))
+ return 1;
+ else
+ return -1;
+}
+
+void free_wwids(struct dm_list *ids)
+{
+ struct dev_wwid *dw, *safe;
+
+ dm_list_iterate_items_safe(dw, safe, ids) {
+ dm_list_del(&dw->list);
+ free(dw);
+ }
+}
+
+/*
+ * wwid type 8 "scsi name string" (which includes "iqn" names) is
+ * included in vpd_pg83, but we currently do not use these for
+ * device ids (maybe in the future.)
+ * They can still be checked by dev-mpath when looking for a device
+ * in /etc/multipath/wwids.
+ */
+
+struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids)
+{
+ struct dev_wwid *dw;
+ int len;
+
+ if (!id_type) {
+ id_type = _wwid_type_num(id);
+ if (id_type == -1)
+ log_debug("unknown wwid type %s", id);
+ }
+
+ if (!(dw = zalloc(sizeof(struct dev_wwid))))
+ return NULL;
+ len = strlen(id);
+ if (len >= DEV_WWID_SIZE)
+ len = DEV_WWID_SIZE - 1;
+ memcpy(dw->id, id, len);
+ dw->type = id_type;
+ dm_list_add(ids, &dw->list);
+ return dw;
+}
+
+#define VPD_SIZE 4096
+
+int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev)
+{
+ unsigned char vpd_data[VPD_SIZE] = { 0 };
+ int vpd_datalen = 0;
+
+ dev->flags |= DEV_ADDED_VPD_WWIDS;
+
+ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
+ return 0;
+ if (!vpd_datalen)
+ return 0;
+
+ /* adds dev_wwid entry to dev->wwids for each id in vpd data */
+ parse_vpd_ids(vpd_data, vpd_datalen, &dev->wwids);
+ return 1;
+}
+
+int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
+ char *buf, int bufsize, struct dev_wwid **dw_out)
+{
+ struct dev_wwid *dw;
+ int ret;
+
+ dev->flags |= DEV_ADDED_SYS_WWID;
+
+ ret = read_sys_block(cmd, dev, "device/wwid", buf, bufsize);
+ if (!ret || !buf[0]) {
+ /* the wwid file is not under device for nvme devs */
+ ret = read_sys_block(cmd, dev, "wwid", buf, bufsize);
+ }
+ if (!ret || !buf[0])
+ return 0;
+
+ /* Note, if wwids are also read from vpd, this same wwid will be added again. */
+
+ if (!(dw = dev_add_wwid(buf, 0, &dev->wwids)))
+ return_0;
+ if (dw_out)
+ *dw_out = dw;
+ return 1;
+}
+
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype)
{
char sysbuf[PATH_MAX] = { 0 };
@@ -328,10 +429,9 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
int i;
if (idtype == DEV_ID_TYPE_SYS_WWID) {
- read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf));
+ dev_read_sys_wwid(cmd, dev, sysbuf, sizeof(sysbuf), NULL);
- if (!sysbuf[0])
- read_sys_block(cmd, dev, "wwid", sysbuf, sizeof(sysbuf));
+ /* FIXME: enable these QEMU t10 wwids */
/* qemu wwid begins "t10.ATA QEMU HARDDISK ..." */
if (strstr(sysbuf, "QEMU HARDDISK"))
@@ -450,6 +550,11 @@ static int _dev_has_stable_id(struct cmd_context *cmd, struct device *dev)
read_sys_block(cmd, dev, "md/uuid", sysbuf, sizeof(sysbuf)))
return 1;
+ if (!(dev->flags & DEV_ADDED_VPD_WWIDS))
+ dev_read_vpd_wwids(cmd, dev);
+ if (!dm_list_empty(&dev->wwids))
+ return 1;
+
out:
/* DEV_ID_TYPE_DEVNAME would be used for this dev. */
return 0;
@@ -1012,14 +1117,18 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
/*
* Choose the device_id type for the device being added.
- *
- * 0. use an idtype specified by the user
- * 1. use an idtype specific to a special/virtual device type
- * e.g. loop, mpath, crypt, lvmlv, md, etc.
- * 2. use an idtype specified by user option.
- * 3. use sys_wwid, if it exists.
- * 4. use sys_serial, if it exists.
- * 5. use devname as the last resort.
+ * possible breakage:
+ * . if the kernel changes what it prints from sys/wwid (e.g. from
+ * the t10 value to the naa value for the dev), this would break
+ * matching du to dev unless lvm tries to match all of the dev's
+ * different wwids from vpd_pg83 against sys_wwid entries.
+ * . adding a new device_id type into the devices file breaks prior
+ * lvm versions that attempt to use the devices file from the new
+ * lvm version.
+ * . using a value for sys_wwid that comes from vpd_pg83 and not
+ * sys/wwid (e.g. taking a naa wwid from vpd_pg83 when sys/wwid
+ * is printing the t10 wwid) would break prior lvm versions that
+ * only match a du against the sys/wwid values.
*/
if (idtype_arg) {
@@ -1060,36 +1169,44 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
/* TODO: kpartx partitions on loop devs. */
if (MAJOR(dev->dev) == cmd->dev_types->loop_major) {
idtype = DEV_ID_TYPE_LOOP_FILE;
- goto id_name;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+ goto id_last;
}
if (MAJOR(dev->dev) == cmd->dev_types->md_major) {
idtype = DEV_ID_TYPE_MD_UUID;
- goto id_name;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+ goto id_last;
}
if (MAJOR(dev->dev) == cmd->dev_types->drbd_major) {
/* TODO */
log_warn("Missing support for DRBD idtype");
+ goto id_last;
}
/*
* No device-specific, existing, or user-specified idtypes,
* so use first available of sys_wwid / sys_serial / devname.
*/
+
idtype = DEV_ID_TYPE_SYS_WWID;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
-id_name:
- if (!(idname = device_id_system_read(cmd, dev, idtype))) {
- if (idtype == DEV_ID_TYPE_SYS_WWID) {
- idtype = DEV_ID_TYPE_SYS_SERIAL;
- goto id_name;
- }
- idtype = DEV_ID_TYPE_DEVNAME;
- goto id_name;
- }
+ idtype = DEV_ID_TYPE_SYS_SERIAL;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
+id_last:
+ idtype = DEV_ID_TYPE_DEVNAME;
+ if ((idname = device_id_system_read(cmd, dev, idtype)))
+ goto id_done;
id_done:
+ if (!idname)
+ return_0;
/*
* Create a dev_id struct for the new idtype on dev->ids.
@@ -1101,7 +1218,9 @@ id_done:
}
}
- if (found_id && idname && strcmp(id->idname, idname)) {
+ if (found_id && idname && (!id->idname || strcmp(id->idname, idname))) {
+ log_debug("Replacing device id %s old %s new %s",
+ idtype_to_str(id->idtype), id->idname ?: ".", idname);
dm_list_del(&id->list);
free_did(id);
found_id = 0;
@@ -1433,8 +1552,13 @@ static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev,
}
/*
- * check for dev->ids entry with du->idtype, if found compare it,
- * if not, system_read of this type and add entry to dev->ids, compare it.
+ * du is a devices file entry. dev is any device on the system.
+ * check if du is for dev by comparing the device's ids to du->idname.
+ *
+ * check for a dev->ids entry with du->idtype, if found compare it,
+ * if not, system_read idtype for the dev, add entry to dev->ids,
+ * compare it to du to check if it matches.
+ *
* When a match is found, set up links among du/id/dev.
*/
@@ -1489,6 +1613,10 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
return 0;
}
+ /*
+ * Try to match du with ids that have already been read for the dev
+ * (and saved on dev->ids to avoid rereading.)
+ */
dm_list_iterate_items(id, &dev->ids) {
if (id->idtype == du->idtype) {
if ((id->idtype == DEV_ID_TYPE_DEVNAME) && _match_dm_devnames(cmd, dev, id, du)) {
@@ -1521,32 +1649,20 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
if (!(id = zalloc(sizeof(struct dev_id))))
return_0;
- if (!(idname = device_id_system_read(cmd, dev, du->idtype))) {
- /*
- * Save a new id in dev->ids for this type to indicate no match
- * to avoid repeated system_read, since this called many times.
- * Setting idtype and NULL idname means no id of this type.
- */
- id->idtype = du->idtype;
- id->dev = dev;
- dm_list_add(&dev->ids, &id->list);
- /*
- log_debug("Mismatch device_id %s %s to %s: no idtype",
- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev));
- */
- return 0;
- }
+ idname = device_id_system_read(cmd, dev, du->idtype);
/*
- * Save this id for the device (so it can be quickly checked again), even
- * if it's not the idtype used to identify the dev in device_id_file.
+ * Save this id for the dev, even if it doesn't exist (NULL)
+ * or doesn't match du. This avoids system_read of this idtype
+ * repeatedly, and the saved id will be found in the loop
+ * over dev->ids above.
*/
id->idtype = du->idtype;
- id->idname = (char *)idname;
+ id->idname = (char *)idname ?: (char *)"";
id->dev = dev;
dm_list_add(&dev->ids, &id->list);
- if (!strcmp(idname, du->idname)) {
+ if (idname && !strcmp(idname, du->idname)) {
du->dev = dev;
dev->id = id;
dev->flags |= DEV_MATCHED_USE_ID;
@@ -1557,8 +1673,9 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
/*
log_debug("Mismatch device_id %s %s to %s: idname %s",
- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), idname);
+ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), idname ?: ".");
*/
+
return 0;
}
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 9b9c9ce03..46ab33784 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -63,4 +63,10 @@ int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
+void free_wwids(struct dm_list *ids);
+struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids);
+int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev);
+int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev,
+ char *buf, int bufsize, struct dev_wwid **dw_out);
+
#endif
diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c
index 4bafa7b9e..99e8c0ec2 100644
--- a/lib/device/parse_vpd.c
+++ b/lib/device/parse_vpd.c
@@ -14,7 +14,9 @@
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
+#include "lib/commands/toolcontext.h"
#include "lib/device/device.h"
+#include "lib/device/device_id.h"
#include <stdio.h>
#include <unistd.h>
@@ -98,6 +100,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list
const unsigned char *d, *cur_id_str;
size_t id_len = ID_BUFSIZE;
int id_size = -1;
+ int type;
uint8_t cur_id_size = 0;
memset(id, 0, ID_BUFSIZE);
@@ -119,7 +122,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
- add_wwid(id, 1, ids);
+ dev_add_wwid(id, 1, ids);
break;
case 0x2:
/* EUI-64 */
@@ -145,7 +148,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
- add_wwid(id, 2, ids);
+ dev_add_wwid(id, 2, ids);
break;
case 0x3:
/* NAA */
@@ -167,7 +170,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
- add_wwid(id, 3, ids);
+ dev_add_wwid(id, 3, ids);
break;
case 0x8:
/* SCSI name string */
@@ -178,17 +181,28 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list
memcpy(id, cur_id_str, cur_id_size);
id_size = cur_id_size;
+ /*
+ * if naa or eui ids are provided as scsi names,
+ * consider them to be naa/eui types.
+ */
+ if (!memcmp(id, "eui.", 4))
+ type = 2;
+ else if (!memcmp(id, "naa.", 4))
+ type = 3;
+ else
+ type = 8;
+
/*
* Not in the kernel version, copying multipath code,
* which checks if this string begins with naa or eui
* and if so does tolower() on the chars.
*/
- if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) {
+ if ((type == 2) || (type == 3)) {
int i;
- for (i = 0; i < id_size; i++)
+ for (i = 0; i < strlen(id); i++)
id[i] = tolower(id[i]);
}
- add_wwid(id, 8, ids);
+ dev_add_wwid(id, type, ids);
break;
default:
break;