summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2022-08-31 15:59:28 -0500
committerDavid Teigland <teigland@redhat.com>2022-10-10 11:47:29 -0500
commit8de87e0207342b0142778ebe9c51f0d552adfab8 (patch)
tree745b1feeac709daf92861282ed1b8d6300ea3b56
parent380ab3f45c48f016fcebe4105bb94b8f024bae71 (diff)
downloadlvm2-8de87e0207342b0142778ebe9c51f0d552adfab8.tar.gz
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.
-rw-r--r--lib/device/device_id.c61
1 files 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;
@@ -1614,6 +1650,16 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct
}
/*
+ * 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",