mfiutil(4)/mrsasutil(4): "show drives" truncates information
Improve mfi_pd_inq_string() by * Reusing buffer sizes from cam/cam.h according to SCSI specification + NULL byte * Don't truncate vendor-specific information by escaping into a too small buffer * Use cam_strvis() from libcam instead of old, outdated local copy * Recaculate size of inq_string based on the reused buffer sizes and format statements PR: 294354 Reviewed by: imp MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D56328
This commit is contained in:
@@ -9,7 +9,7 @@ MLINKS= mfiutil.8 mrsasutil.8
|
|||||||
|
|
||||||
CFLAGS.gcc+= -fno-builtin-strftime
|
CFLAGS.gcc+= -fno-builtin-strftime
|
||||||
|
|
||||||
LIBADD= sbuf util
|
LIBADD= cam sbuf util
|
||||||
|
|
||||||
# Here be dragons
|
# Here be dragons
|
||||||
.ifdef DEBUG
|
.ifdef DEBUG
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <cam/cam.h>
|
||||||
#include <cam/scsi/scsi_all.h>
|
#include <cam/scsi/scsi_all.h>
|
||||||
#include "mfiutil.h"
|
#include "mfiutil.h"
|
||||||
|
|
||||||
@@ -279,50 +280,14 @@ mfi_pd_get_info(int fd, uint16_t device_id, struct mfi_pd_info *info,
|
|||||||
sizeof(struct mfi_pd_info), mbox, 2, statusp));
|
sizeof(struct mfi_pd_info), mbox, 2, statusp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
cam_strvis(char *dst, const char *src, int srclen, int dstlen)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Trim leading/trailing spaces, nulls. */
|
|
||||||
while (srclen > 0 && src[0] == ' ')
|
|
||||||
src++, srclen--;
|
|
||||||
while (srclen > 0
|
|
||||||
&& (src[srclen-1] == ' ' || src[srclen-1] == '\0'))
|
|
||||||
srclen--;
|
|
||||||
|
|
||||||
while (srclen > 0 && dstlen > 1) {
|
|
||||||
char *cur_pos = dst;
|
|
||||||
|
|
||||||
if (*src < 0x20) {
|
|
||||||
/* SCSI-II Specifies that these should never occur. */
|
|
||||||
/* non-printable character */
|
|
||||||
if (dstlen > 4) {
|
|
||||||
*cur_pos++ = '\\';
|
|
||||||
*cur_pos++ = ((*src & 0300) >> 6) + '0';
|
|
||||||
*cur_pos++ = ((*src & 0070) >> 3) + '0';
|
|
||||||
*cur_pos++ = ((*src & 0007) >> 0) + '0';
|
|
||||||
} else {
|
|
||||||
*cur_pos++ = '?';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* normal character */
|
|
||||||
*cur_pos++ = *src;
|
|
||||||
}
|
|
||||||
src++;
|
|
||||||
srclen--;
|
|
||||||
dstlen -= cur_pos - dst;
|
|
||||||
dst = cur_pos;
|
|
||||||
}
|
|
||||||
*dst = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */
|
/* Borrowed heavily from scsi_all.c:scsi_print_inquiry(). */
|
||||||
const char *
|
const char *
|
||||||
mfi_pd_inq_string(struct mfi_pd_info *info)
|
mfi_pd_inq_string(struct mfi_pd_info *info)
|
||||||
{
|
{
|
||||||
struct scsi_inquiry_data iqd, *inq_data = &iqd;
|
struct scsi_inquiry_data iqd, *inq_data = &iqd;
|
||||||
char vendor[16], product[48], revision[16], rstr[12], serial[SID_VENDOR_SPECIFIC_0_SIZE];
|
char vendor[SID_VENDOR_SIZE+1], product[SID_PRODUCT_SIZE+1],
|
||||||
static char inq_string[64];
|
revision[SID_REVISION_SIZE+1], rstr[9], serial[SID_VENDOR_SPECIFIC_0_SIZE+1];
|
||||||
|
static char inq_string[80];
|
||||||
|
|
||||||
memcpy(inq_data, info->inquiry_data,
|
memcpy(inq_data, info->inquiry_data,
|
||||||
(sizeof (iqd) < sizeof (info->inquiry_data))?
|
(sizeof (iqd) < sizeof (info->inquiry_data))?
|
||||||
@@ -334,14 +299,14 @@ mfi_pd_inq_string(struct mfi_pd_info *info)
|
|||||||
if (SID_QUAL(inq_data) != SID_QUAL_LU_CONNECTED)
|
if (SID_QUAL(inq_data) != SID_QUAL_LU_CONNECTED)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
|
cam_strvis_flag(vendor, inq_data->vendor, sizeof(inq_data->vendor),
|
||||||
sizeof(vendor));
|
sizeof(vendor), CAM_STRVIS_FLAG_NONASCII_TRIM);
|
||||||
cam_strvis(product, inq_data->product, sizeof(inq_data->product),
|
cam_strvis_flag(product, inq_data->product, sizeof(inq_data->product),
|
||||||
sizeof(product));
|
sizeof(product), CAM_STRVIS_FLAG_NONASCII_TRIM);
|
||||||
cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
|
cam_strvis_flag(revision, inq_data->revision, sizeof(inq_data->revision),
|
||||||
sizeof(revision));
|
sizeof(revision), CAM_STRVIS_FLAG_NONASCII_TRIM);
|
||||||
cam_strvis(serial, (char *)inq_data->vendor_specific0, sizeof(inq_data->vendor_specific0),
|
cam_strvis_flag(serial, (char *)inq_data->vendor_specific0, sizeof(inq_data->vendor_specific0),
|
||||||
sizeof(serial));
|
sizeof(serial), CAM_STRVIS_FLAG_NONASCII_SPC);
|
||||||
|
|
||||||
/* Hack for SATA disks, no idea how to tell speed. */
|
/* Hack for SATA disks, no idea how to tell speed. */
|
||||||
if (strcmp(vendor, "ATA") == 0) {
|
if (strcmp(vendor, "ATA") == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user