1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte * 25*fcf3ce44SJohn Forte * iSCSI Software Initiator 26*fcf3ce44SJohn Forte */ 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte /* 29*fcf3ce44SJohn Forte * Framework interface routines for iSCSI 30*fcf3ce44SJohn Forte */ 31*fcf3ce44SJohn Forte #include "iscsi.h" /* main header */ 32*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_if.h> /* ioctl interfaces */ 33*fcf3ce44SJohn Forte /* protocol structs and defines */ 34*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_protocol.h> 35*fcf3ce44SJohn Forte #include "persistent.h" 36*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_door.h> 37*fcf3ce44SJohn Forte #include "iscsi_targetparam.h" 38*fcf3ce44SJohn Forte #include <sys/strsubr.h> 39*fcf3ce44SJohn Forte #include <sys/socketvar.h> 40*fcf3ce44SJohn Forte 41*fcf3ce44SJohn Forte static iscsi_status_t iscsi_create_sendtgts_list(iscsi_conn_t *icp, 42*fcf3ce44SJohn Forte char *data, int data_len, iscsi_sendtgts_list_t *stl); 43*fcf3ce44SJohn Forte 44*fcf3ce44SJohn Forte /* 45*fcf3ce44SJohn Forte * iscsi_ioctl_copyin - 46*fcf3ce44SJohn Forte */ 47*fcf3ce44SJohn Forte void * 48*fcf3ce44SJohn Forte iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size) 49*fcf3ce44SJohn Forte { 50*fcf3ce44SJohn Forte void *data = NULL; 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte ASSERT(arg != NULL); 53*fcf3ce44SJohn Forte ASSERT(size != 0); 54*fcf3ce44SJohn Forte 55*fcf3ce44SJohn Forte data = kmem_alloc(size, KM_SLEEP); 56*fcf3ce44SJohn Forte 57*fcf3ce44SJohn Forte if (ddi_copyin(arg, data, size, mode) != 0) { 58*fcf3ce44SJohn Forte kmem_free(data, size); 59*fcf3ce44SJohn Forte data = NULL; 60*fcf3ce44SJohn Forte } 61*fcf3ce44SJohn Forte return (data); 62*fcf3ce44SJohn Forte } 63*fcf3ce44SJohn Forte 64*fcf3ce44SJohn Forte /* 65*fcf3ce44SJohn Forte * iscsi_ioctl_copyout - 66*fcf3ce44SJohn Forte */ 67*fcf3ce44SJohn Forte int 68*fcf3ce44SJohn Forte iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode) 69*fcf3ce44SJohn Forte { 70*fcf3ce44SJohn Forte int rtn; 71*fcf3ce44SJohn Forte 72*fcf3ce44SJohn Forte rtn = EFAULT; 73*fcf3ce44SJohn Forte if (ddi_copyout(data, arg, size, mode) == 0) { 74*fcf3ce44SJohn Forte rtn = 0; 75*fcf3ce44SJohn Forte } 76*fcf3ce44SJohn Forte kmem_free(data, size); 77*fcf3ce44SJohn Forte return (rtn); 78*fcf3ce44SJohn Forte } 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte /* 81*fcf3ce44SJohn Forte * iscsi_conn_list_get_copyin - 82*fcf3ce44SJohn Forte */ 83*fcf3ce44SJohn Forte iscsi_conn_list_t * 84*fcf3ce44SJohn Forte iscsi_ioctl_conn_oid_list_get_copyin(caddr_t arg, int mode) 85*fcf3ce44SJohn Forte { 86*fcf3ce44SJohn Forte iscsi_conn_list_t *cl_tmp; 87*fcf3ce44SJohn Forte iscsi_conn_list_t *cl = NULL; 88*fcf3ce44SJohn Forte size_t alloc_len; 89*fcf3ce44SJohn Forte 90*fcf3ce44SJohn Forte ASSERT(arg != NULL); 91*fcf3ce44SJohn Forte 92*fcf3ce44SJohn Forte cl_tmp = (iscsi_conn_list_t *)kmem_zalloc(sizeof (*cl_tmp), KM_SLEEP); 93*fcf3ce44SJohn Forte 94*fcf3ce44SJohn Forte if (ddi_copyin(arg, cl_tmp, sizeof (*cl_tmp), mode) == 0) { 95*fcf3ce44SJohn Forte 96*fcf3ce44SJohn Forte if (cl_tmp->cl_vers == ISCSI_INTERFACE_VERSION) { 97*fcf3ce44SJohn Forte alloc_len = sizeof (*cl); 98*fcf3ce44SJohn Forte if (cl_tmp->cl_in_cnt != 0) { 99*fcf3ce44SJohn Forte alloc_len += ((cl_tmp->cl_in_cnt - 1) * 100*fcf3ce44SJohn Forte sizeof (iscsi_if_conn_t)); 101*fcf3ce44SJohn Forte } 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte cl = (iscsi_conn_list_t *)kmem_zalloc(alloc_len, 104*fcf3ce44SJohn Forte KM_SLEEP); 105*fcf3ce44SJohn Forte bcopy(cl_tmp, cl, sizeof (*cl_tmp)); 106*fcf3ce44SJohn Forte } 107*fcf3ce44SJohn Forte } 108*fcf3ce44SJohn Forte kmem_free(cl_tmp, sizeof (*cl_tmp)); 109*fcf3ce44SJohn Forte return (cl); 110*fcf3ce44SJohn Forte } 111*fcf3ce44SJohn Forte 112*fcf3ce44SJohn Forte /* 113*fcf3ce44SJohn Forte * iscsi_conn_list_get_copyout - 114*fcf3ce44SJohn Forte */ 115*fcf3ce44SJohn Forte int 116*fcf3ce44SJohn Forte iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *cl, caddr_t arg, 117*fcf3ce44SJohn Forte int mode) 118*fcf3ce44SJohn Forte { 119*fcf3ce44SJohn Forte size_t alloc_len; 120*fcf3ce44SJohn Forte int rtn; 121*fcf3ce44SJohn Forte 122*fcf3ce44SJohn Forte ASSERT(cl != NULL); 123*fcf3ce44SJohn Forte ASSERT(arg != NULL); 124*fcf3ce44SJohn Forte 125*fcf3ce44SJohn Forte rtn = EFAULT; 126*fcf3ce44SJohn Forte alloc_len = sizeof (*cl); 127*fcf3ce44SJohn Forte if (cl->cl_in_cnt != 0) { 128*fcf3ce44SJohn Forte alloc_len += ((cl->cl_in_cnt - 1) * sizeof (iscsi_if_conn_t)); 129*fcf3ce44SJohn Forte } 130*fcf3ce44SJohn Forte 131*fcf3ce44SJohn Forte if (ddi_copyout(cl, arg, alloc_len, mode) == 0) { 132*fcf3ce44SJohn Forte rtn = 0; 133*fcf3ce44SJohn Forte } 134*fcf3ce44SJohn Forte kmem_free(cl, alloc_len); 135*fcf3ce44SJohn Forte return (rtn); 136*fcf3ce44SJohn Forte } 137*fcf3ce44SJohn Forte 138*fcf3ce44SJohn Forte /* 139*fcf3ce44SJohn Forte * iscsi_conn_oid_list_get - 140*fcf3ce44SJohn Forte */ 141*fcf3ce44SJohn Forte boolean_t 142*fcf3ce44SJohn Forte iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp, iscsi_conn_list_t *cl) 143*fcf3ce44SJohn Forte { 144*fcf3ce44SJohn Forte iscsi_sess_t *isp; 145*fcf3ce44SJohn Forte iscsi_conn_t *icp; 146*fcf3ce44SJohn Forte iscsi_if_conn_t *cnx; 147*fcf3ce44SJohn Forte uint32_t target_oid; 148*fcf3ce44SJohn Forte 149*fcf3ce44SJohn Forte /* Let's check the version. */ 150*fcf3ce44SJohn Forte if (cl->cl_vers != ISCSI_INTERFACE_VERSION) { 151*fcf3ce44SJohn Forte return (B_FALSE); 152*fcf3ce44SJohn Forte } 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte /* We preinitialize the output connection counter. */ 155*fcf3ce44SJohn Forte cl->cl_out_cnt = 0; 156*fcf3ce44SJohn Forte 157*fcf3ce44SJohn Forte /* The list of sessions is walked holding the HBA mutex. */ 158*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 159*fcf3ce44SJohn Forte isp = ihp->hba_sess_list; 160*fcf3ce44SJohn Forte 161*fcf3ce44SJohn Forte /* 162*fcf3ce44SJohn Forte * Check to see if oid references a target-param oid. If so, 163*fcf3ce44SJohn Forte * find the associated session oid before getting lu list. 164*fcf3ce44SJohn Forte */ 165*fcf3ce44SJohn Forte if (iscsi_targetparam_get_name(cl->cl_sess_oid) != NULL) { 166*fcf3ce44SJohn Forte for (isp = ihp->hba_sess_list; isp; isp = isp->sess_next) { 167*fcf3ce44SJohn Forte if (isp->sess_target_oid == cl->cl_sess_oid) { 168*fcf3ce44SJohn Forte target_oid = isp->sess_oid; 169*fcf3ce44SJohn Forte break; 170*fcf3ce44SJohn Forte } 171*fcf3ce44SJohn Forte } 172*fcf3ce44SJohn Forte } else { 173*fcf3ce44SJohn Forte target_oid = cl->cl_sess_oid; 174*fcf3ce44SJohn Forte } 175*fcf3ce44SJohn Forte 176*fcf3ce44SJohn Forte while (isp != NULL) { 177*fcf3ce44SJohn Forte ASSERT(isp->sess_sig == ISCSI_SIG_SESS); 178*fcf3ce44SJohn Forte 179*fcf3ce44SJohn Forte /* return connections for NORMAL sessions only */ 180*fcf3ce44SJohn Forte if ((isp->sess_type == ISCSI_SESS_TYPE_NORMAL) && 181*fcf3ce44SJohn Forte ((cl->cl_all_sess == B_TRUE) || 182*fcf3ce44SJohn Forte (target_oid == isp->sess_oid))) { 183*fcf3ce44SJohn Forte /* 184*fcf3ce44SJohn Forte * The list of connections is walked holding 185*fcf3ce44SJohn Forte * the session mutex. 186*fcf3ce44SJohn Forte */ 187*fcf3ce44SJohn Forte rw_enter(&isp->sess_conn_list_rwlock, RW_READER); 188*fcf3ce44SJohn Forte icp = isp->sess_conn_list; 189*fcf3ce44SJohn Forte 190*fcf3ce44SJohn Forte while (icp != NULL) { 191*fcf3ce44SJohn Forte ASSERT(icp->conn_sig == ISCSI_SIG_CONN); 192*fcf3ce44SJohn Forte 193*fcf3ce44SJohn Forte if (icp->conn_state == 194*fcf3ce44SJohn Forte ISCSI_CONN_STATE_LOGGED_IN) { 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte if (cl->cl_out_cnt < cl->cl_in_cnt) { 197*fcf3ce44SJohn Forte /* There's still room. */ 198*fcf3ce44SJohn Forte cnx = 199*fcf3ce44SJohn Forte &cl->cl_list[ 200*fcf3ce44SJohn Forte cl->cl_out_cnt]; 201*fcf3ce44SJohn Forte 202*fcf3ce44SJohn Forte bzero(cnx, sizeof (*cnx)); 203*fcf3ce44SJohn Forte 204*fcf3ce44SJohn Forte cnx->c_cid = icp->conn_cid; 205*fcf3ce44SJohn Forte cnx->c_oid = icp->conn_oid; 206*fcf3ce44SJohn Forte cnx->c_sess_oid = isp->sess_oid; 207*fcf3ce44SJohn Forte } 208*fcf3ce44SJohn Forte ++cl->cl_out_cnt; 209*fcf3ce44SJohn Forte } 210*fcf3ce44SJohn Forte icp = icp->conn_next; 211*fcf3ce44SJohn Forte } 212*fcf3ce44SJohn Forte rw_exit(&isp->sess_conn_list_rwlock); 213*fcf3ce44SJohn Forte 214*fcf3ce44SJohn Forte if (cl->cl_all_sess == B_FALSE) { 215*fcf3ce44SJohn Forte /* 216*fcf3ce44SJohn Forte * We got here because it was the only session 217*fcf3ce44SJohn Forte * we were looking for. We can exit now. 218*fcf3ce44SJohn Forte */ 219*fcf3ce44SJohn Forte break; 220*fcf3ce44SJohn Forte } 221*fcf3ce44SJohn Forte } 222*fcf3ce44SJohn Forte isp = isp->sess_next; 223*fcf3ce44SJohn Forte } 224*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 225*fcf3ce44SJohn Forte return (B_TRUE); 226*fcf3ce44SJohn Forte } 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte /* 229*fcf3ce44SJohn Forte * iscsi_ioctl_conn_props_get - 230*fcf3ce44SJohn Forte */ 231*fcf3ce44SJohn Forte boolean_t 232*fcf3ce44SJohn Forte iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp) 233*fcf3ce44SJohn Forte { 234*fcf3ce44SJohn Forte iscsi_sess_t *isp; 235*fcf3ce44SJohn Forte iscsi_conn_t *icp; 236*fcf3ce44SJohn Forte boolean_t rtn; 237*fcf3ce44SJohn Forte 238*fcf3ce44SJohn Forte /* Let's check the version. */ 239*fcf3ce44SJohn Forte if (cp->cp_vers != ISCSI_INTERFACE_VERSION) { 240*fcf3ce44SJohn Forte return (B_FALSE); 241*fcf3ce44SJohn Forte } 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte /* Let's find the session. */ 244*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 245*fcf3ce44SJohn Forte if (iscsi_sess_get(cp->cp_sess_oid, ihp, &isp) != 0) { 246*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 247*fcf3ce44SJohn Forte return (B_FALSE); 248*fcf3ce44SJohn Forte } 249*fcf3ce44SJohn Forte 250*fcf3ce44SJohn Forte ASSERT(isp->sess_sig == ISCSI_SIG_SESS); 251*fcf3ce44SJohn Forte 252*fcf3ce44SJohn Forte rtn = B_FALSE; 253*fcf3ce44SJohn Forte 254*fcf3ce44SJohn Forte rw_enter(&isp->sess_conn_list_rwlock, RW_READER); 255*fcf3ce44SJohn Forte icp = isp->sess_conn_list; 256*fcf3ce44SJohn Forte cp->cp_params_valid = B_FALSE; 257*fcf3ce44SJohn Forte 258*fcf3ce44SJohn Forte while (icp != NULL) { 259*fcf3ce44SJohn Forte 260*fcf3ce44SJohn Forte ASSERT(icp->conn_sig == ISCSI_SIG_CONN); 261*fcf3ce44SJohn Forte 262*fcf3ce44SJohn Forte if (icp->conn_oid == cp->cp_oid) { 263*fcf3ce44SJohn Forte 264*fcf3ce44SJohn Forte if (icp->conn_socket->so_laddr.soa_len <= 265*fcf3ce44SJohn Forte sizeof (cp->cp_local)) { 266*fcf3ce44SJohn Forte bcopy(icp->conn_socket->so_laddr.soa_sa, 267*fcf3ce44SJohn Forte &cp->cp_local, 268*fcf3ce44SJohn Forte icp->conn_socket->so_laddr.soa_len); 269*fcf3ce44SJohn Forte } 270*fcf3ce44SJohn Forte if (icp->conn_socket->so_faddr.soa_len <= 271*fcf3ce44SJohn Forte sizeof (cp->cp_peer)) { 272*fcf3ce44SJohn Forte bcopy(icp->conn_socket->so_faddr.soa_sa, 273*fcf3ce44SJohn Forte &cp->cp_peer, 274*fcf3ce44SJohn Forte icp->conn_socket->so_faddr.soa_len); 275*fcf3ce44SJohn Forte } 276*fcf3ce44SJohn Forte 277*fcf3ce44SJohn Forte if (icp->conn_state == ISCSI_CONN_STATE_LOGGED_IN) { 278*fcf3ce44SJohn Forte cp->cp_params_valid = B_TRUE; 279*fcf3ce44SJohn Forte bcopy(&icp->conn_params, &cp->cp_params, 280*fcf3ce44SJohn Forte sizeof (icp->conn_params)); 281*fcf3ce44SJohn Forte } 282*fcf3ce44SJohn Forte 283*fcf3ce44SJohn Forte rtn = B_TRUE; 284*fcf3ce44SJohn Forte break; 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte icp = icp->conn_next; 287*fcf3ce44SJohn Forte } 288*fcf3ce44SJohn Forte rw_exit(&isp->sess_conn_list_rwlock); 289*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 290*fcf3ce44SJohn Forte return (rtn); 291*fcf3ce44SJohn Forte } 292*fcf3ce44SJohn Forte 293*fcf3ce44SJohn Forte 294*fcf3ce44SJohn Forte /* 295*fcf3ce44SJohn Forte * iscsi_ioctl_sendtgts_get - 0 on success; errno on failure 296*fcf3ce44SJohn Forte * 297*fcf3ce44SJohn Forte */ 298*fcf3ce44SJohn Forte int 299*fcf3ce44SJohn Forte iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl) 300*fcf3ce44SJohn Forte { 301*fcf3ce44SJohn Forte #define ISCSI_SENDTGTS_REQ_STR "SendTargets=All" 302*fcf3ce44SJohn Forte 303*fcf3ce44SJohn Forte int rtn = EFAULT; 304*fcf3ce44SJohn Forte iscsi_status_t status; 305*fcf3ce44SJohn Forte iscsi_sess_t *isp; 306*fcf3ce44SJohn Forte iscsi_conn_t *icp; 307*fcf3ce44SJohn Forte uint32_t oid; 308*fcf3ce44SJohn Forte char *data; 309*fcf3ce44SJohn Forte uint32_t data_len; 310*fcf3ce44SJohn Forte uint32_t rx_data_len; 311*fcf3ce44SJohn Forte iscsi_sockaddr_t addr_snd; 312*fcf3ce44SJohn Forte 313*fcf3ce44SJohn Forte ASSERT(ihp != NULL); 314*fcf3ce44SJohn Forte ASSERT(stl != NULL); 315*fcf3ce44SJohn Forte 316*fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(stl->stl_entry.e_insize, 317*fcf3ce44SJohn Forte &stl->stl_entry.e_u, stl->stl_entry.e_port, 318*fcf3ce44SJohn Forte &addr_snd.sin); 319*fcf3ce44SJohn Forte 320*fcf3ce44SJohn Forte /* create discovery session */ 321*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER); 322*fcf3ce44SJohn Forte isp = iscsi_sess_create(ihp, iSCSIDiscoveryMethodSendTargets, 323*fcf3ce44SJohn Forte NULL, SENDTARGETS_DISCOVERY, ISCSI_DEFAULT_TPGT, 324*fcf3ce44SJohn Forte ISCSI_SUN_ISID_5, ISCSI_SESS_TYPE_DISCOVERY, &oid); 325*fcf3ce44SJohn Forte if (isp == NULL) { 326*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 327*fcf3ce44SJohn Forte return (1); 328*fcf3ce44SJohn Forte } 329*fcf3ce44SJohn Forte 330*fcf3ce44SJohn Forte /* create connection */ 331*fcf3ce44SJohn Forte rw_enter(&isp->sess_conn_list_rwlock, RW_WRITER); 332*fcf3ce44SJohn Forte status = iscsi_conn_create(&addr_snd.sin, isp, &icp); 333*fcf3ce44SJohn Forte rw_exit(&isp->sess_conn_list_rwlock); 334*fcf3ce44SJohn Forte 335*fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) { 336*fcf3ce44SJohn Forte (void) iscsi_sess_destroy(isp); 337*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 338*fcf3ce44SJohn Forte return (1); 339*fcf3ce44SJohn Forte } 340*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 341*fcf3ce44SJohn Forte 342*fcf3ce44SJohn Forte /* start login */ 343*fcf3ce44SJohn Forte mutex_enter(&icp->conn_state_mutex); 344*fcf3ce44SJohn Forte (void) iscsi_conn_state_machine(icp, ISCSI_CONN_EVENT_T1); 345*fcf3ce44SJohn Forte mutex_exit(&icp->conn_state_mutex); 346*fcf3ce44SJohn Forte 347*fcf3ce44SJohn Forte if (icp->conn_state == ISCSI_CONN_STATE_LOGGED_IN) { 348*fcf3ce44SJohn Forte data_len = icp->conn_params.max_xmit_data_seg_len; 349*fcf3ce44SJohn Forte retry_sendtgts: 350*fcf3ce44SJohn Forte /* alloc/init buffer for SendTargets req/resp */ 351*fcf3ce44SJohn Forte data = kmem_zalloc(data_len, KM_SLEEP); 352*fcf3ce44SJohn Forte bcopy(ISCSI_SENDTGTS_REQ_STR, data, 353*fcf3ce44SJohn Forte sizeof (ISCSI_SENDTGTS_REQ_STR)); 354*fcf3ce44SJohn Forte 355*fcf3ce44SJohn Forte /* execute SendTargets operation */ 356*fcf3ce44SJohn Forte status = iscsi_handle_text(icp, data, data_len, 357*fcf3ce44SJohn Forte sizeof (ISCSI_SENDTGTS_REQ_STR), &rx_data_len); 358*fcf3ce44SJohn Forte 359*fcf3ce44SJohn Forte /* check if allocated buffer is too small for response */ 360*fcf3ce44SJohn Forte if (status == ISCSI_STATUS_DATA_OVERFLOW) { 361*fcf3ce44SJohn Forte kmem_free(data, data_len); 362*fcf3ce44SJohn Forte data_len = rx_data_len; 363*fcf3ce44SJohn Forte goto retry_sendtgts; 364*fcf3ce44SJohn Forte } 365*fcf3ce44SJohn Forte 366*fcf3ce44SJohn Forte if (ISCSI_SUCCESS(status)) { 367*fcf3ce44SJohn Forte status = iscsi_create_sendtgts_list(icp, data, 368*fcf3ce44SJohn Forte rx_data_len, stl); 369*fcf3ce44SJohn Forte if (ISCSI_SUCCESS(status)) { 370*fcf3ce44SJohn Forte rtn = 0; 371*fcf3ce44SJohn Forte } 372*fcf3ce44SJohn Forte } else { 373*fcf3ce44SJohn Forte rtn = EFAULT; 374*fcf3ce44SJohn Forte } 375*fcf3ce44SJohn Forte 376*fcf3ce44SJohn Forte kmem_free(data, data_len); 377*fcf3ce44SJohn Forte } else { 378*fcf3ce44SJohn Forte rtn = EFAULT; 379*fcf3ce44SJohn Forte } 380*fcf3ce44SJohn Forte 381*fcf3ce44SJohn Forte /* 382*fcf3ce44SJohn Forte * check if session is still alive. It may have been destroyed 383*fcf3ce44SJohn Forte * by a driver unload 384*fcf3ce44SJohn Forte */ 385*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER); 386*fcf3ce44SJohn Forte if (iscsi_sess_get(oid, ihp, &isp) == 0) { 387*fcf3ce44SJohn Forte (void) iscsi_sess_destroy(isp); 388*fcf3ce44SJohn Forte } 389*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 390*fcf3ce44SJohn Forte 391*fcf3ce44SJohn Forte return (rtn); 392*fcf3ce44SJohn Forte } 393*fcf3ce44SJohn Forte 394*fcf3ce44SJohn Forte 395*fcf3ce44SJohn Forte /* 396*fcf3ce44SJohn Forte * iscsi_create_sendtgts_list - Based upon the given data, build a 397*fcf3ce44SJohn Forte * linked list of SendTarget information. The data passed into this 398*fcf3ce44SJohn Forte * function is expected to be the data portion(s) of SendTarget text 399*fcf3ce44SJohn Forte * response. 400*fcf3ce44SJohn Forte */ 401*fcf3ce44SJohn Forte static iscsi_status_t 402*fcf3ce44SJohn Forte iscsi_create_sendtgts_list(iscsi_conn_t *icp, char *data, int data_len, 403*fcf3ce44SJohn Forte iscsi_sendtgts_list_t *stl) 404*fcf3ce44SJohn Forte { 405*fcf3ce44SJohn Forte char *line = NULL; 406*fcf3ce44SJohn Forte boolean_t targetname_added = B_FALSE; 407*fcf3ce44SJohn Forte iscsi_sendtgts_entry_t *curr_ste = NULL, 408*fcf3ce44SJohn Forte *prev_ste = NULL; 409*fcf3ce44SJohn Forte struct hostent *hptr; 410*fcf3ce44SJohn Forte int error_num; 411*fcf3ce44SJohn Forte 412*fcf3ce44SJohn Forte /* initialize number of targets found */ 413*fcf3ce44SJohn Forte stl->stl_out_cnt = 0; 414*fcf3ce44SJohn Forte 415*fcf3ce44SJohn Forte if (data_len == 0) 416*fcf3ce44SJohn Forte return (ISCSI_STATUS_SUCCESS); 417*fcf3ce44SJohn Forte 418*fcf3ce44SJohn Forte while ((line = iscsi_get_next_text(data, data_len, line)) != NULL) { 419*fcf3ce44SJohn Forte if (strncmp(TARGETNAME, line, strlen(TARGETNAME)) == 0) { 420*fcf3ce44SJohn Forte /* check if this is first targetname */ 421*fcf3ce44SJohn Forte if (prev_ste != NULL) { 422*fcf3ce44SJohn Forte stl->stl_out_cnt++; 423*fcf3ce44SJohn Forte } 424*fcf3ce44SJohn Forte if (stl->stl_out_cnt >= stl->stl_in_cnt) { 425*fcf3ce44SJohn Forte /* 426*fcf3ce44SJohn Forte * continue processing the data so that 427*fcf3ce44SJohn Forte * the total number of targets are known 428*fcf3ce44SJohn Forte * and the caller can retry with the correct 429*fcf3ce44SJohn Forte * number of entries in the list 430*fcf3ce44SJohn Forte */ 431*fcf3ce44SJohn Forte continue; 432*fcf3ce44SJohn Forte } 433*fcf3ce44SJohn Forte curr_ste = &(stl->stl_list[stl->stl_out_cnt]); 434*fcf3ce44SJohn Forte 435*fcf3ce44SJohn Forte /* 436*fcf3ce44SJohn Forte * This entry will use the IP address and port 437*fcf3ce44SJohn Forte * that was passed into this routine. If the next 438*fcf3ce44SJohn Forte * line that we receive is a TargetAddress we will 439*fcf3ce44SJohn Forte * know to modify this entry with the new IP address, 440*fcf3ce44SJohn Forte * port and portal group tag. If this state flag 441*fcf3ce44SJohn Forte * is not set we'll just create a new entry using 442*fcf3ce44SJohn Forte * only the previous entries targetname. 443*fcf3ce44SJohn Forte */ 444*fcf3ce44SJohn Forte (void) strncpy((char *)curr_ste->ste_name, 445*fcf3ce44SJohn Forte line + strlen(TARGETNAME), 446*fcf3ce44SJohn Forte sizeof (curr_ste->ste_name)); 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte if (icp->conn_base_addr.sin.sa_family == AF_INET) { 449*fcf3ce44SJohn Forte 450*fcf3ce44SJohn Forte struct sockaddr_in *addr_in = 451*fcf3ce44SJohn Forte &icp->conn_base_addr.sin4; 452*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_addr.i_insize = 453*fcf3ce44SJohn Forte sizeof (struct in_addr); 454*fcf3ce44SJohn Forte bcopy(&addr_in->sin_addr.s_addr, 455*fcf3ce44SJohn Forte &curr_ste->ste_ipaddr.a_addr.i_addr, 456*fcf3ce44SJohn Forte sizeof (struct in_addr)); 457*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_port = 458*fcf3ce44SJohn Forte htons(addr_in->sin_port); 459*fcf3ce44SJohn Forte 460*fcf3ce44SJohn Forte } else { 461*fcf3ce44SJohn Forte 462*fcf3ce44SJohn Forte struct sockaddr_in6 *addr_in6 = 463*fcf3ce44SJohn Forte &icp->conn_base_addr.sin6; 464*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_addr.i_insize = 465*fcf3ce44SJohn Forte sizeof (struct in6_addr); 466*fcf3ce44SJohn Forte bcopy(&addr_in6->sin6_addr.s6_addr, 467*fcf3ce44SJohn Forte &curr_ste->ste_ipaddr.a_addr.i_addr, 468*fcf3ce44SJohn Forte sizeof (struct in6_addr)); 469*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_port = 470*fcf3ce44SJohn Forte htons(addr_in6->sin6_port); 471*fcf3ce44SJohn Forte } 472*fcf3ce44SJohn Forte curr_ste->ste_tpgt = -1; 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte targetname_added = B_TRUE; 475*fcf3ce44SJohn Forte 476*fcf3ce44SJohn Forte } else if (strncmp(TARGETADDRESS, line, 477*fcf3ce44SJohn Forte strlen(TARGETADDRESS)) == 0) { 478*fcf3ce44SJohn Forte 479*fcf3ce44SJohn Forte char *in_str, 480*fcf3ce44SJohn Forte *tmp_buf, 481*fcf3ce44SJohn Forte *addr_str, 482*fcf3ce44SJohn Forte *port_str, 483*fcf3ce44SJohn Forte *tpgt_str; 484*fcf3ce44SJohn Forte int type, 485*fcf3ce44SJohn Forte tmp_buf_len; 486*fcf3ce44SJohn Forte long result; 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte /* 489*fcf3ce44SJohn Forte * If TARGETADDRESS is first line a SendTarget response 490*fcf3ce44SJohn Forte * (i.e. no TARGETNAME lines preceding), treat as 491*fcf3ce44SJohn Forte * an error. To check this an assumption is made that 492*fcf3ce44SJohn Forte * at least one sendtarget_entry_t should exist prior 493*fcf3ce44SJohn Forte * to entering this code. 494*fcf3ce44SJohn Forte */ 495*fcf3ce44SJohn Forte if (prev_ste == NULL) { 496*fcf3ce44SJohn Forte cmn_err(CE_NOTE, "SendTargets protocol error: " 497*fcf3ce44SJohn Forte "TARGETADDRESS first"); 498*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 499*fcf3ce44SJohn Forte } 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte /* 502*fcf3ce44SJohn Forte * If we can't find an '=' then the sendtargets 503*fcf3ce44SJohn Forte * response if invalid per spec. Return empty list. 504*fcf3ce44SJohn Forte */ 505*fcf3ce44SJohn Forte in_str = strchr(line, '='); 506*fcf3ce44SJohn Forte if (in_str == NULL) { 507*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 508*fcf3ce44SJohn Forte } 509*fcf3ce44SJohn Forte 510*fcf3ce44SJohn Forte /* move past the '=' */ 511*fcf3ce44SJohn Forte in_str++; 512*fcf3ce44SJohn Forte 513*fcf3ce44SJohn Forte /* Copy addr, port, and tpgt into temporary buffer */ 514*fcf3ce44SJohn Forte tmp_buf_len = strlen(in_str) + 1; 515*fcf3ce44SJohn Forte tmp_buf = kmem_zalloc(tmp_buf_len, KM_SLEEP); 516*fcf3ce44SJohn Forte (void) strncpy(tmp_buf, in_str, tmp_buf_len); 517*fcf3ce44SJohn Forte 518*fcf3ce44SJohn Forte /* 519*fcf3ce44SJohn Forte * Parse the addr, port, and tpgt from 520*fcf3ce44SJohn Forte * sendtarget response 521*fcf3ce44SJohn Forte */ 522*fcf3ce44SJohn Forte if (parse_addr_port_tpgt(tmp_buf, &addr_str, &type, 523*fcf3ce44SJohn Forte &port_str, &tpgt_str) == B_FALSE) { 524*fcf3ce44SJohn Forte /* Unable to extract addr */ 525*fcf3ce44SJohn Forte kmem_free(tmp_buf, tmp_buf_len); 526*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 527*fcf3ce44SJohn Forte } 528*fcf3ce44SJohn Forte 529*fcf3ce44SJohn Forte /* Now convert string addr to binary */ 530*fcf3ce44SJohn Forte hptr = kgetipnodebyname(addr_str, type, 531*fcf3ce44SJohn Forte AI_ALL, &error_num); 532*fcf3ce44SJohn Forte if (!hptr) { 533*fcf3ce44SJohn Forte /* Unable to get valid address */ 534*fcf3ce44SJohn Forte kmem_free(tmp_buf, tmp_buf_len); 535*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 536*fcf3ce44SJohn Forte } 537*fcf3ce44SJohn Forte 538*fcf3ce44SJohn Forte /* Check if space for response */ 539*fcf3ce44SJohn Forte if (targetname_added == B_FALSE) { 540*fcf3ce44SJohn Forte stl->stl_out_cnt++; 541*fcf3ce44SJohn Forte if (stl->stl_out_cnt >= stl->stl_in_cnt) { 542*fcf3ce44SJohn Forte /* 543*fcf3ce44SJohn Forte * continue processing the data so that 544*fcf3ce44SJohn Forte * the total number of targets are 545*fcf3ce44SJohn Forte * known and the caller can retry with 546*fcf3ce44SJohn Forte * the correct number of entries in 547*fcf3ce44SJohn Forte * the list 548*fcf3ce44SJohn Forte */ 549*fcf3ce44SJohn Forte kfreehostent(hptr); 550*fcf3ce44SJohn Forte kmem_free(tmp_buf, tmp_buf_len); 551*fcf3ce44SJohn Forte continue; 552*fcf3ce44SJohn Forte } 553*fcf3ce44SJohn Forte curr_ste = &(stl->stl_list[stl->stl_out_cnt]); 554*fcf3ce44SJohn Forte (void) strcpy((char *)curr_ste->ste_name, 555*fcf3ce44SJohn Forte (char *)prev_ste->ste_name); 556*fcf3ce44SJohn Forte } 557*fcf3ce44SJohn Forte 558*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_addr.i_insize = hptr->h_length; 559*fcf3ce44SJohn Forte bcopy(*hptr->h_addr_list, 560*fcf3ce44SJohn Forte &(curr_ste->ste_ipaddr.a_addr.i_addr), 561*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_addr.i_insize); 562*fcf3ce44SJohn Forte kfreehostent(hptr); 563*fcf3ce44SJohn Forte 564*fcf3ce44SJohn Forte if (port_str != NULL) { 565*fcf3ce44SJohn Forte (void) ddi_strtol(port_str, NULL, 0, &result); 566*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_port = (short)result; 567*fcf3ce44SJohn Forte } else { 568*fcf3ce44SJohn Forte curr_ste->ste_ipaddr.a_port = ISCSI_LISTEN_PORT; 569*fcf3ce44SJohn Forte } 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte if (tpgt_str != NULL) { 572*fcf3ce44SJohn Forte (void) ddi_strtol(tpgt_str, NULL, 0, &result); 573*fcf3ce44SJohn Forte curr_ste->ste_tpgt = (short)result; 574*fcf3ce44SJohn Forte } else { 575*fcf3ce44SJohn Forte cmn_err(CE_NOTE, "SendTargets protocol error: " 576*fcf3ce44SJohn Forte "TPGT not specified"); 577*fcf3ce44SJohn Forte kmem_free(tmp_buf, tmp_buf_len); 578*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 579*fcf3ce44SJohn Forte } 580*fcf3ce44SJohn Forte 581*fcf3ce44SJohn Forte kmem_free(tmp_buf, tmp_buf_len); 582*fcf3ce44SJohn Forte 583*fcf3ce44SJohn Forte targetname_added = B_FALSE; 584*fcf3ce44SJohn Forte 585*fcf3ce44SJohn Forte } else if (strlen(line) != 0) { 586*fcf3ce44SJohn Forte /* 587*fcf3ce44SJohn Forte * Any other string besides an empty string 588*fcf3ce44SJohn Forte * is a protocol error 589*fcf3ce44SJohn Forte */ 590*fcf3ce44SJohn Forte cmn_err(CE_NOTE, "SendTargets protocol error: " 591*fcf3ce44SJohn Forte "unexpected response"); 592*fcf3ce44SJohn Forte return (ISCSI_STATUS_PROTOCOL_ERROR); 593*fcf3ce44SJohn Forte } 594*fcf3ce44SJohn Forte 595*fcf3ce44SJohn Forte prev_ste = curr_ste; 596*fcf3ce44SJohn Forte } 597*fcf3ce44SJohn Forte 598*fcf3ce44SJohn Forte /* 599*fcf3ce44SJohn Forte * If target found increment out count one more time because 600*fcf3ce44SJohn Forte * this is the total number of entries in the list not an index 601*fcf3ce44SJohn Forte * like it was used above 602*fcf3ce44SJohn Forte */ 603*fcf3ce44SJohn Forte if (prev_ste != NULL) { 604*fcf3ce44SJohn Forte stl->stl_out_cnt++; 605*fcf3ce44SJohn Forte } 606*fcf3ce44SJohn Forte 607*fcf3ce44SJohn Forte return (ISCSI_STATUS_SUCCESS); 608*fcf3ce44SJohn Forte } 609*fcf3ce44SJohn Forte 610*fcf3ce44SJohn Forte /* 611*fcf3ce44SJohn Forte * iscsi_set_param - This function is a helper to ISCSI_SET_PARAM 612*fcf3ce44SJohn Forte * IOCTL 613*fcf3ce44SJohn Forte */ 614*fcf3ce44SJohn Forte int 615*fcf3ce44SJohn Forte iscsi_set_param(iscsi_login_params_t *params, iscsi_param_set_t *ipsp) 616*fcf3ce44SJohn Forte { 617*fcf3ce44SJohn Forte int rtn = 0; 618*fcf3ce44SJohn Forte iscsi_param_get_t *ipgp; 619*fcf3ce44SJohn Forte 620*fcf3ce44SJohn Forte /* 621*fcf3ce44SJohn Forte * Use get param to get the min, max and increment values for the 622*fcf3ce44SJohn Forte * given parameter so validation can be done on the new value. 623*fcf3ce44SJohn Forte */ 624*fcf3ce44SJohn Forte ipgp = (iscsi_param_get_t *)kmem_alloc(sizeof (*ipgp), KM_SLEEP); 625*fcf3ce44SJohn Forte ipgp->g_param = ipsp->s_param; 626*fcf3ce44SJohn Forte rtn = iscsi_get_param(params, B_TRUE, ipgp); 627*fcf3ce44SJohn Forte if (rtn != 0) { 628*fcf3ce44SJohn Forte kmem_free(ipgp, sizeof (*ipgp)); 629*fcf3ce44SJohn Forte return (rtn); 630*fcf3ce44SJohn Forte } 631*fcf3ce44SJohn Forte 632*fcf3ce44SJohn Forte if (ipsp->s_param == ISCSI_LOGIN_PARAM_HEADER_DIGEST || 633*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_DATA_DIGEST || 634*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN || 635*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT || 636*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH || 637*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH || 638*fcf3ce44SJohn Forte ipsp->s_param == ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH) { 639*fcf3ce44SJohn Forte 640*fcf3ce44SJohn Forte if (ipsp->s_value.v_integer < ipgp->g_value.v_integer.i_min || 641*fcf3ce44SJohn Forte ipsp->s_value.v_integer > ipgp->g_value.v_integer.i_max || 642*fcf3ce44SJohn Forte (ipsp->s_value.v_integer % 643*fcf3ce44SJohn Forte ipgp->g_value.v_integer.i_incr) != 0) { 644*fcf3ce44SJohn Forte rtn = EINVAL; 645*fcf3ce44SJohn Forte kmem_free(ipgp, sizeof (*ipgp)); 646*fcf3ce44SJohn Forte return (rtn); 647*fcf3ce44SJohn Forte } 648*fcf3ce44SJohn Forte 649*fcf3ce44SJohn Forte } 650*fcf3ce44SJohn Forte kmem_free(ipgp, sizeof (*ipgp)); 651*fcf3ce44SJohn Forte 652*fcf3ce44SJohn Forte 653*fcf3ce44SJohn Forte switch (ipsp->s_param) { 654*fcf3ce44SJohn Forte 655*fcf3ce44SJohn Forte /* 656*fcf3ce44SJohn Forte * Boolean parameters 657*fcf3ce44SJohn Forte */ 658*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER: 659*fcf3ce44SJohn Forte params->data_sequence_in_order = ipsp->s_value.v_bool; 660*fcf3ce44SJohn Forte break; 661*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_IMMEDIATE_DATA: 662*fcf3ce44SJohn Forte params->immediate_data = ipsp->s_value.v_bool; 663*fcf3ce44SJohn Forte break; 664*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_INITIAL_R2T: 665*fcf3ce44SJohn Forte params->initial_r2t = ipsp->s_value.v_bool; 666*fcf3ce44SJohn Forte break; 667*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER: 668*fcf3ce44SJohn Forte params->data_pdu_in_order = ipsp->s_value.v_bool; 669*fcf3ce44SJohn Forte break; 670*fcf3ce44SJohn Forte 671*fcf3ce44SJohn Forte /* 672*fcf3ce44SJohn Forte * Integer parameters 673*fcf3ce44SJohn Forte */ 674*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_HEADER_DIGEST: 675*fcf3ce44SJohn Forte params->header_digest = ipsp->s_value.v_integer; 676*fcf3ce44SJohn Forte break; 677*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_DIGEST: 678*fcf3ce44SJohn Forte params->data_digest = ipsp->s_value.v_integer; 679*fcf3ce44SJohn Forte break; 680*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN: 681*fcf3ce44SJohn Forte params->default_time_to_retain = ipsp->s_value.v_integer; 682*fcf3ce44SJohn Forte break; 683*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT: 684*fcf3ce44SJohn Forte params->default_time_to_wait = ipsp->s_value.v_integer; 685*fcf3ce44SJohn Forte break; 686*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH: 687*fcf3ce44SJohn Forte params->max_recv_data_seg_len = ipsp->s_value.v_integer; 688*fcf3ce44SJohn Forte break; 689*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH: 690*fcf3ce44SJohn Forte if (ipsp->s_value.v_integer <= params->max_burst_length) { 691*fcf3ce44SJohn Forte params->first_burst_length = ipsp->s_value.v_integer; 692*fcf3ce44SJohn Forte } else { 693*fcf3ce44SJohn Forte rtn = EINVAL; 694*fcf3ce44SJohn Forte } 695*fcf3ce44SJohn Forte break; 696*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH: 697*fcf3ce44SJohn Forte if (ipsp->s_value.v_integer >= params->first_burst_length) { 698*fcf3ce44SJohn Forte params->max_burst_length = ipsp->s_value.v_integer; 699*fcf3ce44SJohn Forte } else { 700*fcf3ce44SJohn Forte rtn = EINVAL; 701*fcf3ce44SJohn Forte } 702*fcf3ce44SJohn Forte break; 703*fcf3ce44SJohn Forte 704*fcf3ce44SJohn Forte /* 705*fcf3ce44SJohn Forte * Integer parameters which currently are unsettable 706*fcf3ce44SJohn Forte */ 707*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS: 708*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T: 709*fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL: 710*fcf3ce44SJohn Forte rtn = ENOTSUP; 711*fcf3ce44SJohn Forte break; 712*fcf3ce44SJohn Forte 713*fcf3ce44SJohn Forte default: 714*fcf3ce44SJohn Forte rtn = EINVAL; 715*fcf3ce44SJohn Forte break; 716*fcf3ce44SJohn Forte } 717*fcf3ce44SJohn Forte return (rtn); 718*fcf3ce44SJohn Forte } 719*fcf3ce44SJohn Forte 720*fcf3ce44SJohn Forte int 721*fcf3ce44SJohn Forte iscsi_set_params(iscsi_param_set_t *ils, iscsi_hba_t *ihp, boolean_t persist) 722*fcf3ce44SJohn Forte { 723*fcf3ce44SJohn Forte iscsi_login_params_t *params = NULL; 724*fcf3ce44SJohn Forte uchar_t *name = NULL; 725*fcf3ce44SJohn Forte iscsi_sess_t *isp = NULL; 726*fcf3ce44SJohn Forte iscsi_param_get_t *ilg; 727*fcf3ce44SJohn Forte int rtn = 0; 728*fcf3ce44SJohn Forte 729*fcf3ce44SJohn Forte /* handle special case for Initiator name */ 730*fcf3ce44SJohn Forte if (ils->s_param == ISCSI_LOGIN_PARAM_INITIATOR_NAME) { 731*fcf3ce44SJohn Forte (void) strlcpy((char *)ihp->hba_name, 732*fcf3ce44SJohn Forte (char *)ils->s_value.v_name, ISCSI_MAX_NAME_LEN); 733*fcf3ce44SJohn Forte if (persist) { 734*fcf3ce44SJohn Forte char *name; 735*fcf3ce44SJohn Forte boolean_t rval; 736*fcf3ce44SJohn Forte 737*fcf3ce44SJohn Forte /* save off old Initiator name */ 738*fcf3ce44SJohn Forte name = kmem_alloc(ISCSI_MAX_NAME_LEN, KM_SLEEP); 739*fcf3ce44SJohn Forte rval = persistent_initiator_name_get(name, 740*fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN); 741*fcf3ce44SJohn Forte 742*fcf3ce44SJohn Forte (void) persistent_initiator_name_set( 743*fcf3ce44SJohn Forte (char *)ihp->hba_name); 744*fcf3ce44SJohn Forte if (rval == B_TRUE) { 745*fcf3ce44SJohn Forte /* 746*fcf3ce44SJohn Forte * check to see if we have login param, 747*fcf3ce44SJohn Forte * chap param, or authentication params 748*fcf3ce44SJohn Forte * loaded in persistent that we have to change 749*fcf3ce44SJohn Forte * the name of 750*fcf3ce44SJohn Forte */ 751*fcf3ce44SJohn Forte persistent_param_t *pp; 752*fcf3ce44SJohn Forte iscsi_chap_props_t *chap; 753*fcf3ce44SJohn Forte iscsi_auth_props_t *auth; 754*fcf3ce44SJohn Forte 755*fcf3ce44SJohn Forte /* checking login params */ 756*fcf3ce44SJohn Forte pp = kmem_zalloc(sizeof (persistent_param_t), 757*fcf3ce44SJohn Forte KM_SLEEP); 758*fcf3ce44SJohn Forte if (persistent_param_get(name, pp)) { 759*fcf3ce44SJohn Forte rval = persistent_param_clear(name); 760*fcf3ce44SJohn Forte if (rval == B_TRUE) { 761*fcf3ce44SJohn Forte rval = persistent_param_set( 762*fcf3ce44SJohn Forte (char *)ihp->hba_name, pp); 763*fcf3ce44SJohn Forte } 764*fcf3ce44SJohn Forte if (rval == B_FALSE) { 765*fcf3ce44SJohn Forte rtn = EFAULT; 766*fcf3ce44SJohn Forte } 767*fcf3ce44SJohn Forte } 768*fcf3ce44SJohn Forte kmem_free(pp, sizeof (persistent_param_t)); 769*fcf3ce44SJohn Forte 770*fcf3ce44SJohn Forte /* check chap params */ 771*fcf3ce44SJohn Forte chap = kmem_zalloc(sizeof (iscsi_chap_props_t), 772*fcf3ce44SJohn Forte KM_SLEEP); 773*fcf3ce44SJohn Forte if (persistent_chap_get(name, chap)) { 774*fcf3ce44SJohn Forte rval = persistent_chap_clear(name); 775*fcf3ce44SJohn Forte if (rval == B_TRUE) { 776*fcf3ce44SJohn Forte /* 777*fcf3ce44SJohn Forte * Update CHAP user name only if the 778*fcf3ce44SJohn Forte * original username was set to the 779*fcf3ce44SJohn Forte * initiator node name. Otherwise 780*fcf3ce44SJohn Forte * leave it the way it is. 781*fcf3ce44SJohn Forte */ 782*fcf3ce44SJohn Forte int userSize; 783*fcf3ce44SJohn Forte userSize = 784*fcf3ce44SJohn Forte sizeof (chap->c_user); 785*fcf3ce44SJohn Forte if (strncmp((char *) 786*fcf3ce44SJohn Forte chap->c_user, name, 787*fcf3ce44SJohn Forte sizeof (chap->c_user)) 788*fcf3ce44SJohn Forte == 0) { 789*fcf3ce44SJohn Forte bzero(chap->c_user, 790*fcf3ce44SJohn Forte userSize); 791*fcf3ce44SJohn Forte bcopy((char *) 792*fcf3ce44SJohn Forte ihp->hba_name, 793*fcf3ce44SJohn Forte chap->c_user, 794*fcf3ce44SJohn Forte strlen((char *) 795*fcf3ce44SJohn Forte ihp->hba_name)); 796*fcf3ce44SJohn Forte chap->c_user_len = 797*fcf3ce44SJohn Forte strlen((char *) 798*fcf3ce44SJohn Forte ihp->hba_name); 799*fcf3ce44SJohn Forte 800*fcf3ce44SJohn Forte } 801*fcf3ce44SJohn Forte rval = persistent_chap_set( 802*fcf3ce44SJohn Forte (char *)ihp->hba_name, chap); 803*fcf3ce44SJohn Forte } 804*fcf3ce44SJohn Forte if (rval == B_FALSE) { 805*fcf3ce44SJohn Forte rtn = EFAULT; 806*fcf3ce44SJohn Forte } 807*fcf3ce44SJohn Forte } 808*fcf3ce44SJohn Forte kmem_free(chap, sizeof (iscsi_chap_props_t)); 809*fcf3ce44SJohn Forte 810*fcf3ce44SJohn Forte /* check authentication params */ 811*fcf3ce44SJohn Forte auth = kmem_zalloc(sizeof (iscsi_auth_props_t), 812*fcf3ce44SJohn Forte KM_SLEEP); 813*fcf3ce44SJohn Forte if (persistent_auth_get(name, auth)) { 814*fcf3ce44SJohn Forte rval = persistent_auth_clear(name); 815*fcf3ce44SJohn Forte if (rval == B_TRUE) { 816*fcf3ce44SJohn Forte rval = persistent_auth_set( 817*fcf3ce44SJohn Forte (char *)ihp->hba_name, 818*fcf3ce44SJohn Forte auth); 819*fcf3ce44SJohn Forte } 820*fcf3ce44SJohn Forte if (rval == B_FALSE) { 821*fcf3ce44SJohn Forte rtn = EFAULT; 822*fcf3ce44SJohn Forte } 823*fcf3ce44SJohn Forte } 824*fcf3ce44SJohn Forte kmem_free(auth, sizeof (iscsi_auth_props_t)); 825*fcf3ce44SJohn Forte } 826*fcf3ce44SJohn Forte kmem_free(name, ISCSI_MAX_NAME_LEN); 827*fcf3ce44SJohn Forte } 828*fcf3ce44SJohn Forte } else if (ils->s_param == ISCSI_LOGIN_PARAM_INITIATOR_ALIAS) { 829*fcf3ce44SJohn Forte (void) strlcpy((char *)ihp->hba_alias, 830*fcf3ce44SJohn Forte (char *)ils->s_value.v_name, ISCSI_MAX_NAME_LEN); 831*fcf3ce44SJohn Forte ihp->hba_alias_length = 832*fcf3ce44SJohn Forte strlen((char *)ils->s_value.v_name); 833*fcf3ce44SJohn Forte if (persist) { 834*fcf3ce44SJohn Forte (void) persistent_alias_name_set( 835*fcf3ce44SJohn Forte (char *)ihp->hba_alias); 836*fcf3ce44SJohn Forte } 837*fcf3ce44SJohn Forte } else { 838*fcf3ce44SJohn Forte /* switch login based if looking for initiator params */ 839*fcf3ce44SJohn Forte if (ils->s_oid == ihp->hba_oid) { 840*fcf3ce44SJohn Forte /* initiator */ 841*fcf3ce44SJohn Forte params = &ihp->hba_params; 842*fcf3ce44SJohn Forte name = ihp->hba_name; 843*fcf3ce44SJohn Forte rtn = iscsi_set_param(params, ils); 844*fcf3ce44SJohn Forte } else { 845*fcf3ce44SJohn Forte /* session */ 846*fcf3ce44SJohn Forte name = iscsi_targetparam_get_name(ils->s_oid); 847*fcf3ce44SJohn Forte 848*fcf3ce44SJohn Forte if (persist) { 849*fcf3ce44SJohn Forte boolean_t rval; 850*fcf3ce44SJohn Forte persistent_param_t *pp; 851*fcf3ce44SJohn Forte 852*fcf3ce44SJohn Forte pp = (persistent_param_t *) 853*fcf3ce44SJohn Forte kmem_zalloc(sizeof (*pp), KM_SLEEP); 854*fcf3ce44SJohn Forte if (!persistent_param_get((char *)name, pp)) { 855*fcf3ce44SJohn Forte iscsi_set_default_login_params( 856*fcf3ce44SJohn Forte &pp->p_params); 857*fcf3ce44SJohn Forte } 858*fcf3ce44SJohn Forte 859*fcf3ce44SJohn Forte pp->p_bitmap |= (1 << ils->s_param); 860*fcf3ce44SJohn Forte rtn = iscsi_set_param(&pp->p_params, ils); 861*fcf3ce44SJohn Forte if (rtn == 0) { 862*fcf3ce44SJohn Forte rval = persistent_param_set( 863*fcf3ce44SJohn Forte (char *)name, pp); 864*fcf3ce44SJohn Forte if (rval == B_FALSE) { 865*fcf3ce44SJohn Forte rtn = EFAULT; 866*fcf3ce44SJohn Forte } 867*fcf3ce44SJohn Forte } 868*fcf3ce44SJohn Forte kmem_free(pp, sizeof (*pp)); 869*fcf3ce44SJohn Forte } 870*fcf3ce44SJohn Forte 871*fcf3ce44SJohn Forte /* 872*fcf3ce44SJohn Forte * We may have multiple sessions with different 873*fcf3ce44SJohn Forte * tpgt values. So we need to loop through 874*fcf3ce44SJohn Forte * the sessions and update all sessions. 875*fcf3ce44SJohn Forte */ 876*fcf3ce44SJohn Forte if (rtn == 0) { 877*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 878*fcf3ce44SJohn Forte for (isp = ihp->hba_sess_list; isp; 879*fcf3ce44SJohn Forte isp = isp->sess_next) { 880*fcf3ce44SJohn Forte if (strncmp((char *)isp->sess_name, 881*fcf3ce44SJohn Forte (char *)name, 882*fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN) == 0) { 883*fcf3ce44SJohn Forte mutex_enter(&isp->sess_state_mutex); 884*fcf3ce44SJohn Forte iscsi_sess_state_machine(isp, ISCSI_SESS_EVENT_N7); 885*fcf3ce44SJohn Forte mutex_exit(&isp->sess_state_mutex); 886*fcf3ce44SJohn Forte } 887*fcf3ce44SJohn Forte } 888*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 889*fcf3ce44SJohn Forte } 890*fcf3ce44SJohn Forte 891*fcf3ce44SJohn Forte } /* end of 'else' */ 892*fcf3ce44SJohn Forte 893*fcf3ce44SJohn Forte if (params && persist && (rtn == 0)) { 894*fcf3ce44SJohn Forte boolean_t rval; 895*fcf3ce44SJohn Forte persistent_param_t *pp; 896*fcf3ce44SJohn Forte 897*fcf3ce44SJohn Forte pp = (persistent_param_t *) 898*fcf3ce44SJohn Forte kmem_zalloc(sizeof (*pp), KM_SLEEP); 899*fcf3ce44SJohn Forte (void) persistent_param_get((char *)name, pp); 900*fcf3ce44SJohn Forte pp->p_bitmap |= (1 << ils->s_param); 901*fcf3ce44SJohn Forte bcopy(params, &pp->p_params, sizeof (*params)); 902*fcf3ce44SJohn Forte rval = persistent_param_set((char *)name, pp); 903*fcf3ce44SJohn Forte if (rval == B_FALSE) { 904*fcf3ce44SJohn Forte rtn = EFAULT; 905*fcf3ce44SJohn Forte } 906*fcf3ce44SJohn Forte kmem_free(pp, sizeof (*pp)); 907*fcf3ce44SJohn Forte } 908*fcf3ce44SJohn Forte /* 909*fcf3ce44SJohn Forte * if initiator parameter set, modify all associated 910*fcf3ce44SJohn Forte * sessions that don't already have the parameter 911*fcf3ce44SJohn Forte * overriden 912*fcf3ce44SJohn Forte */ 913*fcf3ce44SJohn Forte if (ils->s_oid == ihp->hba_oid) { 914*fcf3ce44SJohn Forte ilg = (iscsi_param_get_t *) 915*fcf3ce44SJohn Forte kmem_alloc(sizeof (*ilg), KM_SLEEP); 916*fcf3ce44SJohn Forte 917*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 918*fcf3ce44SJohn Forte for (isp = ihp->hba_sess_list; isp; 919*fcf3ce44SJohn Forte isp = isp->sess_next) { 920*fcf3ce44SJohn Forte 921*fcf3ce44SJohn Forte ilg->g_param = ils->s_param; 922*fcf3ce44SJohn Forte params = &isp->sess_params; 923*fcf3ce44SJohn Forte if (iscsi_get_persisted_param( 924*fcf3ce44SJohn Forte isp->sess_name, ilg, params) != 0) { 925*fcf3ce44SJohn Forte 926*fcf3ce44SJohn Forte rtn = iscsi_set_param(params, ils); 927*fcf3ce44SJohn Forte if (rtn != 0) { 928*fcf3ce44SJohn Forte break; 929*fcf3ce44SJohn Forte } 930*fcf3ce44SJohn Forte 931*fcf3ce44SJohn Forte /* 932*fcf3ce44SJohn Forte * Notify the session that 933*fcf3ce44SJohn Forte * the login parameters have 934*fcf3ce44SJohn Forte * changed. 935*fcf3ce44SJohn Forte */ 936*fcf3ce44SJohn Forte mutex_enter(&isp-> 937*fcf3ce44SJohn Forte sess_state_mutex); 938*fcf3ce44SJohn Forte iscsi_sess_state_machine(isp, 939*fcf3ce44SJohn Forte ISCSI_SESS_EVENT_N7); 940*fcf3ce44SJohn Forte mutex_exit(&isp-> 941*fcf3ce44SJohn Forte sess_state_mutex); 942*fcf3ce44SJohn Forte } 943*fcf3ce44SJohn Forte } 944*fcf3ce44SJohn Forte kmem_free(ilg, sizeof (*ilg)); 945*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 946*fcf3ce44SJohn Forte } 947*fcf3ce44SJohn Forte } 948*fcf3ce44SJohn Forte return (rtn); 949*fcf3ce44SJohn Forte } 950*fcf3ce44SJohn Forte 951*fcf3ce44SJohn Forte int 952*fcf3ce44SJohn Forte iscsi_target_prop_mod(iscsi_hba_t *ihp, iscsi_property_t *ipp, int cmd) 953*fcf3ce44SJohn Forte { 954*fcf3ce44SJohn Forte iscsi_sess_t *isp = NULL; 955*fcf3ce44SJohn Forte iscsi_conn_t *icp; 956*fcf3ce44SJohn Forte int rtn; 957*fcf3ce44SJohn Forte char *name; 958*fcf3ce44SJohn Forte 959*fcf3ce44SJohn Forte /* 960*fcf3ce44SJohn Forte * If we're just attempting to get the target properties don't 961*fcf3ce44SJohn Forte * create the session if it doesn't already exist. If we setting 962*fcf3ce44SJohn Forte * the property then create the session if needed because we'll 963*fcf3ce44SJohn Forte * most likely see an ISCSI_LOGIN in a few. 964*fcf3ce44SJohn Forte */ 965*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 966*fcf3ce44SJohn Forte 967*fcf3ce44SJohn Forte /* 968*fcf3ce44SJohn Forte * If the oid does represent a session check to see 969*fcf3ce44SJohn Forte * if it is a target oid. If so, return the target's 970*fcf3ce44SJohn Forte * associated session. 971*fcf3ce44SJohn Forte */ 972*fcf3ce44SJohn Forte rtn = iscsi_sess_get(ipp->p_oid, ihp, &isp); 973*fcf3ce44SJohn Forte if (rtn != 0) { 974*fcf3ce44SJohn Forte rtn = iscsi_sess_get_by_target(ipp->p_oid, ihp, &isp); 975*fcf3ce44SJohn Forte } 976*fcf3ce44SJohn Forte 977*fcf3ce44SJohn Forte /* 978*fcf3ce44SJohn Forte * If rtn is zero then we have found an existing session. 979*fcf3ce44SJohn Forte * Use the session name for database lookup. If rtn is 980*fcf3ce44SJohn Forte * non-zero then create a targetparam object and use 981*fcf3ce44SJohn Forte * its name for database lookup. 982*fcf3ce44SJohn Forte */ 983*fcf3ce44SJohn Forte if (rtn == 0) { 984*fcf3ce44SJohn Forte name = (char *)isp->sess_name; 985*fcf3ce44SJohn Forte } else { 986*fcf3ce44SJohn Forte name = (char *)iscsi_targetparam_get_name(ipp->p_oid); 987*fcf3ce44SJohn Forte isp = NULL; 988*fcf3ce44SJohn Forte } 989*fcf3ce44SJohn Forte 990*fcf3ce44SJohn Forte if (name == NULL) { 991*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 992*fcf3ce44SJohn Forte rtn = EFAULT; 993*fcf3ce44SJohn Forte return (rtn); 994*fcf3ce44SJohn Forte } 995*fcf3ce44SJohn Forte 996*fcf3ce44SJohn Forte rtn = 0; 997*fcf3ce44SJohn Forte if (cmd == ISCSI_TARGET_PROPS_GET) { 998*fcf3ce44SJohn Forte /* 999*fcf3ce44SJohn Forte * If isp is not null get the session's parameters, otherwise 1000*fcf3ce44SJohn Forte * the get is for a target-param object so defaults need to 1001*fcf3ce44SJohn Forte * be returned. 1002*fcf3ce44SJohn Forte */ 1003*fcf3ce44SJohn Forte if (isp != NULL) { 1004*fcf3ce44SJohn Forte int conn_count = 0; 1005*fcf3ce44SJohn Forte 1006*fcf3ce44SJohn Forte bcopy(isp->sess_alias, ipp->p_alias, 1007*fcf3ce44SJohn Forte isp->sess_alias_length); 1008*fcf3ce44SJohn Forte bcopy(isp->sess_name, ipp->p_name, 1009*fcf3ce44SJohn Forte isp->sess_name_length); 1010*fcf3ce44SJohn Forte ipp->p_alias_len = isp->sess_alias_length; 1011*fcf3ce44SJohn Forte ipp->p_name_len = isp->sess_name_length; 1012*fcf3ce44SJohn Forte ipp->p_discovery = isp->sess_discovered_by; 1013*fcf3ce44SJohn Forte ipp->p_last_err = isp->sess_last_err; 1014*fcf3ce44SJohn Forte ipp->p_tpgt_conf = isp->sess_tpgt_conf; 1015*fcf3ce44SJohn Forte ipp->p_tpgt_nego = isp->sess_tpgt_nego; 1016*fcf3ce44SJohn Forte bcopy(isp->sess_isid, ipp->p_isid, ISCSI_ISID_LEN); 1017*fcf3ce44SJohn Forte 1018*fcf3ce44SJohn Forte rw_enter(&isp->sess_conn_list_rwlock, RW_READER); 1019*fcf3ce44SJohn Forte for (icp = isp->sess_conn_list; icp; 1020*fcf3ce44SJohn Forte icp = icp->conn_next) { 1021*fcf3ce44SJohn Forte if (icp->conn_state == 1022*fcf3ce44SJohn Forte ISCSI_CONN_STATE_LOGGED_IN) { 1023*fcf3ce44SJohn Forte conn_count++; 1024*fcf3ce44SJohn Forte } 1025*fcf3ce44SJohn Forte } 1026*fcf3ce44SJohn Forte rw_exit(&isp->sess_conn_list_rwlock); 1027*fcf3ce44SJohn Forte ipp->p_num_of_connections = conn_count; 1028*fcf3ce44SJohn Forte ipp->p_connected = (conn_count > 0) ? B_TRUE : B_FALSE; 1029*fcf3ce44SJohn Forte } else { 1030*fcf3ce44SJohn Forte bcopy(name, ipp->p_name, strlen(name)); 1031*fcf3ce44SJohn Forte ipp->p_name_len = strlen(name); 1032*fcf3ce44SJohn Forte bcopy("", ipp->p_alias, strlen("")); 1033*fcf3ce44SJohn Forte ipp->p_alias_len = strlen(""); 1034*fcf3ce44SJohn Forte ipp->p_discovery = iSCSIDiscoveryMethodUnknown; 1035*fcf3ce44SJohn Forte ipp->p_last_err = NoError; 1036*fcf3ce44SJohn Forte ipp->p_tpgt_conf = ISCSI_DEFAULT_TPGT; 1037*fcf3ce44SJohn Forte ipp->p_tpgt_nego = ISCSI_DEFAULT_TPGT; 1038*fcf3ce44SJohn Forte ipp->p_num_of_connections = 0; 1039*fcf3ce44SJohn Forte ipp->p_connected = B_FALSE; 1040*fcf3ce44SJohn Forte } 1041*fcf3ce44SJohn Forte } else { 1042*fcf3ce44SJohn Forte if (isp == NULL) { 1043*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 1044*fcf3ce44SJohn Forte rtn = EFAULT; 1045*fcf3ce44SJohn Forte return (rtn); 1046*fcf3ce44SJohn Forte } 1047*fcf3ce44SJohn Forte 1048*fcf3ce44SJohn Forte /* ISCSI_TARGET_PROPS_SET */ 1049*fcf3ce44SJohn Forte /* 1050*fcf3ce44SJohn Forte * only update if new, otherwise could clear out alias 1051*fcf3ce44SJohn Forte * if just updating the discovery. 1052*fcf3ce44SJohn Forte */ 1053*fcf3ce44SJohn Forte if (ipp->p_alias_len != 0) { 1054*fcf3ce44SJohn Forte bcopy(ipp->p_alias, isp->sess_alias, 1055*fcf3ce44SJohn Forte ipp->p_alias_len); 1056*fcf3ce44SJohn Forte isp->sess_alias_length = ipp->p_alias_len; 1057*fcf3ce44SJohn Forte } 1058*fcf3ce44SJohn Forte isp->sess_discovered_by = ipp->p_discovery; 1059*fcf3ce44SJohn Forte } 1060*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 1061*fcf3ce44SJohn Forte return (rtn); 1062*fcf3ce44SJohn Forte } 1063*fcf3ce44SJohn Forte 1064*fcf3ce44SJohn Forte /* 1065*fcf3ce44SJohn Forte * iscsi_ioctl_get_config_sess - gets configured session information 1066*fcf3ce44SJohn Forte * 1067*fcf3ce44SJohn Forte * This function is an ioctl helper function to get the 1068*fcf3ce44SJohn Forte * configured session information from the persistent store. 1069*fcf3ce44SJohn Forte */ 1070*fcf3ce44SJohn Forte int 1071*fcf3ce44SJohn Forte iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp, iscsi_config_sess_t *ics) 1072*fcf3ce44SJohn Forte { 1073*fcf3ce44SJohn Forte uchar_t *name; 1074*fcf3ce44SJohn Forte 1075*fcf3ce44SJohn Forte /* Get the matching iscsi node name for the oid */ 1076*fcf3ce44SJohn Forte if (ics->ics_oid == ISCSI_INITIATOR_OID) { 1077*fcf3ce44SJohn Forte /* initiator name */ 1078*fcf3ce44SJohn Forte name = ihp->hba_name; 1079*fcf3ce44SJohn Forte } else { 1080*fcf3ce44SJohn Forte /* target name */ 1081*fcf3ce44SJohn Forte name = iscsi_targetparam_get_name(ics->ics_oid); 1082*fcf3ce44SJohn Forte if (name == NULL) { 1083*fcf3ce44SJohn Forte /* invalid node name */ 1084*fcf3ce44SJohn Forte return (EINVAL); 1085*fcf3ce44SJohn Forte } 1086*fcf3ce44SJohn Forte } 1087*fcf3ce44SJohn Forte 1088*fcf3ce44SJohn Forte /* get configured session information */ 1089*fcf3ce44SJohn Forte if (persistent_get_config_session((char *)name, ics) == B_FALSE) { 1090*fcf3ce44SJohn Forte /* 1091*fcf3ce44SJohn Forte * There might not be anything in the database yet. If 1092*fcf3ce44SJohn Forte * this is a request for the target check the initiator 1093*fcf3ce44SJohn Forte * value. If neither is set return the default value. 1094*fcf3ce44SJohn Forte */ 1095*fcf3ce44SJohn Forte if (ics->ics_oid != ISCSI_INITIATOR_OID) { 1096*fcf3ce44SJohn Forte if (persistent_get_config_session( 1097*fcf3ce44SJohn Forte (char *)ihp->hba_name, ics) == B_FALSE) { 1098*fcf3ce44SJohn Forte /* 1099*fcf3ce44SJohn Forte * No initiator value is set. 1100*fcf3ce44SJohn Forte * Return the defaults. 1101*fcf3ce44SJohn Forte */ 1102*fcf3ce44SJohn Forte ics->ics_out = ISCSI_DEFAULT_SESS_NUM; 1103*fcf3ce44SJohn Forte ics->ics_bound = ISCSI_DEFAULT_SESS_BOUND; 1104*fcf3ce44SJohn Forte } 1105*fcf3ce44SJohn Forte } else { 1106*fcf3ce44SJohn Forte ics->ics_out = ISCSI_DEFAULT_SESS_NUM; 1107*fcf3ce44SJohn Forte ics->ics_bound = ISCSI_DEFAULT_SESS_BOUND; 1108*fcf3ce44SJohn Forte } 1109*fcf3ce44SJohn Forte } 1110*fcf3ce44SJohn Forte 1111*fcf3ce44SJohn Forte return (0); 1112*fcf3ce44SJohn Forte } 1113*fcf3ce44SJohn Forte 1114*fcf3ce44SJohn Forte /* 1115*fcf3ce44SJohn Forte * iscsi_ioctl_set_config_sess - sets configured session information 1116*fcf3ce44SJohn Forte * 1117*fcf3ce44SJohn Forte * This function is an ioctl helper function to set the 1118*fcf3ce44SJohn Forte * configured session information in the persistent store. 1119*fcf3ce44SJohn Forte * In addition it will notify any active sessions of the 1120*fcf3ce44SJohn Forte * changed so this can update binding information. It 1121*fcf3ce44SJohn Forte * will also destroy sessions that were removed and add 1122*fcf3ce44SJohn Forte * new sessions. 1123*fcf3ce44SJohn Forte */ 1124*fcf3ce44SJohn Forte int 1125*fcf3ce44SJohn Forte iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp, iscsi_config_sess_t *ics) 1126*fcf3ce44SJohn Forte { 1127*fcf3ce44SJohn Forte uchar_t *name; 1128*fcf3ce44SJohn Forte iscsi_sess_t *isp; 1129*fcf3ce44SJohn Forte 1130*fcf3ce44SJohn Forte /* check range infomration */ 1131*fcf3ce44SJohn Forte if ((ics->ics_in < ISCSI_MIN_CONFIG_SESSIONS) || 1132*fcf3ce44SJohn Forte (ics->ics_in > ISCSI_MAX_CONFIG_SESSIONS)) { 1133*fcf3ce44SJohn Forte /* invalid range information */ 1134*fcf3ce44SJohn Forte return (EINVAL); 1135*fcf3ce44SJohn Forte } 1136*fcf3ce44SJohn Forte 1137*fcf3ce44SJohn Forte if (ics->ics_oid == ISCSI_INITIATOR_OID) { 1138*fcf3ce44SJohn Forte name = ihp->hba_name; 1139*fcf3ce44SJohn Forte } else { 1140*fcf3ce44SJohn Forte /* get target name */ 1141*fcf3ce44SJohn Forte name = iscsi_targetparam_get_name(ics->ics_oid); 1142*fcf3ce44SJohn Forte if (name == NULL) { 1143*fcf3ce44SJohn Forte /* invalid node name */ 1144*fcf3ce44SJohn Forte return (EINVAL); 1145*fcf3ce44SJohn Forte } 1146*fcf3ce44SJohn Forte } 1147*fcf3ce44SJohn Forte 1148*fcf3ce44SJohn Forte /* store the new information */ 1149*fcf3ce44SJohn Forte if (persistent_set_config_session((char *)name, ics) == B_FALSE) { 1150*fcf3ce44SJohn Forte /* failed to store new information */ 1151*fcf3ce44SJohn Forte return (EINVAL); 1152*fcf3ce44SJohn Forte } 1153*fcf3ce44SJohn Forte 1154*fcf3ce44SJohn Forte /* notify existing sessions of change */ 1155*fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_READER); 1156*fcf3ce44SJohn Forte isp = ihp->hba_sess_list; 1157*fcf3ce44SJohn Forte while (isp != NULL) { 1158*fcf3ce44SJohn Forte 1159*fcf3ce44SJohn Forte if ((ics->ics_oid == ISCSI_INITIATOR_OID) || 1160*fcf3ce44SJohn Forte (strncmp((char *)isp->sess_name, (char *)name, 1161*fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN) == 0)) { 1162*fcf3ce44SJohn Forte 1163*fcf3ce44SJohn Forte /* 1164*fcf3ce44SJohn Forte * If this sessions least signficant byte 1165*fcf3ce44SJohn Forte * of the isid is less than or equal to 1166*fcf3ce44SJohn Forte * the the number of configured sessions 1167*fcf3ce44SJohn Forte * then we need to tear down this session. 1168*fcf3ce44SJohn Forte */ 1169*fcf3ce44SJohn Forte if (ics->ics_in <= isp->sess_isid[5]) { 1170*fcf3ce44SJohn Forte /* First attempt to destory the session */ 1171*fcf3ce44SJohn Forte if (ISCSI_SUCCESS(iscsi_sess_destroy(isp))) { 1172*fcf3ce44SJohn Forte isp = ihp->hba_sess_list; 1173*fcf3ce44SJohn Forte } else { 1174*fcf3ce44SJohn Forte /* 1175*fcf3ce44SJohn Forte * If we can't destroy it then 1176*fcf3ce44SJohn Forte * atleast poke it to disconnect 1177*fcf3ce44SJohn Forte * it. 1178*fcf3ce44SJohn Forte */ 1179*fcf3ce44SJohn Forte mutex_enter(&isp->sess_state_mutex); 1180*fcf3ce44SJohn Forte iscsi_sess_state_machine(isp, 1181*fcf3ce44SJohn Forte ISCSI_SESS_EVENT_N7); 1182*fcf3ce44SJohn Forte mutex_exit(&isp->sess_state_mutex); 1183*fcf3ce44SJohn Forte isp = isp->sess_next; 1184*fcf3ce44SJohn Forte } 1185*fcf3ce44SJohn Forte } else { 1186*fcf3ce44SJohn Forte isp = isp->sess_next; 1187*fcf3ce44SJohn Forte } 1188*fcf3ce44SJohn Forte } else { 1189*fcf3ce44SJohn Forte isp = isp->sess_next; 1190*fcf3ce44SJohn Forte } 1191*fcf3ce44SJohn Forte } 1192*fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock); 1193*fcf3ce44SJohn Forte 1194*fcf3ce44SJohn Forte /* 1195*fcf3ce44SJohn Forte * The number of targets has changed. Since we don't expect 1196*fcf3ce44SJohn Forte * this to be a common operation lets keep the code simple and 1197*fcf3ce44SJohn Forte * just use a slightly larger hammer and poke discovery. This 1198*fcf3ce44SJohn Forte * force the reevaulation of this target and all other targets. 1199*fcf3ce44SJohn Forte */ 1200*fcf3ce44SJohn Forte iscsid_poke_discovery(ihp, iSCSIDiscoveryMethodUnknown); 1201*fcf3ce44SJohn Forte /* lock so only one config operation occrs */ 1202*fcf3ce44SJohn Forte sema_p(&iscsid_config_semaphore); 1203*fcf3ce44SJohn Forte iscsid_config_all(ihp, B_FALSE); 1204*fcf3ce44SJohn Forte sema_v(&iscsid_config_semaphore); 1205*fcf3ce44SJohn Forte 1206*fcf3ce44SJohn Forte return (0); 1207*fcf3ce44SJohn Forte } 1208