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; } } /*