Mercurial > illumos > illumos-gate
changeset 10967:0f20d1dba80d
6886050 scsav3: scsi_hba_pkt_comp should detect double completions of same packet
6896150 st: doing intentional uscsi path selection causes unintended recovery.
6897284 scsi_vhci: Attempting path selection with an invalid path asserts.
6897299 ses: ses a non root user can do USCSICMD's
author | Randall Ralphs <Randall.Ralphs@Sun.COM> |
---|---|
date | Thu, 05 Nov 2009 15:47:57 -0700 |
parents | 37e5dcdf36d3 |
children | 7ccd43cefe5e |
files | usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c usr/src/uts/common/io/scsi/impl/scsi_hba.c usr/src/uts/common/io/scsi/impl/scsi_transport.c usr/src/uts/common/io/scsi/targets/ses.c usr/src/uts/common/io/scsi/targets/st.c usr/src/uts/common/sys/scsi/scsi_pkt.h |
diffstat | 6 files changed, 60 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c Thu Nov 05 15:47:57 2009 -0700 @@ -2283,7 +2283,8 @@ } goto bind_path; } - } else if (rval == MDI_FAILURE) { + } else if ((rval == MDI_FAILURE) || + ((rval == MDI_NOPATH) && (path_instance))) { if (pgr_sema_held) { sema_v(&vlun->svl_pgr_sema); }
--- a/usr/src/uts/common/io/scsi/impl/scsi_hba.c Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/io/scsi/impl/scsi_hba.c Thu Nov 05 15:47:57 2009 -0700 @@ -5206,6 +5206,23 @@ uint8_t *sensep; ASSERT(pkt); + + /* + * Catch second call on the same packet before doing anything else. + */ + if (pkt->pkt_flags & FLAG_PKT_COMP_CALLED) { + cmn_err( +#ifdef DEBUG + CE_PANIC, +#else + CE_WARN, +#endif + "%s duplicate scsi_hba_pkt_comp(9F) on same scsi_pkt(9S)", + mod_containing_pc(caller())); + } + + pkt->pkt_flags |= FLAG_PKT_COMP_CALLED; + if (pkt->pkt_comp == NULL) return;
--- a/usr/src/uts/common/io/scsi/impl/scsi_transport.c Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/io/scsi/impl/scsi_transport.c Thu Nov 05 15:47:57 2009 -0700 @@ -54,10 +54,20 @@ * we used to set the callback_done value to NULL after the callback * but this interfered with esp/fas drivers that also set the callback * to NULL to prevent callbacks during error recovery - * to prevent confusion, create a truly unique value + * to prevent confusion, create a truly unique value. + * The scsi_callback_done() function is used to detect a packet + * completion being called a second time. */ -static int scsi_callback_done; -#define CALLBACK_DONE ((void (*)(struct scsi_pkt *))(&scsi_callback_done)) +/* ARGSUSED */ +void +scsi_callback_done(struct scsi_pkt *pkt) +{ + cmn_err(CE_PANIC, + "%s: duplicate scsi_callback_done() on same scsi_pkt(9s)", + mod_containing_pc(caller())); +} + +#define CALLBACK_DONE (scsi_callback_done) static void scsi_flag_nointr_comp(struct scsi_pkt *pkt) @@ -127,6 +137,9 @@ #endif /* DEBUG */ } + /* Some retryed packets come with this flag not cleared */ + pkt->pkt_flags &= ~FLAG_PKT_COMP_CALLED; + /* * Check if we are required to do polled I/O. We can * get scsi_pkts that don't have the FLAG_NOINTR bit
--- a/usr/src/uts/common/io/scsi/targets/ses.c Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/io/scsi/targets/ses.c Thu Nov 05 15:47:57 2009 -0700 @@ -754,6 +754,10 @@ break; case SESIOC_INIT: + if (drv_priv(cred_p) != 0) { + rv = EPERM; + break; + } rv = (*ssc->ses_vec.init_enc)(ssc); break; @@ -776,6 +780,10 @@ break; case SESIOC_SETENCSTAT: + if (drv_priv(cred_p) != 0) { + rv = EPERM; + break; + } if (ddi_copyin((void *)arg, &t, sizeof (t), flg)) rv = EFAULT; else @@ -809,6 +817,10 @@ break; case SESIOC_SETOBJSTAT: + if (drv_priv(cred_p) != 0) { + rv = EPERM; + break; + } if (ddi_copyin((void *)arg, &x, sizeof (x), flg)) { rv = EFAULT; break; @@ -826,6 +838,10 @@ break; case USCSICMD: + if (drv_priv(cred_p) != 0) { + rv = EPERM; + break; + } rv = ses_uscsi_cmd(ssc, (Uscmd *)arg, flg); break;
--- a/usr/src/uts/common/io/scsi/targets/st.c Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/io/scsi/targets/st.c Thu Nov 05 15:47:57 2009 -0700 @@ -9708,7 +9708,7 @@ if (un->un_multipath) { struct uscsi_cmd *ucmd = BP_UCMD(bp); - int pkt_valid; + int pkt_valid = 0; if (ucmd) { /* @@ -9730,7 +9730,13 @@ */ if ((pkt_valid != 0) && (un->un_last_path_instance != pkt->pkt_path_instance)) { - if (un->un_state > ST_STATE_OPENING) { + /* + * Don't recover the path change if it was done + * intentionally or if the device has not completely + * opened yet. + */ + if (((pkt->pkt_flags & FLAG_PKT_PATH_INSTANCE) == 0) && + (un->un_state > ST_STATE_OPENING)) { ST_RECOV(ST_DEVINFO, st_label, CE_NOTE, "Failover detected, action is %s\n", errstatenames[action]);
--- a/usr/src/uts/common/sys/scsi/scsi_pkt.h Thu Nov 05 14:34:36 2009 -0800 +++ b/usr/src/uts/common/sys/scsi/scsi_pkt.h Thu Nov 05 15:47:57 2009 -0700 @@ -181,6 +181,7 @@ */ #define FLAG_NOQUEUE 0x80000000 #define FLAG_PKT_PATH_INSTANCE 0x40000000 /* Tell vhci the path to use */ +#define FLAG_PKT_COMP_CALLED 0x20000000 /* Set once pkt_comp called */ /* * Definitions for the pkt_reason field.