1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte /*
22904e51f6SJack Meng * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23*7284664aSJoshua M. Clulow * Copyright 2019 Joshua M. Clulow <josh@sysmgr.org>
24fcf3ce44SJohn Forte */
25fcf3ce44SJohn Forte
26fcf3ce44SJohn Forte /*
27fcf3ce44SJohn Forte * ISCSID --
28fcf3ce44SJohn Forte *
29fcf3ce44SJohn Forte * Discovery of targets and access to the persistent storage starts here.
30fcf3ce44SJohn Forte */
31fcf3ce44SJohn Forte
32fcf3ce44SJohn Forte #include <sys/thread.h>
33fcf3ce44SJohn Forte #include <sys/types.h>
34fcf3ce44SJohn Forte #include <sys/proc.h> /* declares: p0 */
35fcf3ce44SJohn Forte #include <sys/cmn_err.h>
36fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_if.h>
37fcf3ce44SJohn Forte #include <netinet/in.h>
38fcf3ce44SJohn Forte #include "iscsi_targetparam.h"
39fcf3ce44SJohn Forte #include "isns_client.h"
40fcf3ce44SJohn Forte #include "isns_protocol.h"
41fcf3ce44SJohn Forte #include "persistent.h"
42fcf3ce44SJohn Forte #include "iscsi.h"
43fcf3ce44SJohn Forte #include <sys/ethernet.h>
446cefaae1SJack Meng #include <sys/bootprops.h>
45fcf3ce44SJohn Forte
46fcf3ce44SJohn Forte /*
47fcf3ce44SJohn Forte * local function prototypes
48fcf3ce44SJohn Forte */
49fcf3ce44SJohn Forte static boolean_t iscsid_init_config(iscsi_hba_t *ihp);
50fcf3ce44SJohn Forte static boolean_t iscsid_init_targets(iscsi_hba_t *ihp);
51fcf3ce44SJohn Forte static void iscsid_thread_static(iscsi_thread_t *thread, void *p);
52fcf3ce44SJohn Forte static void iscsid_thread_sendtgts(iscsi_thread_t *thread, void *p);
53fcf3ce44SJohn Forte static void iscsid_thread_isns(iscsi_thread_t *thread, void *p);
54fcf3ce44SJohn Forte static void iscsid_thread_slp(iscsi_thread_t *thread, void *p);
556cefaae1SJack Meng static void iscsid_thread_boot_wd(iscsi_thread_t *thread, void *p);
56fcf3ce44SJohn Forte static void iscsid_threads_create(iscsi_hba_t *ihp);
57fcf3ce44SJohn Forte static void iscsid_threads_destroy(void);
58fcf3ce44SJohn Forte static int iscsid_copyto_param_set(uint32_t param_id,
59fcf3ce44SJohn Forte iscsi_login_params_t *params, iscsi_param_set_t *ipsp);
60fcf3ce44SJohn Forte static void iscsid_add_pg_list_to_cache(iscsi_hba_t *ihp,
61fcf3ce44SJohn Forte isns_portal_group_list_t *pg_list);
62fcf3ce44SJohn Forte static void iscsid_remove_target_param(char *name);
63fcf3ce44SJohn Forte static boolean_t iscsid_add(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method,
64fcf3ce44SJohn Forte struct sockaddr *addr_dsc, char *target_name, int tpgt,
65fcf3ce44SJohn Forte struct sockaddr *addr_tgt);
66fcf3ce44SJohn Forte static void iscsi_discovery_event(iscsi_hba_t *ihp,
67fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t m, boolean_t start);
686cefaae1SJack Meng static boolean_t iscsid_boot_init_config(iscsi_hba_t *ihp);
696cefaae1SJack Meng static iscsi_sess_t *iscsi_add_boot_sess(iscsi_hba_t *ihp, int isid);
706cefaae1SJack Meng static boolean_t iscsid_make_entry(ib_boot_prop_t *boot_prop_entry,
716cefaae1SJack Meng entry_t *entry);
72f53e1f19SJack Meng static boolean_t iscsid_check_active_boot_conn(iscsi_hba_t *ihp);
736cefaae1SJack Meng
746cefaae1SJack Meng extern int modrootloaded;
756cefaae1SJack Meng int iscsi_configroot_retry = 20;
766cefaae1SJack Meng static boolean_t iscsi_configroot_printed = FALSE;
7730e7468fSPeter Dunlap static int iscsi_net_up = 0;
786cefaae1SJack Meng extern ib_boot_prop_t *iscsiboot_prop;
79fcf3ce44SJohn Forte
80f53e1f19SJack Meng #define ISCSI_CONFIGROOT_DELAY 1
81f53e1f19SJack Meng
82fcf3ce44SJohn Forte /*
83fcf3ce44SJohn Forte * iSCSI target discovery thread table
84fcf3ce44SJohn Forte */
85fcf3ce44SJohn Forte typedef struct iscsid_thr_table {
86fcf3ce44SJohn Forte void (*func_start)(iscsi_thread_t *, void *);
87fcf3ce44SJohn Forte iscsi_thread_t *thr_id;
88fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t method;
89fcf3ce44SJohn Forte char *name;
90fcf3ce44SJohn Forte } iscsid_thr_table;
91fcf3ce44SJohn Forte
92fcf3ce44SJohn Forte static iscsid_thr_table iscsid_thr[] = {
93fcf3ce44SJohn Forte { iscsid_thread_static, NULL,
94fcf3ce44SJohn Forte iSCSIDiscoveryMethodStatic,
95fcf3ce44SJohn Forte "Static" },
96fcf3ce44SJohn Forte { iscsid_thread_sendtgts, NULL,
97fcf3ce44SJohn Forte iSCSIDiscoveryMethodSendTargets,
98fcf3ce44SJohn Forte "SendTarget" },
99fcf3ce44SJohn Forte { iscsid_thread_slp, NULL,
100fcf3ce44SJohn Forte iSCSIDiscoveryMethodSLP,
101fcf3ce44SJohn Forte "SLP" },
102fcf3ce44SJohn Forte { iscsid_thread_isns, NULL,
103fcf3ce44SJohn Forte iSCSIDiscoveryMethodISNS,
104fcf3ce44SJohn Forte "iSNS" },
105fcf3ce44SJohn Forte { NULL, NULL,
106fcf3ce44SJohn Forte iSCSIDiscoveryMethodUnknown,
107fcf3ce44SJohn Forte NULL }
108fcf3ce44SJohn Forte };
109fcf3ce44SJohn Forte
110fcf3ce44SJohn Forte /*
111fcf3ce44SJohn Forte * discovery method event table
112fcf3ce44SJohn Forte */
113fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t for_failure[] = {
114fcf3ce44SJohn Forte iSCSIDiscoveryMethodStatic,
115fcf3ce44SJohn Forte iSCSIDiscoveryMethodSLP,
116fcf3ce44SJohn Forte iSCSIDiscoveryMethodISNS,
117fcf3ce44SJohn Forte iSCSIDiscoveryMethodSendTargets,
118fcf3ce44SJohn Forte iSCSIDiscoveryMethodUnknown /* terminating value */
119fcf3ce44SJohn Forte };
120fcf3ce44SJohn Forte
1216cefaae1SJack Meng /*
1226cefaae1SJack Meng * The following private tunable, set in /etc/system, e.g.,
1236cefaae1SJack Meng * set iscsi:iscsi_boot_max_delay = 360
1246cefaae1SJack Meng * , provides with customer a max wait time in
1256cefaae1SJack Meng * seconds to wait for boot lun online during iscsi boot.
1266cefaae1SJack Meng * Defaults to 180s.
1276cefaae1SJack Meng */
1286cefaae1SJack Meng int iscsi_boot_max_delay = ISCSI_BOOT_DEFAULT_MAX_DELAY;
1296cefaae1SJack Meng
130fcf3ce44SJohn Forte /*
131fcf3ce44SJohn Forte * discovery configuration semaphore
132fcf3ce44SJohn Forte */
133fcf3ce44SJohn Forte ksema_t iscsid_config_semaphore;
134fcf3ce44SJohn Forte
1356cefaae1SJack Meng static iscsi_thread_t *iscsi_boot_wd_handle = NULL;
1366cefaae1SJack Meng
137fcf3ce44SJohn Forte #define CHECK_METHOD(v) ((dm & v) ? B_TRUE : B_FALSE)
138fcf3ce44SJohn Forte
1396cefaae1SJack Meng /*
1406cefaae1SJack Meng * Check if IP is valid
1416cefaae1SJack Meng */
1426cefaae1SJack Meng static boolean_t
iscsid_ip_check(char * ip)1436cefaae1SJack Meng iscsid_ip_check(char *ip)
1446cefaae1SJack Meng {
1456cefaae1SJack Meng int i = 0;
1466cefaae1SJack Meng
1476cefaae1SJack Meng if (!ip)
1486cefaae1SJack Meng return (B_FALSE);
1496cefaae1SJack Meng for (; (ip[i] == 0) && (i < IB_IP_BUFLEN); i++) {}
1506cefaae1SJack Meng if (i == IB_IP_BUFLEN) {
1516cefaae1SJack Meng /* invalid IP address */
1526cefaae1SJack Meng return (B_FALSE);
1536cefaae1SJack Meng }
1546cefaae1SJack Meng return (B_TRUE);
1556cefaae1SJack Meng }
1566cefaae1SJack Meng
1576cefaae1SJack Meng /*
1586cefaae1SJack Meng * Make an entry for the boot target.
1596cefaae1SJack Meng * return B_TRUE upon success
1606cefaae1SJack Meng * B_FALSE if fail
1616cefaae1SJack Meng */
1626cefaae1SJack Meng static boolean_t
iscsid_make_entry(ib_boot_prop_t * boot_prop_entry,entry_t * entry)1636cefaae1SJack Meng iscsid_make_entry(ib_boot_prop_t *boot_prop_entry, entry_t *entry)
1646cefaae1SJack Meng {
1656cefaae1SJack Meng if (entry == NULL || boot_prop_entry == NULL) {
1666cefaae1SJack Meng return (B_FALSE);
1676cefaae1SJack Meng }
1686cefaae1SJack Meng
1696cefaae1SJack Meng if (!iscsid_ip_check(
1706cefaae1SJack Meng (char *)&boot_prop_entry->boot_tgt.tgt_ip_u))
1716cefaae1SJack Meng return (B_FALSE);
1726cefaae1SJack Meng
1736cefaae1SJack Meng if (boot_prop_entry->boot_tgt.sin_family != AF_INET &&
1746cefaae1SJack Meng boot_prop_entry->boot_tgt.sin_family != AF_INET6)
1756cefaae1SJack Meng return (B_FALSE);
1766cefaae1SJack Meng
1776cefaae1SJack Meng entry->e_vers = ISCSI_INTERFACE_VERSION;
1786cefaae1SJack Meng
1796cefaae1SJack Meng mutex_enter(&iscsi_oid_mutex);
1806cefaae1SJack Meng entry->e_oid = iscsi_oid++;
1816cefaae1SJack Meng mutex_exit(&iscsi_oid_mutex);
1826cefaae1SJack Meng
1836cefaae1SJack Meng entry->e_tpgt = ISCSI_DEFAULT_TPGT;
1846cefaae1SJack Meng
1856cefaae1SJack Meng if (boot_prop_entry->boot_tgt.sin_family == AF_INET) {
1866cefaae1SJack Meng entry->e_u.u_in4.s_addr =
1876cefaae1SJack Meng boot_prop_entry->boot_tgt.tgt_ip_u.u_in4.s_addr;
1886cefaae1SJack Meng entry->e_insize = sizeof (struct in_addr);
1896cefaae1SJack Meng } else {
1906cefaae1SJack Meng (void) bcopy(
1916cefaae1SJack Meng &boot_prop_entry->boot_tgt.tgt_ip_u.u_in6.s6_addr,
1926cefaae1SJack Meng entry->e_u.u_in6.s6_addr, 16);
1936cefaae1SJack Meng entry->e_insize = sizeof (struct in6_addr);
1946cefaae1SJack Meng }
1956cefaae1SJack Meng
1966cefaae1SJack Meng entry->e_port = boot_prop_entry->boot_tgt.tgt_port;
1976cefaae1SJack Meng entry->e_boot = B_TRUE;
1986cefaae1SJack Meng return (B_TRUE);
1996cefaae1SJack Meng }
2006cefaae1SJack Meng
2016cefaae1SJack Meng /*
2026cefaae1SJack Meng * Create the boot session
2036cefaae1SJack Meng */
2046cefaae1SJack Meng static void
iscsi_boot_session_create(iscsi_hba_t * ihp,ib_boot_prop_t * boot_prop_table)2056cefaae1SJack Meng iscsi_boot_session_create(iscsi_hba_t *ihp,
2066cefaae1SJack Meng ib_boot_prop_t *boot_prop_table)
2076cefaae1SJack Meng {
2086cefaae1SJack Meng iSCSIDiscoveryMethod_t dm;
2096cefaae1SJack Meng entry_t e;
2106cefaae1SJack Meng iscsi_sockaddr_t addr_dsc;
2116cefaae1SJack Meng
2126cefaae1SJack Meng if (ihp == NULL || boot_prop_table == NULL) {
2136cefaae1SJack Meng return;
2146cefaae1SJack Meng }
2156cefaae1SJack Meng
2166cefaae1SJack Meng if (!iscsid_ip_check(
2176cefaae1SJack Meng (char *)&boot_prop_table->boot_tgt.tgt_ip_u)) {
2186cefaae1SJack Meng return;
2196cefaae1SJack Meng }
2206cefaae1SJack Meng
2216cefaae1SJack Meng if (boot_prop_table->boot_tgt.tgt_name != NULL) {
2226cefaae1SJack Meng dm = iSCSIDiscoveryMethodStatic |
2236cefaae1SJack Meng iSCSIDiscoveryMethodBoot;
2246cefaae1SJack Meng if (!iscsid_make_entry(boot_prop_table, &e))
2256cefaae1SJack Meng return;
2266cefaae1SJack Meng iscsid_addr_to_sockaddr(e.e_insize, &e.e_u,
2276cefaae1SJack Meng e.e_port, &addr_dsc.sin);
2286cefaae1SJack Meng
2296cefaae1SJack Meng (void) iscsid_add(ihp, dm, &addr_dsc.sin,
2306cefaae1SJack Meng (char *)boot_prop_table->boot_tgt.tgt_name,
2316cefaae1SJack Meng e.e_tpgt, &addr_dsc.sin);
2326cefaae1SJack Meng } else {
2336cefaae1SJack Meng dm = iSCSIDiscoveryMethodSendTargets |
2346cefaae1SJack Meng iSCSIDiscoveryMethodBoot;
2356cefaae1SJack Meng if (!iscsid_make_entry(boot_prop_table, &e))
2366cefaae1SJack Meng return;
2376cefaae1SJack Meng iscsid_addr_to_sockaddr(e.e_insize, &e.e_u,
2386cefaae1SJack Meng e.e_port, &addr_dsc.sin);
2396cefaae1SJack Meng iscsid_do_sendtgts(&e);
2406cefaae1SJack Meng (void) iscsid_login_tgt(ihp, NULL, dm,
2416cefaae1SJack Meng &addr_dsc.sin);
2426cefaae1SJack Meng }
2436cefaae1SJack Meng }
2446cefaae1SJack Meng
245fcf3ce44SJohn Forte /*
2464246c8e9SJack Meng * iscsid_init -- to initialize stuffs related to iscsi daemon,
2474246c8e9SJack Meng * and to create boot session if needed
248fcf3ce44SJohn Forte */
249fcf3ce44SJohn Forte boolean_t
iscsid_init(iscsi_hba_t * ihp)2504246c8e9SJack Meng iscsid_init(iscsi_hba_t *ihp)
251fcf3ce44SJohn Forte {
2524246c8e9SJack Meng boolean_t rval = B_TRUE;
253fcf3ce44SJohn Forte
254fcf3ce44SJohn Forte sema_init(&iscsid_config_semaphore, 1, NULL,
255fcf3ce44SJohn Forte SEMA_DRIVER, NULL);
2564246c8e9SJack Meng persistent_init();
2574246c8e9SJack Meng iscsid_threads_create(ihp);
258fcf3ce44SJohn Forte
259*7284664aSJoshua M. Clulow if (modrootloaded) {
260*7284664aSJoshua M. Clulow /*
261*7284664aSJoshua M. Clulow * The root file system is available so we can load the
262*7284664aSJoshua M. Clulow * persistent store.
263*7284664aSJoshua M. Clulow */
2644246c8e9SJack Meng if (persistent_load() == B_TRUE) {
2654246c8e9SJack Meng ihp->hba_persistent_loaded = B_TRUE;
2666cefaae1SJack Meng } else {
2674246c8e9SJack Meng return (B_FALSE);
268fcf3ce44SJohn Forte }
269*7284664aSJoshua M. Clulow } else {
270*7284664aSJoshua M. Clulow /*
271*7284664aSJoshua M. Clulow * If the root file system is not yet mounted then we _must_ be
272*7284664aSJoshua M. Clulow * booting from an iSCSI device. If not, we want to fail to
273*7284664aSJoshua M. Clulow * attach so that we can try again after the VFS root is
274*7284664aSJoshua M. Clulow * available.
275*7284664aSJoshua M. Clulow */
276*7284664aSJoshua M. Clulow if (iscsiboot_prop == NULL) {
277*7284664aSJoshua M. Clulow return (B_FALSE);
278*7284664aSJoshua M. Clulow }
279fcf3ce44SJohn Forte
2806cefaae1SJack Meng if (!iscsid_boot_init_config(ihp)) {
2816cefaae1SJack Meng rval = B_FALSE;
2826cefaae1SJack Meng } else {
2836cefaae1SJack Meng iscsi_boot_session_create(ihp, iscsiboot_prop);
2846cefaae1SJack Meng iscsi_boot_wd_handle =
2856cefaae1SJack Meng iscsi_thread_create(ihp->hba_dip,
2866cefaae1SJack Meng "BootWD", iscsid_thread_boot_wd, ihp);
287*7284664aSJoshua M. Clulow if (iscsi_boot_wd_handle != NULL) {
2886cefaae1SJack Meng rval = iscsi_thread_start(
2896cefaae1SJack Meng iscsi_boot_wd_handle);
2906cefaae1SJack Meng } else {
2916cefaae1SJack Meng rval = B_FALSE;
2926cefaae1SJack Meng }
2936cefaae1SJack Meng }
2944246c8e9SJack Meng if (rval == B_FALSE) {
2954246c8e9SJack Meng cmn_err(CE_NOTE, "Initializaton of iscsi boot session"
2966cefaae1SJack Meng " partially failed");
2976cefaae1SJack Meng }
2984246c8e9SJack Meng }
299fcf3ce44SJohn Forte
3004246c8e9SJack Meng return (rval);
3014246c8e9SJack Meng }
3026cefaae1SJack Meng
3034246c8e9SJack Meng /*
3044246c8e9SJack Meng * iscsid_start -- start the iscsi initiator daemon, actually this code
3054246c8e9SJack Meng * is just to enable discovery methods which are set enabled in
3064246c8e9SJack Meng * persistent store, as an economic way to present the 'daemon' funtionality
3074246c8e9SJack Meng */
3084246c8e9SJack Meng boolean_t
iscsid_start(iscsi_hba_t * ihp)309*7284664aSJoshua M. Clulow iscsid_start(iscsi_hba_t *ihp)
310*7284664aSJoshua M. Clulow {
3114246c8e9SJack Meng boolean_t rval = B_FALSE;
3124246c8e9SJack Meng iSCSIDiscoveryMethod_t dm;
3134246c8e9SJack Meng iSCSIDiscoveryMethod_t *fdm;
3144246c8e9SJack Meng
3154246c8e9SJack Meng rval = iscsid_init_config(ihp);
3164246c8e9SJack Meng if (rval == B_TRUE) {
3174246c8e9SJack Meng rval = iscsid_init_targets(ihp);
3184246c8e9SJack Meng }
3196cefaae1SJack Meng
3204246c8e9SJack Meng if (rval == B_TRUE) {
3214246c8e9SJack Meng dm = persistent_disc_meth_get();
3224246c8e9SJack Meng rval = iscsid_enable_discovery(ihp, dm, B_TRUE);
3234246c8e9SJack Meng if (rval == B_TRUE) {
3244246c8e9SJack Meng iscsid_poke_discovery(ihp,
3254246c8e9SJack Meng iSCSIDiscoveryMethodUnknown);
3264246c8e9SJack Meng (void) iscsid_login_tgt(ihp, NULL,
3274246c8e9SJack Meng iSCSIDiscoveryMethodUnknown, NULL);
3286cefaae1SJack Meng }
3294246c8e9SJack Meng }
3304246c8e9SJack Meng
3314246c8e9SJack Meng if (rval == B_FALSE) {
3324246c8e9SJack Meng /*
3334246c8e9SJack Meng * In case of failure the events still need to be sent
3344246c8e9SJack Meng * because the door daemon will pause until all these
3354246c8e9SJack Meng * events have occurred.
3364246c8e9SJack Meng */
3374246c8e9SJack Meng for (fdm = &for_failure[0]; *fdm !=
3384246c8e9SJack Meng iSCSIDiscoveryMethodUnknown; fdm++) {
3394246c8e9SJack Meng /* ---- Send both start and end events ---- */
3404246c8e9SJack Meng iscsi_discovery_event(ihp, *fdm, B_TRUE);
3414246c8e9SJack Meng iscsi_discovery_event(ihp, *fdm, B_FALSE);
342fcf3ce44SJohn Forte }
343fcf3ce44SJohn Forte }
3444246c8e9SJack Meng
3454246c8e9SJack Meng return (rval);
3464246c8e9SJack Meng }
3474246c8e9SJack Meng
3484246c8e9SJack Meng /*
3494246c8e9SJack Meng * iscsid_stop -- stop the iscsi initiator daemon, by disabling
3504246c8e9SJack Meng * all the discovery methods first, and then try to stop all
35108dcd69cSJack Meng * related threads. This is a try-best effort, leave any 'busy' device
35208dcd69cSJack Meng * (and therefore session) there and just return.
3534246c8e9SJack Meng */
3544246c8e9SJack Meng boolean_t
iscsid_stop(iscsi_hba_t * ihp)355*7284664aSJoshua M. Clulow iscsid_stop(iscsi_hba_t *ihp)
356*7284664aSJoshua M. Clulow {
3574246c8e9SJack Meng boolean_t rval = B_FALSE;
358aefdd131Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_t *isp = NULL;
3594246c8e9SJack Meng
36008dcd69cSJack Meng (void) iscsid_disable_discovery(ihp, ISCSI_ALL_DISCOVERY_METHODS);
3614246c8e9SJack Meng
3624246c8e9SJack Meng /* final check */
3634246c8e9SJack Meng rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
3644246c8e9SJack Meng if (ihp->hba_sess_list == NULL) {
3654246c8e9SJack Meng rval = B_TRUE;
366aefdd131Sbing zhao - Sun Microsystems - Beijing China } else {
367aefdd131Sbing zhao - Sun Microsystems - Beijing China /*
368aefdd131Sbing zhao - Sun Microsystems - Beijing China * If only boot session is left, that is OK.
36908dcd69cSJack Meng * Otherwise, we should report that some sessions are left.
370aefdd131Sbing zhao - Sun Microsystems - Beijing China */
371aefdd131Sbing zhao - Sun Microsystems - Beijing China rval = B_TRUE;
372aefdd131Sbing zhao - Sun Microsystems - Beijing China for (isp = ihp->hba_sess_list; isp != NULL;
373aefdd131Sbing zhao - Sun Microsystems - Beijing China isp = isp->sess_next) {
374aefdd131Sbing zhao - Sun Microsystems - Beijing China if (isp->sess_boot == B_FALSE) {
375aefdd131Sbing zhao - Sun Microsystems - Beijing China rval = B_FALSE;
376aefdd131Sbing zhao - Sun Microsystems - Beijing China break;
377aefdd131Sbing zhao - Sun Microsystems - Beijing China }
378aefdd131Sbing zhao - Sun Microsystems - Beijing China }
3794246c8e9SJack Meng }
3804246c8e9SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
3814246c8e9SJack Meng
382fcf3ce44SJohn Forte return (rval);
383fcf3ce44SJohn Forte }
384fcf3ce44SJohn Forte
385fcf3ce44SJohn Forte /*
386fcf3ce44SJohn Forte * iscsid_fini -- do whatever is required to clean up
387fcf3ce44SJohn Forte */
388fcf3ce44SJohn Forte /* ARGSUSED */
389fcf3ce44SJohn Forte void
iscsid_fini()390fcf3ce44SJohn Forte iscsid_fini()
391fcf3ce44SJohn Forte {
3926cefaae1SJack Meng if (iscsi_boot_wd_handle != NULL) {
3936cefaae1SJack Meng iscsi_thread_destroy(iscsi_boot_wd_handle);
3946cefaae1SJack Meng iscsi_boot_wd_handle = NULL;
3956cefaae1SJack Meng }
3964246c8e9SJack Meng iscsid_threads_destroy();
397fcf3ce44SJohn Forte persistent_fini();
398fcf3ce44SJohn Forte sema_destroy(&iscsid_config_semaphore);
399fcf3ce44SJohn Forte }
400fcf3ce44SJohn Forte
401fcf3ce44SJohn Forte /*
402fcf3ce44SJohn Forte * iscsid_props -- returns discovery thread information, used by ioctl code
403fcf3ce44SJohn Forte */
404fcf3ce44SJohn Forte void
iscsid_props(iSCSIDiscoveryProperties_t * props)405fcf3ce44SJohn Forte iscsid_props(iSCSIDiscoveryProperties_t *props)
406fcf3ce44SJohn Forte {
407fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t dm;
408fcf3ce44SJohn Forte
409fcf3ce44SJohn Forte dm = persistent_disc_meth_get();
410fcf3ce44SJohn Forte
411fcf3ce44SJohn Forte props->vers = ISCSI_INTERFACE_VERSION;
412fcf3ce44SJohn Forte
413fcf3ce44SJohn Forte /* ---- change once thread is implemented ---- */
414fcf3ce44SJohn Forte props->iSNSDiscoverySettable = B_FALSE;
415fcf3ce44SJohn Forte props->SLPDiscoverySettable = B_FALSE;
416fcf3ce44SJohn Forte props->StaticDiscoverySettable = B_TRUE;
417fcf3ce44SJohn Forte props->SendTargetsDiscoverySettable = B_TRUE;
418fcf3ce44SJohn Forte props->iSNSDiscoveryMethod = iSNSDiscoveryMethodStatic;
419fcf3ce44SJohn Forte
420fcf3ce44SJohn Forte props->iSNSDiscoveryEnabled = CHECK_METHOD(iSCSIDiscoveryMethodISNS);
421fcf3ce44SJohn Forte props->StaticDiscoveryEnabled =
422fcf3ce44SJohn Forte CHECK_METHOD(iSCSIDiscoveryMethodStatic);
423fcf3ce44SJohn Forte props->SendTargetsDiscoveryEnabled =
424fcf3ce44SJohn Forte CHECK_METHOD(iSCSIDiscoveryMethodSendTargets);
425fcf3ce44SJohn Forte props->SLPDiscoveryEnabled = CHECK_METHOD(iSCSIDiscoveryMethodSLP);
426fcf3ce44SJohn Forte }
427fcf3ce44SJohn Forte
428fcf3ce44SJohn Forte /*
429fcf3ce44SJohn Forte * iscsid_enable_discovery - start specified discovery methods
430fcf3ce44SJohn Forte */
431fcf3ce44SJohn Forte /* ARGSUSED */
432fcf3ce44SJohn Forte boolean_t
iscsid_enable_discovery(iscsi_hba_t * ihp,iSCSIDiscoveryMethod_t idm,boolean_t poke)433fcf3ce44SJohn Forte iscsid_enable_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t idm,
434fcf3ce44SJohn Forte boolean_t poke)
435fcf3ce44SJohn Forte {
436fcf3ce44SJohn Forte boolean_t rval = B_TRUE;
437fcf3ce44SJohn Forte iscsid_thr_table *dt;
438fcf3ce44SJohn Forte
439fcf3ce44SJohn Forte /*
440fcf3ce44SJohn Forte * start the specified discovery method(s)
441fcf3ce44SJohn Forte */
442fcf3ce44SJohn Forte for (dt = &iscsid_thr[0]; dt->method != iSCSIDiscoveryMethodUnknown;
443fcf3ce44SJohn Forte dt++) {
444fcf3ce44SJohn Forte if (idm & dt->method) {
445fcf3ce44SJohn Forte if (dt->thr_id != NULL) {
446fcf3ce44SJohn Forte rval = iscsi_thread_start(dt->thr_id);
447fcf3ce44SJohn Forte if (rval == B_FALSE) {
448fcf3ce44SJohn Forte break;
449fcf3ce44SJohn Forte }
450fcf3ce44SJohn Forte if (poke == B_TRUE) {
45149311b35SJack Meng (void) iscsi_thread_send_wakeup(
45249311b35SJack Meng dt->thr_id);
453fcf3ce44SJohn Forte }
454fcf3ce44SJohn Forte } else {
455fcf3ce44SJohn Forte /*
456fcf3ce44SJohn Forte * unexpected condition. The threads for each
457fcf3ce44SJohn Forte * discovery method should have started at
458fcf3ce44SJohn Forte * initialization
459fcf3ce44SJohn Forte */
460fcf3ce44SJohn Forte ASSERT(B_FALSE);
461fcf3ce44SJohn Forte }
462fcf3ce44SJohn Forte }
463fcf3ce44SJohn Forte } /* END for() */
464fcf3ce44SJohn Forte
465fcf3ce44SJohn Forte return (rval);
466fcf3ce44SJohn Forte }
467fcf3ce44SJohn Forte
468fcf3ce44SJohn Forte
469fcf3ce44SJohn Forte /*
470fcf3ce44SJohn Forte * iscsid_disable_discovery - stop specified discovery methods
471fcf3ce44SJohn Forte */
472fcf3ce44SJohn Forte boolean_t
iscsid_disable_discovery(iscsi_hba_t * ihp,iSCSIDiscoveryMethod_t idm)473fcf3ce44SJohn Forte iscsid_disable_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t idm)
474fcf3ce44SJohn Forte {
475fcf3ce44SJohn Forte boolean_t rval = B_TRUE;
476fcf3ce44SJohn Forte iscsid_thr_table *dt;
477fcf3ce44SJohn Forte
478fcf3ce44SJohn Forte /*
479fcf3ce44SJohn Forte * stop the specified discovery method(s)
480fcf3ce44SJohn Forte */
481fcf3ce44SJohn Forte for (dt = &iscsid_thr[0]; dt->method != iSCSIDiscoveryMethodUnknown;
482fcf3ce44SJohn Forte dt++) {
483fcf3ce44SJohn Forte if (idm & dt->method) {
484fcf3ce44SJohn Forte
485fcf3ce44SJohn Forte /* signal discovery event change - begin */
486fcf3ce44SJohn Forte iscsi_discovery_event(ihp, dt->method, B_TRUE);
487fcf3ce44SJohn Forte
488fcf3ce44SJohn Forte /* Attempt to logout of all associated targets */
489fcf3ce44SJohn Forte rval = iscsid_del(ihp, NULL, dt->method, NULL);
490fcf3ce44SJohn Forte if (rval == B_TRUE) {
491fcf3ce44SJohn Forte /* Successfully logged out of targets */
492fcf3ce44SJohn Forte if (dt->thr_id != NULL) {
493fcf3ce44SJohn Forte rval = iscsi_thread_stop(dt->thr_id);
494fcf3ce44SJohn Forte if (rval == B_FALSE) {
495fcf3ce44SJohn Forte /*
496fcf3ce44SJohn Forte * signal discovery
497fcf3ce44SJohn Forte * event change - end
498fcf3ce44SJohn Forte */
499fcf3ce44SJohn Forte iscsi_discovery_event(ihp,
500fcf3ce44SJohn Forte dt->method, B_FALSE);
501fcf3ce44SJohn Forte break;
502fcf3ce44SJohn Forte }
503fcf3ce44SJohn Forte
504fcf3ce44SJohn Forte } else {
505fcf3ce44SJohn Forte /*
506fcf3ce44SJohn Forte * unexpected condition. The threads
507fcf3ce44SJohn Forte * for each discovery method should
508fcf3ce44SJohn Forte * have started at initialization
509fcf3ce44SJohn Forte */
510fcf3ce44SJohn Forte ASSERT(B_FALSE);
511fcf3ce44SJohn Forte }
512fcf3ce44SJohn Forte }
513fcf3ce44SJohn Forte
514fcf3ce44SJohn Forte /* signal discovery event change - end */
515fcf3ce44SJohn Forte iscsi_discovery_event(ihp, dt->method, B_FALSE);
516fcf3ce44SJohn Forte
517fcf3ce44SJohn Forte }
518fcf3ce44SJohn Forte } /* END for() */
519fcf3ce44SJohn Forte
520fcf3ce44SJohn Forte return (rval);
521fcf3ce44SJohn Forte }
522fcf3ce44SJohn Forte
523fcf3ce44SJohn Forte /*
524fcf3ce44SJohn Forte * iscsid_poke_discovery - wakeup discovery methods to find any new targets
525fcf3ce44SJohn Forte * and wait for all discovery processes to complete.
526fcf3ce44SJohn Forte */
527fcf3ce44SJohn Forte void
iscsid_poke_discovery(iscsi_hba_t * ihp,iSCSIDiscoveryMethod_t method)528fcf3ce44SJohn Forte iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method)
529fcf3ce44SJohn Forte {
530fcf3ce44SJohn Forte #define ISCSI_DISCOVERY_DELAY 1
531fcf3ce44SJohn Forte
532fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t dm;
533fcf3ce44SJohn Forte iscsid_thr_table *dt;
53449311b35SJack Meng boolean_t send_wakeup;
535fcf3ce44SJohn Forte
536fcf3ce44SJohn Forte ASSERT(ihp != NULL);
537fcf3ce44SJohn Forte
538fcf3ce44SJohn Forte /* reset discovery flags */
539fcf3ce44SJohn Forte mutex_enter(&ihp->hba_discovery_events_mutex);
540fcf3ce44SJohn Forte ihp->hba_discovery_in_progress = B_TRUE;
541fcf3ce44SJohn Forte ihp->hba_discovery_events = iSCSIDiscoveryMethodUnknown;
542fcf3ce44SJohn Forte mutex_exit(&ihp->hba_discovery_events_mutex);
543fcf3ce44SJohn Forte
544fcf3ce44SJohn Forte /* start all enabled discovery methods */
545fcf3ce44SJohn Forte dm = persistent_disc_meth_get();
546fcf3ce44SJohn Forte for (dt = &iscsid_thr[0]; dt->method != iSCSIDiscoveryMethodUnknown;
547fcf3ce44SJohn Forte dt++) {
54849311b35SJack Meng send_wakeup = B_FALSE;
54949311b35SJack Meng
550fcf3ce44SJohn Forte if ((method == iSCSIDiscoveryMethodUnknown) ||
551fcf3ce44SJohn Forte (method == dt->method)) {
552fcf3ce44SJohn Forte if ((dm & dt->method) && (dt->thr_id != NULL)) {
55349311b35SJack Meng if (iscsi_thread_send_wakeup(dt->thr_id) ==
55449311b35SJack Meng B_TRUE) {
55549311b35SJack Meng send_wakeup = B_TRUE;
55649311b35SJack Meng }
557fcf3ce44SJohn Forte }
55849311b35SJack Meng }
55949311b35SJack Meng
56049311b35SJack Meng if (send_wakeup == B_FALSE) {
561fcf3ce44SJohn Forte iscsi_discovery_event(ihp, dt->method, B_TRUE);
562fcf3ce44SJohn Forte iscsi_discovery_event(ihp, dt->method, B_FALSE);
563fcf3ce44SJohn Forte }
564fcf3ce44SJohn Forte }
565fcf3ce44SJohn Forte
566fcf3ce44SJohn Forte mutex_enter(&ihp->hba_discovery_events_mutex);
567fcf3ce44SJohn Forte while (ihp->hba_discovery_events != ISCSI_ALL_DISCOVERY_METHODS) {
568fcf3ce44SJohn Forte mutex_exit(&ihp->hba_discovery_events_mutex);
569fcf3ce44SJohn Forte delay(SEC_TO_TICK(ISCSI_DISCOVERY_DELAY));
570fcf3ce44SJohn Forte mutex_enter(&ihp->hba_discovery_events_mutex);
571fcf3ce44SJohn Forte }
572fcf3ce44SJohn Forte ihp->hba_discovery_in_progress = B_FALSE;
573fcf3ce44SJohn Forte mutex_exit(&ihp->hba_discovery_events_mutex);
574fcf3ce44SJohn Forte
575fcf3ce44SJohn Forte }
576fcf3ce44SJohn Forte
577fcf3ce44SJohn Forte /*
578fcf3ce44SJohn Forte * iscsid_do_sendtgts - issue send targets command to the given discovery
579fcf3ce44SJohn Forte * address and then add the discovered targets to the discovery queue
580fcf3ce44SJohn Forte */
581fcf3ce44SJohn Forte void
iscsid_do_sendtgts(entry_t * disc_addr)582fcf3ce44SJohn Forte iscsid_do_sendtgts(entry_t *disc_addr)
583fcf3ce44SJohn Forte {
584fcf3ce44SJohn Forte
585fcf3ce44SJohn Forte #define SENDTGTS_DEFAULT_NUM_TARGETS 10
586fcf3ce44SJohn Forte
587fcf3ce44SJohn Forte int stl_sz;
588fcf3ce44SJohn Forte int stl_num_tgts = SENDTGTS_DEFAULT_NUM_TARGETS;
589fcf3ce44SJohn Forte iscsi_sendtgts_list_t *stl_hdr = NULL;
590fcf3ce44SJohn Forte boolean_t retry = B_TRUE;
591fcf3ce44SJohn Forte char inp_buf[INET6_ADDRSTRLEN];
592fcf3ce44SJohn Forte const char *ip;
593fcf3ce44SJohn Forte int ctr;
594fcf3ce44SJohn Forte int rc;
5956cefaae1SJack Meng iscsi_hba_t *ihp;
5966cefaae1SJack Meng iSCSIDiscoveryMethod_t dm = iSCSIDiscoveryMethodSendTargets;
597fcf3ce44SJohn Forte
598fcf3ce44SJohn Forte /* allocate and initialize sendtargets list header */
599fcf3ce44SJohn Forte stl_sz = sizeof (*stl_hdr) + ((stl_num_tgts - 1) *
600fcf3ce44SJohn Forte sizeof (iscsi_sendtgts_entry_t));
601fcf3ce44SJohn Forte stl_hdr = kmem_zalloc(stl_sz, KM_SLEEP);
602fcf3ce44SJohn Forte
603fcf3ce44SJohn Forte retry_sendtgts:
604fcf3ce44SJohn Forte stl_hdr->stl_in_cnt = stl_num_tgts;
605fcf3ce44SJohn Forte bcopy(disc_addr, &(stl_hdr->stl_entry),
606fcf3ce44SJohn Forte sizeof (stl_hdr->stl_entry));
607fcf3ce44SJohn Forte stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION;
608fcf3ce44SJohn Forte
609fcf3ce44SJohn Forte /* lock interface so only one SendTargets operation occurs */
610fcf3ce44SJohn Forte if ((ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state, 0)) == NULL) {
611fcf3ce44SJohn Forte cmn_err(CE_NOTE, "!iscsi discovery failure - SendTargets. "
612fcf3ce44SJohn Forte "failure to get soft state");
613fcf3ce44SJohn Forte kmem_free(stl_hdr, stl_sz);
614fcf3ce44SJohn Forte return;
615fcf3ce44SJohn Forte }
616fcf3ce44SJohn Forte sema_p(&ihp->hba_sendtgts_semaphore);
617fcf3ce44SJohn Forte rc = iscsi_ioctl_sendtgts_get(ihp, stl_hdr);
618fcf3ce44SJohn Forte sema_v(&ihp->hba_sendtgts_semaphore);
619fcf3ce44SJohn Forte if (rc) {
620fcf3ce44SJohn Forte ip = inet_ntop((disc_addr->e_insize ==
621fcf3ce44SJohn Forte sizeof (struct in_addr) ? AF_INET : AF_INET6),
622fcf3ce44SJohn Forte &disc_addr->e_u, inp_buf, sizeof (inp_buf));
623fcf3ce44SJohn Forte cmn_err(CE_NOTE,
624fcf3ce44SJohn Forte "iscsi discovery failure - SendTargets (%s)\n", ip);
625fcf3ce44SJohn Forte kmem_free(stl_hdr, stl_sz);
626fcf3ce44SJohn Forte return;
627fcf3ce44SJohn Forte }
628fcf3ce44SJohn Forte
629fcf3ce44SJohn Forte /* check if all targets received */
630fcf3ce44SJohn Forte if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) {
631fcf3ce44SJohn Forte if (retry == B_TRUE) {
632fcf3ce44SJohn Forte stl_num_tgts = stl_hdr->stl_out_cnt;
633fcf3ce44SJohn Forte kmem_free(stl_hdr, stl_sz);
634fcf3ce44SJohn Forte stl_sz = sizeof (*stl_hdr) +
635fcf3ce44SJohn Forte ((stl_num_tgts - 1) *
636fcf3ce44SJohn Forte sizeof (iscsi_sendtgts_entry_t));
637fcf3ce44SJohn Forte stl_hdr = kmem_zalloc(stl_sz, KM_SLEEP);
638fcf3ce44SJohn Forte retry = B_FALSE;
639fcf3ce44SJohn Forte goto retry_sendtgts;
640fcf3ce44SJohn Forte } else {
641fcf3ce44SJohn Forte ip = inet_ntop((disc_addr->e_insize ==
642fcf3ce44SJohn Forte sizeof (struct in_addr) ?
643fcf3ce44SJohn Forte AF_INET : AF_INET6), &disc_addr->e_u,
644fcf3ce44SJohn Forte inp_buf, sizeof (inp_buf));
645fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi discovery failure - "
646fcf3ce44SJohn Forte "SendTargets overflow (%s)\n", ip);
647fcf3ce44SJohn Forte kmem_free(stl_hdr, stl_sz);
648fcf3ce44SJohn Forte return;
649fcf3ce44SJohn Forte }
650fcf3ce44SJohn Forte }
651fcf3ce44SJohn Forte
652fcf3ce44SJohn Forte for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) {
653fcf3ce44SJohn Forte iscsi_sockaddr_t addr_dsc;
654fcf3ce44SJohn Forte iscsi_sockaddr_t addr_tgt;
655fcf3ce44SJohn Forte
656fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(disc_addr->e_insize,
657fcf3ce44SJohn Forte &disc_addr->e_u, disc_addr->e_port, &addr_dsc.sin);
658fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(
659fcf3ce44SJohn Forte stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize,
660fcf3ce44SJohn Forte &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr),
661fcf3ce44SJohn Forte stl_hdr->stl_list[ctr].ste_ipaddr.a_port,
662fcf3ce44SJohn Forte &addr_tgt.sin);
6636cefaae1SJack Meng if (disc_addr->e_boot == B_TRUE) {
6646cefaae1SJack Meng dm = dm | iSCSIDiscoveryMethodBoot;
6656cefaae1SJack Meng }
6666cefaae1SJack Meng (void) iscsid_add(ihp, dm,
667fcf3ce44SJohn Forte &addr_dsc.sin, (char *)stl_hdr->stl_list[ctr].ste_name,
668fcf3ce44SJohn Forte stl_hdr->stl_list[ctr].ste_tpgt,
669fcf3ce44SJohn Forte &addr_tgt.sin);
670fcf3ce44SJohn Forte }
671fcf3ce44SJohn Forte kmem_free(stl_hdr, stl_sz);
672fcf3ce44SJohn Forte }
673fcf3ce44SJohn Forte
674fcf3ce44SJohn Forte void
iscsid_do_isns_query_one_server(iscsi_hba_t * ihp,entry_t * isns_server)675fcf3ce44SJohn Forte iscsid_do_isns_query_one_server(iscsi_hba_t *ihp, entry_t *isns_server)
676fcf3ce44SJohn Forte {
677fcf3ce44SJohn Forte int pg_sz, query_status;
678fcf3ce44SJohn Forte iscsi_addr_t *ap;
679fcf3ce44SJohn Forte isns_portal_group_list_t *pg_list;
680fcf3ce44SJohn Forte
681fcf3ce44SJohn Forte ap = (iscsi_addr_t *)kmem_zalloc(sizeof (iscsi_addr_t), KM_SLEEP);
682fcf3ce44SJohn Forte ap->a_port = isns_server->e_port;
683fcf3ce44SJohn Forte ap->a_addr.i_insize = isns_server->e_insize;
684fcf3ce44SJohn Forte
685fcf3ce44SJohn Forte if (isns_server->e_insize == sizeof (struct in_addr)) {
686fcf3ce44SJohn Forte ap->a_addr.i_addr.in4.s_addr = (isns_server->e_u.u_in4.s_addr);
687fcf3ce44SJohn Forte } else if (isns_server->e_insize == sizeof (struct in6_addr)) {
688fcf3ce44SJohn Forte bcopy(&(isns_server->e_u.u_in6.s6_addr),
689fcf3ce44SJohn Forte ap->a_addr.i_addr.in6.s6_addr, 16);
690fcf3ce44SJohn Forte } else {
691fcf3ce44SJohn Forte kmem_free(ap, sizeof (iscsi_addr_t));
692fcf3ce44SJohn Forte return;
693fcf3ce44SJohn Forte }
694fcf3ce44SJohn Forte
695fcf3ce44SJohn Forte pg_list = NULL;
696fcf3ce44SJohn Forte query_status = isns_query_one_server(
697fcf3ce44SJohn Forte ap, ihp->hba_isid,
698fcf3ce44SJohn Forte ihp->hba_name, ihp->hba_alias,
699fcf3ce44SJohn Forte ISNS_INITIATOR_NODE_TYPE, &pg_list);
700fcf3ce44SJohn Forte kmem_free(ap, sizeof (iscsi_addr_t));
701fcf3ce44SJohn Forte if (query_status != isns_ok || pg_list == NULL) {
702fcf3ce44SJohn Forte DTRACE_PROBE1(iscsid_do_isns_query_one_server_status,
703fcf3ce44SJohn Forte int, query_status);
704fcf3ce44SJohn Forte return;
705fcf3ce44SJohn Forte }
706fcf3ce44SJohn Forte
707fcf3ce44SJohn Forte iscsid_add_pg_list_to_cache(ihp, pg_list);
708fcf3ce44SJohn Forte pg_sz = sizeof (isns_portal_group_list_t);
709fcf3ce44SJohn Forte if (pg_list->pg_out_cnt > 0) {
710fcf3ce44SJohn Forte pg_sz += (pg_list->pg_out_cnt - 1) *
711fcf3ce44SJohn Forte sizeof (isns_portal_group_t);
712fcf3ce44SJohn Forte }
713fcf3ce44SJohn Forte kmem_free(pg_list, pg_sz);
714fcf3ce44SJohn Forte }
715fcf3ce44SJohn Forte
716fcf3ce44SJohn Forte void
iscsid_do_isns_query(iscsi_hba_t * ihp)717fcf3ce44SJohn Forte iscsid_do_isns_query(iscsi_hba_t *ihp)
718fcf3ce44SJohn Forte {
719fcf3ce44SJohn Forte int pg_sz, query_status;
720fcf3ce44SJohn Forte isns_portal_group_list_t *pg_list;
721fcf3ce44SJohn Forte
722fcf3ce44SJohn Forte pg_list = NULL;
723fcf3ce44SJohn Forte query_status = isns_query(ihp->hba_isid,
724fcf3ce44SJohn Forte ihp->hba_name,
725fcf3ce44SJohn Forte ihp->hba_alias,
726fcf3ce44SJohn Forte ISNS_INITIATOR_NODE_TYPE,
727fcf3ce44SJohn Forte &pg_list);
7286362598eSbing zhao - Sun Microsystems - Beijing China
7296362598eSbing zhao - Sun Microsystems - Beijing China if (pg_list == NULL) {
7306362598eSbing zhao - Sun Microsystems - Beijing China DTRACE_PROBE1(iscsid_do_isns_query_status,
7316362598eSbing zhao - Sun Microsystems - Beijing China int, query_status);
7326362598eSbing zhao - Sun Microsystems - Beijing China return;
7336362598eSbing zhao - Sun Microsystems - Beijing China }
7346362598eSbing zhao - Sun Microsystems - Beijing China
735fcf3ce44SJohn Forte if ((query_status != isns_ok &&
7366362598eSbing zhao - Sun Microsystems - Beijing China query_status != isns_op_partially_failed)) {
737fcf3ce44SJohn Forte DTRACE_PROBE1(iscsid_do_isns_query_status,
738fcf3ce44SJohn Forte int, query_status);
7396362598eSbing zhao - Sun Microsystems - Beijing China pg_sz = sizeof (isns_portal_group_list_t);
7406362598eSbing zhao - Sun Microsystems - Beijing China if (pg_list->pg_out_cnt > 0) {
7416362598eSbing zhao - Sun Microsystems - Beijing China pg_sz += (pg_list->pg_out_cnt - 1) *
7426362598eSbing zhao - Sun Microsystems - Beijing China sizeof (isns_portal_group_t);
7436362598eSbing zhao - Sun Microsystems - Beijing China }
7446362598eSbing zhao - Sun Microsystems - Beijing China kmem_free(pg_list, pg_sz);
745fcf3ce44SJohn Forte return;
746fcf3ce44SJohn Forte }
7476362598eSbing zhao - Sun Microsystems - Beijing China
748fcf3ce44SJohn Forte iscsid_add_pg_list_to_cache(ihp, pg_list);
749fcf3ce44SJohn Forte
750fcf3ce44SJohn Forte pg_sz = sizeof (isns_portal_group_list_t);
751fcf3ce44SJohn Forte if (pg_list->pg_out_cnt > 0) {
752fcf3ce44SJohn Forte pg_sz += (pg_list->pg_out_cnt - 1) *
753fcf3ce44SJohn Forte sizeof (isns_portal_group_t);
754fcf3ce44SJohn Forte }
755fcf3ce44SJohn Forte kmem_free(pg_list, pg_sz);
756fcf3ce44SJohn Forte }
757fcf3ce44SJohn Forte
758fcf3ce44SJohn Forte /*
759fcf3ce44SJohn Forte * iscsid_config_one - for the given target name, attempt
760fcf3ce44SJohn Forte * to login to all targets associated with name. If target
761fcf3ce44SJohn Forte * name is not found in discovery queue, reset the discovery
762fcf3ce44SJohn Forte * queue, kick the discovery processes, and then retry.
763fcf3ce44SJohn Forte *
764fcf3ce44SJohn Forte * NOTE: The caller of this function must hold the
765fcf3ce44SJohn Forte * iscsid_config_semaphore across this call.
766fcf3ce44SJohn Forte */
767fcf3ce44SJohn Forte void
iscsid_config_one(iscsi_hba_t * ihp,char * name,boolean_t protect)768fcf3ce44SJohn Forte iscsid_config_one(iscsi_hba_t *ihp, char *name, boolean_t protect)
769fcf3ce44SJohn Forte {
7706cefaae1SJack Meng boolean_t rc = B_FALSE;
7716cefaae1SJack Meng int retry = 0;
7726cefaae1SJack Meng int lun_online = 0;
7736cefaae1SJack Meng int cur_sec = 0;
7746cefaae1SJack Meng
7756cefaae1SJack Meng if (!modrootloaded && (iscsiboot_prop != NULL)) {
7766cefaae1SJack Meng if (!iscsi_configroot_printed) {
7776cefaae1SJack Meng cmn_err(CE_NOTE, "Configuring"
7786cefaae1SJack Meng " iSCSI boot session...");
7796cefaae1SJack Meng iscsi_configroot_printed = B_TRUE;
7806cefaae1SJack Meng }
78130e7468fSPeter Dunlap if (iscsi_net_up == 0) {
782bbe72583SJack Meng if (iscsi_net_interface(B_FALSE) ==
783bbe72583SJack Meng ISCSI_STATUS_SUCCESS) {
78430e7468fSPeter Dunlap iscsi_net_up = 1;
78530e7468fSPeter Dunlap } else {
78630e7468fSPeter Dunlap cmn_err(CE_WARN, "Failed to configure interface"
78730e7468fSPeter Dunlap " for iSCSI boot session");
78830e7468fSPeter Dunlap return;
78930e7468fSPeter Dunlap }
79030e7468fSPeter Dunlap }
7916cefaae1SJack Meng while (rc == B_FALSE && retry <
7926cefaae1SJack Meng iscsi_configroot_retry) {
7936cefaae1SJack Meng rc = iscsid_login_tgt(ihp, name,
7946cefaae1SJack Meng iSCSIDiscoveryMethodBoot, NULL);
7956cefaae1SJack Meng if (rc == B_FALSE) {
7966cefaae1SJack Meng /*
7976cefaae1SJack Meng * create boot session
7986cefaae1SJack Meng */
7996cefaae1SJack Meng iscsi_boot_session_create(ihp,
8006cefaae1SJack Meng iscsiboot_prop);
801f53e1f19SJack Meng retry++;
802f53e1f19SJack Meng continue;
803f53e1f19SJack Meng }
804f53e1f19SJack Meng rc = iscsid_check_active_boot_conn(ihp);
805f53e1f19SJack Meng if (rc == B_FALSE) {
8066cefaae1SJack Meng /*
807f53e1f19SJack Meng * no active connection for the boot
808f53e1f19SJack Meng * session, retry the login until
809f53e1f19SJack Meng * one is found or the retry count
810f53e1f19SJack Meng * is exceeded
8116cefaae1SJack Meng */
812f53e1f19SJack Meng delay(SEC_TO_TICK(ISCSI_CONFIGROOT_DELAY));
813f53e1f19SJack Meng retry++;
814f53e1f19SJack Meng continue;
8156cefaae1SJack Meng }
816f53e1f19SJack Meng /*
817f53e1f19SJack Meng * The boot session has been created with active
818f53e1f19SJack Meng * connection. If the target lun has not been online,
819f53e1f19SJack Meng * we should wait here for a while
820f53e1f19SJack Meng */
821f53e1f19SJack Meng do {
822f53e1f19SJack Meng lun_online =
823f53e1f19SJack Meng iscsiboot_prop->boot_tgt.lun_online;
824f53e1f19SJack Meng if (lun_online == 0) {
825f53e1f19SJack Meng delay(SEC_TO_TICK(
826f53e1f19SJack Meng ISCSI_CONFIGROOT_DELAY));
827f53e1f19SJack Meng cur_sec++;
828f53e1f19SJack Meng }
829f53e1f19SJack Meng } while ((lun_online == 0) &&
830f53e1f19SJack Meng (cur_sec < iscsi_boot_max_delay));
8316cefaae1SJack Meng retry++;
8326cefaae1SJack Meng }
8336cefaae1SJack Meng if (!rc) {
8346cefaae1SJack Meng cmn_err(CE_WARN, "Failed to configure iSCSI"
8356cefaae1SJack Meng " boot session");
8366cefaae1SJack Meng }
8376cefaae1SJack Meng } else {
8386cefaae1SJack Meng rc = iscsid_login_tgt(ihp, name, iSCSIDiscoveryMethodUnknown,
8396cefaae1SJack Meng NULL);
840fcf3ce44SJohn Forte /*
8416cefaae1SJack Meng * If we didn't login to the device we might have
8426cefaae1SJack Meng * to update our discovery information and attempt
8436cefaae1SJack Meng * the login again.
844fcf3ce44SJohn Forte */
8456cefaae1SJack Meng if (rc == B_FALSE) {
8466cefaae1SJack Meng /*
8476cefaae1SJack Meng * Stale /dev links can cause us to get floods
8486cefaae1SJack Meng * of config requests. Prevent these repeated
8496cefaae1SJack Meng * requests from causing unneeded discovery updates
8506cefaae1SJack Meng * if ISCSI_CONFIG_STORM_PROTECT is set.
8516cefaae1SJack Meng */
8526cefaae1SJack Meng if ((protect == B_FALSE) ||
8536cefaae1SJack Meng (ddi_get_lbolt() > ihp->hba_config_lbolt +
8546cefaae1SJack Meng SEC_TO_TICK(ihp->hba_config_storm_delay))) {
8556cefaae1SJack Meng ihp->hba_config_lbolt = ddi_get_lbolt();
8566cefaae1SJack Meng iscsid_poke_discovery(ihp,
8576cefaae1SJack Meng iSCSIDiscoveryMethodUnknown);
8586cefaae1SJack Meng (void) iscsid_login_tgt(ihp, name,
8596cefaae1SJack Meng iSCSIDiscoveryMethodUnknown, NULL);
8606cefaae1SJack Meng }
861fcf3ce44SJohn Forte }
862fcf3ce44SJohn Forte }
863fcf3ce44SJohn Forte }
864fcf3ce44SJohn Forte
865fcf3ce44SJohn Forte /*
866fcf3ce44SJohn Forte * iscsid_config_all - reset the discovery queue, kick the
867fcf3ce44SJohn Forte * discovery processes, and login to all targets found
868fcf3ce44SJohn Forte *
869fcf3ce44SJohn Forte * NOTE: The caller of this function must hold the
870fcf3ce44SJohn Forte * iscsid_config_semaphore across this call.
871fcf3ce44SJohn Forte */
872fcf3ce44SJohn Forte void
iscsid_config_all(iscsi_hba_t * ihp,boolean_t protect)873fcf3ce44SJohn Forte iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect)
874fcf3ce44SJohn Forte {
8756cefaae1SJack Meng boolean_t rc = B_FALSE;
8766cefaae1SJack Meng int retry = 0;
8776cefaae1SJack Meng int lun_online = 0;
8786cefaae1SJack Meng int cur_sec = 0;
8796cefaae1SJack Meng
8806cefaae1SJack Meng if (!modrootloaded && iscsiboot_prop != NULL) {
8816cefaae1SJack Meng if (!iscsi_configroot_printed) {
8826cefaae1SJack Meng cmn_err(CE_NOTE, "Configuring"
8836cefaae1SJack Meng " iSCSI boot session...");
8846cefaae1SJack Meng iscsi_configroot_printed = B_TRUE;
8856cefaae1SJack Meng }
88630e7468fSPeter Dunlap if (iscsi_net_up == 0) {
887bbe72583SJack Meng if (iscsi_net_interface(B_FALSE) ==
888bbe72583SJack Meng ISCSI_STATUS_SUCCESS) {
88930e7468fSPeter Dunlap iscsi_net_up = 1;
89030e7468fSPeter Dunlap }
89130e7468fSPeter Dunlap }
8926cefaae1SJack Meng while (rc == B_FALSE && retry <
8936cefaae1SJack Meng iscsi_configroot_retry) {
8946cefaae1SJack Meng rc = iscsid_login_tgt(ihp, NULL,
8956cefaae1SJack Meng iSCSIDiscoveryMethodBoot, NULL);
8966cefaae1SJack Meng if (rc == B_FALSE) {
8976cefaae1SJack Meng /*
8986cefaae1SJack Meng * No boot session has been created.
8996cefaae1SJack Meng * We would like to create the boot
9006cefaae1SJack Meng * Session first.
9016cefaae1SJack Meng */
9026cefaae1SJack Meng iscsi_boot_session_create(ihp,
9036cefaae1SJack Meng iscsiboot_prop);
904f53e1f19SJack Meng retry++;
905f53e1f19SJack Meng continue;
906f53e1f19SJack Meng }
907f53e1f19SJack Meng rc = iscsid_check_active_boot_conn(ihp);
908f53e1f19SJack Meng if (rc == B_FALSE) {
9096cefaae1SJack Meng /*
910f53e1f19SJack Meng * no active connection for the boot
911f53e1f19SJack Meng * session, retry the login until
912f53e1f19SJack Meng * one is found or the retry count
913f53e1f19SJack Meng * is exceeded
9146cefaae1SJack Meng */
915f53e1f19SJack Meng delay(SEC_TO_TICK(ISCSI_CONFIGROOT_DELAY));
916f53e1f19SJack Meng retry++;
917f53e1f19SJack Meng continue;
9186cefaae1SJack Meng }
919f53e1f19SJack Meng /*
920f53e1f19SJack Meng * The boot session has been created with active
921f53e1f19SJack Meng * connection. If the target lun has not been online,
922f53e1f19SJack Meng * we should wait here for a while
923f53e1f19SJack Meng */
924f53e1f19SJack Meng do {
925f53e1f19SJack Meng lun_online =
926f53e1f19SJack Meng iscsiboot_prop->boot_tgt.lun_online;
927f53e1f19SJack Meng if (lun_online == 0) {
928f53e1f19SJack Meng delay(SEC_TO_TICK(
929f53e1f19SJack Meng ISCSI_CONFIGROOT_DELAY));
930f53e1f19SJack Meng cur_sec++;
931f53e1f19SJack Meng }
932f53e1f19SJack Meng } while ((lun_online == 0) &&
933f53e1f19SJack Meng (cur_sec < iscsi_boot_max_delay));
9346cefaae1SJack Meng retry++;
9356cefaae1SJack Meng }
9366cefaae1SJack Meng if (!rc) {
9376cefaae1SJack Meng cmn_err(CE_WARN, "Failed to configure"
9386cefaae1SJack Meng " boot session");
9396cefaae1SJack Meng }
9406cefaae1SJack Meng } else {
9416cefaae1SJack Meng /*
9426cefaae1SJack Meng * Stale /dev links can cause us to get floods
9436cefaae1SJack Meng * of config requests. Prevent these repeated
9446cefaae1SJack Meng * requests from causing unneeded discovery updates
9456cefaae1SJack Meng * if ISCSI_CONFIG_STORM_PROTECT is set.
9466cefaae1SJack Meng */
9476cefaae1SJack Meng if ((protect == B_FALSE) ||
9486cefaae1SJack Meng (ddi_get_lbolt() > ihp->hba_config_lbolt +
9496cefaae1SJack Meng SEC_TO_TICK(ihp->hba_config_storm_delay))) {
9506cefaae1SJack Meng ihp->hba_config_lbolt = ddi_get_lbolt();
9516cefaae1SJack Meng iscsid_poke_discovery(ihp,
9526cefaae1SJack Meng iSCSIDiscoveryMethodUnknown);
9536cefaae1SJack Meng }
9546cefaae1SJack Meng (void) iscsid_login_tgt(ihp, NULL,
9556cefaae1SJack Meng iSCSIDiscoveryMethodUnknown, NULL);
9566cefaae1SJack Meng }
957fcf3ce44SJohn Forte }
958fcf3ce44SJohn Forte
959fcf3ce44SJohn Forte /*
960fcf3ce44SJohn Forte * isns_scn_callback - iSNS client received an SCN
961fcf3ce44SJohn Forte *
962fcf3ce44SJohn Forte * This code processes the iSNS client SCN events. These
963fcf3ce44SJohn Forte * could relate to the addition, removal, or update of a
964fcf3ce44SJohn Forte * logical unit.
965fcf3ce44SJohn Forte */
966fcf3ce44SJohn Forte void
isns_scn_callback(void * arg)967fcf3ce44SJohn Forte isns_scn_callback(void *arg)
968fcf3ce44SJohn Forte {
969fcf3ce44SJohn Forte int i, pg_sz;
970fcf3ce44SJohn Forte int qry_status;
971fcf3ce44SJohn Forte isns_portal_group_list_t *pg_list;
972fcf3ce44SJohn Forte uint32_t scn_type;
973fcf3ce44SJohn Forte iscsi_hba_t *ihp;
974fcf3ce44SJohn Forte
975fcf3ce44SJohn Forte if (arg == NULL) {
976fcf3ce44SJohn Forte /* No argument */
977fcf3ce44SJohn Forte return;
978fcf3ce44SJohn Forte }
979fcf3ce44SJohn Forte
980fcf3ce44SJohn Forte if ((ihp = (iscsi_hba_t *)ddi_get_soft_state(iscsi_state, 0)) == NULL) {
9814246c8e9SJack Meng kmem_free(arg, sizeof (isns_scn_callback_arg_t));
9824246c8e9SJack Meng return;
9834246c8e9SJack Meng }
9844246c8e9SJack Meng
9854246c8e9SJack Meng /*
9864246c8e9SJack Meng * All isns callbacks are from a standalone taskq
9874246c8e9SJack Meng * therefore the blocking here doesn't affect the enable/disable
9884246c8e9SJack Meng * of isns discovery method
9894246c8e9SJack Meng */
9904246c8e9SJack Meng if (iscsi_client_request_service(ihp) == B_FALSE) {
9914246c8e9SJack Meng kmem_free(arg, sizeof (isns_scn_callback_arg_t));
992fcf3ce44SJohn Forte return;
993fcf3ce44SJohn Forte }
994fcf3ce44SJohn Forte
995fcf3ce44SJohn Forte scn_type = ((isns_scn_callback_arg_t *)arg)->scn_type;
996fcf3ce44SJohn Forte DTRACE_PROBE1(isns_scn_callback_scn_type, int, scn_type);
997fcf3ce44SJohn Forte switch (scn_type) {
998fcf3ce44SJohn Forte /*
999fcf3ce44SJohn Forte * ISNS_OBJ_ADDED - An object has been added.
1000fcf3ce44SJohn Forte */
1001fcf3ce44SJohn Forte case ISNS_OBJ_ADDED:
1002fcf3ce44SJohn Forte /* Query iSNS server for contact information */
1003fcf3ce44SJohn Forte pg_list = NULL;
1004fcf3ce44SJohn Forte qry_status = isns_query_one_node(
1005fcf3ce44SJohn Forte ((isns_scn_callback_arg_t *)arg)->source_key_attr,
1006fcf3ce44SJohn Forte ihp->hba_isid,
1007fcf3ce44SJohn Forte ihp->hba_name,
1008fcf3ce44SJohn Forte (uint8_t *)"",
1009fcf3ce44SJohn Forte ISNS_INITIATOR_NODE_TYPE,
1010fcf3ce44SJohn Forte &pg_list);
1011fcf3ce44SJohn Forte
1012fcf3ce44SJohn Forte /* Verify portal group is found */
1013fcf3ce44SJohn Forte if ((qry_status != isns_ok &&
1014fcf3ce44SJohn Forte qry_status != isns_op_partially_failed) ||
1015fcf3ce44SJohn Forte pg_list == NULL) {
1016fcf3ce44SJohn Forte break;
1017fcf3ce44SJohn Forte }
1018fcf3ce44SJohn Forte
1019fcf3ce44SJohn Forte DTRACE_PROBE1(pg_list,
1020fcf3ce44SJohn Forte isns_portal_group_list_t *, pg_list);
1021fcf3ce44SJohn Forte
1022fcf3ce44SJohn Forte /* Add all portals for logical unit to discovery cache */
1023fcf3ce44SJohn Forte for (i = 0; i < pg_list->pg_out_cnt; i++) {
1024fcf3ce44SJohn Forte iscsi_sockaddr_t addr_dsc;
1025fcf3ce44SJohn Forte iscsi_sockaddr_t addr_tgt;
1026fcf3ce44SJohn Forte
1027fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(
1028fcf3ce44SJohn Forte pg_list->pg_list[i].isns_server_ip.i_insize,
1029fcf3ce44SJohn Forte &pg_list->pg_list[i].isns_server_ip.i_addr,
1030fcf3ce44SJohn Forte pg_list->pg_list[i].isns_server_port,
1031fcf3ce44SJohn Forte &addr_dsc.sin);
1032fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(pg_list->pg_list[i].insize,
1033fcf3ce44SJohn Forte &pg_list->pg_list[i].pg_ip_addr,
1034fcf3ce44SJohn Forte pg_list->pg_list[i].pg_port, &addr_tgt.sin);
1035fcf3ce44SJohn Forte
1036fcf3ce44SJohn Forte (void) iscsid_add(ihp, iSCSIDiscoveryMethodISNS,
1037fcf3ce44SJohn Forte &addr_dsc.sin, (char *)pg_list->pg_list[i].
1038fcf3ce44SJohn Forte pg_iscsi_name, pg_list->pg_list[i].pg_tag,
1039fcf3ce44SJohn Forte &addr_tgt.sin);
1040fcf3ce44SJohn Forte
1041fcf3ce44SJohn Forte /* Force target to login */
1042fcf3ce44SJohn Forte (void) iscsid_login_tgt(ihp, (char *)pg_list->
1043fcf3ce44SJohn Forte pg_list[i].pg_iscsi_name, iSCSIDiscoveryMethodISNS,
1044fcf3ce44SJohn Forte NULL);
1045fcf3ce44SJohn Forte }
1046fcf3ce44SJohn Forte
1047fcf3ce44SJohn Forte if (pg_list != NULL) {
1048fcf3ce44SJohn Forte pg_sz = sizeof (isns_portal_group_list_t);
1049fcf3ce44SJohn Forte if (pg_list->pg_out_cnt > 0) {
1050fcf3ce44SJohn Forte pg_sz += (pg_list->pg_out_cnt - 1) *
1051fcf3ce44SJohn Forte sizeof (isns_portal_group_t);
1052fcf3ce44SJohn Forte }
1053fcf3ce44SJohn Forte kmem_free(pg_list, pg_sz);
1054fcf3ce44SJohn Forte }
1055fcf3ce44SJohn Forte break;
1056fcf3ce44SJohn Forte
1057fcf3ce44SJohn Forte /*
1058fcf3ce44SJohn Forte * ISNS_OBJ_REMOVED - logical unit has been removed
1059fcf3ce44SJohn Forte */
1060fcf3ce44SJohn Forte case ISNS_OBJ_REMOVED:
1061fcf3ce44SJohn Forte if (iscsid_del(ihp,
1062fcf3ce44SJohn Forte (char *)((isns_scn_callback_arg_t *)arg)->
1063fcf3ce44SJohn Forte source_key_attr, iSCSIDiscoveryMethodISNS, NULL) !=
1064fcf3ce44SJohn Forte B_TRUE) {
1065fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi initiator - "
1066fcf3ce44SJohn Forte "isns remove scn failed for target %s\n",
1067fcf3ce44SJohn Forte (char *)((isns_scn_callback_arg_t *)arg)->
1068fcf3ce44SJohn Forte source_key_attr);
1069fcf3ce44SJohn Forte
1070fcf3ce44SJohn Forte }
1071fcf3ce44SJohn Forte break;
1072fcf3ce44SJohn Forte
1073fcf3ce44SJohn Forte /*
1074fcf3ce44SJohn Forte * ISNS_OBJ_UPDATED - logical unit has changed
1075fcf3ce44SJohn Forte */
1076fcf3ce44SJohn Forte case ISNS_OBJ_UPDATED:
1077fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi initiator - "
1078fcf3ce44SJohn Forte "received iSNS update SCN for %s\n",
1079fcf3ce44SJohn Forte (char *)((isns_scn_callback_arg_t *)arg)->
1080fcf3ce44SJohn Forte source_key_attr);
1081fcf3ce44SJohn Forte break;
1082fcf3ce44SJohn Forte
1083fcf3ce44SJohn Forte /*
1084fcf3ce44SJohn Forte * ISNS_OBJ_UNKNOWN -
1085fcf3ce44SJohn Forte */
1086fcf3ce44SJohn Forte default:
1087fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi initiator - "
1088fcf3ce44SJohn Forte "received unknown iSNS SCN type 0x%x\n", scn_type);
1089fcf3ce44SJohn Forte break;
1090fcf3ce44SJohn Forte }
1091fcf3ce44SJohn Forte
10924246c8e9SJack Meng iscsi_client_release_service(ihp);
1093fcf3ce44SJohn Forte kmem_free(arg, sizeof (isns_scn_callback_arg_t));
1094fcf3ce44SJohn Forte }
1095fcf3ce44SJohn Forte
1096fcf3ce44SJohn Forte
1097fcf3ce44SJohn Forte /*
1098fcf3ce44SJohn Forte * iscsid_add - Creates discovered session and connection
1099fcf3ce44SJohn Forte */
1100fcf3ce44SJohn Forte static boolean_t
iscsid_add(iscsi_hba_t * ihp,iSCSIDiscoveryMethod_t method,struct sockaddr * addr_dsc,char * target_name,int tpgt,struct sockaddr * addr_tgt)1101fcf3ce44SJohn Forte iscsid_add(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method,
1102fcf3ce44SJohn Forte struct sockaddr *addr_dsc, char *target_name, int tpgt,
1103fcf3ce44SJohn Forte struct sockaddr *addr_tgt)
1104fcf3ce44SJohn Forte {
1105fcf3ce44SJohn Forte boolean_t rtn = B_TRUE;
1106fcf3ce44SJohn Forte iscsi_sess_t *isp;
1107fcf3ce44SJohn Forte iscsi_conn_t *icp;
1108fcf3ce44SJohn Forte uint_t oid;
1109fcf3ce44SJohn Forte int idx;
1110fcf3ce44SJohn Forte int isid;
1111fcf3ce44SJohn Forte iscsi_config_sess_t *ics;
1112fcf3ce44SJohn Forte int size;
1113fcf3ce44SJohn Forte char *tmp;
1114fcf3ce44SJohn Forte
1115fcf3ce44SJohn Forte ASSERT(ihp != NULL);
1116fcf3ce44SJohn Forte ASSERT(addr_dsc != NULL);
1117fcf3ce44SJohn Forte ASSERT(target_name != NULL);
1118fcf3ce44SJohn Forte ASSERT(addr_tgt != NULL);
1119fcf3ce44SJohn Forte
1120fcf3ce44SJohn Forte /* setup initial buffer for configured session information */
1121fcf3ce44SJohn Forte size = sizeof (*ics);
1122fcf3ce44SJohn Forte ics = kmem_zalloc(size, KM_SLEEP);
1123fcf3ce44SJohn Forte ics->ics_in = 1;
1124fcf3ce44SJohn Forte
1125fcf3ce44SJohn Forte /* get configured sessions information */
1126fcf3ce44SJohn Forte tmp = target_name;
1127fcf3ce44SJohn Forte if (persistent_get_config_session(tmp, ics) == B_FALSE) {
1128fcf3ce44SJohn Forte /*
1129fcf3ce44SJohn Forte * No target information available check for
1130fcf3ce44SJohn Forte * initiator information.
1131fcf3ce44SJohn Forte */
1132fcf3ce44SJohn Forte tmp = (char *)ihp->hba_name;
1133fcf3ce44SJohn Forte if (persistent_get_config_session(tmp, ics) == B_FALSE) {
1134fcf3ce44SJohn Forte /*
1135fcf3ce44SJohn Forte * No hba information is
1136fcf3ce44SJohn Forte * found. So assume default
1137fcf3ce44SJohn Forte * one session unbound behavior.
1138fcf3ce44SJohn Forte */
1139fcf3ce44SJohn Forte ics->ics_out = 1;
1140fcf3ce44SJohn Forte ics->ics_bound = B_TRUE;
1141fcf3ce44SJohn Forte }
1142fcf3ce44SJohn Forte }
1143fcf3ce44SJohn Forte
11446cefaae1SJack Meng if (iscsiboot_prop && (ics->ics_out > 1) &&
11456cefaae1SJack Meng !iscsi_chk_bootlun_mpxio(ihp)) {
11466cefaae1SJack Meng /*
11476cefaae1SJack Meng * iscsi boot with mpxio disabled
11486cefaae1SJack Meng * no need to search configured boot session
11496cefaae1SJack Meng */
11506cefaae1SJack Meng
11516cefaae1SJack Meng if (iscsi_cmp_boot_ini_name(tmp) ||
11526cefaae1SJack Meng iscsi_cmp_boot_tgt_name(tmp)) {
11536cefaae1SJack Meng ics->ics_out = 1;
11546cefaae1SJack Meng ics->ics_bound = B_FALSE;
11556cefaae1SJack Meng }
11566cefaae1SJack Meng }
1157fcf3ce44SJohn Forte /* Check to see if we need to get more information */
1158fcf3ce44SJohn Forte if (ics->ics_out > 1) {
1159fcf3ce44SJohn Forte /* record new size and free last buffer */
1160fcf3ce44SJohn Forte idx = ics->ics_out;
1161fcf3ce44SJohn Forte size = ISCSI_SESSION_CONFIG_SIZE(ics->ics_out);
1162fcf3ce44SJohn Forte kmem_free(ics, sizeof (*ics));
1163fcf3ce44SJohn Forte
1164fcf3ce44SJohn Forte /* allocate new buffer */
1165fcf3ce44SJohn Forte ics = kmem_zalloc(size, KM_SLEEP);
1166fcf3ce44SJohn Forte ics->ics_in = idx;
1167fcf3ce44SJohn Forte
1168fcf3ce44SJohn Forte /* get configured sessions information */
1169fcf3ce44SJohn Forte if (persistent_get_config_session(tmp, ics) != B_TRUE) {
1170fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi session(%s) - "
1171fcf3ce44SJohn Forte "unable to get configured session information\n",
1172fcf3ce44SJohn Forte target_name);
1173fcf3ce44SJohn Forte kmem_free(ics, size);
1174fcf3ce44SJohn Forte return (B_FALSE);
1175fcf3ce44SJohn Forte }
1176fcf3ce44SJohn Forte }
1177fcf3ce44SJohn Forte
1178fcf3ce44SJohn Forte /* loop for all configured sessions */
1179fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
1180fcf3ce44SJohn Forte for (isid = 0; isid < ics->ics_out; isid++) {
1181fcf3ce44SJohn Forte /* create or find matching session */
1182fcf3ce44SJohn Forte isp = iscsi_sess_create(ihp, method, addr_dsc, target_name,
1183fcf3ce44SJohn Forte tpgt, isid, ISCSI_SESS_TYPE_NORMAL, &oid);
1184fcf3ce44SJohn Forte if (isp == NULL) {
1185fcf3ce44SJohn Forte rtn = B_FALSE;
1186fcf3ce44SJohn Forte break;
1187fcf3ce44SJohn Forte }
1188fcf3ce44SJohn Forte
1189fcf3ce44SJohn Forte /* create or find matching connection */
1190fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(iscsi_conn_create(addr_tgt, isp, &icp))) {
119130e7468fSPeter Dunlap /*
119230e7468fSPeter Dunlap * Teardown the session we just created. It can't
119330e7468fSPeter Dunlap * have any luns or connections associated with it
119430e7468fSPeter Dunlap * so this should always succeed (luckily since what
119530e7468fSPeter Dunlap * would we do if it failed?)
119630e7468fSPeter Dunlap */
119730e7468fSPeter Dunlap (void) iscsi_sess_destroy(isp);
1198fcf3ce44SJohn Forte rtn = B_FALSE;
1199fcf3ce44SJohn Forte break;
1200fcf3ce44SJohn Forte }
1201fcf3ce44SJohn Forte }
1202fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock);
1203fcf3ce44SJohn Forte kmem_free(ics, size);
1204fcf3ce44SJohn Forte return (rtn);
1205fcf3ce44SJohn Forte }
1206fcf3ce44SJohn Forte
1207fcf3ce44SJohn Forte /*
1208fcf3ce44SJohn Forte * iscsid_del - Attempts to delete all associated sessions
1209fcf3ce44SJohn Forte */
1210fcf3ce44SJohn Forte boolean_t
iscsid_del(iscsi_hba_t * ihp,char * target_name,iSCSIDiscoveryMethod_t method,struct sockaddr * addr_dsc)1211fcf3ce44SJohn Forte iscsid_del(iscsi_hba_t *ihp, char *target_name,
1212fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc)
1213fcf3ce44SJohn Forte {
1214fcf3ce44SJohn Forte boolean_t rtn = B_TRUE;
1215fcf3ce44SJohn Forte iscsi_status_t status;
1216fcf3ce44SJohn Forte iscsi_sess_t *isp;
1217fcf3ce44SJohn Forte char name[ISCSI_MAX_NAME_LEN];
1218fcf3ce44SJohn Forte
1219fcf3ce44SJohn Forte ASSERT(ihp != NULL);
1220fcf3ce44SJohn Forte /* target name can be NULL or !NULL */
1221fcf3ce44SJohn Forte /* addr_dsc can be NULL or !NULL */
1222fcf3ce44SJohn Forte
1223fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
1224fcf3ce44SJohn Forte isp = ihp->hba_sess_list;
1225fcf3ce44SJohn Forte while (isp != NULL) {
1226fcf3ce44SJohn Forte /*
1227fcf3ce44SJohn Forte * If no target_name is listed (meaning all targets)
1228fcf3ce44SJohn Forte * or this specific target was listed. And the same
1229fcf3ce44SJohn Forte * discovery method discovered this target then
1230fcf3ce44SJohn Forte * continue evaulation. Otherwise fail.
1231fcf3ce44SJohn Forte */
1232fcf3ce44SJohn Forte if (((target_name == NULL) ||
1233fcf3ce44SJohn Forte (strcmp((char *)isp->sess_name, target_name) == 0)) &&
1234fcf3ce44SJohn Forte (isp->sess_discovered_by == method)) {
1235fcf3ce44SJohn Forte boolean_t try_destroy;
1236fcf3ce44SJohn Forte
1237fcf3ce44SJohn Forte /*
1238fcf3ce44SJohn Forte * If iSNS, SendTargets, or Static then special
1239fcf3ce44SJohn Forte * handling for disc_addr.
1240fcf3ce44SJohn Forte */
1241fcf3ce44SJohn Forte if ((method == iSCSIDiscoveryMethodISNS) ||
1242fcf3ce44SJohn Forte (method == iSCSIDiscoveryMethodSendTargets)) {
1243fcf3ce44SJohn Forte /*
1244fcf3ce44SJohn Forte * If NULL addr_dsc (meaning all disc_addr)
1245fcf3ce44SJohn Forte * or matching discovered addr.
1246fcf3ce44SJohn Forte */
1247fcf3ce44SJohn Forte if ((addr_dsc == NULL) ||
1248fcf3ce44SJohn Forte (bcmp(addr_dsc, &isp->sess_discovered_addr,
1249fcf3ce44SJohn Forte SIZEOF_SOCKADDR(
1250fcf3ce44SJohn Forte &isp->sess_discovered_addr.sin)) == 0)) {
1251fcf3ce44SJohn Forte try_destroy = B_TRUE;
1252fcf3ce44SJohn Forte } else {
1253fcf3ce44SJohn Forte try_destroy = B_FALSE;
1254fcf3ce44SJohn Forte }
1255fcf3ce44SJohn Forte } else if (method == iSCSIDiscoveryMethodStatic) {
1256fcf3ce44SJohn Forte /*
1257fcf3ce44SJohn Forte * If NULL addr_dsc (meaning all disc_addr)
1258fcf3ce44SJohn Forte * or matching active connection.
1259fcf3ce44SJohn Forte */
1260fcf3ce44SJohn Forte if ((addr_dsc == NULL) ||
1261fcf3ce44SJohn Forte ((isp->sess_conn_act != NULL) &&
1262fcf3ce44SJohn Forte (bcmp(addr_dsc,
1263fcf3ce44SJohn Forte &isp->sess_conn_act->conn_base_addr.sin,
1264fcf3ce44SJohn Forte SIZEOF_SOCKADDR(
1265fcf3ce44SJohn Forte &isp->sess_conn_act->conn_base_addr.sin))
1266fcf3ce44SJohn Forte == 0))) {
1267fcf3ce44SJohn Forte try_destroy = B_TRUE;
1268fcf3ce44SJohn Forte } else {
1269fcf3ce44SJohn Forte try_destroy = B_FALSE;
1270fcf3ce44SJohn Forte }
1271fcf3ce44SJohn Forte } else {
1272fcf3ce44SJohn Forte /* Unknown discovery specified */
1273fcf3ce44SJohn Forte try_destroy = B_TRUE;
1274fcf3ce44SJohn Forte }
1275fcf3ce44SJohn Forte
12766cefaae1SJack Meng if (try_destroy == B_TRUE &&
12776cefaae1SJack Meng isp->sess_boot == B_FALSE) {
1278fcf3ce44SJohn Forte (void) strcpy(name, (char *)isp->sess_name);
1279fcf3ce44SJohn Forte status = iscsi_sess_destroy(isp);
1280fcf3ce44SJohn Forte if (ISCSI_SUCCESS(status)) {
1281fcf3ce44SJohn Forte iscsid_remove_target_param(name);
1282fcf3ce44SJohn Forte isp = ihp->hba_sess_list;
12835295a27aSJack Meng } else if (status == ISCSI_STATUS_BUSY) {
1284fcf3ce44SJohn Forte /*
1285fcf3ce44SJohn Forte * The most likely destroy failure
1286fcf3ce44SJohn Forte * is that ndi/mdi offline failed.
1287fcf3ce44SJohn Forte * This means that the resource is
1288fcf3ce44SJohn Forte * in_use/busy.
1289fcf3ce44SJohn Forte */
12905295a27aSJack Meng cmn_err(CE_NOTE, "iscsi session(%d) - "
12915295a27aSJack Meng "resource is in use\n",
12925295a27aSJack Meng isp->sess_oid);
12935295a27aSJack Meng isp = isp->sess_next;
12945295a27aSJack Meng rtn = B_FALSE;
12955295a27aSJack Meng } else {
1296fcf3ce44SJohn Forte cmn_err(CE_NOTE, "iscsi session(%d) - "
1297fcf3ce44SJohn Forte "session logout failed (%d)\n",
1298fcf3ce44SJohn Forte isp->sess_oid, status);
1299fcf3ce44SJohn Forte isp = isp->sess_next;
1300fcf3ce44SJohn Forte rtn = B_FALSE;
1301fcf3ce44SJohn Forte }
1302fcf3ce44SJohn Forte } else {
1303fcf3ce44SJohn Forte isp = isp->sess_next;
1304fcf3ce44SJohn Forte }
1305fcf3ce44SJohn Forte } else {
1306fcf3ce44SJohn Forte isp = isp->sess_next;
1307fcf3ce44SJohn Forte }
1308fcf3ce44SJohn Forte }
1309fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock);
1310fcf3ce44SJohn Forte return (rtn);
1311fcf3ce44SJohn Forte }
1312fcf3ce44SJohn Forte
1313fcf3ce44SJohn Forte
1314fcf3ce44SJohn Forte /*
1315fcf3ce44SJohn Forte * iscsid_login_tgt - request target(s) to login
1316fcf3ce44SJohn Forte */
1317fcf3ce44SJohn Forte boolean_t
iscsid_login_tgt(iscsi_hba_t * ihp,char * target_name,iSCSIDiscoveryMethod_t method,struct sockaddr * addr_dsc)1318fcf3ce44SJohn Forte iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name,
1319fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc)
1320fcf3ce44SJohn Forte {
1321a9ccff55Sbing zhao - Sun Microsystems - Beijing China boolean_t rtn = B_FALSE;
1322a9ccff55Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_t *isp = NULL;
1323a9ccff55Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_list_t *isp_list = NULL;
1324a9ccff55Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_list_t *last_sess = NULL;
1325a9ccff55Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_list_t *cur_sess = NULL;
1326a9ccff55Sbing zhao - Sun Microsystems - Beijing China int total = 0;
1327a9ccff55Sbing zhao - Sun Microsystems - Beijing China ddi_taskq_t *login_taskq = NULL;
1328a9ccff55Sbing zhao - Sun Microsystems - Beijing China char taskq_name[ISCSI_TH_MAX_NAME_LEN] = {0};
1329a9ccff55Sbing zhao - Sun Microsystems - Beijing China time_t time_stamp;
1330fcf3ce44SJohn Forte
1331fcf3ce44SJohn Forte ASSERT(ihp != NULL);
1332fcf3ce44SJohn Forte
1333fcf3ce44SJohn Forte rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
1334fcf3ce44SJohn Forte /* Loop thru sessions */
1335fcf3ce44SJohn Forte isp = ihp->hba_sess_list;
1336fcf3ce44SJohn Forte while (isp != NULL) {
1337fcf3ce44SJohn Forte boolean_t try_online;
13386cefaae1SJack Meng if (!(method & iSCSIDiscoveryMethodBoot)) {
13396cefaae1SJack Meng if (target_name == NULL) {
13406cefaae1SJack Meng if (method == iSCSIDiscoveryMethodUnknown) {
13416cefaae1SJack Meng /* unknown method mean login to all */
13426cefaae1SJack Meng try_online = B_TRUE;
13436cefaae1SJack Meng } else if (isp->sess_discovered_by & method) {
13446cefaae1SJack Meng if ((method ==
13456cefaae1SJack Meng iSCSIDiscoveryMethodISNS) ||
13466cefaae1SJack Meng (method ==
13476cefaae1SJack Meng iSCSIDiscoveryMethodSendTargets)) {
13486cefaae1SJack Meng #define SESS_DISC_ADDR isp->sess_discovered_addr.sin
13496cefaae1SJack Meng if ((addr_dsc == NULL) ||
13506cefaae1SJack Meng (bcmp(
13516cefaae1SJack Meng &isp->sess_discovered_addr,
13526cefaae1SJack Meng addr_dsc, SIZEOF_SOCKADDR(
13536cefaae1SJack Meng &SESS_DISC_ADDR))
13546cefaae1SJack Meng == 0)) {
13556cefaae1SJack Meng /*
13566cefaae1SJack Meng * iSNS or sendtarget
13576cefaae1SJack Meng * discovery and
13586cefaae1SJack Meng * discovery address
13596cefaae1SJack Meng * is NULL or match
13606cefaae1SJack Meng */
13616cefaae1SJack Meng try_online = B_TRUE;
13626cefaae1SJack Meng } else {
1363fcf3ce44SJohn Forte /* addr_dsc not a match */
13646cefaae1SJack Meng try_online = B_FALSE;
13656cefaae1SJack Meng }
13666cefaae1SJack Meng #undef SESS_DISC_ADDR
13676cefaae1SJack Meng } else {
13686cefaae1SJack Meng /* static configuration */
13696cefaae1SJack Meng try_online = B_TRUE;
1370fcf3ce44SJohn Forte }
1371fcf3ce44SJohn Forte } else {
13726cefaae1SJack Meng /* method not a match */
13736cefaae1SJack Meng try_online = B_FALSE;
1374fcf3ce44SJohn Forte }
13756cefaae1SJack Meng } else if (strcmp(target_name,
13766cefaae1SJack Meng (char *)isp->sess_name) == 0) {
13776cefaae1SJack Meng /* target_name match */
13786cefaae1SJack Meng try_online = B_TRUE;
1379fcf3ce44SJohn Forte } else {
13806cefaae1SJack Meng /* target_name not a match */
1381fcf3ce44SJohn Forte try_online = B_FALSE;
1382fcf3ce44SJohn Forte }
1383fcf3ce44SJohn Forte } else {
13846cefaae1SJack Meng /*
13856cefaae1SJack Meng * online the boot session.
13866cefaae1SJack Meng */
13876cefaae1SJack Meng if (isp->sess_boot == B_TRUE) {
13886cefaae1SJack Meng try_online = B_TRUE;
13896cefaae1SJack Meng }
1390fcf3ce44SJohn Forte }
1391fcf3ce44SJohn Forte
1392a9ccff55Sbing zhao - Sun Microsystems - Beijing China if (try_online == B_TRUE &&
1393a9ccff55Sbing zhao - Sun Microsystems - Beijing China isp->sess_type == ISCSI_SESS_TYPE_NORMAL) {
1394a9ccff55Sbing zhao - Sun Microsystems - Beijing China total++;
1395a9ccff55Sbing zhao - Sun Microsystems - Beijing China /* Copy these sessions to the list. */
1396a9ccff55Sbing zhao - Sun Microsystems - Beijing China if (isp_list == NULL) {
1397a9ccff55Sbing zhao - Sun Microsystems - Beijing China isp_list =
1398a9ccff55Sbing zhao - Sun Microsystems - Beijing China (iscsi_sess_list_t *)kmem_zalloc(
1399a9ccff55Sbing zhao - Sun Microsystems - Beijing China sizeof (iscsi_sess_list_t), KM_SLEEP);
1400a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess = isp_list;
1401a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess->session = isp;
1402a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess->next = NULL;
1403a9ccff55Sbing zhao - Sun Microsystems - Beijing China } else {
1404a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess->next =
1405a9ccff55Sbing zhao - Sun Microsystems - Beijing China (iscsi_sess_list_t *)kmem_zalloc(
1406a9ccff55Sbing zhao - Sun Microsystems - Beijing China sizeof (iscsi_sess_list_t), KM_SLEEP);
1407a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess->next->session = isp;
1408a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess->next->next = NULL;
1409a9ccff55Sbing zhao - Sun Microsystems - Beijing China last_sess = last_sess->next;
1410a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1411fcf3ce44SJohn Forte rtn = B_TRUE;
1412fcf3ce44SJohn Forte }
1413a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1414fcf3ce44SJohn Forte isp = isp->sess_next;
1415fcf3ce44SJohn Forte }
1416a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1417a9ccff55Sbing zhao - Sun Microsystems - Beijing China if (total > 0) {
1418a9ccff55Sbing zhao - Sun Microsystems - Beijing China time_stamp = ddi_get_time();
1419a9ccff55Sbing zhao - Sun Microsystems - Beijing China (void) snprintf(taskq_name, (ISCSI_TH_MAX_NAME_LEN - 1),
1420a9ccff55Sbing zhao - Sun Microsystems - Beijing China "login_queue.%lx", time_stamp);
1421a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1422a9ccff55Sbing zhao - Sun Microsystems - Beijing China login_taskq = ddi_taskq_create(ihp->hba_dip,
1423a9ccff55Sbing zhao - Sun Microsystems - Beijing China taskq_name, total, TASKQ_DEFAULTPRI, 0);
1424a9ccff55Sbing zhao - Sun Microsystems - Beijing China if (login_taskq == NULL) {
1425a9ccff55Sbing zhao - Sun Microsystems - Beijing China while (isp_list != NULL) {
1426a9ccff55Sbing zhao - Sun Microsystems - Beijing China cur_sess = isp_list;
1427a9ccff55Sbing zhao - Sun Microsystems - Beijing China isp_list = isp_list->next;
1428a9ccff55Sbing zhao - Sun Microsystems - Beijing China kmem_free(cur_sess, sizeof (iscsi_sess_list_t));
1429a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1430a9ccff55Sbing zhao - Sun Microsystems - Beijing China rtn = B_FALSE;
1431a9ccff55Sbing zhao - Sun Microsystems - Beijing China rw_exit(&ihp->hba_sess_list_rwlock);
1432a9ccff55Sbing zhao - Sun Microsystems - Beijing China return (rtn);
1433a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1434a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1435a9ccff55Sbing zhao - Sun Microsystems - Beijing China for (cur_sess = isp_list; cur_sess != NULL;
1436a9ccff55Sbing zhao - Sun Microsystems - Beijing China cur_sess = cur_sess->next) {
1437a9ccff55Sbing zhao - Sun Microsystems - Beijing China if (ddi_taskq_dispatch(login_taskq,
1438a9ccff55Sbing zhao - Sun Microsystems - Beijing China iscsi_sess_online, (void *)cur_sess->session,
1439a9ccff55Sbing zhao - Sun Microsystems - Beijing China DDI_SLEEP) != DDI_SUCCESS) {
1440a9ccff55Sbing zhao - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "Can't dispatch the task "
1441a9ccff55Sbing zhao - Sun Microsystems - Beijing China "for login to the target: %s",
1442a9ccff55Sbing zhao - Sun Microsystems - Beijing China cur_sess->session->sess_name);
1443a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1444a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1445a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1446a9ccff55Sbing zhao - Sun Microsystems - Beijing China ddi_taskq_wait(login_taskq);
1447a9ccff55Sbing zhao - Sun Microsystems - Beijing China ddi_taskq_destroy(login_taskq);
1448a9ccff55Sbing zhao - Sun Microsystems - Beijing China while (isp_list != NULL) {
1449a9ccff55Sbing zhao - Sun Microsystems - Beijing China cur_sess = isp_list;
1450a9ccff55Sbing zhao - Sun Microsystems - Beijing China isp_list = isp_list->next;
1451a9ccff55Sbing zhao - Sun Microsystems - Beijing China kmem_free(cur_sess, sizeof (iscsi_sess_list_t));
1452a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1453a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1454a9ccff55Sbing zhao - Sun Microsystems - Beijing China }
1455a9ccff55Sbing zhao - Sun Microsystems - Beijing China
1456fcf3ce44SJohn Forte rw_exit(&ihp->hba_sess_list_rwlock);
1457fcf3ce44SJohn Forte return (rtn);
1458fcf3ce44SJohn Forte }
1459fcf3ce44SJohn Forte
1460fcf3ce44SJohn Forte /*
1461fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
1462fcf3ce44SJohn Forte * | Local Helper Functions |
1463fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
1464fcf3ce44SJohn Forte */
1465fcf3ce44SJohn Forte
1466fcf3ce44SJohn Forte /*
1467fcf3ce44SJohn Forte * iscsid_init_config -- initialize configuration parameters of iSCSI initiator
1468fcf3ce44SJohn Forte */
1469fcf3ce44SJohn Forte static boolean_t
iscsid_init_config(iscsi_hba_t * ihp)1470fcf3ce44SJohn Forte iscsid_init_config(iscsi_hba_t *ihp)
1471fcf3ce44SJohn Forte {
1472fcf3ce44SJohn Forte iscsi_param_set_t ips;
1473fcf3ce44SJohn Forte void *v = NULL;
1474fcf3ce44SJohn Forte char *name;
1475fcf3ce44SJohn Forte char *initiatorName;
1476fcf3ce44SJohn Forte persistent_param_t pp;
1477aff4bce5Syi zhang - Sun Microsystems - Beijing China persistent_tunable_param_t pparam;
1478fcf3ce44SJohn Forte uint32_t param_id;
1479fcf3ce44SJohn Forte int rc;
1480fcf3ce44SJohn Forte
1481fcf3ce44SJohn Forte /* allocate memory to hold initiator names */
1482fcf3ce44SJohn Forte initiatorName = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
1483fcf3ce44SJohn Forte
1484fcf3ce44SJohn Forte /*
1485fcf3ce44SJohn Forte * initialize iSCSI initiator name
1486fcf3ce44SJohn Forte */
1487fcf3ce44SJohn Forte bzero(&ips, sizeof (ips));
1488fcf3ce44SJohn Forte if (persistent_initiator_name_get(initiatorName,
1489fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN) == B_TRUE) {
1490fcf3ce44SJohn Forte ips.s_vers = ISCSI_INTERFACE_VERSION;
1491fcf3ce44SJohn Forte ips.s_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME;
1492fcf3ce44SJohn Forte
14936cefaae1SJack Meng if (iscsiboot_prop && !iscsi_cmp_boot_ini_name(initiatorName)) {
14946cefaae1SJack Meng (void) strncpy(initiatorName,
14956cefaae1SJack Meng (const char *)iscsiboot_prop->boot_init.ini_name,
14966cefaae1SJack Meng ISCSI_MAX_NAME_LEN);
14976cefaae1SJack Meng (void) strncpy((char *)ips.s_value.v_name,
14986cefaae1SJack Meng (const char *)iscsiboot_prop->boot_init.ini_name,
14996cefaae1SJack Meng sizeof (ips.s_value.v_name));
15006cefaae1SJack Meng (void) iscsi_set_params(&ips, ihp, B_TRUE);
1501aff4bce5Syi zhang - Sun Microsystems - Beijing China /* use default tunable value */
1502aff4bce5Syi zhang - Sun Microsystems - Beijing China ihp->hba_tunable_params.recv_login_rsp_timeout =
1503aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_RX_TIMEOUT_VALUE;
1504aff4bce5Syi zhang - Sun Microsystems - Beijing China ihp->hba_tunable_params.polling_login_delay =
1505aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_LOGIN_POLLING_DELAY;
1506aff4bce5Syi zhang - Sun Microsystems - Beijing China ihp->hba_tunable_params.conn_login_max =
1507aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX;
15086cefaae1SJack Meng cmn_err(CE_NOTE, "Set initiator's name"
15096cefaae1SJack Meng " from firmware");
15106cefaae1SJack Meng } else {
15116cefaae1SJack Meng (void) strncpy((char *)ips.s_value.v_name,
15126cefaae1SJack Meng initiatorName, sizeof (ips.s_value.v_name));
15136cefaae1SJack Meng
15146cefaae1SJack Meng (void) iscsi_set_params(&ips, ihp, B_FALSE);
1515aff4bce5Syi zhang - Sun Microsystems - Beijing China if (persistent_get_tunable_param(initiatorName,
1516aff4bce5Syi zhang - Sun Microsystems - Beijing China &pparam) == B_FALSE) {
1517aff4bce5Syi zhang - Sun Microsystems - Beijing China /* use default value */
1518aff4bce5Syi zhang - Sun Microsystems - Beijing China pparam.p_params.recv_login_rsp_timeout =
1519aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_RX_TIMEOUT_VALUE;
1520aff4bce5Syi zhang - Sun Microsystems - Beijing China pparam.p_params.polling_login_delay =
1521aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_LOGIN_POLLING_DELAY;
1522aff4bce5Syi zhang - Sun Microsystems - Beijing China pparam.p_params.conn_login_max =
1523aff4bce5Syi zhang - Sun Microsystems - Beijing China ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX;
1524aff4bce5Syi zhang - Sun Microsystems - Beijing China }
1525aff4bce5Syi zhang - Sun Microsystems - Beijing China bcopy(&pparam.p_params, &ihp->hba_tunable_params,
1526aff4bce5Syi zhang - Sun Microsystems - Beijing China sizeof (iscsi_tunable_params_t));
15276cefaae1SJack Meng }
1528fcf3ce44SJohn Forte } else {
1529fcf3ce44SJohn Forte /*
15306cefaae1SJack Meng * if no initiator-node name available it is most
15316cefaae1SJack Meng * likely due to a fresh install, or the persistent
15326cefaae1SJack Meng * store is not working correctly. Set
15336cefaae1SJack Meng * a default initiator name so that the initiator can
1534fcf3ce44SJohn Forte * be brought up properly.
1535fcf3ce44SJohn Forte */
1536329c9e3dSJack Meng iscsid_set_default_initiator_node_settings(ihp, B_FALSE);
15376cefaae1SJack Meng (void) strncpy(initiatorName, (const char *)ihp->hba_name,
15386cefaae1SJack Meng ISCSI_MAX_NAME_LEN);
1539fcf3ce44SJohn Forte }
1540fcf3ce44SJohn Forte
1541fcf3ce44SJohn Forte /*
1542fcf3ce44SJohn Forte * initialize iSCSI initiator alias (if any)
1543fcf3ce44SJohn Forte */
1544fcf3ce44SJohn Forte bzero(&ips, sizeof (ips));
1545fcf3ce44SJohn Forte if (persistent_alias_name_get((char *)ips.s_value.v_name,
1546fcf3ce44SJohn Forte sizeof (ips.s_value.v_name)) == B_TRUE) {
1547fcf3ce44SJohn Forte ips.s_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS;
1548fcf3ce44SJohn Forte (void) iscsi_set_params(&ips, ihp, B_FALSE);
1549fcf3ce44SJohn Forte } else {
1550fcf3ce44SJohn Forte /* EMPTY */
1551fcf3ce44SJohn Forte /* No alias defined - not a problem. */
1552fcf3ce44SJohn Forte }
1553fcf3ce44SJohn Forte
1554fcf3ce44SJohn Forte /*
1555fcf3ce44SJohn Forte * load up the overriden iSCSI initiator parameters
1556fcf3ce44SJohn Forte */
1557fcf3ce44SJohn Forte name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
1558fcf3ce44SJohn Forte persistent_param_lock();
1559fcf3ce44SJohn Forte v = NULL;
1560fcf3ce44SJohn Forte while (persistent_param_next(&v, name, &pp) == B_TRUE) {
1561fcf3ce44SJohn Forte if (strncmp(name, initiatorName, ISCSI_MAX_NAME_LEN) == 0) {
1562fcf3ce44SJohn Forte ips.s_oid = ihp->hba_oid;
1563fcf3ce44SJohn Forte ips.s_vers = ISCSI_INTERFACE_VERSION;
1564fcf3ce44SJohn Forte for (param_id = 0; param_id < ISCSI_NUM_LOGIN_PARAM;
1565fcf3ce44SJohn Forte param_id++) {
1566fcf3ce44SJohn Forte if (pp.p_bitmap & (1 << param_id)) {
1567fcf3ce44SJohn Forte rc = iscsid_copyto_param_set(param_id,
1568fcf3ce44SJohn Forte &pp.p_params, &ips);
1569fcf3ce44SJohn Forte if (rc == 0) {
1570fcf3ce44SJohn Forte rc = iscsi_set_params(&ips,
1571fcf3ce44SJohn Forte ihp, B_FALSE);
1572fcf3ce44SJohn Forte }
1573fcf3ce44SJohn Forte if (rc != 0) {
1574fcf3ce44SJohn Forte /* note error but continue */
1575fcf3ce44SJohn Forte cmn_err(CE_NOTE,
1576fcf3ce44SJohn Forte "Failed to set "
1577fcf3ce44SJohn Forte "param %d for OID %d",
1578fcf3ce44SJohn Forte ips.s_param, ips.s_oid);
1579fcf3ce44SJohn Forte }
1580fcf3ce44SJohn Forte }
1581fcf3ce44SJohn Forte } /* END for() */
15826cefaae1SJack Meng if (iscsiboot_prop &&
15836cefaae1SJack Meng iscsi_chk_bootlun_mpxio(ihp)) {
15846cefaae1SJack Meng (void) iscsi_reconfig_boot_sess(ihp);
15856cefaae1SJack Meng }
1586fcf3ce44SJohn Forte break;
1587fcf3ce44SJohn Forte }
1588fcf3ce44SJohn Forte } /* END while() */
1589fcf3ce44SJohn Forte persistent_param_unlock();
1590fcf3ce44SJohn Forte
1591fcf3ce44SJohn Forte kmem_free(initiatorName, ISCSI_MAX_NAME_LEN);
1592fcf3ce44SJohn Forte kmem_free(name, ISCSI_MAX_NAME_LEN);
1593fcf3ce44SJohn Forte return (B_TRUE);
1594fcf3ce44SJohn Forte }
1595fcf3ce44SJohn Forte
1596fcf3ce44SJohn Forte
1597fcf3ce44SJohn Forte /*
1598fcf3ce44SJohn Forte * iscsid_init_targets -- Load up the driver with known static targets and
1599fcf3ce44SJohn Forte * targets whose parameters have been modified.
1600fcf3ce44SJohn Forte *
1601fcf3ce44SJohn Forte * This is done so that the CLI can find a list of targets the driver
1602fcf3ce44SJohn Forte * currently knows about.
1603fcf3ce44SJohn Forte *
1604fcf3ce44SJohn Forte * The driver doesn't need to log into these targets. Log in is done based
1605fcf3ce44SJohn Forte * upon the enabled discovery methods.
1606fcf3ce44SJohn Forte */
1607fcf3ce44SJohn Forte static boolean_t
iscsid_init_targets(iscsi_hba_t * ihp)1608fcf3ce44SJohn Forte iscsid_init_targets(iscsi_hba_t *ihp)
1609fcf3ce44SJohn Forte {
1610fcf3ce44SJohn Forte void *v = NULL;
1611fcf3ce44SJohn Forte char *name;
1612fcf3ce44SJohn Forte iscsi_param_set_t ips;
1613fcf3ce44SJohn Forte persistent_param_t pp;
1614fcf3ce44SJohn Forte char *iname;
1615fcf3ce44SJohn Forte uint32_t param_id;
1616fcf3ce44SJohn Forte int rc;
1617fcf3ce44SJohn Forte
1618fcf3ce44SJohn Forte ASSERT(ihp != NULL);
1619fcf3ce44SJohn Forte
1620fcf3ce44SJohn Forte /* allocate memory to hold target names */
1621fcf3ce44SJohn Forte name = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
1622fcf3ce44SJohn Forte
1623fcf3ce44SJohn Forte /*
1624fcf3ce44SJohn Forte * load up targets whose parameters have been overriden
1625fcf3ce44SJohn Forte */
1626fcf3ce44SJohn Forte
1627fcf3ce44SJohn Forte /* ---- only need to be set once ---- */
1628fcf3ce44SJohn Forte bzero(&ips, sizeof (ips));
1629fcf3ce44SJohn Forte ips.s_vers = ISCSI_INTERFACE_VERSION;
1630fcf3ce44SJohn Forte
1631fcf3ce44SJohn Forte /* allocate memory to hold initiator name */
1632fcf3ce44SJohn Forte iname = kmem_zalloc(ISCSI_MAX_NAME_LEN, KM_SLEEP);
1633fcf3ce44SJohn Forte (void) persistent_initiator_name_get(iname, ISCSI_MAX_NAME_LEN);
1634fcf3ce44SJohn Forte
1635fcf3ce44SJohn Forte persistent_param_lock();
1636fcf3ce44SJohn Forte v = NULL;
1637fcf3ce44SJohn Forte while (persistent_param_next(&v, name, &pp) == B_TRUE) {
1638fcf3ce44SJohn Forte
1639fcf3ce44SJohn Forte if (strncmp(iname, name, ISCSI_MAX_NAME_LEN) == 0) {
1640fcf3ce44SJohn Forte /*
1641fcf3ce44SJohn Forte * target name matched initiator's name so,
1642fcf3ce44SJohn Forte * continue to next target. Initiator's
1643fcf3ce44SJohn Forte * parmeters have already been set.
1644fcf3ce44SJohn Forte */
1645fcf3ce44SJohn Forte continue;
1646fcf3ce44SJohn Forte }
1647fcf3ce44SJohn Forte
16486cefaae1SJack Meng if (iscsiboot_prop && iscsi_cmp_boot_tgt_name(name) &&
16496cefaae1SJack Meng !iscsi_chk_bootlun_mpxio(ihp)) {
16506cefaae1SJack Meng /*
16516cefaae1SJack Meng * boot target is not mpxio enabled
16526cefaae1SJack Meng * simply ignore these overriden parameters
16536cefaae1SJack Meng */
16546cefaae1SJack Meng continue;
16556cefaae1SJack Meng }
16566cefaae1SJack Meng
1657fcf3ce44SJohn Forte ips.s_oid = iscsi_targetparam_get_oid((unsigned char *)name);
1658fcf3ce44SJohn Forte
1659fcf3ce44SJohn Forte for (param_id = 0; param_id < ISCSI_NUM_LOGIN_PARAM;
1660fcf3ce44SJohn Forte param_id++) {
1661fcf3ce44SJohn Forte if (pp.p_bitmap & (1 << param_id)) {
1662fcf3ce44SJohn Forte rc = iscsid_copyto_param_set(param_id,
1663fcf3ce44SJohn Forte &pp.p_params, &ips);
1664fcf3ce44SJohn Forte if (rc == 0) {
1665fcf3ce44SJohn Forte rc = iscsi_set_params(&ips,
1666fcf3ce44SJohn Forte ihp, B_FALSE);
1667fcf3ce44SJohn Forte }
1668fcf3ce44SJohn Forte if (rc != 0) {
1669fcf3ce44SJohn Forte /* note error but continue ---- */
1670fcf3ce44SJohn Forte cmn_err(CE_NOTE, "Failed to set "
1671fcf3ce44SJohn Forte "param %d for OID %d",
1672fcf3ce44SJohn Forte ips.s_param, ips.s_oid);
1673fcf3ce44SJohn Forte }
1674fcf3ce44SJohn Forte }
1675fcf3ce44SJohn Forte } /* END for() */
16766cefaae1SJack Meng if (iscsiboot_prop && iscsi_cmp_boot_tgt_name(name) &&
16776cefaae1SJack Meng iscsi_chk_bootlun_mpxio(ihp)) {
16786cefaae1SJack Meng (void) iscsi_reconfig_boot_sess(ihp);
16796cefaae1SJack Meng }
1680fcf3ce44SJohn Forte } /* END while() */
1681fcf3ce44SJohn Forte persistent_param_unlock();
1682fcf3ce44SJohn Forte
1683fcf3ce44SJohn Forte kmem_free(iname, ISCSI_MAX_NAME_LEN);
1684fcf3ce44SJohn Forte kmem_free(name, ISCSI_MAX_NAME_LEN);
1685fcf3ce44SJohn Forte
1686fcf3ce44SJohn Forte return (B_TRUE);
1687fcf3ce44SJohn Forte }
1688fcf3ce44SJohn Forte
1689fcf3ce44SJohn Forte
1690fcf3ce44SJohn Forte /*
1691fcf3ce44SJohn Forte * iscsid_thread_static -- If static discovery is enabled, this routine obtains
1692fcf3ce44SJohn Forte * all statically configured targets from the peristent store and issues a
1693fcf3ce44SJohn Forte * login request to the driver.
1694fcf3ce44SJohn Forte */
1695fcf3ce44SJohn Forte /* ARGSUSED */
1696fcf3ce44SJohn Forte static void
iscsid_thread_static(iscsi_thread_t * thread,void * p)1697fcf3ce44SJohn Forte iscsid_thread_static(iscsi_thread_t *thread, void *p)
1698fcf3ce44SJohn Forte {
1699fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t dm;
1700fcf3ce44SJohn Forte entry_t entry;
1701fcf3ce44SJohn Forte char name[ISCSI_MAX_NAME_LEN];
1702fcf3ce44SJohn Forte void *v = NULL;
1703fcf3ce44SJohn Forte iscsi_hba_t *ihp = (iscsi_hba_t *)p;
1704fcf3ce44SJohn Forte
1705fcf3ce44SJohn Forte while (iscsi_thread_wait(thread, -1) != 0) {
1706fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodStatic, B_TRUE);
1707fcf3ce44SJohn Forte
1708fcf3ce44SJohn Forte /* ---- ensure static target discovery is enabled ---- */
1709fcf3ce44SJohn Forte dm = persistent_disc_meth_get();
1710fcf3ce44SJohn Forte if ((dm & iSCSIDiscoveryMethodStatic) == 0) {
1711fcf3ce44SJohn Forte cmn_err(CE_NOTE,
1712fcf3ce44SJohn Forte "iscsi discovery failure - "
1713fcf3ce44SJohn Forte "StaticTargets method is not enabled");
1714fcf3ce44SJohn Forte iscsi_discovery_event(ihp,
1715fcf3ce44SJohn Forte iSCSIDiscoveryMethodStatic, B_FALSE);
1716fcf3ce44SJohn Forte continue;
1717fcf3ce44SJohn Forte }
1718fcf3ce44SJohn Forte
1719fcf3ce44SJohn Forte /*
1720fcf3ce44SJohn Forte * walk list of the statically configured targets from the
1721fcf3ce44SJohn Forte * persistent store
1722fcf3ce44SJohn Forte */
1723fcf3ce44SJohn Forte v = NULL;
1724fcf3ce44SJohn Forte persistent_static_addr_lock();
1725fcf3ce44SJohn Forte while (persistent_static_addr_next(&v, name, &entry) ==
1726fcf3ce44SJohn Forte B_TRUE) {
1727fcf3ce44SJohn Forte iscsi_sockaddr_t addr;
1728fcf3ce44SJohn Forte
1729fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(entry.e_insize,
1730fcf3ce44SJohn Forte &(entry.e_u), entry.e_port, &addr.sin);
1731fcf3ce44SJohn Forte
1732fcf3ce44SJohn Forte (void) iscsid_add(ihp, iSCSIDiscoveryMethodStatic,
1733fcf3ce44SJohn Forte &addr.sin, name, entry.e_tpgt, &addr.sin);
1734fcf3ce44SJohn Forte }
1735fcf3ce44SJohn Forte persistent_static_addr_unlock();
1736fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodStatic, B_FALSE);
1737fcf3ce44SJohn Forte }
1738fcf3ce44SJohn Forte }
1739fcf3ce44SJohn Forte
1740fcf3ce44SJohn Forte
1741fcf3ce44SJohn Forte /*
1742fcf3ce44SJohn Forte * iscsid_thread_sendtgts -- If SendTargets discovery is enabled, this routine
1743fcf3ce44SJohn Forte * obtains all target discovery addresses configured from the peristent store
1744fcf3ce44SJohn Forte * and probe the IP/port addresses for possible targets. It will then issue
1745fcf3ce44SJohn Forte * a login request to the driver for all discoveryed targets.
1746fcf3ce44SJohn Forte */
1747fcf3ce44SJohn Forte static void
iscsid_thread_sendtgts(iscsi_thread_t * thread,void * p)1748fcf3ce44SJohn Forte iscsid_thread_sendtgts(iscsi_thread_t *thread, void *p)
1749fcf3ce44SJohn Forte {
1750fcf3ce44SJohn Forte iscsi_hba_t *ihp = (iscsi_hba_t *)p;
1751fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t dm;
1752fcf3ce44SJohn Forte entry_t entry;
1753fcf3ce44SJohn Forte void *v = NULL;
1754fcf3ce44SJohn Forte
1755fcf3ce44SJohn Forte while (iscsi_thread_wait(thread, -1) != 0) {
1756fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodSendTargets,
1757fcf3ce44SJohn Forte B_TRUE);
1758fcf3ce44SJohn Forte
1759fcf3ce44SJohn Forte /* ---- ensure SendTargets discovery is enabled ---- */
1760fcf3ce44SJohn Forte dm = persistent_disc_meth_get();
1761fcf3ce44SJohn Forte if ((dm & iSCSIDiscoveryMethodSendTargets) == 0) {
1762fcf3ce44SJohn Forte cmn_err(CE_NOTE,
1763fcf3ce44SJohn Forte "iscsi discovery failure - "
1764fcf3ce44SJohn Forte "SendTargets method is not enabled");
1765fcf3ce44SJohn Forte iscsi_discovery_event(ihp,
1766fcf3ce44SJohn Forte iSCSIDiscoveryMethodSendTargets, B_FALSE);
1767fcf3ce44SJohn Forte continue;
1768fcf3ce44SJohn Forte }
1769fcf3ce44SJohn Forte /*
1770fcf3ce44SJohn Forte * walk list of the SendTarget discovery addresses from the
1771fcf3ce44SJohn Forte * persistent store
1772fcf3ce44SJohn Forte */
1773fcf3ce44SJohn Forte v = NULL;
1774fcf3ce44SJohn Forte persistent_disc_addr_lock();
1775fcf3ce44SJohn Forte while (persistent_disc_addr_next(&v, &entry) == B_TRUE) {
1776fcf3ce44SJohn Forte iscsid_do_sendtgts(&entry);
1777fcf3ce44SJohn Forte }
1778fcf3ce44SJohn Forte persistent_disc_addr_unlock();
1779fcf3ce44SJohn Forte
1780fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodSendTargets,
1781fcf3ce44SJohn Forte B_FALSE);
1782fcf3ce44SJohn Forte }
1783fcf3ce44SJohn Forte }
1784fcf3ce44SJohn Forte
1785fcf3ce44SJohn Forte /*
1786fcf3ce44SJohn Forte * iscsid_thread_slp -- If SLP discovery is enabled, this routine provides
1787fcf3ce44SJohn Forte * the SLP discovery service.
1788fcf3ce44SJohn Forte */
1789fcf3ce44SJohn Forte static void
iscsid_thread_slp(iscsi_thread_t * thread,void * p)1790fcf3ce44SJohn Forte iscsid_thread_slp(iscsi_thread_t *thread, void *p)
1791fcf3ce44SJohn Forte {
1792fcf3ce44SJohn Forte iscsi_hba_t *ihp = (iscsi_hba_t *)p;
1793fcf3ce44SJohn Forte
1794fcf3ce44SJohn Forte do {
1795fcf3ce44SJohn Forte /*
1796fcf3ce44SJohn Forte * Even though we don't have support for SLP at this point
1797fcf3ce44SJohn Forte * we'll send the events if someone has enabled this thread.
1798fcf3ce44SJohn Forte * If this is not done the daemon waiting for discovery to
1799fcf3ce44SJohn Forte * complete will pause forever holding up the boot process.
1800fcf3ce44SJohn Forte */
1801fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodSLP, B_TRUE);
1802fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodSLP, B_FALSE);
1803fcf3ce44SJohn Forte } while (iscsi_thread_wait(thread, -1) != 0);
1804fcf3ce44SJohn Forte }
1805fcf3ce44SJohn Forte
1806fcf3ce44SJohn Forte /*
1807fcf3ce44SJohn Forte * iscsid_thread_isns --
1808fcf3ce44SJohn Forte */
1809fcf3ce44SJohn Forte static void
iscsid_thread_isns(iscsi_thread_t * thread,void * ptr)1810fcf3ce44SJohn Forte iscsid_thread_isns(iscsi_thread_t *thread, void *ptr)
1811fcf3ce44SJohn Forte {
1812fcf3ce44SJohn Forte iscsi_hba_t *ihp = (iscsi_hba_t *)ptr;
1813fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t dm;
1814fcf3ce44SJohn Forte
1815fcf3ce44SJohn Forte while (iscsi_thread_wait(thread, -1) != 0) {
1816fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodISNS, B_TRUE);
1817fcf3ce44SJohn Forte
1818fcf3ce44SJohn Forte /* ---- ensure iSNS discovery is enabled ---- */
1819fcf3ce44SJohn Forte dm = persistent_disc_meth_get();
1820fcf3ce44SJohn Forte if ((dm & iSCSIDiscoveryMethodISNS) == 0) {
1821fcf3ce44SJohn Forte cmn_err(CE_NOTE,
1822fcf3ce44SJohn Forte "iscsi discovery failure - "
1823fcf3ce44SJohn Forte "iSNS method is not enabled");
1824fcf3ce44SJohn Forte iscsi_discovery_event(ihp,
1825fcf3ce44SJohn Forte iSCSIDiscoveryMethodISNS, B_FALSE);
1826fcf3ce44SJohn Forte continue;
1827fcf3ce44SJohn Forte }
1828fcf3ce44SJohn Forte
1829fcf3ce44SJohn Forte (void) isns_reg(ihp->hba_isid,
1830fcf3ce44SJohn Forte ihp->hba_name,
1831fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN,
1832fcf3ce44SJohn Forte ihp->hba_alias,
1833fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN,
1834fcf3ce44SJohn Forte ISNS_INITIATOR_NODE_TYPE,
1835fcf3ce44SJohn Forte isns_scn_callback);
1836fcf3ce44SJohn Forte iscsid_do_isns_query(ihp);
1837fcf3ce44SJohn Forte iscsi_discovery_event(ihp, iSCSIDiscoveryMethodISNS, B_FALSE);
1838fcf3ce44SJohn Forte }
1839fcf3ce44SJohn Forte
1840fcf3ce44SJohn Forte /* Thread stopped. Deregister from iSNS servers(s). */
1841fcf3ce44SJohn Forte (void) isns_dereg(ihp->hba_isid, ihp->hba_name);
1842fcf3ce44SJohn Forte }
1843fcf3ce44SJohn Forte
1844fcf3ce44SJohn Forte
1845fcf3ce44SJohn Forte /*
1846fcf3ce44SJohn Forte * iscsid_threads_create -- Creates all the discovery threads.
1847fcf3ce44SJohn Forte */
1848fcf3ce44SJohn Forte static void
iscsid_threads_create(iscsi_hba_t * ihp)1849fcf3ce44SJohn Forte iscsid_threads_create(iscsi_hba_t *ihp)
1850fcf3ce44SJohn Forte {
1851fcf3ce44SJohn Forte iscsid_thr_table *t;
1852fcf3ce44SJohn Forte
1853fcf3ce44SJohn Forte /*
1854fcf3ce44SJohn Forte * start a thread for each discovery method
1855fcf3ce44SJohn Forte */
1856fcf3ce44SJohn Forte for (t = &iscsid_thr[0]; t->method != iSCSIDiscoveryMethodUnknown;
1857fcf3ce44SJohn Forte t++) {
1858fcf3ce44SJohn Forte if (t->thr_id == NULL) {
1859fcf3ce44SJohn Forte t->thr_id = iscsi_thread_create(ihp->hba_dip, t->name,
1860fcf3ce44SJohn Forte t->func_start, ihp);
1861fcf3ce44SJohn Forte }
1862fcf3ce44SJohn Forte }
1863fcf3ce44SJohn Forte }
1864fcf3ce44SJohn Forte
1865fcf3ce44SJohn Forte /*
1866fcf3ce44SJohn Forte * iscsid_threads_destroy -- Destroys all the discovery threads.
1867fcf3ce44SJohn Forte */
1868fcf3ce44SJohn Forte static void
iscsid_threads_destroy(void)1869fcf3ce44SJohn Forte iscsid_threads_destroy(void)
1870fcf3ce44SJohn Forte {
1871fcf3ce44SJohn Forte iscsid_thr_table *t;
1872fcf3ce44SJohn Forte
1873fcf3ce44SJohn Forte for (t = &iscsid_thr[0]; t->method != iSCSIDiscoveryMethodUnknown;
1874fcf3ce44SJohn Forte t++) {
1875fcf3ce44SJohn Forte if (t->thr_id != NULL) {
1876fcf3ce44SJohn Forte iscsi_thread_destroy(t->thr_id);
1877fcf3ce44SJohn Forte t->thr_id = NULL;
1878fcf3ce44SJohn Forte }
1879fcf3ce44SJohn Forte }
1880fcf3ce44SJohn Forte }
1881fcf3ce44SJohn Forte
1882fcf3ce44SJohn Forte /*
1883fcf3ce44SJohn Forte * iscsid_copyto_param_set - helper function for iscsid_init_params.
1884fcf3ce44SJohn Forte */
1885fcf3ce44SJohn Forte static int
iscsid_copyto_param_set(uint32_t param_id,iscsi_login_params_t * params,iscsi_param_set_t * ipsp)1886fcf3ce44SJohn Forte iscsid_copyto_param_set(uint32_t param_id, iscsi_login_params_t *params,
1887fcf3ce44SJohn Forte iscsi_param_set_t *ipsp)
1888fcf3ce44SJohn Forte {
1889fcf3ce44SJohn Forte int rtn = 0;
1890fcf3ce44SJohn Forte
1891fcf3ce44SJohn Forte if (param_id >= ISCSI_NUM_LOGIN_PARAM) {
1892fcf3ce44SJohn Forte return (EINVAL);
1893fcf3ce44SJohn Forte }
1894fcf3ce44SJohn Forte
1895fcf3ce44SJohn Forte switch (param_id) {
1896fcf3ce44SJohn Forte
1897fcf3ce44SJohn Forte /*
1898fcf3ce44SJohn Forte * Boolean parameters
1899fcf3ce44SJohn Forte */
1900fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER:
1901fcf3ce44SJohn Forte ipsp->s_value.v_bool = params->data_pdu_in_order;
1902fcf3ce44SJohn Forte break;
1903fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_IMMEDIATE_DATA:
1904fcf3ce44SJohn Forte ipsp->s_value.v_bool = params->immediate_data;
1905fcf3ce44SJohn Forte break;
1906fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_INITIAL_R2T:
1907fcf3ce44SJohn Forte ipsp->s_value.v_bool = params->initial_r2t;
1908fcf3ce44SJohn Forte break;
1909fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER:
1910fcf3ce44SJohn Forte ipsp->s_value.v_bool = params->data_pdu_in_order;
1911fcf3ce44SJohn Forte break;
1912fcf3ce44SJohn Forte
1913fcf3ce44SJohn Forte /*
1914fcf3ce44SJohn Forte * Integer parameters
1915fcf3ce44SJohn Forte */
1916fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_HEADER_DIGEST:
1917fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->header_digest;
1918fcf3ce44SJohn Forte break;
1919fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DATA_DIGEST:
1920fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->data_digest;
1921fcf3ce44SJohn Forte break;
1922fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN:
1923fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->default_time_to_retain;
1924fcf3ce44SJohn Forte break;
1925fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT:
1926fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->default_time_to_wait;
1927fcf3ce44SJohn Forte break;
1928fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH:
1929fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->max_recv_data_seg_len;
1930fcf3ce44SJohn Forte break;
1931fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH:
1932fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->first_burst_length;
1933fcf3ce44SJohn Forte break;
1934fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH:
1935fcf3ce44SJohn Forte ipsp->s_value.v_integer = params->max_burst_length;
1936fcf3ce44SJohn Forte break;
1937fcf3ce44SJohn Forte
1938fcf3ce44SJohn Forte /*
1939fcf3ce44SJohn Forte * Integer parameters which currently are unsettable
1940fcf3ce44SJohn Forte */
1941fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS:
1942fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T:
1943fcf3ce44SJohn Forte case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL:
1944fcf3ce44SJohn Forte /* ---- drop through to default case ---- */
1945fcf3ce44SJohn Forte default:
1946fcf3ce44SJohn Forte rtn = EINVAL;
1947fcf3ce44SJohn Forte break;
1948fcf3ce44SJohn Forte }
1949fcf3ce44SJohn Forte
1950fcf3ce44SJohn Forte /* if all is well, set the parameter identifier */
1951fcf3ce44SJohn Forte if (rtn == 0) {
1952fcf3ce44SJohn Forte ipsp->s_param = param_id;
1953fcf3ce44SJohn Forte }
1954fcf3ce44SJohn Forte
1955fcf3ce44SJohn Forte return (rtn);
1956fcf3ce44SJohn Forte }
1957fcf3ce44SJohn Forte
1958fcf3ce44SJohn Forte /*
1959fcf3ce44SJohn Forte * iscsid_add_pg_list_to_cache - Add portal groups in the list to the
1960fcf3ce44SJohn Forte * discovery cache.
1961fcf3ce44SJohn Forte */
1962fcf3ce44SJohn Forte static void
iscsid_add_pg_list_to_cache(iscsi_hba_t * ihp,isns_portal_group_list_t * pg_list)1963fcf3ce44SJohn Forte iscsid_add_pg_list_to_cache(iscsi_hba_t *ihp,
1964fcf3ce44SJohn Forte isns_portal_group_list_t *pg_list)
1965fcf3ce44SJohn Forte {
1966fcf3ce44SJohn Forte int i;
1967fcf3ce44SJohn Forte
1968fcf3ce44SJohn Forte for (i = 0; i < pg_list->pg_out_cnt; i++) {
1969fcf3ce44SJohn Forte iscsi_sockaddr_t addr_dsc;
1970fcf3ce44SJohn Forte iscsi_sockaddr_t addr_tgt;
1971fcf3ce44SJohn Forte
1972fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(
1973fcf3ce44SJohn Forte pg_list->pg_list[i].isns_server_ip.i_insize,
1974fcf3ce44SJohn Forte &pg_list->pg_list[i].isns_server_ip.i_addr,
1975fcf3ce44SJohn Forte pg_list->pg_list[i].isns_server_port,
1976fcf3ce44SJohn Forte &addr_dsc.sin);
1977fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(
1978fcf3ce44SJohn Forte pg_list->pg_list[i].insize,
1979fcf3ce44SJohn Forte &pg_list->pg_list[i].pg_ip_addr,
1980fcf3ce44SJohn Forte pg_list->pg_list[i].pg_port,
1981fcf3ce44SJohn Forte &addr_tgt.sin);
1982fcf3ce44SJohn Forte
1983fcf3ce44SJohn Forte (void) iscsid_add(ihp, iSCSIDiscoveryMethodISNS, &addr_dsc.sin,
1984fcf3ce44SJohn Forte (char *)pg_list->pg_list[i].pg_iscsi_name,
1985fcf3ce44SJohn Forte pg_list->pg_list[i].pg_tag, &addr_tgt.sin);
1986fcf3ce44SJohn Forte }
1987fcf3ce44SJohn Forte }
1988fcf3ce44SJohn Forte
1989fcf3ce44SJohn Forte /*
1990fcf3ce44SJohn Forte * set_initiator_name - set default initiator name and alias.
1991fcf3ce44SJohn Forte *
1992fcf3ce44SJohn Forte * This sets the default initiator name and alias. The
1993fcf3ce44SJohn Forte * initiator name is composed of sun's reverse domain name
1994fcf3ce44SJohn Forte * and registration followed and a unique classifier. This
1995fcf3ce44SJohn Forte * classifier is the mac address of the first NIC in the
1996fcf3ce44SJohn Forte * host and a timestamp to make sure the classifier is
1997fcf3ce44SJohn Forte * unique if the NIC is moved between hosts. The alias
1998fcf3ce44SJohn Forte * is just the hostname.
1999fcf3ce44SJohn Forte */
2000329c9e3dSJack Meng void
iscsid_set_default_initiator_node_settings(iscsi_hba_t * ihp,boolean_t minimal)2001329c9e3dSJack Meng iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp, boolean_t minimal)
2002fcf3ce44SJohn Forte {
2003fcf3ce44SJohn Forte int i;
2004fcf3ce44SJohn Forte time_t x;
2005fcf3ce44SJohn Forte struct ether_addr eaddr;
2006fcf3ce44SJohn Forte char val[10];
2007fcf3ce44SJohn Forte iscsi_chap_props_t *chap = NULL;
2008fcf3ce44SJohn Forte
2009fcf3ce44SJohn Forte /* Set default initiator-node name */
20106cefaae1SJack Meng if (iscsiboot_prop && iscsiboot_prop->boot_init.ini_name != NULL) {
20116cefaae1SJack Meng (void) strncpy((char *)ihp->hba_name,
20126cefaae1SJack Meng (const char *)iscsiboot_prop->boot_init.ini_name,
20136cefaae1SJack Meng ISCSI_MAX_NAME_LEN);
20146cefaae1SJack Meng } else {
20156cefaae1SJack Meng (void) snprintf((char *)ihp->hba_name,
20166cefaae1SJack Meng ISCSI_MAX_NAME_LEN,
20176cefaae1SJack Meng "iqn.1986-03.com.sun:01:");
20186cefaae1SJack Meng
20196cefaae1SJack Meng (void) localetheraddr(NULL, &eaddr);
20206cefaae1SJack Meng for (i = 0; i < ETHERADDRL; i++) {
20216cefaae1SJack Meng (void) snprintf(val, sizeof (val), "%02x",
20226cefaae1SJack Meng eaddr.ether_addr_octet[i]);
20236cefaae1SJack Meng (void) strncat((char *)ihp->hba_name, val,
20246cefaae1SJack Meng ISCSI_MAX_NAME_LEN);
20256cefaae1SJack Meng }
20266cefaae1SJack Meng
20276cefaae1SJack Meng /* Set default initiator-node alias */
20286cefaae1SJack Meng x = ddi_get_time();
20296cefaae1SJack Meng (void) snprintf(val, sizeof (val), ".%lx", x);
2030fcf3ce44SJohn Forte (void) strncat((char *)ihp->hba_name, val, ISCSI_MAX_NAME_LEN);
2031fcf3ce44SJohn Forte
20326cefaae1SJack Meng if (ihp->hba_alias[0] == '\0') {
20336cefaae1SJack Meng (void) strncpy((char *)ihp->hba_alias,
20346cefaae1SJack Meng utsname.nodename, ISCSI_MAX_NAME_LEN);
20356cefaae1SJack Meng ihp->hba_alias_length = strlen((char *)ihp->hba_alias);
2036329c9e3dSJack Meng if (minimal == B_FALSE) {
2037329c9e3dSJack Meng (void) persistent_alias_name_set(
2038329c9e3dSJack Meng (char *)ihp->hba_alias);
2039329c9e3dSJack Meng }
20406cefaae1SJack Meng }
2041fcf3ce44SJohn Forte }
2042329c9e3dSJack Meng
2043329c9e3dSJack Meng if (minimal == B_TRUE) {
2044329c9e3dSJack Meng return;
2045329c9e3dSJack Meng }
2046329c9e3dSJack Meng
20476cefaae1SJack Meng (void) persistent_initiator_name_set((char *)ihp->hba_name);
2048fcf3ce44SJohn Forte
2049fcf3ce44SJohn Forte /* Set default initiator-node CHAP settings */
2050fcf3ce44SJohn Forte if (persistent_initiator_name_get((char *)ihp->hba_name,
2051fcf3ce44SJohn Forte ISCSI_MAX_NAME_LEN) == B_TRUE) {
2052fcf3ce44SJohn Forte chap = (iscsi_chap_props_t *)kmem_zalloc(sizeof (*chap),
2053fcf3ce44SJohn Forte KM_SLEEP);
2054fcf3ce44SJohn Forte if (persistent_chap_get((char *)ihp->hba_name, chap) ==
2055fcf3ce44SJohn Forte B_FALSE) {
2056fcf3ce44SJohn Forte bcopy((char *)ihp->hba_name, chap->c_user,
2057fcf3ce44SJohn Forte strlen((char *)ihp->hba_name));
2058fcf3ce44SJohn Forte chap->c_user_len = strlen((char *)ihp->hba_name);
2059fcf3ce44SJohn Forte (void) persistent_chap_set((char *)ihp->hba_name, chap);
2060fcf3ce44SJohn Forte }
2061fcf3ce44SJohn Forte kmem_free(chap, sizeof (*chap));
2062fcf3ce44SJohn Forte }
2063fcf3ce44SJohn Forte }
2064fcf3ce44SJohn Forte
2065fcf3ce44SJohn Forte static void
iscsid_remove_target_param(char * name)2066fcf3ce44SJohn Forte iscsid_remove_target_param(char *name)
2067fcf3ce44SJohn Forte {
2068fcf3ce44SJohn Forte persistent_param_t *pparam;
2069fcf3ce44SJohn Forte uint32_t t_oid;
2070fcf3ce44SJohn Forte iscsi_config_sess_t *ics;
2071fcf3ce44SJohn Forte
2072fcf3ce44SJohn Forte ASSERT(name != NULL);
2073fcf3ce44SJohn Forte
2074fcf3ce44SJohn Forte /*
2075fcf3ce44SJohn Forte * Remove target-param <-> target mapping.
2076fcf3ce44SJohn Forte * Only remove if there is not any overridden
2077fcf3ce44SJohn Forte * parameters in the persistent store
2078fcf3ce44SJohn Forte */
2079fcf3ce44SJohn Forte pparam = (persistent_param_t *)kmem_zalloc(sizeof (*pparam), KM_SLEEP);
2080fcf3ce44SJohn Forte
2081fcf3ce44SJohn Forte /*
2082fcf3ce44SJohn Forte * setup initial buffer for configured session
2083fcf3ce44SJohn Forte * information
2084fcf3ce44SJohn Forte */
2085fcf3ce44SJohn Forte ics = (iscsi_config_sess_t *)kmem_zalloc(sizeof (*ics), KM_SLEEP);
2086fcf3ce44SJohn Forte ics->ics_in = 1;
2087fcf3ce44SJohn Forte
2088fcf3ce44SJohn Forte if ((persistent_param_get(name, pparam) == B_FALSE) &&
2089fcf3ce44SJohn Forte (persistent_get_config_session(name, ics) == B_FALSE)) {
2090fcf3ce44SJohn Forte t_oid = iscsi_targetparam_get_oid((uchar_t *)name);
2091fcf3ce44SJohn Forte (void) iscsi_targetparam_remove_target(t_oid);
2092fcf3ce44SJohn Forte }
2093fcf3ce44SJohn Forte
2094fcf3ce44SJohn Forte kmem_free(pparam, sizeof (*pparam));
2095fcf3ce44SJohn Forte pparam = NULL;
2096fcf3ce44SJohn Forte kmem_free(ics, sizeof (*ics));
2097fcf3ce44SJohn Forte ics = NULL;
2098fcf3ce44SJohn Forte }
2099fcf3ce44SJohn Forte
2100fcf3ce44SJohn Forte /*
2101fcf3ce44SJohn Forte * iscsid_addr_to_sockaddr - convert other types to struct sockaddr
2102fcf3ce44SJohn Forte */
2103fcf3ce44SJohn Forte void
iscsid_addr_to_sockaddr(int src_insize,void * src_addr,int src_port,struct sockaddr * dst_addr)2104fcf3ce44SJohn Forte iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port,
2105fcf3ce44SJohn Forte struct sockaddr *dst_addr)
2106fcf3ce44SJohn Forte {
2107fcf3ce44SJohn Forte ASSERT((src_insize == sizeof (struct in_addr)) ||
2108fcf3ce44SJohn Forte (src_insize == sizeof (struct in6_addr)));
2109fcf3ce44SJohn Forte ASSERT(src_addr != NULL);
2110fcf3ce44SJohn Forte ASSERT(dst_addr != NULL);
2111fcf3ce44SJohn Forte
2112fcf3ce44SJohn Forte bzero(dst_addr, sizeof (*dst_addr));
2113fcf3ce44SJohn Forte
2114fcf3ce44SJohn Forte /* translate discovery information */
2115fcf3ce44SJohn Forte if (src_insize == sizeof (struct in_addr)) {
2116fcf3ce44SJohn Forte struct sockaddr_in *addr_in =
2117fcf3ce44SJohn Forte (struct sockaddr_in *)dst_addr;
2118fcf3ce44SJohn Forte addr_in->sin_family = AF_INET;
2119fcf3ce44SJohn Forte bcopy(src_addr, &addr_in->sin_addr.s_addr,
2120fcf3ce44SJohn Forte sizeof (struct in_addr));
2121fcf3ce44SJohn Forte addr_in->sin_port = htons(src_port);
2122fcf3ce44SJohn Forte } else {
2123fcf3ce44SJohn Forte struct sockaddr_in6 *addr_in6 =
2124fcf3ce44SJohn Forte (struct sockaddr_in6 *)dst_addr;
2125fcf3ce44SJohn Forte addr_in6->sin6_family = AF_INET6;
2126fcf3ce44SJohn Forte bcopy(src_addr, &addr_in6->sin6_addr.s6_addr,
2127fcf3ce44SJohn Forte sizeof (struct in6_addr));
2128fcf3ce44SJohn Forte addr_in6->sin6_port = htons(src_port);
2129fcf3ce44SJohn Forte }
2130fcf3ce44SJohn Forte }
2131fcf3ce44SJohn Forte
2132fcf3ce44SJohn Forte /*
2133fcf3ce44SJohn Forte * iscsi_discovery_event -- send event associated with discovery operations
2134fcf3ce44SJohn Forte *
2135fcf3ce44SJohn Forte * Each discovery event has a start and end event. Which is sent is based
2136fcf3ce44SJohn Forte * on the boolean argument start with the obvious results.
2137fcf3ce44SJohn Forte */
2138fcf3ce44SJohn Forte static void
iscsi_discovery_event(iscsi_hba_t * ihp,iSCSIDiscoveryMethod_t m,boolean_t start)2139fcf3ce44SJohn Forte iscsi_discovery_event(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t m,
2140fcf3ce44SJohn Forte boolean_t start)
2141fcf3ce44SJohn Forte {
2142fcf3ce44SJohn Forte char *subclass = NULL;
2143fcf3ce44SJohn Forte
2144fcf3ce44SJohn Forte mutex_enter(&ihp->hba_discovery_events_mutex);
2145fcf3ce44SJohn Forte switch (m) {
2146fcf3ce44SJohn Forte case iSCSIDiscoveryMethodStatic:
2147fcf3ce44SJohn Forte if (start == B_TRUE) {
2148fcf3ce44SJohn Forte subclass = ESC_ISCSI_STATIC_START;
2149fcf3ce44SJohn Forte } else {
2150fcf3ce44SJohn Forte ihp->hba_discovery_events |= iSCSIDiscoveryMethodStatic;
2151fcf3ce44SJohn Forte subclass = ESC_ISCSI_STATIC_END;
2152fcf3ce44SJohn Forte }
2153fcf3ce44SJohn Forte break;
2154fcf3ce44SJohn Forte
2155fcf3ce44SJohn Forte case iSCSIDiscoveryMethodSendTargets:
2156fcf3ce44SJohn Forte if (start == B_TRUE) {
2157fcf3ce44SJohn Forte subclass = ESC_ISCSI_SEND_TARGETS_START;
2158fcf3ce44SJohn Forte } else {
2159fcf3ce44SJohn Forte ihp->hba_discovery_events |=
2160fcf3ce44SJohn Forte iSCSIDiscoveryMethodSendTargets;
2161fcf3ce44SJohn Forte subclass = ESC_ISCSI_SEND_TARGETS_END;
2162fcf3ce44SJohn Forte }
2163fcf3ce44SJohn Forte break;
2164fcf3ce44SJohn Forte
2165fcf3ce44SJohn Forte case iSCSIDiscoveryMethodSLP:
2166fcf3ce44SJohn Forte if (start == B_TRUE) {
2167fcf3ce44SJohn Forte subclass = ESC_ISCSI_SLP_START;
2168fcf3ce44SJohn Forte } else {
2169fcf3ce44SJohn Forte ihp->hba_discovery_events |= iSCSIDiscoveryMethodSLP;
2170fcf3ce44SJohn Forte subclass = ESC_ISCSI_SLP_END;
2171fcf3ce44SJohn Forte }
2172fcf3ce44SJohn Forte break;
2173fcf3ce44SJohn Forte
2174fcf3ce44SJohn Forte case iSCSIDiscoveryMethodISNS:
2175fcf3ce44SJohn Forte if (start == B_TRUE) {
2176fcf3ce44SJohn Forte subclass = ESC_ISCSI_ISNS_START;
2177fcf3ce44SJohn Forte } else {
2178fcf3ce44SJohn Forte ihp->hba_discovery_events |= iSCSIDiscoveryMethodISNS;
2179fcf3ce44SJohn Forte subclass = ESC_ISCSI_ISNS_END;
2180fcf3ce44SJohn Forte }
2181fcf3ce44SJohn Forte break;
2182fcf3ce44SJohn Forte }
2183fcf3ce44SJohn Forte mutex_exit(&ihp->hba_discovery_events_mutex);
2184c60a6da3Sbing zhao - Sun Microsystems - Beijing China iscsi_send_sysevent(ihp, EC_ISCSI, subclass, NULL);
2185fcf3ce44SJohn Forte }
2186fcf3ce44SJohn Forte
2187fcf3ce44SJohn Forte /*
2188c60a6da3Sbing zhao - Sun Microsystems - Beijing China * iscsi_send_sysevent -- send sysevent using specified class
2189fcf3ce44SJohn Forte */
2190c60a6da3Sbing zhao - Sun Microsystems - Beijing China void
iscsi_send_sysevent(iscsi_hba_t * ihp,char * eventclass,char * subclass,nvlist_t * np)2191c60a6da3Sbing zhao - Sun Microsystems - Beijing China iscsi_send_sysevent(
2192c60a6da3Sbing zhao - Sun Microsystems - Beijing China iscsi_hba_t *ihp,
2193c60a6da3Sbing zhao - Sun Microsystems - Beijing China char *eventclass,
2194c60a6da3Sbing zhao - Sun Microsystems - Beijing China char *subclass,
2195c60a6da3Sbing zhao - Sun Microsystems - Beijing China nvlist_t *np)
2196fcf3ce44SJohn Forte {
2197c60a6da3Sbing zhao - Sun Microsystems - Beijing China (void) ddi_log_sysevent(ihp->hba_dip, DDI_VENDOR_SUNW, eventclass,
2198fcf3ce44SJohn Forte subclass, np, NULL, DDI_SLEEP);
2199fcf3ce44SJohn Forte }
22006cefaae1SJack Meng
22016cefaae1SJack Meng static boolean_t
iscsid_boot_init_config(iscsi_hba_t * ihp)22026cefaae1SJack Meng iscsid_boot_init_config(iscsi_hba_t *ihp)
22036cefaae1SJack Meng {
22046cefaae1SJack Meng if (strlen((const char *)iscsiboot_prop->boot_init.ini_name) != 0) {
22056cefaae1SJack Meng bcopy(iscsiboot_prop->boot_init.ini_name,
22066cefaae1SJack Meng ihp->hba_name,
22076cefaae1SJack Meng strlen((const char *)iscsiboot_prop->boot_init.ini_name));
22086cefaae1SJack Meng }
22096cefaae1SJack Meng /* or using default login param for boot session */
22106cefaae1SJack Meng return (B_TRUE);
22116cefaae1SJack Meng }
22126cefaae1SJack Meng
22136cefaae1SJack Meng boolean_t
iscsi_reconfig_boot_sess(iscsi_hba_t * ihp)22146cefaae1SJack Meng iscsi_reconfig_boot_sess(iscsi_hba_t *ihp)
22156cefaae1SJack Meng {
22166cefaae1SJack Meng iscsi_config_sess_t *ics;
22176cefaae1SJack Meng int idx;
22186cefaae1SJack Meng iscsi_sess_t *isp, *t_isp;
22196cefaae1SJack Meng int isid, size;
22206cefaae1SJack Meng char *name;
22216cefaae1SJack Meng boolean_t rtn = B_TRUE;
2222904e51f6SJack Meng uint32_t event_count;
22236cefaae1SJack Meng
22246cefaae1SJack Meng if (iscsiboot_prop == NULL) {
22256cefaae1SJack Meng return (B_FALSE);
22266cefaae1SJack Meng }
22276cefaae1SJack Meng size = sizeof (*ics);
22286cefaae1SJack Meng ics = kmem_zalloc(size, KM_SLEEP);
22296cefaae1SJack Meng ics->ics_in = 1;
22306cefaae1SJack Meng
22316cefaae1SJack Meng /* get information of number of sessions to be configured */
22326cefaae1SJack Meng name = (char *)iscsiboot_prop->boot_tgt.tgt_name;
22336cefaae1SJack Meng if (persistent_get_config_session(name, ics) == B_FALSE) {
22346cefaae1SJack Meng /*
22356cefaae1SJack Meng * No target information available to check
22366cefaae1SJack Meng * initiator information. Assume one session
22376cefaae1SJack Meng * by default.
22386cefaae1SJack Meng */
22396cefaae1SJack Meng name = (char *)iscsiboot_prop->boot_init.ini_name;
22406cefaae1SJack Meng if (persistent_get_config_session(name, ics) == B_FALSE) {
22416cefaae1SJack Meng ics->ics_out = 1;
22426cefaae1SJack Meng ics->ics_bound = B_TRUE;
22436cefaae1SJack Meng }
22446cefaae1SJack Meng }
22456cefaae1SJack Meng
22466cefaae1SJack Meng /* get necessary information */
22476cefaae1SJack Meng if (ics->ics_out > 1) {
22486cefaae1SJack Meng idx = ics->ics_out;
22496cefaae1SJack Meng size = ISCSI_SESSION_CONFIG_SIZE(ics->ics_out);
22506cefaae1SJack Meng kmem_free(ics, sizeof (*ics));
22516cefaae1SJack Meng
22526cefaae1SJack Meng ics = kmem_zalloc(size, KM_SLEEP);
22536cefaae1SJack Meng ics->ics_in = idx;
22546cefaae1SJack Meng
22556cefaae1SJack Meng /* get configured sessions information */
22566cefaae1SJack Meng if (persistent_get_config_session((char *)name,
22576cefaae1SJack Meng ics) != B_TRUE) {
22586cefaae1SJack Meng cmn_err(CE_NOTE, "session(%s) - "
22596cefaae1SJack Meng "failed to setup multiple sessions",
22606cefaae1SJack Meng name);
22616cefaae1SJack Meng kmem_free(ics, size);
22626cefaae1SJack Meng return (B_FALSE);
22636cefaae1SJack Meng }
22646cefaae1SJack Meng }
22656cefaae1SJack Meng
22666cefaae1SJack Meng /* create a temporary session to keep boot session connective */
22676cefaae1SJack Meng t_isp = iscsi_add_boot_sess(ihp, ISCSI_MAX_CONFIG_SESSIONS);
22686cefaae1SJack Meng if (t_isp == NULL) {
22696cefaae1SJack Meng cmn_err(CE_NOTE, "session(%s) - "
22706cefaae1SJack Meng "failed to setup multiple sessions", name);
22716cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
22726cefaae1SJack Meng kmem_free(ics, size);
22736cefaae1SJack Meng return (B_FALSE);
22746cefaae1SJack Meng }
22756cefaae1SJack Meng
22766cefaae1SJack Meng /* destroy all old boot sessions */
22776cefaae1SJack Meng rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
22786cefaae1SJack Meng isp = ihp->hba_sess_list;
22796cefaae1SJack Meng while (isp != NULL) {
22806cefaae1SJack Meng if (iscsi_chk_bootlun_mpxio(ihp) && isp->sess_boot) {
22816cefaae1SJack Meng if (isp->sess_isid[5] != ISCSI_MAX_CONFIG_SESSIONS) {
22826cefaae1SJack Meng /*
22836cefaae1SJack Meng * destroy all stale sessions
22846cefaae1SJack Meng * except temporary boot session
22856cefaae1SJack Meng */
22866cefaae1SJack Meng if (ISCSI_SUCCESS(iscsi_sess_destroy(
22876cefaae1SJack Meng isp))) {
22886cefaae1SJack Meng isp = ihp->hba_sess_list;
22896cefaae1SJack Meng } else {
22906cefaae1SJack Meng /*
22916cefaae1SJack Meng * couldn't destroy stale sessions
22926cefaae1SJack Meng * at least poke it to disconnect
22936cefaae1SJack Meng */
2294904e51f6SJack Meng event_count = atomic_inc_32_nv(
2295904e51f6SJack Meng &isp->sess_state_event_count);
2296904e51f6SJack Meng iscsi_sess_enter_state_zone(isp);
22976cefaae1SJack Meng iscsi_sess_state_machine(isp,
2298904e51f6SJack Meng ISCSI_SESS_EVENT_N7, event_count);
2299904e51f6SJack Meng iscsi_sess_exit_state_zone(isp);
2300904e51f6SJack Meng
23016cefaae1SJack Meng isp = isp->sess_next;
23026cefaae1SJack Meng cmn_err(CE_NOTE, "session(%s) - "
23036cefaae1SJack Meng "failed to setup multiple"
23046cefaae1SJack Meng " sessions", name);
23056cefaae1SJack Meng }
23066cefaae1SJack Meng } else {
23076cefaae1SJack Meng isp = isp->sess_next;
23086cefaae1SJack Meng }
23096cefaae1SJack Meng } else {
23106cefaae1SJack Meng isp = isp->sess_next;
23116cefaae1SJack Meng }
23126cefaae1SJack Meng }
23136cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23146cefaae1SJack Meng
23156cefaae1SJack Meng for (isid = 0; isid < ics->ics_out; isid++) {
23166cefaae1SJack Meng isp = iscsi_add_boot_sess(ihp, isid);
23176cefaae1SJack Meng if (isp == NULL) {
23186cefaae1SJack Meng cmn_err(CE_NOTE, "session(%s) - failed to setup"
23196cefaae1SJack Meng " multiple sessions", name);
23206cefaae1SJack Meng rtn = B_FALSE;
23216cefaae1SJack Meng break;
23226cefaae1SJack Meng }
23236cefaae1SJack Meng }
23246cefaae1SJack Meng if (!rtn && (isid == 0)) {
23256cefaae1SJack Meng /*
23266cefaae1SJack Meng * fail to create any new boot session
23276cefaae1SJack Meng * so only the temporary session is alive
23286cefaae1SJack Meng * quit without destroying it
23296cefaae1SJack Meng */
23306cefaae1SJack Meng kmem_free(ics, size);
23316cefaae1SJack Meng return (rtn);
23326cefaae1SJack Meng }
23336cefaae1SJack Meng
23346cefaae1SJack Meng rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
23356cefaae1SJack Meng if (!ISCSI_SUCCESS(iscsi_sess_destroy(t_isp))) {
23366cefaae1SJack Meng /* couldn't destroy temp boot session */
23376cefaae1SJack Meng cmn_err(CE_NOTE, "session(%s) - "
23386cefaae1SJack Meng "failed to setup multiple sessions", name);
23396cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23406cefaae1SJack Meng rtn = B_FALSE;
23416cefaae1SJack Meng }
23426cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23436cefaae1SJack Meng
23446cefaae1SJack Meng kmem_free(ics, size);
23456cefaae1SJack Meng return (rtn);
23466cefaae1SJack Meng }
23476cefaae1SJack Meng
23486cefaae1SJack Meng static iscsi_sess_t *
iscsi_add_boot_sess(iscsi_hba_t * ihp,int isid)23496cefaae1SJack Meng iscsi_add_boot_sess(iscsi_hba_t *ihp, int isid)
23506cefaae1SJack Meng {
23516cefaae1SJack Meng iscsi_sess_t *isp;
23526cefaae1SJack Meng iscsi_conn_t *icp;
23536cefaae1SJack Meng uint_t oid;
23546cefaae1SJack Meng
23556cefaae1SJack Meng iscsi_sockaddr_t addr_dst;
23566cefaae1SJack Meng
23576cefaae1SJack Meng addr_dst.sin.sa_family = iscsiboot_prop->boot_tgt.sin_family;
23586cefaae1SJack Meng if (addr_dst.sin.sa_family == AF_INET) {
23596cefaae1SJack Meng bcopy(&iscsiboot_prop->boot_tgt.tgt_ip_u.u_in4.s_addr,
23606cefaae1SJack Meng &addr_dst.sin4.sin_addr.s_addr, sizeof (struct in_addr));
23616cefaae1SJack Meng addr_dst.sin4.sin_port =
23626cefaae1SJack Meng htons(iscsiboot_prop->boot_tgt.tgt_port);
23636cefaae1SJack Meng } else {
23646cefaae1SJack Meng bcopy(&iscsiboot_prop->boot_tgt.tgt_ip_u.u_in6.s6_addr,
23656cefaae1SJack Meng &addr_dst.sin6.sin6_addr.s6_addr,
23666cefaae1SJack Meng sizeof (struct in6_addr));
23676cefaae1SJack Meng addr_dst.sin6.sin6_port =
23686cefaae1SJack Meng htons(iscsiboot_prop->boot_tgt.tgt_port);
23696cefaae1SJack Meng }
23706cefaae1SJack Meng
23716cefaae1SJack Meng rw_enter(&ihp->hba_sess_list_rwlock, RW_WRITER);
23726cefaae1SJack Meng isp = iscsi_sess_create(ihp,
23736cefaae1SJack Meng iSCSIDiscoveryMethodBoot|iSCSIDiscoveryMethodStatic,
23746cefaae1SJack Meng (struct sockaddr *)&addr_dst,
23756cefaae1SJack Meng (char *)iscsiboot_prop->boot_tgt.tgt_name,
23766cefaae1SJack Meng ISCSI_DEFAULT_TPGT, isid, ISCSI_SESS_TYPE_NORMAL, &oid);
23776cefaae1SJack Meng if (isp == NULL) {
23786cefaae1SJack Meng /* create temp booting session failed */
23796cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23806cefaae1SJack Meng return (NULL);
23816cefaae1SJack Meng }
23826cefaae1SJack Meng isp->sess_boot = B_TRUE;
23836cefaae1SJack Meng
23846cefaae1SJack Meng if (!ISCSI_SUCCESS(iscsi_conn_create((struct sockaddr *)&addr_dst,
23856cefaae1SJack Meng isp, &icp))) {
23866cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23876cefaae1SJack Meng return (NULL);
23886cefaae1SJack Meng }
23896cefaae1SJack Meng
23906cefaae1SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
23916cefaae1SJack Meng /* now online created session */
23926cefaae1SJack Meng if (iscsid_login_tgt(ihp, (char *)iscsiboot_prop->boot_tgt.tgt_name,
23936cefaae1SJack Meng iSCSIDiscoveryMethodBoot|iSCSIDiscoveryMethodStatic,
23946cefaae1SJack Meng (struct sockaddr *)&addr_dst) == B_FALSE) {
23956cefaae1SJack Meng return (NULL);
23966cefaae1SJack Meng }
23976cefaae1SJack Meng
23986cefaae1SJack Meng return (isp);
23996cefaae1SJack Meng }
24006cefaae1SJack Meng
24016cefaae1SJack Meng static void
iscsid_thread_boot_wd(iscsi_thread_t * thread,void * p)24026cefaae1SJack Meng iscsid_thread_boot_wd(iscsi_thread_t *thread, void *p)
24036cefaae1SJack Meng {
24044246c8e9SJack Meng int rc = 1;
24056cefaae1SJack Meng iscsi_hba_t *ihp = (iscsi_hba_t *)p;
24064246c8e9SJack Meng boolean_t reconfigured = B_FALSE;
24076cefaae1SJack Meng
24086cefaae1SJack Meng while (rc != 0) {
24094246c8e9SJack Meng if (iscsiboot_prop && (modrootloaded == 1)) {
24104246c8e9SJack Meng if (ihp->hba_persistent_loaded == B_FALSE) {
24114246c8e9SJack Meng if (persistent_load() == B_TRUE) {
24124246c8e9SJack Meng ihp->hba_persistent_loaded = B_TRUE;
24134246c8e9SJack Meng }
24144246c8e9SJack Meng }
24154246c8e9SJack Meng if ((ihp->hba_persistent_loaded == B_TRUE) &&
24164246c8e9SJack Meng (reconfigured == B_FALSE)) {
2417169c6dc4SJack Meng if (iscsi_chk_bootlun_mpxio(ihp) == B_TRUE) {
2418169c6dc4SJack Meng (void) iscsi_reconfig_boot_sess(ihp);
2419169c6dc4SJack Meng iscsid_poke_discovery(ihp,
2420169c6dc4SJack Meng iSCSIDiscoveryMethodUnknown);
2421169c6dc4SJack Meng (void) iscsid_login_tgt(ihp, NULL,
2422169c6dc4SJack Meng iSCSIDiscoveryMethodUnknown, NULL);
2423169c6dc4SJack Meng }
24244246c8e9SJack Meng reconfigured = B_TRUE;
24254246c8e9SJack Meng }
24266cefaae1SJack Meng break;
24276cefaae1SJack Meng }
24286cefaae1SJack Meng rc = iscsi_thread_wait(thread, SEC_TO_TICK(1));
24296cefaae1SJack Meng }
24306cefaae1SJack Meng }
24316cefaae1SJack Meng
24326cefaae1SJack Meng boolean_t
iscsi_cmp_boot_tgt_name(char * name)24336cefaae1SJack Meng iscsi_cmp_boot_tgt_name(char *name)
24346cefaae1SJack Meng {
24356cefaae1SJack Meng if (iscsiboot_prop && (strncmp((const char *)name,
24366cefaae1SJack Meng (const char *)iscsiboot_prop->boot_tgt.tgt_name,
24376cefaae1SJack Meng ISCSI_MAX_NAME_LEN) == 0)) {
24386cefaae1SJack Meng return (B_TRUE);
24396cefaae1SJack Meng } else {
24406cefaae1SJack Meng return (B_FALSE);
24416cefaae1SJack Meng }
24426cefaae1SJack Meng }
24436cefaae1SJack Meng
24446cefaae1SJack Meng boolean_t
iscsi_cmp_boot_ini_name(char * name)24456cefaae1SJack Meng iscsi_cmp_boot_ini_name(char *name)
24466cefaae1SJack Meng {
24476cefaae1SJack Meng if (iscsiboot_prop && (strncmp((const char *)name,
24486cefaae1SJack Meng (const char *)iscsiboot_prop->boot_init.ini_name,
24496cefaae1SJack Meng ISCSI_MAX_NAME_LEN) == 0)) {
24506cefaae1SJack Meng return (B_TRUE);
24516cefaae1SJack Meng } else {
24526cefaae1SJack Meng return (B_FALSE);
24536cefaae1SJack Meng }
24546cefaae1SJack Meng }
24556cefaae1SJack Meng
24566cefaae1SJack Meng boolean_t
iscsi_chk_bootlun_mpxio(iscsi_hba_t * ihp)24576cefaae1SJack Meng iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp)
24586cefaae1SJack Meng {
24596cefaae1SJack Meng iscsi_sess_t *isp;
24606cefaae1SJack Meng iscsi_lun_t *ilp;
24616cefaae1SJack Meng isp = ihp->hba_sess_list;
24626cefaae1SJack Meng boolean_t tgt_mpxio_enabled = B_FALSE;
24636cefaae1SJack Meng boolean_t bootlun_found = B_FALSE;
24646cefaae1SJack Meng uint16_t lun_num;
24656cefaae1SJack Meng
24666cefaae1SJack Meng if (iscsiboot_prop == NULL) {
24676cefaae1SJack Meng return (B_FALSE);
24686cefaae1SJack Meng }
24696cefaae1SJack Meng
24706cefaae1SJack Meng if (!ihp->hba_mpxio_enabled) {
24716cefaae1SJack Meng return (B_FALSE);
24726cefaae1SJack Meng }
24736cefaae1SJack Meng
24746cefaae1SJack Meng lun_num = *((uint64_t *)(iscsiboot_prop->boot_tgt.tgt_boot_lun));
24756cefaae1SJack Meng
24766cefaae1SJack Meng while (isp != NULL) {
24776cefaae1SJack Meng if ((strncmp((char *)isp->sess_name,
24786cefaae1SJack Meng (const char *)iscsiboot_prop->boot_tgt.tgt_name,
24796cefaae1SJack Meng ISCSI_MAX_NAME_LEN) == 0) &&
24806cefaae1SJack Meng (isp->sess_boot == B_TRUE)) {
24816cefaae1SJack Meng /*
24826cefaae1SJack Meng * found boot session.
24836cefaae1SJack Meng * check its mdi path info is null or not
24846cefaae1SJack Meng */
24856cefaae1SJack Meng ilp = isp->sess_lun_list;
24866cefaae1SJack Meng while (ilp != NULL) {
24876cefaae1SJack Meng if (lun_num == ilp->lun_num) {
24886cefaae1SJack Meng if (ilp->lun_pip) {
24896cefaae1SJack Meng tgt_mpxio_enabled = B_TRUE;
24906cefaae1SJack Meng }
24916cefaae1SJack Meng bootlun_found = B_TRUE;
24926cefaae1SJack Meng }
24936cefaae1SJack Meng ilp = ilp->lun_next;
24946cefaae1SJack Meng }
24956cefaae1SJack Meng }
24966cefaae1SJack Meng isp = isp->sess_next;
24976cefaae1SJack Meng }
24986cefaae1SJack Meng if (bootlun_found) {
24996cefaae1SJack Meng return (tgt_mpxio_enabled);
25006cefaae1SJack Meng } else {
25016cefaae1SJack Meng /*
25026cefaae1SJack Meng * iscsiboot_prop not NULL while no boot lun found
25036cefaae1SJack Meng * in most cases this is none iscsi boot while iscsiboot_prop
25046cefaae1SJack Meng * is not NULL, in this scenario return iscsi HBA's mpxio config
25056cefaae1SJack Meng */
25066cefaae1SJack Meng return (ihp->hba_mpxio_enabled);
25076cefaae1SJack Meng }
25086cefaae1SJack Meng }
2509f53e1f19SJack Meng
2510f53e1f19SJack Meng static boolean_t
iscsid_check_active_boot_conn(iscsi_hba_t * ihp)2511f53e1f19SJack Meng iscsid_check_active_boot_conn(iscsi_hba_t *ihp)
2512f53e1f19SJack Meng {
2513f53e1f19SJack Meng iscsi_sess_t *isp = NULL;
2514f53e1f19SJack Meng iscsi_conn_t *icp = NULL;
2515f53e1f19SJack Meng
2516f53e1f19SJack Meng rw_enter(&ihp->hba_sess_list_rwlock, RW_READER);
2517f53e1f19SJack Meng isp = ihp->hba_sess_list;
2518f53e1f19SJack Meng while (isp != NULL) {
2519f53e1f19SJack Meng if (isp->sess_boot == B_TRUE) {
2520f53e1f19SJack Meng rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
2521f53e1f19SJack Meng icp = isp->sess_conn_list;
2522f53e1f19SJack Meng while (icp != NULL) {
2523f53e1f19SJack Meng if (icp->conn_state ==
2524f53e1f19SJack Meng ISCSI_CONN_STATE_LOGGED_IN) {
2525f53e1f19SJack Meng rw_exit(&isp->sess_conn_list_rwlock);
2526f53e1f19SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
2527f53e1f19SJack Meng return (B_TRUE);
2528f53e1f19SJack Meng }
2529f53e1f19SJack Meng icp = icp->conn_next;
2530f53e1f19SJack Meng }
2531f53e1f19SJack Meng rw_exit(&isp->sess_conn_list_rwlock);
2532f53e1f19SJack Meng }
2533f53e1f19SJack Meng isp = isp->sess_next;
2534f53e1f19SJack Meng }
2535f53e1f19SJack Meng rw_exit(&ihp->hba_sess_list_rwlock);
2536f53e1f19SJack Meng
2537f53e1f19SJack Meng return (B_FALSE);
2538f53e1f19SJack Meng }
2539