summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authoryi zhang - Sun Microsystems - Beijing China <Zhang.Yi@Sun.COM>2009-11-06 13:10:19 +0800
committeryi zhang - Sun Microsystems - Beijing China <Zhang.Yi@Sun.COM>2009-11-06 13:10:19 +0800
commit8a29b80e78549f0575b492f20643e203dffb61f8 (patch)
tree8c0f0dda1ef91ca254b5047992bd630097008ad5 /usr/src
parentcc831366e9cb9a5741d11df679e00a7ae1f84218 (diff)
downloadillumos-joyent-8a29b80e78549f0575b492f20643e203dffb61f8.tar.gz
6863434 iscsi panic when try destroy iscsi target-param
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.c b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.c
index 0c88e4bd0b..ccb5b1f02d 100644
--- a/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.c
+++ b/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.c
@@ -1887,8 +1887,13 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
if ((e.e_oid != ihp->hba_oid) &&
(e.e_oid != ISCSI_OID_NOTSET)) {
+ boolean_t rval1, rval2, rval3;
uchar_t *t_name;
iscsi_sess_t *t_isp;
+ boolean_t t_rtn = B_TRUE;
+ persistent_param_t t_param;
+ iscsi_config_sess_t t_ics;
+ persistent_tunable_param_t t_tpsg;
rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
/*
@@ -1926,6 +1931,22 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
(void) strncpy((char *)name, (char *)t_name,
ISCSI_MAX_NAME_LEN);
+ t_ics.ics_in = 1;
+ rval1 = persistent_param_get((char *)name, &t_param);
+ rval2 = persistent_get_config_session((char *)name,
+ &t_ics);
+ rval3 = persistent_get_tunable_param((char *)name,
+ &t_tpsg);
+
+ if ((rval1 == B_FALSE) && (rval2 == B_FALSE) &&
+ (rval3 == B_FALSE)) {
+ /* no any target parameters get */
+ kmem_free(name, ISCSI_MAX_NAME_LEN);
+ rw_exit(&ihp->hba_sess_list_rwlock);
+ rtn = EIO;
+ break;
+ }
+
if (persistent_param_clear((char *)name) == B_FALSE) {
kmem_free(name, ISCSI_MAX_NAME_LEN);
rw_exit(&ihp->hba_sess_list_rwlock);
@@ -1977,14 +1998,8 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
*/
if (!ISCSI_SUCCESS(
iscsi_sess_destroy(isp))) {
- kmem_free(ics,
- sizeof (*ics));
- kmem_free(name,
- ISCSI_MAX_NAME_LEN);
- rw_exit(&ihp->
- hba_sess_list_rwlock);
- rtn = EBUSY;
- break;
+ t_rtn = B_FALSE;
+ continue;
}
isp = ihp->hba_sess_list;
} else {
@@ -2018,6 +2033,38 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
}
}
}
+ if (t_rtn == B_FALSE) {
+ boolean_t t_rval = B_TRUE;
+ /* Failure!, restore target's parameters */
+ if (rval1 == B_TRUE) {
+ rval1 = persistent_param_set(
+ (char *)name, &t_param);
+ if (rval1 == B_FALSE) {
+ t_rval = B_FALSE;
+ }
+ }
+ if (rval2 == B_TRUE) {
+ rval2 = persistent_set_config_session(
+ (char *)name, &t_ics);
+ if (rval2 == B_FALSE) {
+ t_rval = B_FALSE;
+ }
+ }
+ if (rval3 == B_TRUE) {
+ rval3 = persistent_set_tunable_param(
+ (char *)name, &t_tpsg);
+ if (rval3 == B_FALSE) {
+ t_rval = B_FALSE;
+ }
+ }
+ if (t_rval == B_FALSE) {
+ cmn_err(CE_WARN, "Failed to restore "
+ "target's parameters after remove "
+ "session related to target "
+ "parameters failure.");
+ }
+ rtn = EBUSY;
+ }
kmem_free(ics, sizeof (*ics));
kmem_free(name, ISCSI_MAX_NAME_LEN);
rw_exit(&ihp->hba_sess_list_rwlock);
@@ -2488,8 +2535,6 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
}
if (name == NULL) {
- rw_exit(
- &ihp->hba_sess_list_rwlock);
rtn = EFAULT;
break;
}
@@ -3728,8 +3773,6 @@ iscsi_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
}
if (name == NULL) {
- rw_exit(
- &ihp->hba_sess_list_rwlock);
rtn = EFAULT;
break;
}