summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-04-08 11:41:51 -0700
committerDan Williams <dan.j.williams@intel.com>2009-04-08 11:41:51 -0700
commit316e2bf426350bc5f8dec16ad7fc079d9c8ba725 (patch)
treeba95a3defdbc33f541a5a7bba4ab52861596560e
parentb9d77223eb68a211410131b5b0895c547a6d5734 (diff)
downloadmdadm-316e2bf426350bc5f8dec16ad7fc079d9c8ba725.tar.gz
mdadm-316e2bf426350bc5f8dec16ad7fc079d9c8ba725.tar.xz
mdadm-316e2bf426350bc5f8dec16ad7fc079d9c8ba725.zip
imsm: extract right-most whitespace stripped serial number
According to new documentation the metadata expects that all whitespace (characters <= 0x20) are stripped from the incoming serial number. If the length remains longer than MAX_RAID_SERIAL_LEN then only the right-most characters are preserved. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--super-intel.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/super-intel.c b/super-intel.c
index b47371e..5413659 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1461,7 +1461,10 @@ static int imsm_read_serial(int fd, char *devname,
int rv;
int rsp_len;
int len;
- char *c, *rsp_buf;
+ char *dest;
+ char *src;
+ char *rsp_buf;
+ int i;
memset(scsi_serial, 0, sizeof(scsi_serial));
@@ -1481,7 +1484,6 @@ static int imsm_read_serial(int fd, char *devname,
return rv;
}
- /* trim leading whitespace */
rsp_len = scsi_serial[3];
if (!rsp_len) {
if (devname)
@@ -1491,24 +1493,33 @@ static int imsm_read_serial(int fd, char *devname,
return 2;
}
rsp_buf = (char *) &scsi_serial[4];
- c = rsp_buf;
- while (isspace(*c))
- c++;
- /* truncate len to the end of rsp_buf if necessary */
- if (c + MAX_RAID_SERIAL_LEN > rsp_buf + rsp_len)
- len = rsp_len - (c - rsp_buf);
- else
+ /* trim all whitespace and non-printable characters and convert
+ * ':' to ';'
+ */
+ for (i = 0, dest = rsp_buf; i < rsp_len; i++) {
+ src = &rsp_buf[i];
+ if (*src > 0x20) {
+ /* ':' is reserved for use in placeholder serial
+ * numbers for missing disks
+ */
+ if (*src == ':')
+ *dest++ = ';';
+ else
+ *dest++ = *src;
+ }
+ }
+ len = dest - rsp_buf;
+ dest = rsp_buf;
+
+ /* truncate leading characters */
+ if (len > MAX_RAID_SERIAL_LEN) {
+ dest += len - MAX_RAID_SERIAL_LEN;
len = MAX_RAID_SERIAL_LEN;
+ }
- /* initialize the buffer and copy rsp_buf characters */
memset(serial, 0, MAX_RAID_SERIAL_LEN);
- memcpy(serial, c, len);
-
- /* trim trailing whitespace starting with the last character copied */
- c = (char *) &serial[len - 1];
- while (isspace(*c) || *c == '\0')
- *c-- = '\0';
+ memcpy(serial, dest, len);
return 0;
}