Print this page
NEX-16174 scsi error messages should go to system log only
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
1787 SATL fails to handle returned SMART sense data
Reviewed by: Richard Elling <richard.elling@richardelling.com>
Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
*** 469,484 ****
}
}
char *
! scsi_cname(uchar_t cmd, register char **cmdvec)
{
! while (*cmdvec != (char *)0) {
! if (cmd == **cmdvec) {
! return ((char *)((long)(*cmdvec)+1));
! }
cmdvec++;
}
return (sprintf(scsi_tmpname, "<undecoded cmd 0x%x>", cmd));
}
--- 469,483 ----
}
}
char *
! scsi_cname(uchar_t cmd, char **cmdvec)
{
! while (*cmdvec != NULL) {
! if (cmd == **cmdvec)
! return ((char *)(uintptr_t)(*cmdvec + 1));
cmdvec++;
}
return (sprintf(scsi_tmpname, "<undecoded cmd 0x%x>", cmd));
}
*** 1023,1055 ****
} else {
return (sense_keys[sense_key]);
}
}
-
- /*
- * Print a piece of inquiry data- cleaned up for non-printable characters.
- */
- static void
- inq_fill(char *p, int l, char *s)
- {
- register unsigned i = 0;
- char c;
-
- if (!p)
- return;
-
- while (i++ < l) {
- /* clean string of non-printing chars */
- if ((c = *p++) < ' ' || c >= 0177) {
- c = ' ';
- }
- *s++ = c;
- }
- *s++ = 0;
- }
-
static char *
scsi_asc_search(uint_t asc, uint_t ascq,
struct scsi_asq_key_strings *list)
{
int i = 0;
--- 1022,1031 ----
*** 1081,1224 ****
}
return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
}
! /*
! * The first part/column of the error message will be at least this length.
! * This number has been calculated so that each line fits in 80 chars.
! */
! #define SCSI_ERRMSG_COLUMN_LEN 42
! #define SCSI_ERRMSG_BUF_LEN 256
void
scsi_generic_errmsg(struct scsi_device *devp, char *label, int severity,
daddr_t blkno, daddr_t err_blkno,
uchar_t cmd_name, struct scsi_key_strings *cmdlist,
uint8_t *sensep, struct scsi_asq_key_strings *asc_list,
char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
{
! uchar_t com;
! static char buf[SCSI_ERRMSG_BUF_LEN];
! static char buf1[SCSI_ERRMSG_BUF_LEN];
! static char tmpbuf[64];
! static char pad[SCSI_ERRMSG_COLUMN_LEN];
! dev_info_t *dev = devp->sd_dev;
static char *error_classes[] = {
"All", "Unknown", "Informational",
"Recovered", "Retryable", "Fatal"
};
- uchar_t sense_key, asc, ascq, fru_code;
- uchar_t *fru_code_ptr;
- int i, buflen;
mutex_enter(&scsi_log_mutex);
! /*
! * We need to put our space padding code because kernel version
! * of sprintf(9F) doesn't support %-<number>s type of left alignment.
! */
! for (i = 0; i < SCSI_ERRMSG_COLUMN_LEN; i++) {
! pad[i] = ' ';
! }
! bzero(buf, SCSI_ERRMSG_BUF_LEN);
! com = cmd_name;
! (void) sprintf(buf, "Error for Command: %s",
! scsi_cmd_name(com, cmdlist, tmpbuf));
! buflen = strlen(buf);
! if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
! pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
! (void) sprintf(&buf[buflen], "%s Error Level: %s",
! pad, error_classes[severity]);
! pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
! } else {
! (void) sprintf(&buf[buflen], " Error Level: %s",
! error_classes[severity]);
}
- impl_scsi_log(dev, label, CE_WARN, buf);
! if (blkno != -1 || err_blkno != -1 &&
! ((com & 0xf) == SCMD_READ) || ((com & 0xf) == SCMD_WRITE)) {
! bzero(buf, SCSI_ERRMSG_BUF_LEN);
! (void) sprintf(buf, "Requested Block: %ld", blkno);
! buflen = strlen(buf);
! if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
! pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
! (void) sprintf(&buf[buflen], "%s Error Block: %ld\n",
! pad, err_blkno);
! pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
! } else {
! (void) sprintf(&buf[buflen], " Error Block: %ld\n",
! err_blkno);
! }
! impl_scsi_log(dev, label, CE_CONT, buf);
! }
- bzero(buf, SCSI_ERRMSG_BUF_LEN);
- (void) strcpy(buf, "Vendor: ");
- inq_fill(devp->sd_inq->inq_vid, 8, &buf[strlen(buf)]);
- buflen = strlen(buf);
- if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
- pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
- (void) sprintf(&buf[strlen(buf)], "%s Serial Number: ", pad);
- pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
- } else {
- (void) sprintf(&buf[strlen(buf)], " Serial Number: ");
- }
- inq_fill(devp->sd_inq->inq_serial, 12, &buf[strlen(buf)]);
- impl_scsi_log(dev, label, CE_CONT, "%s\n", buf);
-
- if (sensep) {
sense_key = scsi_sense_key(sensep);
asc = scsi_sense_asc(sensep);
ascq = scsi_sense_ascq(sensep);
scsi_ext_sense_fields(sensep, SENSE_LENGTH,
NULL, NULL, &fru_code_ptr, NULL, NULL);
- fru_code = (fru_code_ptr ? *fru_code_ptr : 0);
! bzero(buf, SCSI_ERRMSG_BUF_LEN);
! (void) sprintf(buf, "Sense Key: %s\n",
! sense_keys[sense_key]);
! impl_scsi_log(dev, label, CE_CONT, buf);
! bzero(buf, SCSI_ERRMSG_BUF_LEN);
! if ((fru_code != 0) &&
! (decode_fru != NULL)) {
! (*decode_fru)(devp, buf, SCSI_ERRMSG_BUF_LEN,
! fru_code);
! if (buf[0] != NULL) {
! bzero(buf1, SCSI_ERRMSG_BUF_LEN);
! (void) sprintf(&buf1[strlen(buf1)],
! "ASC: 0x%x (%s)", asc,
! scsi_asc_ascq_name(asc, ascq,
! tmpbuf, asc_list));
! buflen = strlen(buf1);
! if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
! pad[SCSI_ERRMSG_COLUMN_LEN - buflen] =
! '\0';
! (void) sprintf(&buf1[buflen],
! "%s ASCQ: 0x%x", pad, ascq);
! } else {
! (void) sprintf(&buf1[buflen],
! " ASCQ: 0x%x", ascq);
}
- impl_scsi_log(dev,
- label, CE_CONT, "%s\n", buf1);
- impl_scsi_log(dev,
- label, CE_CONT, "FRU: 0x%x (%s)\n",
- fru_code, buf);
- mutex_exit(&scsi_log_mutex);
- return;
}
}
! (void) sprintf(&buf[strlen(buf)],
! "ASC: 0x%x (%s), ASCQ: 0x%x, FRU: 0x%x",
! asc, scsi_asc_ascq_name(asc, ascq, tmpbuf, asc_list),
! ascq, fru_code);
! impl_scsi_log(dev, label, CE_CONT, "%s\n", buf);
! }
mutex_exit(&scsi_log_mutex);
}
void
scsi_vu_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
--- 1057,1128 ----
}
return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
}
! #define SCSI_LOGBUF_LEN 512
void
scsi_generic_errmsg(struct scsi_device *devp, char *label, int severity,
daddr_t blkno, daddr_t err_blkno,
uchar_t cmd_name, struct scsi_key_strings *cmdlist,
uint8_t *sensep, struct scsi_asq_key_strings *asc_list,
char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
{
! char cmdbuf[SCSI_LOGBUF_LEN];
! char blkbuf[SCSI_LOGBUF_LEN];
! char sensebuf[SCSI_LOGBUF_LEN];
! char frubuf[SCSI_LOGBUF_LEN];
! char tmpbuf[SCSI_LOGBUF_LEN];
static char *error_classes[] = {
"All", "Unknown", "Informational",
"Recovered", "Retryable", "Fatal"
};
mutex_enter(&scsi_log_mutex);
! (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s: cmd=%s",
! error_classes[severity], scsi_cmd_name(cmd_name, cmdlist, tmpbuf));
! blkbuf[0] = '\0';
! if ((blkno != -1 || err_blkno != -1) &&
! ((cmd_name & 0xf) == SCMD_READ || (cmd_name & 0xf) == SCMD_WRITE)) {
! (void) snprintf(blkbuf, sizeof (blkbuf),
! " (reqblk=%ld errblk=%ld)", blkno, err_blkno);
}
! sensebuf[0] = '\0';
! frubuf[0] = '\0';
! if (sensep != NULL) {
! uchar_t sense_key, asc, ascq, fru_code;
! uchar_t *fru_code_ptr;
sense_key = scsi_sense_key(sensep);
asc = scsi_sense_asc(sensep);
ascq = scsi_sense_ascq(sensep);
scsi_ext_sense_fields(sensep, SENSE_LENGTH,
NULL, NULL, &fru_code_ptr, NULL, NULL);
! (void) snprintf(sensebuf, sizeof (sensebuf),
! " key=%s asc/ascq=0x%x/0x%x (\"%s\")",
! sense_keys[sense_key], asc, ascq,
! scsi_asc_ascq_name(asc, ascq, tmpbuf, asc_list));
! fru_code = (fru_code_ptr != NULL ? *fru_code_ptr : 0);
! if (fru_code != 0 &&
! decode_fru != NULL) {
! (*decode_fru)(devp, tmpbuf, sizeof (tmpbuf), fru_code);
! if (tmpbuf[0] != '\0') {
! (void) snprintf(frubuf, sizeof (frubuf),
! " fru=0x%x (\"%s\")", fru_code, tmpbuf);
}
}
}
!
! impl_scsi_log(devp->sd_dev, label, CE_WARN, "!%s%s%s%s",
! cmdbuf, blkbuf, sensebuf, frubuf);
!
mutex_exit(&scsi_log_mutex);
}
void
scsi_vu_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
*** 1231,1242 ****
com = ((union scsi_cdb *)pkt->pkt_cdbp)->scc_cmd;
scsi_generic_errmsg(devp, label, severity, blkno, err_blkno,
com, cmdlist, (uint8_t *)sensep, asc_list, decode_fru);
-
-
}
void
scsi_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
int severity, daddr_t blkno, daddr_t err_blkno,
--- 1135,1144 ----
*** 1272,1284 ****
va_start(ap, fmt);
v_scsi_log(dev, label, level, fmt, ap);
va_end(ap);
}
-
- char *ddi_pathname(dev_info_t *dip, char *path);
-
/*PRINTFLIKE4*/
static void
v_scsi_log(dev_info_t *dev, char *label, uint_t level,
const char *fmt, va_list ap)
{
--- 1174,1183 ----
*** 1287,1310 ****
int boot_only = 0;
int console_only = 0;
ASSERT(mutex_owned(&scsi_log_mutex));
! if (dev) {
if (level == CE_PANIC || level == CE_WARN ||
! level == CE_NOTE) {
! (void) sprintf(name, "%s (%s%d):\n",
! ddi_pathname(dev, scsi_log_buffer),
! label, ddi_get_instance(dev));
! } else if (level >= (uint_t)SCSI_DEBUG) {
! (void) sprintf(name,
! "%s%d:", label, ddi_get_instance(dev));
} else {
name[0] = '\0';
}
} else {
! (void) sprintf(name, "%s:", label);
}
(void) vsprintf(scsi_log_buffer, fmt, ap);
switch (scsi_log_buffer[0]) {
--- 1186,1205 ----
int boot_only = 0;
int console_only = 0;
ASSERT(mutex_owned(&scsi_log_mutex));
! if (dev != NULL) {
if (level == CE_PANIC || level == CE_WARN ||
! level == CE_NOTE || level >= (uint_t)SCSI_DEBUG) {
! (void) snprintf(name, sizeof (name), "%s%d: ",
! ddi_driver_name(dev), ddi_get_instance(dev));
} else {
name[0] = '\0';
}
} else {
! (void) sprintf(name, "%s: ", label);
}
(void) vsprintf(scsi_log_buffer, fmt, ap);
switch (scsi_log_buffer[0]) {
*** 1325,1346 ****
/* FALLTHROUGH */
case CE_CONT:
case CE_WARN:
case CE_PANIC:
if (boot_only) {
! cmn_err(level, "?%s\t%s", name, &scsi_log_buffer[1]);
} else if (console_only) {
! cmn_err(level, "^%s\t%s", name, &scsi_log_buffer[1]);
} else if (log_only) {
! cmn_err(level, "!%s\t%s", name, &scsi_log_buffer[1]);
} else {
! cmn_err(level, "%s\t%s", name, scsi_log_buffer);
}
break;
case (uint_t)SCSI_DEBUG:
default:
! cmn_err(CE_CONT, "^DEBUG: %s\t%s", name, scsi_log_buffer);
break;
}
}
/*
--- 1220,1241 ----
/* FALLTHROUGH */
case CE_CONT:
case CE_WARN:
case CE_PANIC:
if (boot_only) {
! cmn_err(level, "?%s%s", name, &scsi_log_buffer[1]);
} else if (console_only) {
! cmn_err(level, "^%s%s", name, &scsi_log_buffer[1]);
} else if (log_only) {
! cmn_err(level, "!%s%s", name, &scsi_log_buffer[1]);
} else {
! cmn_err(level, "%s%s", name, scsi_log_buffer);
}
break;
case (uint_t)SCSI_DEBUG:
default:
! cmn_err(CE_CONT, "?DEBUG: %s%s", name, scsi_log_buffer);
break;
}
}
/*