From: Dan Williams Date: Wed, 8 Apr 2009 18:41:51 +0000 (-0700) Subject: imsm: extract right-most whitespace stripped serial number X-Git-Tag: mdadm-3.0-rc1~28^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=316e2bf426350bc5f8dec16ad7fc079d9c8ba725;p=thirdparty%2Fmdadm.git 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 --- diff --git a/super-intel.c b/super-intel.c index b47371ee..54136596 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; }