iscsi_lun.c revision 6cefaae1e90a413ba01560575bb3998e1a3df40e
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iSCSI logical unit interfaces
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* tpgt bytes in string form */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* logical unit number bytes in string form */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Addition addr size of size of ',' + max str form of tpgt (2 bytes) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ',' + max str form of logical unit number (4 bytes).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ADDR_EXT_SIZE (1 + TPGT_EXT_SIZE + 1 + LUN_EXT_SIZE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* internal interfaces */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic iscsi_status_t iscsi_lun_virt_create(iscsi_sess_t *isp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t lun_num, iscsi_lun_t *ilp, struct scsi_inquiry *inq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic iscsi_status_t iscsi_lun_phys_create(iscsi_sess_t *isp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t lun_num, iscsi_lun_t *ilp, struct scsi_inquiry *inq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | External Connection Interfaces |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_create - This function will create a lun mapping.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * logic specific to MPxIO vs. NDI node creation is switched
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * out to a helper function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, uint8_t lun_addr_type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_status_t rtn = ISCSI_STATUS_INTERNAL_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte addr = kmem_zalloc((strlen((char *)isp->sess_name) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* allocate space for lun struct */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilp = kmem_zalloc(sizeof (iscsi_lun_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* initialize common LU information */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(inq->inq_vid, ilp->lun_vid, sizeof (inq->inq_vid));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(inq->inq_pid, ilp->lun_pid, sizeof (inq->inq_pid));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* store GUID if valid one exists */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilp->lun_guid = kmem_zalloc(ilp->lun_guid_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We need to add the lun to our lists now because during the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lun creation we will get called back into multiple times
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * depending on the createion type. These callbacks will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * occur via our tran_init_lun, tran_get_name, tran_get_bus_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tran_init_pkt, tran_start.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Attempt to create a scsi_vhci binding if GUID is available */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rtn = iscsi_lun_virt_create(isp, lun_num, ilp, inq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* unable to bind under scsi_vhci, failback to ndi */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rtn = iscsi_lun_phys_create(isp, lun_num, ilp, inq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If NOT successful we need to remove the lun from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * session and free any related resources.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if head, set head to our next */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if not head, set prev lun's next to our next */
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng /* Check whether this is the required LUN for iscsi boot */
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng if (iscsiboot_prop != NULL && isp->sess_boot == B_TRUE &&
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng (uint64_t *)iscsiboot_prop->boot_tgt.tgt_boot_lun;
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng * During iscsi boot, the boot lun has been
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng * online, we should set the "online flag".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_destroy - offline and remove lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This interface is called when a name service change has
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * occured and the storage is no longer available to this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * initiator. This function will offline and free the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * solaris node resources. Then it will free all iscsi lun
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * resources.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function can fail with ISCSI_STATUS_BUSY if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * logical unit is in use. The user should unmount or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * close the device and perform the nameservice operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * again if this occurs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_destroy(iscsi_hba_t *ihp, iscsi_lun_t *ilp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* attempt to offline and free solaris node */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If we successfully unplumbed the lun remove it from our lists */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* target first item in list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * search session list for ilp pointing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to lun being removed. Then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * update that luns next pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* couldn't find session */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* release its memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ilp->lun_addr, (strlen((char *)isp->sess_name) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | External Logical Unit Interfaces |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------------------------------------------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_virt_create - Creates solaris logical unit via MDI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_virt_create(iscsi_sess_t *isp, uint16_t lun_num, iscsi_lun_t *ilp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_status_t rtn = ISCSI_STATUS_INTERNAL_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Generate compatible property
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if nodename can't be determined then print a message and skip it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver found no compatible driver "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "for %s lun %d dtype:0x%02x", isp->sess_name, lun_num,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mdi_rtn = mdi_pi_alloc_compatible(ihp->hba_dip, nodename,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilp->lun_guid, ilp->lun_addr, compatible, ncompatible,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (MDI_GUID)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (TARGET_PROP)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (LUN_PROP)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mdi_prop_update_string_array(pip, "compatible",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (COMPATIBLE)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_hba_nodename_compatible_free(nodename, compatible);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_phys_create - creates solaris logical unit via NDI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_phys_create(iscsi_sess_t *isp, uint16_t lun_num,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_status_t rtn = ISCSI_STATUS_INTERNAL_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get the 'scsi-binding-set' property */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_prop_lookup_string(DDI_DEV_T_ANY, isp->sess_hba->hba_dip,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "scsi-binding-set",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* generate compatible property */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_hba_nodename_compatible_get(inq, scsi_binding_set,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if nodename can't be determined then print a message and skip it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver found no compatible driver "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if lun alloc success, set props */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (TARGET_PROP)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (LUN_PROP)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to create "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "property for %s lun %d (COMPATIBLE)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If props were setup ok, online the lun */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Try to online the new node */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If success set rtn flag, else unwire alloc'd lun */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Assign the instance number for the dev_link
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * generator. This will ensure the link name is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unique and persistent across reboots.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "iscsi driver unable to online "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_hba_nodename_compatible_free(nodename, compatible);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_online - _di_online logical unit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is called after a path has recovered it will cause
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an offline path to become online/active again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_online(iscsi_hba_t *ihp, iscsi_lun_t *ilp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((ilp->lun_pip != NULL) || (ilp->lun_dip != NULL));
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng /* Check whether this is the required LUN for iscsi boot */
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng (uint64_t *)iscsiboot_prop->boot_tgt.tgt_boot_lun;
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng * During iscsi boot, the boot lun has been
6cefaae1e90a413ba01560575bb3998e1a3df40eJack Meng * online, we should set the "online flag".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_offline - attempt _di_offline [and optional _di_free]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is called via two paths. When a transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * path has failed it will be called to offline the logical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * unit. When nameservice access has been removed it will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be called to both offline and free the logical unit.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (This operates soley on the solaris node states.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_lun_destroy() should be called when attempting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to free all iscsi lun resources.)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function can fail with ISCSI_STATUS_BUSY if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * logical unit is in use. The user should unmount or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * close the device and perform the nameservice operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * again if this occurs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_lun_offline(iscsi_hba_t *ihp, iscsi_lun_t *ilp, boolean_t lun_free)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT((ilp->lun_pip != NULL) || (ilp->lun_dip != NULL));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since we carry the logical units parent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * lock across the offline call it will not
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * issue devfs_clean() and may fail with a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * devi_ref count > 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Make sure node is attached otherwise
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it won't have related cache nodes to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clean up. i_ddi_devi_attached is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * similiar to i_ddi_node_state(cdip) >=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DS_ATTACHED. We should clean up only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when lun_free is set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get parent dip */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get full devname */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Release lock before devfs_clean() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Clean cache */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Attempt to offline the logical units */