1*a6d42e7dSPeter Dunlap /* 2*a6d42e7dSPeter Dunlap * CDDL HEADER START 3*a6d42e7dSPeter Dunlap * 4*a6d42e7dSPeter Dunlap * The contents of this file are subject to the terms of the 5*a6d42e7dSPeter Dunlap * Common Development and Distribution License (the "License"). 6*a6d42e7dSPeter Dunlap * You may not use this file except in compliance with the License. 7*a6d42e7dSPeter Dunlap * 8*a6d42e7dSPeter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*a6d42e7dSPeter Dunlap * or http://www.opensolaris.org/os/licensing. 10*a6d42e7dSPeter Dunlap * See the License for the specific language governing permissions 11*a6d42e7dSPeter Dunlap * and limitations under the License. 12*a6d42e7dSPeter Dunlap * 13*a6d42e7dSPeter Dunlap * When distributing Covered Code, include this CDDL HEADER in each 14*a6d42e7dSPeter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*a6d42e7dSPeter Dunlap * If applicable, add the following below this CDDL HEADER, with the 16*a6d42e7dSPeter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying 17*a6d42e7dSPeter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner] 18*a6d42e7dSPeter Dunlap * 19*a6d42e7dSPeter Dunlap * CDDL HEADER END 20*a6d42e7dSPeter Dunlap */ 21*a6d42e7dSPeter Dunlap /* 22*a6d42e7dSPeter Dunlap * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*a6d42e7dSPeter Dunlap * Use is subject to license terms. 24*a6d42e7dSPeter Dunlap */ 25*a6d42e7dSPeter Dunlap 26*a6d42e7dSPeter Dunlap #include <sys/time.h> 27*a6d42e7dSPeter Dunlap 28*a6d42e7dSPeter Dunlap #if defined(_KERNEL) 29*a6d42e7dSPeter Dunlap #include <sys/ddi.h> 30*a6d42e7dSPeter Dunlap #include <sys/types.h> 31*a6d42e7dSPeter Dunlap #include <sys/sunddi.h> 32*a6d42e7dSPeter Dunlap #include <sys/socket.h> 33*a6d42e7dSPeter Dunlap #include <inet/tcp.h> 34*a6d42e7dSPeter Dunlap #else 35*a6d42e7dSPeter Dunlap #include <stdio.h> 36*a6d42e7dSPeter Dunlap #include <strings.h> 37*a6d42e7dSPeter Dunlap #include <stdlib.h> 38*a6d42e7dSPeter Dunlap #include <errno.h> 39*a6d42e7dSPeter Dunlap #include <sys/types.h> 40*a6d42e7dSPeter Dunlap #include <sys/socket.h> 41*a6d42e7dSPeter Dunlap #include <netinet/in.h> 42*a6d42e7dSPeter Dunlap #include <arpa/inet.h> 43*a6d42e7dSPeter Dunlap #endif 44*a6d42e7dSPeter Dunlap 45*a6d42e7dSPeter Dunlap #include <sys/iscsit/iscsit_common.h> 46*a6d42e7dSPeter Dunlap #include <sys/iscsi_protocol.h> 47*a6d42e7dSPeter Dunlap #include <sys/iscsit/isns_protocol.h> 48*a6d42e7dSPeter Dunlap 49*a6d42e7dSPeter Dunlap void * 50*a6d42e7dSPeter Dunlap iscsit_zalloc(size_t size) 51*a6d42e7dSPeter Dunlap { 52*a6d42e7dSPeter Dunlap #if defined(_KERNEL) 53*a6d42e7dSPeter Dunlap return (kmem_zalloc(size, KM_SLEEP)); 54*a6d42e7dSPeter Dunlap #else 55*a6d42e7dSPeter Dunlap return (calloc(1, size)); 56*a6d42e7dSPeter Dunlap #endif 57*a6d42e7dSPeter Dunlap } 58*a6d42e7dSPeter Dunlap 59*a6d42e7dSPeter Dunlap void 60*a6d42e7dSPeter Dunlap iscsit_free(void *buf, size_t size) /* ARGSUSED */ 61*a6d42e7dSPeter Dunlap { 62*a6d42e7dSPeter Dunlap #if defined(_KERNEL) 63*a6d42e7dSPeter Dunlap kmem_free(buf, size); 64*a6d42e7dSPeter Dunlap #else 65*a6d42e7dSPeter Dunlap free(buf); 66*a6d42e7dSPeter Dunlap #endif 67*a6d42e7dSPeter Dunlap } 68*a6d42e7dSPeter Dunlap 69*a6d42e7dSPeter Dunlap /* 70*a6d42e7dSPeter Dunlap * default_port should be the port to be used, if not specified 71*a6d42e7dSPeter Dunlap * as part of the supplied string 'arg'. 72*a6d42e7dSPeter Dunlap */ 73*a6d42e7dSPeter Dunlap 74*a6d42e7dSPeter Dunlap #define NI_MAXHOST 1025 75*a6d42e7dSPeter Dunlap #define NI_MAXSERV 32 76*a6d42e7dSPeter Dunlap 77*a6d42e7dSPeter Dunlap 78*a6d42e7dSPeter Dunlap struct sockaddr_storage * 79*a6d42e7dSPeter Dunlap it_common_convert_sa(char *arg, struct sockaddr_storage *buf, 80*a6d42e7dSPeter Dunlap uint32_t default_port) 81*a6d42e7dSPeter Dunlap { 82*a6d42e7dSPeter Dunlap /* Why does addrbuf need to be this big!??! XXX */ 83*a6d42e7dSPeter Dunlap char addrbuf[NI_MAXHOST + NI_MAXSERV + 1]; 84*a6d42e7dSPeter Dunlap char *addr_str; 85*a6d42e7dSPeter Dunlap char *port_str; 86*a6d42e7dSPeter Dunlap #ifndef _KERNEL 87*a6d42e7dSPeter Dunlap char *errchr; 88*a6d42e7dSPeter Dunlap #endif 89*a6d42e7dSPeter Dunlap long tmp_port = 0; 90*a6d42e7dSPeter Dunlap sa_family_t af; 91*a6d42e7dSPeter Dunlap 92*a6d42e7dSPeter Dunlap struct sockaddr_in *sin; 93*a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6; 94*a6d42e7dSPeter Dunlap struct sockaddr_storage *sa = buf; 95*a6d42e7dSPeter Dunlap 96*a6d42e7dSPeter Dunlap if (!arg || !buf) { 97*a6d42e7dSPeter Dunlap return (NULL); 98*a6d42e7dSPeter Dunlap } 99*a6d42e7dSPeter Dunlap 100*a6d42e7dSPeter Dunlap bzero(buf, sizeof (struct sockaddr_storage)); 101*a6d42e7dSPeter Dunlap 102*a6d42e7dSPeter Dunlap /* don't modify the passed-in string */ 103*a6d42e7dSPeter Dunlap (void) strlcpy(addrbuf, arg, sizeof (addrbuf)); 104*a6d42e7dSPeter Dunlap 105*a6d42e7dSPeter Dunlap addr_str = addrbuf; 106*a6d42e7dSPeter Dunlap 107*a6d42e7dSPeter Dunlap if (*addr_str == '[') { 108*a6d42e7dSPeter Dunlap /* 109*a6d42e7dSPeter Dunlap * An IPv6 address must be inside square brackets 110*a6d42e7dSPeter Dunlap */ 111*a6d42e7dSPeter Dunlap port_str = strchr(addr_str, ']'); 112*a6d42e7dSPeter Dunlap if (!port_str) { 113*a6d42e7dSPeter Dunlap /* No closing bracket */ 114*a6d42e7dSPeter Dunlap return (NULL); 115*a6d42e7dSPeter Dunlap } 116*a6d42e7dSPeter Dunlap 117*a6d42e7dSPeter Dunlap /* strip off the square brackets so we can convert */ 118*a6d42e7dSPeter Dunlap addr_str++; 119*a6d42e7dSPeter Dunlap *port_str = '\0'; 120*a6d42e7dSPeter Dunlap port_str++; 121*a6d42e7dSPeter Dunlap 122*a6d42e7dSPeter Dunlap if (*port_str == ':') { 123*a6d42e7dSPeter Dunlap /* TCP port to follow */ 124*a6d42e7dSPeter Dunlap port_str++; 125*a6d42e7dSPeter Dunlap } else if (*port_str == '\0') { 126*a6d42e7dSPeter Dunlap /* No port specified */ 127*a6d42e7dSPeter Dunlap port_str = NULL; 128*a6d42e7dSPeter Dunlap } else { 129*a6d42e7dSPeter Dunlap /* malformed */ 130*a6d42e7dSPeter Dunlap return (NULL); 131*a6d42e7dSPeter Dunlap } 132*a6d42e7dSPeter Dunlap af = AF_INET6; 133*a6d42e7dSPeter Dunlap } else { 134*a6d42e7dSPeter Dunlap port_str = strchr(addr_str, ':'); 135*a6d42e7dSPeter Dunlap if (port_str) { 136*a6d42e7dSPeter Dunlap *port_str = '\0'; 137*a6d42e7dSPeter Dunlap port_str++; 138*a6d42e7dSPeter Dunlap } 139*a6d42e7dSPeter Dunlap af = AF_INET; 140*a6d42e7dSPeter Dunlap } 141*a6d42e7dSPeter Dunlap 142*a6d42e7dSPeter Dunlap if (port_str) { 143*a6d42e7dSPeter Dunlap #if defined(_KERNEL) 144*a6d42e7dSPeter Dunlap if (ddi_strtol(port_str, NULL, 10, &tmp_port) != 0) { 145*a6d42e7dSPeter Dunlap return (NULL); 146*a6d42e7dSPeter Dunlap } 147*a6d42e7dSPeter Dunlap #else 148*a6d42e7dSPeter Dunlap tmp_port = strtol(port_str, &errchr, 10); 149*a6d42e7dSPeter Dunlap #endif 150*a6d42e7dSPeter Dunlap if (tmp_port < 0 || tmp_port > 65535) { 151*a6d42e7dSPeter Dunlap return (NULL); 152*a6d42e7dSPeter Dunlap } 153*a6d42e7dSPeter Dunlap } else { 154*a6d42e7dSPeter Dunlap tmp_port = default_port; 155*a6d42e7dSPeter Dunlap } 156*a6d42e7dSPeter Dunlap 157*a6d42e7dSPeter Dunlap sa->ss_family = af; 158*a6d42e7dSPeter Dunlap 159*a6d42e7dSPeter Dunlap sin = (struct sockaddr_in *)sa; 160*a6d42e7dSPeter Dunlap if (af == AF_INET) { 161*a6d42e7dSPeter Dunlap if (inet_pton(af, addr_str, 162*a6d42e7dSPeter Dunlap (void *)&(sin->sin_addr.s_addr)) != 1) { 163*a6d42e7dSPeter Dunlap return (NULL); 164*a6d42e7dSPeter Dunlap } 165*a6d42e7dSPeter Dunlap /* 166*a6d42e7dSPeter Dunlap * intet_pton does not seem to convert to network 167*a6d42e7dSPeter Dunlap * order in kernel. This is a workaround until the 168*a6d42e7dSPeter Dunlap * inet_pton works or we have our own inet_pton function. 169*a6d42e7dSPeter Dunlap */ 170*a6d42e7dSPeter Dunlap #ifdef _KERNEL 171*a6d42e7dSPeter Dunlap sin->sin_addr.s_addr = ntohl((uint32_t)sin->sin_addr.s_addr); 172*a6d42e7dSPeter Dunlap #endif 173*a6d42e7dSPeter Dunlap sin->sin_port = htons(tmp_port); 174*a6d42e7dSPeter Dunlap } else { 175*a6d42e7dSPeter Dunlap sin6 = (struct sockaddr_in6 *)sa; 176*a6d42e7dSPeter Dunlap if (inet_pton(af, addr_str, 177*a6d42e7dSPeter Dunlap (void *)&(sin6->sin6_addr.s6_addr)) != 1) { 178*a6d42e7dSPeter Dunlap return (NULL); 179*a6d42e7dSPeter Dunlap } 180*a6d42e7dSPeter Dunlap sin6->sin6_port = htons(tmp_port); 181*a6d42e7dSPeter Dunlap } 182*a6d42e7dSPeter Dunlap 183*a6d42e7dSPeter Dunlap /* successful */ 184*a6d42e7dSPeter Dunlap return (sa); 185*a6d42e7dSPeter Dunlap } 186*a6d42e7dSPeter Dunlap 187*a6d42e7dSPeter Dunlap 188*a6d42e7dSPeter Dunlap /* Functions to convert iSCSI target structures to/from nvlists. */ 189*a6d42e7dSPeter Dunlap 190*a6d42e7dSPeter Dunlap #ifndef _KERNEL 191*a6d42e7dSPeter Dunlap int 192*a6d42e7dSPeter Dunlap it_config_to_nv(it_config_t *cfg, nvlist_t **nvl) 193*a6d42e7dSPeter Dunlap { 194*a6d42e7dSPeter Dunlap int ret; 195*a6d42e7dSPeter Dunlap nvlist_t *nv; 196*a6d42e7dSPeter Dunlap nvlist_t *lnv = NULL; 197*a6d42e7dSPeter Dunlap 198*a6d42e7dSPeter Dunlap if (!nvl) { 199*a6d42e7dSPeter Dunlap return (EINVAL); 200*a6d42e7dSPeter Dunlap } 201*a6d42e7dSPeter Dunlap 202*a6d42e7dSPeter Dunlap *nvl = NULL; 203*a6d42e7dSPeter Dunlap 204*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&nv, NV_UNIQUE_NAME_TYPE, 0); 205*a6d42e7dSPeter Dunlap if (ret != 0) { 206*a6d42e7dSPeter Dunlap return (ret); 207*a6d42e7dSPeter Dunlap } 208*a6d42e7dSPeter Dunlap 209*a6d42e7dSPeter Dunlap /* if there's no config, store an empty list */ 210*a6d42e7dSPeter Dunlap if (!cfg) { 211*a6d42e7dSPeter Dunlap *nvl = nv; 212*a6d42e7dSPeter Dunlap return (0); 213*a6d42e7dSPeter Dunlap } 214*a6d42e7dSPeter Dunlap 215*a6d42e7dSPeter Dunlap ret = nvlist_add_uint32(nv, "cfgVersion", cfg->config_version); 216*a6d42e7dSPeter Dunlap if (ret == 0) { 217*a6d42e7dSPeter Dunlap ret = it_tgtlist_to_nv(cfg->config_tgt_list, &lnv); 218*a6d42e7dSPeter Dunlap } 219*a6d42e7dSPeter Dunlap 220*a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) { 221*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "targetList", lnv); 222*a6d42e7dSPeter Dunlap nvlist_free(lnv); 223*a6d42e7dSPeter Dunlap lnv = NULL; 224*a6d42e7dSPeter Dunlap } 225*a6d42e7dSPeter Dunlap 226*a6d42e7dSPeter Dunlap if (ret == 0) { 227*a6d42e7dSPeter Dunlap ret = it_tpglist_to_nv(cfg->config_tpg_list, &lnv); 228*a6d42e7dSPeter Dunlap } 229*a6d42e7dSPeter Dunlap 230*a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) { 231*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "tpgList", lnv); 232*a6d42e7dSPeter Dunlap nvlist_free(lnv); 233*a6d42e7dSPeter Dunlap lnv = NULL; 234*a6d42e7dSPeter Dunlap } 235*a6d42e7dSPeter Dunlap 236*a6d42e7dSPeter Dunlap if (ret == 0) { 237*a6d42e7dSPeter Dunlap ret = it_inilist_to_nv(cfg->config_ini_list, &lnv); 238*a6d42e7dSPeter Dunlap } 239*a6d42e7dSPeter Dunlap 240*a6d42e7dSPeter Dunlap if ((ret == 0) && (lnv != NULL)) { 241*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "iniList", lnv); 242*a6d42e7dSPeter Dunlap nvlist_free(lnv); 243*a6d42e7dSPeter Dunlap lnv = NULL; 244*a6d42e7dSPeter Dunlap } 245*a6d42e7dSPeter Dunlap 246*a6d42e7dSPeter Dunlap if (ret == 0) { 247*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(nv, "globalProperties", 248*a6d42e7dSPeter Dunlap cfg->config_global_properties); 249*a6d42e7dSPeter Dunlap } 250*a6d42e7dSPeter Dunlap 251*a6d42e7dSPeter Dunlap if (ret == 0) { 252*a6d42e7dSPeter Dunlap *nvl = nv; 253*a6d42e7dSPeter Dunlap } else { 254*a6d42e7dSPeter Dunlap nvlist_free(nv); 255*a6d42e7dSPeter Dunlap } 256*a6d42e7dSPeter Dunlap 257*a6d42e7dSPeter Dunlap return (ret); 258*a6d42e7dSPeter Dunlap } 259*a6d42e7dSPeter Dunlap #endif /* !_KERNEL */ 260*a6d42e7dSPeter Dunlap 261*a6d42e7dSPeter Dunlap /* 262*a6d42e7dSPeter Dunlap * nvlist version of config is 3 list-of-list, + 1 proplist. arrays 263*a6d42e7dSPeter Dunlap * are interesting, but lists-of-lists are more useful when doing 264*a6d42e7dSPeter Dunlap * individual lookups when we later add support for it. Also, no 265*a6d42e7dSPeter Dunlap * need to store name in individual struct representation. 266*a6d42e7dSPeter Dunlap */ 267*a6d42e7dSPeter Dunlap int 268*a6d42e7dSPeter Dunlap it_nv_to_config(nvlist_t *nvl, it_config_t **cfg) 269*a6d42e7dSPeter Dunlap { 270*a6d42e7dSPeter Dunlap int ret; 271*a6d42e7dSPeter Dunlap uint32_t intval; 272*a6d42e7dSPeter Dunlap nvlist_t *listval; 273*a6d42e7dSPeter Dunlap it_config_t *tmpcfg; 274*a6d42e7dSPeter Dunlap 275*a6d42e7dSPeter Dunlap if (!cfg) { 276*a6d42e7dSPeter Dunlap return (EINVAL); 277*a6d42e7dSPeter Dunlap } 278*a6d42e7dSPeter Dunlap 279*a6d42e7dSPeter Dunlap /* initialize output */ 280*a6d42e7dSPeter Dunlap *cfg = NULL; 281*a6d42e7dSPeter Dunlap 282*a6d42e7dSPeter Dunlap tmpcfg = iscsit_zalloc(sizeof (it_config_t)); 283*a6d42e7dSPeter Dunlap if (tmpcfg == NULL) { 284*a6d42e7dSPeter Dunlap return (ENOMEM); 285*a6d42e7dSPeter Dunlap } 286*a6d42e7dSPeter Dunlap 287*a6d42e7dSPeter Dunlap if (!nvl) { 288*a6d42e7dSPeter Dunlap /* nothing to decode, but return the empty cfg struct */ 289*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&tmpcfg->config_global_properties, 290*a6d42e7dSPeter Dunlap NV_UNIQUE_NAME, 0); 291*a6d42e7dSPeter Dunlap if (ret != 0) { 292*a6d42e7dSPeter Dunlap iscsit_free(tmpcfg, sizeof (it_config_t)); 293*a6d42e7dSPeter Dunlap return (ret); 294*a6d42e7dSPeter Dunlap } 295*a6d42e7dSPeter Dunlap *cfg = tmpcfg; 296*a6d42e7dSPeter Dunlap return (0); 297*a6d42e7dSPeter Dunlap } 298*a6d42e7dSPeter Dunlap 299*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint32(nvl, "cfgVersion", &intval); 300*a6d42e7dSPeter Dunlap if (ret != 0) { 301*a6d42e7dSPeter Dunlap iscsit_free(tmpcfg, sizeof (it_config_t)); 302*a6d42e7dSPeter Dunlap return (ret); 303*a6d42e7dSPeter Dunlap } 304*a6d42e7dSPeter Dunlap 305*a6d42e7dSPeter Dunlap tmpcfg->config_version = intval; 306*a6d42e7dSPeter Dunlap 307*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "targetList", &listval); 308*a6d42e7dSPeter Dunlap if (ret == 0) { 309*a6d42e7dSPeter Dunlap /* decode list of it_tgt_t */ 310*a6d42e7dSPeter Dunlap ret = it_nv_to_tgtlist(listval, &(tmpcfg->config_tgt_count), 311*a6d42e7dSPeter Dunlap &(tmpcfg->config_tgt_list)); 312*a6d42e7dSPeter Dunlap } 313*a6d42e7dSPeter Dunlap 314*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "tpgList", &listval); 315*a6d42e7dSPeter Dunlap if (ret == 0) { 316*a6d42e7dSPeter Dunlap /* decode list of it_tpg_t */ 317*a6d42e7dSPeter Dunlap ret = it_nv_to_tpglist(listval, &(tmpcfg->config_tpg_count), 318*a6d42e7dSPeter Dunlap &(tmpcfg->config_tpg_list)); 319*a6d42e7dSPeter Dunlap } 320*a6d42e7dSPeter Dunlap 321*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "iniList", &listval); 322*a6d42e7dSPeter Dunlap if (ret == 0) { 323*a6d42e7dSPeter Dunlap /* decode list of initiators */ 324*a6d42e7dSPeter Dunlap ret = it_nv_to_inilist(listval, &(tmpcfg->config_ini_count), 325*a6d42e7dSPeter Dunlap &(tmpcfg->config_ini_list)); 326*a6d42e7dSPeter Dunlap } 327*a6d42e7dSPeter Dunlap 328*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "globalProperties", &listval); 329*a6d42e7dSPeter Dunlap if (ret == 0) { 330*a6d42e7dSPeter Dunlap /* 331*a6d42e7dSPeter Dunlap * don't depend on the original nvlist staying in-scope, 332*a6d42e7dSPeter Dunlap * duplicate the nvlist 333*a6d42e7dSPeter Dunlap */ 334*a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(tmpcfg->config_global_properties), 335*a6d42e7dSPeter Dunlap 0); 336*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 337*a6d42e7dSPeter Dunlap /* 338*a6d42e7dSPeter Dunlap * No global properties defined, make an empty list 339*a6d42e7dSPeter Dunlap */ 340*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&tmpcfg->config_global_properties, 341*a6d42e7dSPeter Dunlap NV_UNIQUE_NAME, 0); 342*a6d42e7dSPeter Dunlap } 343*a6d42e7dSPeter Dunlap 344*a6d42e7dSPeter Dunlap if (ret == 0) { 345*a6d42e7dSPeter Dunlap char **isnsArray = NULL; 346*a6d42e7dSPeter Dunlap uint32_t numisns = 0; 347*a6d42e7dSPeter Dunlap 348*a6d42e7dSPeter Dunlap /* 349*a6d42e7dSPeter Dunlap * decode the list of iSNS server information to make 350*a6d42e7dSPeter Dunlap * references from the kernel simpler. 351*a6d42e7dSPeter Dunlap */ 352*a6d42e7dSPeter Dunlap if (tmpcfg->config_global_properties) { 353*a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array( 354*a6d42e7dSPeter Dunlap tmpcfg->config_global_properties, 355*a6d42e7dSPeter Dunlap PROP_ISNS_SERVER, 356*a6d42e7dSPeter Dunlap &isnsArray, &numisns); 357*a6d42e7dSPeter Dunlap if (ret == 0) { 358*a6d42e7dSPeter Dunlap ret = it_array_to_portallist(isnsArray, 359*a6d42e7dSPeter Dunlap numisns, ISNS_DEFAULT_SERVER_PORT, 360*a6d42e7dSPeter Dunlap &tmpcfg->config_isns_svr_list, 361*a6d42e7dSPeter Dunlap &tmpcfg->config_isns_svr_count); 362*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 363*a6d42e7dSPeter Dunlap /* It's OK if we don't have any iSNS servers */ 364*a6d42e7dSPeter Dunlap ret = 0; 365*a6d42e7dSPeter Dunlap } 366*a6d42e7dSPeter Dunlap } 367*a6d42e7dSPeter Dunlap } 368*a6d42e7dSPeter Dunlap 369*a6d42e7dSPeter Dunlap if (ret == 0) { 370*a6d42e7dSPeter Dunlap *cfg = tmpcfg; 371*a6d42e7dSPeter Dunlap } else { 372*a6d42e7dSPeter Dunlap it_config_free_cmn(tmpcfg); 373*a6d42e7dSPeter Dunlap } 374*a6d42e7dSPeter Dunlap 375*a6d42e7dSPeter Dunlap return (ret); 376*a6d42e7dSPeter Dunlap } 377*a6d42e7dSPeter Dunlap 378*a6d42e7dSPeter Dunlap it_tgt_t * 379*a6d42e7dSPeter Dunlap it_tgt_lookup(it_config_t *cfg, char *tgt_name) 380*a6d42e7dSPeter Dunlap { 381*a6d42e7dSPeter Dunlap it_tgt_t *cfg_tgt = NULL; 382*a6d42e7dSPeter Dunlap 383*a6d42e7dSPeter Dunlap for (cfg_tgt = cfg->config_tgt_list; 384*a6d42e7dSPeter Dunlap cfg_tgt != NULL; 385*a6d42e7dSPeter Dunlap cfg_tgt = cfg_tgt->tgt_next) { 386*a6d42e7dSPeter Dunlap if (strncmp(cfg_tgt->tgt_name, tgt_name, 387*a6d42e7dSPeter Dunlap MAX_ISCSI_NODENAMELEN) == 0) { 388*a6d42e7dSPeter Dunlap return (cfg_tgt); 389*a6d42e7dSPeter Dunlap } 390*a6d42e7dSPeter Dunlap } 391*a6d42e7dSPeter Dunlap 392*a6d42e7dSPeter Dunlap return (NULL); 393*a6d42e7dSPeter Dunlap } 394*a6d42e7dSPeter Dunlap 395*a6d42e7dSPeter Dunlap int 396*a6d42e7dSPeter Dunlap it_nv_to_tgtlist(nvlist_t *nvl, uint32_t *count, it_tgt_t **tgtlist) 397*a6d42e7dSPeter Dunlap { 398*a6d42e7dSPeter Dunlap int ret = 0; 399*a6d42e7dSPeter Dunlap it_tgt_t *tgt; 400*a6d42e7dSPeter Dunlap it_tgt_t *prev = NULL; 401*a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 402*a6d42e7dSPeter Dunlap nvlist_t *nvt; 403*a6d42e7dSPeter Dunlap char *name; 404*a6d42e7dSPeter Dunlap 405*a6d42e7dSPeter Dunlap if (!tgtlist || !count) { 406*a6d42e7dSPeter Dunlap return (EINVAL); 407*a6d42e7dSPeter Dunlap } 408*a6d42e7dSPeter Dunlap 409*a6d42e7dSPeter Dunlap *tgtlist = NULL; 410*a6d42e7dSPeter Dunlap *count = 0; 411*a6d42e7dSPeter Dunlap 412*a6d42e7dSPeter Dunlap if (!nvl) { 413*a6d42e7dSPeter Dunlap /* nothing to do */ 414*a6d42e7dSPeter Dunlap return (0); 415*a6d42e7dSPeter Dunlap } 416*a6d42e7dSPeter Dunlap 417*a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 418*a6d42e7dSPeter Dunlap name = nvpair_name(nvp); 419*a6d42e7dSPeter Dunlap 420*a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt); 421*a6d42e7dSPeter Dunlap if (ret != 0) { 422*a6d42e7dSPeter Dunlap /* invalid entry? */ 423*a6d42e7dSPeter Dunlap continue; 424*a6d42e7dSPeter Dunlap } 425*a6d42e7dSPeter Dunlap 426*a6d42e7dSPeter Dunlap ret = it_nv_to_tgt(nvt, name, &tgt); 427*a6d42e7dSPeter Dunlap if (ret != 0) { 428*a6d42e7dSPeter Dunlap break; 429*a6d42e7dSPeter Dunlap } 430*a6d42e7dSPeter Dunlap 431*a6d42e7dSPeter Dunlap (*count)++; 432*a6d42e7dSPeter Dunlap 433*a6d42e7dSPeter Dunlap if (*tgtlist == NULL) { 434*a6d42e7dSPeter Dunlap *tgtlist = tgt; 435*a6d42e7dSPeter Dunlap } else { 436*a6d42e7dSPeter Dunlap prev->tgt_next = tgt; 437*a6d42e7dSPeter Dunlap } 438*a6d42e7dSPeter Dunlap prev = tgt; 439*a6d42e7dSPeter Dunlap } 440*a6d42e7dSPeter Dunlap 441*a6d42e7dSPeter Dunlap if (ret != 0) { 442*a6d42e7dSPeter Dunlap it_tgt_free_cmn(*tgtlist); 443*a6d42e7dSPeter Dunlap *tgtlist = NULL; 444*a6d42e7dSPeter Dunlap } 445*a6d42e7dSPeter Dunlap 446*a6d42e7dSPeter Dunlap return (ret); 447*a6d42e7dSPeter Dunlap } 448*a6d42e7dSPeter Dunlap 449*a6d42e7dSPeter Dunlap int 450*a6d42e7dSPeter Dunlap it_tgtlist_to_nv(it_tgt_t *tgtlist, nvlist_t **nvl) 451*a6d42e7dSPeter Dunlap { 452*a6d42e7dSPeter Dunlap int ret; 453*a6d42e7dSPeter Dunlap it_tgt_t *tgtp = tgtlist; 454*a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL; 455*a6d42e7dSPeter Dunlap nvlist_t *tnv; 456*a6d42e7dSPeter Dunlap 457*a6d42e7dSPeter Dunlap if (!nvl) { 458*a6d42e7dSPeter Dunlap return (EINVAL); 459*a6d42e7dSPeter Dunlap } 460*a6d42e7dSPeter Dunlap 461*a6d42e7dSPeter Dunlap if (!tgtlist) { 462*a6d42e7dSPeter Dunlap /* nothing to do */ 463*a6d42e7dSPeter Dunlap return (0); 464*a6d42e7dSPeter Dunlap } 465*a6d42e7dSPeter Dunlap 466*a6d42e7dSPeter Dunlap /* create the target list if required */ 467*a6d42e7dSPeter Dunlap if (*nvl == NULL) { 468*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0); 469*a6d42e7dSPeter Dunlap if (ret != 0) { 470*a6d42e7dSPeter Dunlap return (ret); 471*a6d42e7dSPeter Dunlap } 472*a6d42e7dSPeter Dunlap *nvl = pnv; 473*a6d42e7dSPeter Dunlap } 474*a6d42e7dSPeter Dunlap 475*a6d42e7dSPeter Dunlap while (tgtp) { 476*a6d42e7dSPeter Dunlap ret = it_tgt_to_nv(tgtp, &tnv); 477*a6d42e7dSPeter Dunlap 478*a6d42e7dSPeter Dunlap if (ret != 0) { 479*a6d42e7dSPeter Dunlap break; 480*a6d42e7dSPeter Dunlap } 481*a6d42e7dSPeter Dunlap 482*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, tgtp->tgt_name, tnv); 483*a6d42e7dSPeter Dunlap 484*a6d42e7dSPeter Dunlap if (ret != 0) { 485*a6d42e7dSPeter Dunlap break; 486*a6d42e7dSPeter Dunlap } 487*a6d42e7dSPeter Dunlap 488*a6d42e7dSPeter Dunlap nvlist_free(tnv); 489*a6d42e7dSPeter Dunlap 490*a6d42e7dSPeter Dunlap tgtp = tgtp->tgt_next; 491*a6d42e7dSPeter Dunlap } 492*a6d42e7dSPeter Dunlap 493*a6d42e7dSPeter Dunlap if (ret != 0) { 494*a6d42e7dSPeter Dunlap if (pnv) { 495*a6d42e7dSPeter Dunlap nvlist_free(pnv); 496*a6d42e7dSPeter Dunlap *nvl = NULL; 497*a6d42e7dSPeter Dunlap } 498*a6d42e7dSPeter Dunlap } 499*a6d42e7dSPeter Dunlap 500*a6d42e7dSPeter Dunlap return (ret); 501*a6d42e7dSPeter Dunlap } 502*a6d42e7dSPeter Dunlap 503*a6d42e7dSPeter Dunlap int 504*a6d42e7dSPeter Dunlap it_tgt_to_nv(it_tgt_t *tgt, nvlist_t **nvl) 505*a6d42e7dSPeter Dunlap { 506*a6d42e7dSPeter Dunlap int ret; 507*a6d42e7dSPeter Dunlap nvlist_t *tnv = NULL; 508*a6d42e7dSPeter Dunlap 509*a6d42e7dSPeter Dunlap if (!nvl) { 510*a6d42e7dSPeter Dunlap return (EINVAL); 511*a6d42e7dSPeter Dunlap } 512*a6d42e7dSPeter Dunlap 513*a6d42e7dSPeter Dunlap if (!tgt) { 514*a6d42e7dSPeter Dunlap /* nothing to do */ 515*a6d42e7dSPeter Dunlap return (0); 516*a6d42e7dSPeter Dunlap } 517*a6d42e7dSPeter Dunlap 518*a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0); 519*a6d42e7dSPeter Dunlap if (ret != 0) { 520*a6d42e7dSPeter Dunlap return (ret); 521*a6d42e7dSPeter Dunlap } 522*a6d42e7dSPeter Dunlap 523*a6d42e7dSPeter Dunlap if (tgt->tgt_properties) { 524*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "properties", 525*a6d42e7dSPeter Dunlap tgt->tgt_properties); 526*a6d42e7dSPeter Dunlap } 527*a6d42e7dSPeter Dunlap 528*a6d42e7dSPeter Dunlap if (ret == 0) { 529*a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation", 530*a6d42e7dSPeter Dunlap tgt->tgt_generation); 531*a6d42e7dSPeter Dunlap } 532*a6d42e7dSPeter Dunlap 533*a6d42e7dSPeter Dunlap if (ret == 0) { 534*a6d42e7dSPeter Dunlap ret = it_tpgtlist_to_nv(tgt->tgt_tpgt_list, &tnv); 535*a6d42e7dSPeter Dunlap } 536*a6d42e7dSPeter Dunlap 537*a6d42e7dSPeter Dunlap if ((ret == 0) && tnv) { 538*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "tpgtList", tnv); 539*a6d42e7dSPeter Dunlap nvlist_free(tnv); 540*a6d42e7dSPeter Dunlap } 541*a6d42e7dSPeter Dunlap 542*a6d42e7dSPeter Dunlap if (ret != 0) { 543*a6d42e7dSPeter Dunlap nvlist_free(*nvl); 544*a6d42e7dSPeter Dunlap *nvl = NULL; 545*a6d42e7dSPeter Dunlap } 546*a6d42e7dSPeter Dunlap 547*a6d42e7dSPeter Dunlap return (ret); 548*a6d42e7dSPeter Dunlap } 549*a6d42e7dSPeter Dunlap 550*a6d42e7dSPeter Dunlap int 551*a6d42e7dSPeter Dunlap it_nv_to_tgt(nvlist_t *nvl, char *name, it_tgt_t **tgt) 552*a6d42e7dSPeter Dunlap { 553*a6d42e7dSPeter Dunlap int ret; 554*a6d42e7dSPeter Dunlap it_tgt_t *ttgt; 555*a6d42e7dSPeter Dunlap nvlist_t *listval; 556*a6d42e7dSPeter Dunlap uint32_t intval; 557*a6d42e7dSPeter Dunlap 558*a6d42e7dSPeter Dunlap if (!nvl || !tgt || !name) { 559*a6d42e7dSPeter Dunlap return (EINVAL); 560*a6d42e7dSPeter Dunlap } 561*a6d42e7dSPeter Dunlap 562*a6d42e7dSPeter Dunlap *tgt = NULL; 563*a6d42e7dSPeter Dunlap 564*a6d42e7dSPeter Dunlap ttgt = iscsit_zalloc(sizeof (it_tgt_t)); 565*a6d42e7dSPeter Dunlap if (!ttgt) { 566*a6d42e7dSPeter Dunlap return (ENOMEM); 567*a6d42e7dSPeter Dunlap } 568*a6d42e7dSPeter Dunlap 569*a6d42e7dSPeter Dunlap (void) strlcpy(ttgt->tgt_name, name, sizeof (ttgt->tgt_name)); 570*a6d42e7dSPeter Dunlap 571*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "properties", &listval); 572*a6d42e7dSPeter Dunlap if (ret == 0) { 573*a6d42e7dSPeter Dunlap /* duplicate list so it does not go out of context */ 574*a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(ttgt->tgt_properties), 0); 575*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 576*a6d42e7dSPeter Dunlap ret = 0; 577*a6d42e7dSPeter Dunlap } 578*a6d42e7dSPeter Dunlap 579*a6d42e7dSPeter Dunlap if (ret == 0) { 580*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation", 581*a6d42e7dSPeter Dunlap &(ttgt->tgt_generation)); 582*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 583*a6d42e7dSPeter Dunlap ret = 0; 584*a6d42e7dSPeter Dunlap } 585*a6d42e7dSPeter Dunlap 586*a6d42e7dSPeter Dunlap if (ret == 0) { 587*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "tpgtList", &listval); 588*a6d42e7dSPeter Dunlap } 589*a6d42e7dSPeter Dunlap 590*a6d42e7dSPeter Dunlap if (ret == 0) { 591*a6d42e7dSPeter Dunlap ret = it_nv_to_tpgtlist(listval, &intval, 592*a6d42e7dSPeter Dunlap &(ttgt->tgt_tpgt_list)); 593*a6d42e7dSPeter Dunlap ttgt->tgt_tpgt_count = intval; 594*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 595*a6d42e7dSPeter Dunlap ret = 0; 596*a6d42e7dSPeter Dunlap } 597*a6d42e7dSPeter Dunlap 598*a6d42e7dSPeter Dunlap if (ret == 0) { 599*a6d42e7dSPeter Dunlap *tgt = ttgt; 600*a6d42e7dSPeter Dunlap } else { 601*a6d42e7dSPeter Dunlap it_tgt_free_cmn(ttgt); 602*a6d42e7dSPeter Dunlap } 603*a6d42e7dSPeter Dunlap 604*a6d42e7dSPeter Dunlap return (ret); 605*a6d42e7dSPeter Dunlap } 606*a6d42e7dSPeter Dunlap 607*a6d42e7dSPeter Dunlap int 608*a6d42e7dSPeter Dunlap it_tpgt_to_nv(it_tpgt_t *tpgt, nvlist_t **nvl) 609*a6d42e7dSPeter Dunlap { 610*a6d42e7dSPeter Dunlap int ret; 611*a6d42e7dSPeter Dunlap 612*a6d42e7dSPeter Dunlap if (!nvl) { 613*a6d42e7dSPeter Dunlap return (EINVAL); 614*a6d42e7dSPeter Dunlap } 615*a6d42e7dSPeter Dunlap 616*a6d42e7dSPeter Dunlap if (!tpgt) { 617*a6d42e7dSPeter Dunlap /* nothing to do */ 618*a6d42e7dSPeter Dunlap return (0); 619*a6d42e7dSPeter Dunlap } 620*a6d42e7dSPeter Dunlap 621*a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0); 622*a6d42e7dSPeter Dunlap if (ret != 0) { 623*a6d42e7dSPeter Dunlap return (ret); 624*a6d42e7dSPeter Dunlap } 625*a6d42e7dSPeter Dunlap 626*a6d42e7dSPeter Dunlap ret = nvlist_add_uint16(*nvl, "tag", tpgt->tpgt_tag); 627*a6d42e7dSPeter Dunlap if (ret == 0) { 628*a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation", 629*a6d42e7dSPeter Dunlap tpgt->tpgt_generation); 630*a6d42e7dSPeter Dunlap } 631*a6d42e7dSPeter Dunlap 632*a6d42e7dSPeter Dunlap if (ret != 0) { 633*a6d42e7dSPeter Dunlap nvlist_free(*nvl); 634*a6d42e7dSPeter Dunlap *nvl = NULL; 635*a6d42e7dSPeter Dunlap } 636*a6d42e7dSPeter Dunlap 637*a6d42e7dSPeter Dunlap return (ret); 638*a6d42e7dSPeter Dunlap } 639*a6d42e7dSPeter Dunlap 640*a6d42e7dSPeter Dunlap int 641*a6d42e7dSPeter Dunlap it_nv_to_tpgt(nvlist_t *nvl, char *name, it_tpgt_t **tpgt) 642*a6d42e7dSPeter Dunlap { 643*a6d42e7dSPeter Dunlap int ret; 644*a6d42e7dSPeter Dunlap it_tpgt_t *ptr; 645*a6d42e7dSPeter Dunlap 646*a6d42e7dSPeter Dunlap if (!tpgt || !name) { 647*a6d42e7dSPeter Dunlap return (EINVAL); 648*a6d42e7dSPeter Dunlap } 649*a6d42e7dSPeter Dunlap 650*a6d42e7dSPeter Dunlap *tpgt = NULL; 651*a6d42e7dSPeter Dunlap 652*a6d42e7dSPeter Dunlap if (!nvl) { 653*a6d42e7dSPeter Dunlap return (0); 654*a6d42e7dSPeter Dunlap } 655*a6d42e7dSPeter Dunlap 656*a6d42e7dSPeter Dunlap ptr = iscsit_zalloc(sizeof (it_tpgt_t)); 657*a6d42e7dSPeter Dunlap if (!ptr) { 658*a6d42e7dSPeter Dunlap return (ENOMEM); 659*a6d42e7dSPeter Dunlap } 660*a6d42e7dSPeter Dunlap 661*a6d42e7dSPeter Dunlap (void) strlcpy(ptr->tpgt_tpg_name, name, sizeof (ptr->tpgt_tpg_name)); 662*a6d42e7dSPeter Dunlap 663*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint16(nvl, "tag", &(ptr->tpgt_tag)); 664*a6d42e7dSPeter Dunlap if (ret == 0) { 665*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation", 666*a6d42e7dSPeter Dunlap &(ptr->tpgt_generation)); 667*a6d42e7dSPeter Dunlap } 668*a6d42e7dSPeter Dunlap 669*a6d42e7dSPeter Dunlap if (ret == 0) { 670*a6d42e7dSPeter Dunlap *tpgt = ptr; 671*a6d42e7dSPeter Dunlap } else { 672*a6d42e7dSPeter Dunlap iscsit_free(ptr, sizeof (it_tpgt_t)); 673*a6d42e7dSPeter Dunlap } 674*a6d42e7dSPeter Dunlap 675*a6d42e7dSPeter Dunlap return (ret); 676*a6d42e7dSPeter Dunlap } 677*a6d42e7dSPeter Dunlap 678*a6d42e7dSPeter Dunlap int 679*a6d42e7dSPeter Dunlap it_tpgtlist_to_nv(it_tpgt_t *tpgtlist, nvlist_t **nvl) 680*a6d42e7dSPeter Dunlap { 681*a6d42e7dSPeter Dunlap int ret; 682*a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL; 683*a6d42e7dSPeter Dunlap nvlist_t *tnv; 684*a6d42e7dSPeter Dunlap it_tpgt_t *ptr = tpgtlist; 685*a6d42e7dSPeter Dunlap 686*a6d42e7dSPeter Dunlap if (!nvl) { 687*a6d42e7dSPeter Dunlap return (EINVAL); 688*a6d42e7dSPeter Dunlap } 689*a6d42e7dSPeter Dunlap 690*a6d42e7dSPeter Dunlap if (!tpgtlist) { 691*a6d42e7dSPeter Dunlap /* nothing to do */ 692*a6d42e7dSPeter Dunlap return (0); 693*a6d42e7dSPeter Dunlap } 694*a6d42e7dSPeter Dunlap 695*a6d42e7dSPeter Dunlap /* create the target list if required */ 696*a6d42e7dSPeter Dunlap if (*nvl == NULL) { 697*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0); 698*a6d42e7dSPeter Dunlap if (ret != 0) { 699*a6d42e7dSPeter Dunlap return (ret); 700*a6d42e7dSPeter Dunlap } 701*a6d42e7dSPeter Dunlap *nvl = pnv; 702*a6d42e7dSPeter Dunlap } 703*a6d42e7dSPeter Dunlap 704*a6d42e7dSPeter Dunlap while (ptr) { 705*a6d42e7dSPeter Dunlap ret = it_tpgt_to_nv(ptr, &tnv); 706*a6d42e7dSPeter Dunlap 707*a6d42e7dSPeter Dunlap if (ret != 0) { 708*a6d42e7dSPeter Dunlap break; 709*a6d42e7dSPeter Dunlap } 710*a6d42e7dSPeter Dunlap 711*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->tpgt_tpg_name, tnv); 712*a6d42e7dSPeter Dunlap 713*a6d42e7dSPeter Dunlap if (ret != 0) { 714*a6d42e7dSPeter Dunlap break; 715*a6d42e7dSPeter Dunlap } 716*a6d42e7dSPeter Dunlap 717*a6d42e7dSPeter Dunlap nvlist_free(tnv); 718*a6d42e7dSPeter Dunlap 719*a6d42e7dSPeter Dunlap ptr = ptr->tpgt_next; 720*a6d42e7dSPeter Dunlap } 721*a6d42e7dSPeter Dunlap 722*a6d42e7dSPeter Dunlap if (ret != 0) { 723*a6d42e7dSPeter Dunlap if (pnv) { 724*a6d42e7dSPeter Dunlap nvlist_free(pnv); 725*a6d42e7dSPeter Dunlap *nvl = NULL; 726*a6d42e7dSPeter Dunlap } 727*a6d42e7dSPeter Dunlap } 728*a6d42e7dSPeter Dunlap 729*a6d42e7dSPeter Dunlap return (ret); 730*a6d42e7dSPeter Dunlap } 731*a6d42e7dSPeter Dunlap 732*a6d42e7dSPeter Dunlap int 733*a6d42e7dSPeter Dunlap it_nv_to_tpgtlist(nvlist_t *nvl, uint32_t *count, it_tpgt_t **tpgtlist) 734*a6d42e7dSPeter Dunlap { 735*a6d42e7dSPeter Dunlap int ret = 0; 736*a6d42e7dSPeter Dunlap it_tpgt_t *tpgt; 737*a6d42e7dSPeter Dunlap it_tpgt_t *prev = NULL; 738*a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 739*a6d42e7dSPeter Dunlap nvlist_t *nvt; 740*a6d42e7dSPeter Dunlap char *name; 741*a6d42e7dSPeter Dunlap 742*a6d42e7dSPeter Dunlap if (!tpgtlist || !count) { 743*a6d42e7dSPeter Dunlap return (EINVAL); 744*a6d42e7dSPeter Dunlap } 745*a6d42e7dSPeter Dunlap 746*a6d42e7dSPeter Dunlap *tpgtlist = NULL; 747*a6d42e7dSPeter Dunlap *count = 0; 748*a6d42e7dSPeter Dunlap 749*a6d42e7dSPeter Dunlap if (!nvl) { 750*a6d42e7dSPeter Dunlap /* nothing to do */ 751*a6d42e7dSPeter Dunlap return (0); 752*a6d42e7dSPeter Dunlap } 753*a6d42e7dSPeter Dunlap 754*a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 755*a6d42e7dSPeter Dunlap name = nvpair_name(nvp); 756*a6d42e7dSPeter Dunlap 757*a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt); 758*a6d42e7dSPeter Dunlap if (ret != 0) { 759*a6d42e7dSPeter Dunlap /* invalid entry? */ 760*a6d42e7dSPeter Dunlap continue; 761*a6d42e7dSPeter Dunlap } 762*a6d42e7dSPeter Dunlap 763*a6d42e7dSPeter Dunlap ret = it_nv_to_tpgt(nvt, name, &tpgt); 764*a6d42e7dSPeter Dunlap if (ret != 0) { 765*a6d42e7dSPeter Dunlap break; 766*a6d42e7dSPeter Dunlap } 767*a6d42e7dSPeter Dunlap 768*a6d42e7dSPeter Dunlap (*count)++; 769*a6d42e7dSPeter Dunlap 770*a6d42e7dSPeter Dunlap if (*tpgtlist == NULL) { 771*a6d42e7dSPeter Dunlap *tpgtlist = tpgt; 772*a6d42e7dSPeter Dunlap } else { 773*a6d42e7dSPeter Dunlap prev->tpgt_next = tpgt; 774*a6d42e7dSPeter Dunlap } 775*a6d42e7dSPeter Dunlap 776*a6d42e7dSPeter Dunlap prev = tpgt; 777*a6d42e7dSPeter Dunlap } 778*a6d42e7dSPeter Dunlap 779*a6d42e7dSPeter Dunlap if (ret != 0) { 780*a6d42e7dSPeter Dunlap it_tpgt_free_cmn(*tpgtlist); 781*a6d42e7dSPeter Dunlap *tpgtlist = NULL; 782*a6d42e7dSPeter Dunlap } 783*a6d42e7dSPeter Dunlap 784*a6d42e7dSPeter Dunlap return (ret); 785*a6d42e7dSPeter Dunlap } 786*a6d42e7dSPeter Dunlap 787*a6d42e7dSPeter Dunlap #ifndef _KERNEL 788*a6d42e7dSPeter Dunlap int 789*a6d42e7dSPeter Dunlap it_tpg_to_nv(it_tpg_t *tpg, nvlist_t **nvl) 790*a6d42e7dSPeter Dunlap { 791*a6d42e7dSPeter Dunlap int ret; 792*a6d42e7dSPeter Dunlap char **portalArray = NULL; 793*a6d42e7dSPeter Dunlap int i; 794*a6d42e7dSPeter Dunlap it_portal_t *ptr; 795*a6d42e7dSPeter Dunlap 796*a6d42e7dSPeter Dunlap if (!nvl) { 797*a6d42e7dSPeter Dunlap return (EINVAL); 798*a6d42e7dSPeter Dunlap } 799*a6d42e7dSPeter Dunlap 800*a6d42e7dSPeter Dunlap if (!tpg) { 801*a6d42e7dSPeter Dunlap /* nothing to do */ 802*a6d42e7dSPeter Dunlap return (0); 803*a6d42e7dSPeter Dunlap } 804*a6d42e7dSPeter Dunlap 805*a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0); 806*a6d42e7dSPeter Dunlap if (ret != 0) { 807*a6d42e7dSPeter Dunlap return (ret); 808*a6d42e7dSPeter Dunlap } 809*a6d42e7dSPeter Dunlap 810*a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation", tpg->tpg_generation); 811*a6d42e7dSPeter Dunlap 812*a6d42e7dSPeter Dunlap if ((ret == 0) && tpg->tpg_portal_list) { 813*a6d42e7dSPeter Dunlap /* add the portals */ 814*a6d42e7dSPeter Dunlap portalArray = iscsit_zalloc(tpg->tpg_portal_count * 815*a6d42e7dSPeter Dunlap sizeof (it_portal_t)); 816*a6d42e7dSPeter Dunlap if (portalArray == NULL) { 817*a6d42e7dSPeter Dunlap nvlist_free(*nvl); 818*a6d42e7dSPeter Dunlap *nvl = NULL; 819*a6d42e7dSPeter Dunlap return (ENOMEM); 820*a6d42e7dSPeter Dunlap } 821*a6d42e7dSPeter Dunlap 822*a6d42e7dSPeter Dunlap i = 0; 823*a6d42e7dSPeter Dunlap ptr = tpg->tpg_portal_list; 824*a6d42e7dSPeter Dunlap 825*a6d42e7dSPeter Dunlap while (ptr && (i < tpg->tpg_portal_count)) { 826*a6d42e7dSPeter Dunlap ret = sockaddr_to_str(&(ptr->portal_addr), 827*a6d42e7dSPeter Dunlap &(portalArray[i])); 828*a6d42e7dSPeter Dunlap if (ret != 0) { 829*a6d42e7dSPeter Dunlap break; 830*a6d42e7dSPeter Dunlap } 831*a6d42e7dSPeter Dunlap ptr = ptr->next; 832*a6d42e7dSPeter Dunlap i++; 833*a6d42e7dSPeter Dunlap } 834*a6d42e7dSPeter Dunlap } 835*a6d42e7dSPeter Dunlap 836*a6d42e7dSPeter Dunlap if ((ret == 0) && portalArray) { 837*a6d42e7dSPeter Dunlap ret = nvlist_add_string_array(*nvl, "portalList", 838*a6d42e7dSPeter Dunlap portalArray, i); 839*a6d42e7dSPeter Dunlap } 840*a6d42e7dSPeter Dunlap 841*a6d42e7dSPeter Dunlap 842*a6d42e7dSPeter Dunlap if (portalArray) { 843*a6d42e7dSPeter Dunlap while (i > 0) { 844*a6d42e7dSPeter Dunlap if (portalArray[i]) { 845*a6d42e7dSPeter Dunlap iscsit_free(portalArray[i], 846*a6d42e7dSPeter Dunlap strlen(portalArray[i] + 1)); 847*a6d42e7dSPeter Dunlap } 848*a6d42e7dSPeter Dunlap i--; 849*a6d42e7dSPeter Dunlap } 850*a6d42e7dSPeter Dunlap iscsit_free(portalArray, 851*a6d42e7dSPeter Dunlap tpg->tpg_portal_count * sizeof (it_portal_t)); 852*a6d42e7dSPeter Dunlap } 853*a6d42e7dSPeter Dunlap 854*a6d42e7dSPeter Dunlap if (ret != 0) { 855*a6d42e7dSPeter Dunlap nvlist_free(*nvl); 856*a6d42e7dSPeter Dunlap *nvl = NULL; 857*a6d42e7dSPeter Dunlap } 858*a6d42e7dSPeter Dunlap 859*a6d42e7dSPeter Dunlap return (ret); 860*a6d42e7dSPeter Dunlap } 861*a6d42e7dSPeter Dunlap #endif /* !_KERNEL */ 862*a6d42e7dSPeter Dunlap 863*a6d42e7dSPeter Dunlap int 864*a6d42e7dSPeter Dunlap it_nv_to_tpg(nvlist_t *nvl, char *name, it_tpg_t **tpg) 865*a6d42e7dSPeter Dunlap { 866*a6d42e7dSPeter Dunlap int ret; 867*a6d42e7dSPeter Dunlap it_tpg_t *ptpg; 868*a6d42e7dSPeter Dunlap char **portalArray = NULL; 869*a6d42e7dSPeter Dunlap uint32_t count = 0; 870*a6d42e7dSPeter Dunlap 871*a6d42e7dSPeter Dunlap if (!name || !tpg) { 872*a6d42e7dSPeter Dunlap return (EINVAL); 873*a6d42e7dSPeter Dunlap } 874*a6d42e7dSPeter Dunlap 875*a6d42e7dSPeter Dunlap *tpg = NULL; 876*a6d42e7dSPeter Dunlap 877*a6d42e7dSPeter Dunlap ptpg = iscsit_zalloc(sizeof (it_tpg_t)); 878*a6d42e7dSPeter Dunlap if (ptpg == NULL) { 879*a6d42e7dSPeter Dunlap return (ENOMEM); 880*a6d42e7dSPeter Dunlap } 881*a6d42e7dSPeter Dunlap 882*a6d42e7dSPeter Dunlap (void) strlcpy(ptpg->tpg_name, name, sizeof (ptpg->tpg_name)); 883*a6d42e7dSPeter Dunlap 884*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation", 885*a6d42e7dSPeter Dunlap &(ptpg->tpg_generation)); 886*a6d42e7dSPeter Dunlap 887*a6d42e7dSPeter Dunlap if (ret == 0) { 888*a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array(nvl, "portalList", 889*a6d42e7dSPeter Dunlap &portalArray, &count); 890*a6d42e7dSPeter Dunlap } 891*a6d42e7dSPeter Dunlap 892*a6d42e7dSPeter Dunlap if (ret == 0) { 893*a6d42e7dSPeter Dunlap /* set the portals */ 894*a6d42e7dSPeter Dunlap ret = it_array_to_portallist(portalArray, count, 895*a6d42e7dSPeter Dunlap ISCSI_LISTEN_PORT, &ptpg->tpg_portal_list, 896*a6d42e7dSPeter Dunlap &ptpg->tpg_portal_count); 897*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 898*a6d42e7dSPeter Dunlap ret = 0; 899*a6d42e7dSPeter Dunlap } 900*a6d42e7dSPeter Dunlap 901*a6d42e7dSPeter Dunlap if (ret == 0) { 902*a6d42e7dSPeter Dunlap *tpg = ptpg; 903*a6d42e7dSPeter Dunlap } else { 904*a6d42e7dSPeter Dunlap it_tpg_free_cmn(ptpg); 905*a6d42e7dSPeter Dunlap } 906*a6d42e7dSPeter Dunlap 907*a6d42e7dSPeter Dunlap return (ret); 908*a6d42e7dSPeter Dunlap } 909*a6d42e7dSPeter Dunlap 910*a6d42e7dSPeter Dunlap 911*a6d42e7dSPeter Dunlap 912*a6d42e7dSPeter Dunlap 913*a6d42e7dSPeter Dunlap #ifndef _KERNEL 914*a6d42e7dSPeter Dunlap int 915*a6d42e7dSPeter Dunlap it_tpglist_to_nv(it_tpg_t *tpglist, nvlist_t **nvl) 916*a6d42e7dSPeter Dunlap { 917*a6d42e7dSPeter Dunlap int ret; 918*a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL; 919*a6d42e7dSPeter Dunlap nvlist_t *tnv; 920*a6d42e7dSPeter Dunlap it_tpg_t *ptr = tpglist; 921*a6d42e7dSPeter Dunlap 922*a6d42e7dSPeter Dunlap if (!nvl) { 923*a6d42e7dSPeter Dunlap return (EINVAL); 924*a6d42e7dSPeter Dunlap } 925*a6d42e7dSPeter Dunlap 926*a6d42e7dSPeter Dunlap if (!tpglist) { 927*a6d42e7dSPeter Dunlap /* nothing to do */ 928*a6d42e7dSPeter Dunlap return (0); 929*a6d42e7dSPeter Dunlap } 930*a6d42e7dSPeter Dunlap 931*a6d42e7dSPeter Dunlap /* create the target portal group list if required */ 932*a6d42e7dSPeter Dunlap if (*nvl == NULL) { 933*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0); 934*a6d42e7dSPeter Dunlap if (ret != 0) { 935*a6d42e7dSPeter Dunlap return (ret); 936*a6d42e7dSPeter Dunlap } 937*a6d42e7dSPeter Dunlap *nvl = pnv; 938*a6d42e7dSPeter Dunlap } 939*a6d42e7dSPeter Dunlap 940*a6d42e7dSPeter Dunlap while (ptr) { 941*a6d42e7dSPeter Dunlap ret = it_tpg_to_nv(ptr, &tnv); 942*a6d42e7dSPeter Dunlap 943*a6d42e7dSPeter Dunlap if (ret != 0) { 944*a6d42e7dSPeter Dunlap break; 945*a6d42e7dSPeter Dunlap } 946*a6d42e7dSPeter Dunlap 947*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->tpg_name, tnv); 948*a6d42e7dSPeter Dunlap 949*a6d42e7dSPeter Dunlap if (ret != 0) { 950*a6d42e7dSPeter Dunlap break; 951*a6d42e7dSPeter Dunlap } 952*a6d42e7dSPeter Dunlap 953*a6d42e7dSPeter Dunlap nvlist_free(tnv); 954*a6d42e7dSPeter Dunlap 955*a6d42e7dSPeter Dunlap ptr = ptr->tpg_next; 956*a6d42e7dSPeter Dunlap } 957*a6d42e7dSPeter Dunlap 958*a6d42e7dSPeter Dunlap if (ret != 0) { 959*a6d42e7dSPeter Dunlap if (pnv) { 960*a6d42e7dSPeter Dunlap nvlist_free(pnv); 961*a6d42e7dSPeter Dunlap *nvl = NULL; 962*a6d42e7dSPeter Dunlap } 963*a6d42e7dSPeter Dunlap } 964*a6d42e7dSPeter Dunlap 965*a6d42e7dSPeter Dunlap return (ret); 966*a6d42e7dSPeter Dunlap } 967*a6d42e7dSPeter Dunlap #endif /* !_KERNEL */ 968*a6d42e7dSPeter Dunlap 969*a6d42e7dSPeter Dunlap it_tpg_t * 970*a6d42e7dSPeter Dunlap it_tpg_lookup(it_config_t *cfg, char *tpg_name) 971*a6d42e7dSPeter Dunlap { 972*a6d42e7dSPeter Dunlap it_tpg_t *cfg_tpg = NULL; 973*a6d42e7dSPeter Dunlap 974*a6d42e7dSPeter Dunlap for (cfg_tpg = cfg->config_tpg_list; 975*a6d42e7dSPeter Dunlap cfg_tpg != NULL; 976*a6d42e7dSPeter Dunlap cfg_tpg = cfg_tpg->tpg_next) { 977*a6d42e7dSPeter Dunlap if (strncmp(&cfg_tpg->tpg_name[0], tpg_name, 978*a6d42e7dSPeter Dunlap MAX_TPG_NAMELEN) == 0) { 979*a6d42e7dSPeter Dunlap return (cfg_tpg); 980*a6d42e7dSPeter Dunlap } 981*a6d42e7dSPeter Dunlap } 982*a6d42e7dSPeter Dunlap 983*a6d42e7dSPeter Dunlap return (NULL); 984*a6d42e7dSPeter Dunlap } 985*a6d42e7dSPeter Dunlap 986*a6d42e7dSPeter Dunlap int 987*a6d42e7dSPeter Dunlap it_sa_compare(struct sockaddr_storage *sa1, struct sockaddr_storage *sa2) 988*a6d42e7dSPeter Dunlap { 989*a6d42e7dSPeter Dunlap struct sockaddr_in *sin1, *sin2; 990*a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6_1, *sin6_2; 991*a6d42e7dSPeter Dunlap 992*a6d42e7dSPeter Dunlap /* 993*a6d42e7dSPeter Dunlap * XXX - should we check here for IPv4 addrs mapped to v6? 994*a6d42e7dSPeter Dunlap * see also iscsit_is_v4_mapped in iscsit_login.c 995*a6d42e7dSPeter Dunlap */ 996*a6d42e7dSPeter Dunlap 997*a6d42e7dSPeter Dunlap if (sa1->ss_family != sa2->ss_family) { 998*a6d42e7dSPeter Dunlap return (1); 999*a6d42e7dSPeter Dunlap } 1000*a6d42e7dSPeter Dunlap 1001*a6d42e7dSPeter Dunlap /* 1002*a6d42e7dSPeter Dunlap * sockaddr_in has padding which may not be initialized. 1003*a6d42e7dSPeter Dunlap * be more specific in the comparison, and don't trust the 1004*a6d42e7dSPeter Dunlap * caller has fully initialized the structure. 1005*a6d42e7dSPeter Dunlap */ 1006*a6d42e7dSPeter Dunlap if (sa1->ss_family == AF_INET) { 1007*a6d42e7dSPeter Dunlap sin1 = (struct sockaddr_in *)sa1; 1008*a6d42e7dSPeter Dunlap sin2 = (struct sockaddr_in *)sa2; 1009*a6d42e7dSPeter Dunlap if ((bcmp(&sin1->sin_addr, &sin2->sin_addr, 1010*a6d42e7dSPeter Dunlap sizeof (struct in_addr)) == 0) && 1011*a6d42e7dSPeter Dunlap (sin1->sin_port == sin2->sin_port)) { 1012*a6d42e7dSPeter Dunlap return (0); 1013*a6d42e7dSPeter Dunlap } 1014*a6d42e7dSPeter Dunlap } else if (sa1->ss_family == AF_INET6) { 1015*a6d42e7dSPeter Dunlap sin6_1 = (struct sockaddr_in6 *)sa1; 1016*a6d42e7dSPeter Dunlap sin6_2 = (struct sockaddr_in6 *)sa2; 1017*a6d42e7dSPeter Dunlap if (bcmp(sin6_1, sin6_2, sizeof (struct sockaddr_in6)) == 0) { 1018*a6d42e7dSPeter Dunlap return (0); 1019*a6d42e7dSPeter Dunlap } 1020*a6d42e7dSPeter Dunlap } 1021*a6d42e7dSPeter Dunlap 1022*a6d42e7dSPeter Dunlap return (1); 1023*a6d42e7dSPeter Dunlap } 1024*a6d42e7dSPeter Dunlap 1025*a6d42e7dSPeter Dunlap it_portal_t * 1026*a6d42e7dSPeter Dunlap it_portal_lookup(it_tpg_t *tpg, struct sockaddr_storage *sa) 1027*a6d42e7dSPeter Dunlap { 1028*a6d42e7dSPeter Dunlap it_portal_t *cfg_portal; 1029*a6d42e7dSPeter Dunlap 1030*a6d42e7dSPeter Dunlap for (cfg_portal = tpg->tpg_portal_list; 1031*a6d42e7dSPeter Dunlap cfg_portal != NULL; 1032*a6d42e7dSPeter Dunlap cfg_portal = cfg_portal->next) { 1033*a6d42e7dSPeter Dunlap if (it_sa_compare(sa, &cfg_portal->portal_addr) == 0) 1034*a6d42e7dSPeter Dunlap return (cfg_portal); 1035*a6d42e7dSPeter Dunlap } 1036*a6d42e7dSPeter Dunlap 1037*a6d42e7dSPeter Dunlap return (NULL); 1038*a6d42e7dSPeter Dunlap } 1039*a6d42e7dSPeter Dunlap 1040*a6d42e7dSPeter Dunlap it_portal_t * 1041*a6d42e7dSPeter Dunlap it_sns_svr_lookup(it_config_t *cfg, struct sockaddr_storage *sa) 1042*a6d42e7dSPeter Dunlap { 1043*a6d42e7dSPeter Dunlap it_portal_t *cfg_portal; 1044*a6d42e7dSPeter Dunlap 1045*a6d42e7dSPeter Dunlap for (cfg_portal = cfg->config_isns_svr_list; 1046*a6d42e7dSPeter Dunlap cfg_portal != NULL; 1047*a6d42e7dSPeter Dunlap cfg_portal = cfg_portal->next) { 1048*a6d42e7dSPeter Dunlap if (it_sa_compare(sa, &cfg_portal->portal_addr) == 0) 1049*a6d42e7dSPeter Dunlap return (cfg_portal); 1050*a6d42e7dSPeter Dunlap } 1051*a6d42e7dSPeter Dunlap 1052*a6d42e7dSPeter Dunlap return (NULL); 1053*a6d42e7dSPeter Dunlap } 1054*a6d42e7dSPeter Dunlap 1055*a6d42e7dSPeter Dunlap int 1056*a6d42e7dSPeter Dunlap it_nv_to_tpglist(nvlist_t *nvl, uint32_t *count, it_tpg_t **tpglist) 1057*a6d42e7dSPeter Dunlap { 1058*a6d42e7dSPeter Dunlap int ret = 0; 1059*a6d42e7dSPeter Dunlap it_tpg_t *tpg; 1060*a6d42e7dSPeter Dunlap it_tpg_t *prev = NULL; 1061*a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1062*a6d42e7dSPeter Dunlap nvlist_t *nvt; 1063*a6d42e7dSPeter Dunlap char *name; 1064*a6d42e7dSPeter Dunlap 1065*a6d42e7dSPeter Dunlap if (!tpglist || !count) { 1066*a6d42e7dSPeter Dunlap return (EINVAL); 1067*a6d42e7dSPeter Dunlap } 1068*a6d42e7dSPeter Dunlap 1069*a6d42e7dSPeter Dunlap *tpglist = NULL; 1070*a6d42e7dSPeter Dunlap *count = 0; 1071*a6d42e7dSPeter Dunlap 1072*a6d42e7dSPeter Dunlap if (!nvl) { 1073*a6d42e7dSPeter Dunlap /* nothing to do */ 1074*a6d42e7dSPeter Dunlap return (0); 1075*a6d42e7dSPeter Dunlap } 1076*a6d42e7dSPeter Dunlap 1077*a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 1078*a6d42e7dSPeter Dunlap name = nvpair_name(nvp); 1079*a6d42e7dSPeter Dunlap 1080*a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt); 1081*a6d42e7dSPeter Dunlap if (ret != 0) { 1082*a6d42e7dSPeter Dunlap /* invalid entry? */ 1083*a6d42e7dSPeter Dunlap continue; 1084*a6d42e7dSPeter Dunlap } 1085*a6d42e7dSPeter Dunlap 1086*a6d42e7dSPeter Dunlap ret = it_nv_to_tpg(nvt, name, &tpg); 1087*a6d42e7dSPeter Dunlap if (ret != 0) { 1088*a6d42e7dSPeter Dunlap break; 1089*a6d42e7dSPeter Dunlap } 1090*a6d42e7dSPeter Dunlap 1091*a6d42e7dSPeter Dunlap (*count)++; 1092*a6d42e7dSPeter Dunlap 1093*a6d42e7dSPeter Dunlap if (*tpglist == NULL) { 1094*a6d42e7dSPeter Dunlap *tpglist = tpg; 1095*a6d42e7dSPeter Dunlap } else { 1096*a6d42e7dSPeter Dunlap prev->tpg_next = tpg; 1097*a6d42e7dSPeter Dunlap } 1098*a6d42e7dSPeter Dunlap prev = tpg; 1099*a6d42e7dSPeter Dunlap } 1100*a6d42e7dSPeter Dunlap 1101*a6d42e7dSPeter Dunlap if (ret != 0) { 1102*a6d42e7dSPeter Dunlap it_tpg_free_cmn(*tpglist); 1103*a6d42e7dSPeter Dunlap *tpglist = NULL; 1104*a6d42e7dSPeter Dunlap } 1105*a6d42e7dSPeter Dunlap 1106*a6d42e7dSPeter Dunlap return (ret); 1107*a6d42e7dSPeter Dunlap } 1108*a6d42e7dSPeter Dunlap 1109*a6d42e7dSPeter Dunlap int 1110*a6d42e7dSPeter Dunlap it_ini_to_nv(it_ini_t *ini, nvlist_t **nvl) 1111*a6d42e7dSPeter Dunlap { 1112*a6d42e7dSPeter Dunlap int ret; 1113*a6d42e7dSPeter Dunlap 1114*a6d42e7dSPeter Dunlap if (!nvl) { 1115*a6d42e7dSPeter Dunlap return (EINVAL); 1116*a6d42e7dSPeter Dunlap } 1117*a6d42e7dSPeter Dunlap 1118*a6d42e7dSPeter Dunlap if (!ini) { 1119*a6d42e7dSPeter Dunlap return (0); 1120*a6d42e7dSPeter Dunlap } 1121*a6d42e7dSPeter Dunlap 1122*a6d42e7dSPeter Dunlap ret = nvlist_alloc(nvl, NV_UNIQUE_NAME, 0); 1123*a6d42e7dSPeter Dunlap if (ret != 0) { 1124*a6d42e7dSPeter Dunlap return (ret); 1125*a6d42e7dSPeter Dunlap } 1126*a6d42e7dSPeter Dunlap 1127*a6d42e7dSPeter Dunlap if (ini->ini_properties) { 1128*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, "properties", 1129*a6d42e7dSPeter Dunlap ini->ini_properties); 1130*a6d42e7dSPeter Dunlap } 1131*a6d42e7dSPeter Dunlap 1132*a6d42e7dSPeter Dunlap if (ret == 0) { 1133*a6d42e7dSPeter Dunlap ret = nvlist_add_uint64(*nvl, "generation", 1134*a6d42e7dSPeter Dunlap ini->ini_generation); 1135*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 1136*a6d42e7dSPeter Dunlap ret = 0; 1137*a6d42e7dSPeter Dunlap } 1138*a6d42e7dSPeter Dunlap 1139*a6d42e7dSPeter Dunlap if (ret != 0) { 1140*a6d42e7dSPeter Dunlap nvlist_free(*nvl); 1141*a6d42e7dSPeter Dunlap *nvl = NULL; 1142*a6d42e7dSPeter Dunlap } 1143*a6d42e7dSPeter Dunlap 1144*a6d42e7dSPeter Dunlap return (ret); 1145*a6d42e7dSPeter Dunlap } 1146*a6d42e7dSPeter Dunlap 1147*a6d42e7dSPeter Dunlap int 1148*a6d42e7dSPeter Dunlap it_nv_to_ini(nvlist_t *nvl, char *name, it_ini_t **ini) 1149*a6d42e7dSPeter Dunlap { 1150*a6d42e7dSPeter Dunlap int ret; 1151*a6d42e7dSPeter Dunlap it_ini_t *inip; 1152*a6d42e7dSPeter Dunlap nvlist_t *listval; 1153*a6d42e7dSPeter Dunlap 1154*a6d42e7dSPeter Dunlap if (!name || !ini) { 1155*a6d42e7dSPeter Dunlap return (EINVAL); 1156*a6d42e7dSPeter Dunlap } 1157*a6d42e7dSPeter Dunlap 1158*a6d42e7dSPeter Dunlap *ini = NULL; 1159*a6d42e7dSPeter Dunlap 1160*a6d42e7dSPeter Dunlap if (!nvl) { 1161*a6d42e7dSPeter Dunlap return (0); 1162*a6d42e7dSPeter Dunlap } 1163*a6d42e7dSPeter Dunlap 1164*a6d42e7dSPeter Dunlap inip = iscsit_zalloc(sizeof (it_ini_t)); 1165*a6d42e7dSPeter Dunlap if (!inip) { 1166*a6d42e7dSPeter Dunlap return (ENOMEM); 1167*a6d42e7dSPeter Dunlap } 1168*a6d42e7dSPeter Dunlap 1169*a6d42e7dSPeter Dunlap (void) strlcpy(inip->ini_name, name, sizeof (inip->ini_name)); 1170*a6d42e7dSPeter Dunlap 1171*a6d42e7dSPeter Dunlap ret = nvlist_lookup_nvlist(nvl, "properties", &listval); 1172*a6d42e7dSPeter Dunlap if (ret == 0) { 1173*a6d42e7dSPeter Dunlap ret = nvlist_dup(listval, &(inip->ini_properties), 0); 1174*a6d42e7dSPeter Dunlap } else if (ret == ENOENT) { 1175*a6d42e7dSPeter Dunlap ret = 0; 1176*a6d42e7dSPeter Dunlap } 1177*a6d42e7dSPeter Dunlap 1178*a6d42e7dSPeter Dunlap if (ret == 0) { 1179*a6d42e7dSPeter Dunlap ret = nvlist_lookup_uint64(nvl, "generation", 1180*a6d42e7dSPeter Dunlap &(inip->ini_generation)); 1181*a6d42e7dSPeter Dunlap } 1182*a6d42e7dSPeter Dunlap 1183*a6d42e7dSPeter Dunlap if (ret == 0) { 1184*a6d42e7dSPeter Dunlap *ini = inip; 1185*a6d42e7dSPeter Dunlap } else { 1186*a6d42e7dSPeter Dunlap it_ini_free_cmn(inip); 1187*a6d42e7dSPeter Dunlap } 1188*a6d42e7dSPeter Dunlap 1189*a6d42e7dSPeter Dunlap return (ret); 1190*a6d42e7dSPeter Dunlap } 1191*a6d42e7dSPeter Dunlap 1192*a6d42e7dSPeter Dunlap int 1193*a6d42e7dSPeter Dunlap it_inilist_to_nv(it_ini_t *inilist, nvlist_t **nvl) 1194*a6d42e7dSPeter Dunlap { 1195*a6d42e7dSPeter Dunlap int ret; 1196*a6d42e7dSPeter Dunlap nvlist_t *pnv = NULL; 1197*a6d42e7dSPeter Dunlap nvlist_t *tnv; 1198*a6d42e7dSPeter Dunlap it_ini_t *ptr = inilist; 1199*a6d42e7dSPeter Dunlap 1200*a6d42e7dSPeter Dunlap if (!nvl) { 1201*a6d42e7dSPeter Dunlap return (EINVAL); 1202*a6d42e7dSPeter Dunlap } 1203*a6d42e7dSPeter Dunlap 1204*a6d42e7dSPeter Dunlap if (!inilist) { 1205*a6d42e7dSPeter Dunlap return (0); 1206*a6d42e7dSPeter Dunlap } 1207*a6d42e7dSPeter Dunlap 1208*a6d42e7dSPeter Dunlap /* create the target list if required */ 1209*a6d42e7dSPeter Dunlap if (*nvl == NULL) { 1210*a6d42e7dSPeter Dunlap ret = nvlist_alloc(&pnv, NV_UNIQUE_NAME, 0); 1211*a6d42e7dSPeter Dunlap if (ret != 0) { 1212*a6d42e7dSPeter Dunlap return (ret); 1213*a6d42e7dSPeter Dunlap } 1214*a6d42e7dSPeter Dunlap *nvl = pnv; 1215*a6d42e7dSPeter Dunlap } 1216*a6d42e7dSPeter Dunlap 1217*a6d42e7dSPeter Dunlap while (ptr) { 1218*a6d42e7dSPeter Dunlap ret = it_ini_to_nv(ptr, &tnv); 1219*a6d42e7dSPeter Dunlap 1220*a6d42e7dSPeter Dunlap if (ret != 0) { 1221*a6d42e7dSPeter Dunlap break; 1222*a6d42e7dSPeter Dunlap } 1223*a6d42e7dSPeter Dunlap 1224*a6d42e7dSPeter Dunlap ret = nvlist_add_nvlist(*nvl, ptr->ini_name, tnv); 1225*a6d42e7dSPeter Dunlap 1226*a6d42e7dSPeter Dunlap if (ret != 0) { 1227*a6d42e7dSPeter Dunlap break; 1228*a6d42e7dSPeter Dunlap } 1229*a6d42e7dSPeter Dunlap 1230*a6d42e7dSPeter Dunlap nvlist_free(tnv); 1231*a6d42e7dSPeter Dunlap 1232*a6d42e7dSPeter Dunlap ptr = ptr->ini_next; 1233*a6d42e7dSPeter Dunlap } 1234*a6d42e7dSPeter Dunlap 1235*a6d42e7dSPeter Dunlap if (ret != 0) { 1236*a6d42e7dSPeter Dunlap if (pnv) { 1237*a6d42e7dSPeter Dunlap nvlist_free(pnv); 1238*a6d42e7dSPeter Dunlap *nvl = NULL; 1239*a6d42e7dSPeter Dunlap } 1240*a6d42e7dSPeter Dunlap } 1241*a6d42e7dSPeter Dunlap 1242*a6d42e7dSPeter Dunlap return (ret); 1243*a6d42e7dSPeter Dunlap } 1244*a6d42e7dSPeter Dunlap 1245*a6d42e7dSPeter Dunlap int 1246*a6d42e7dSPeter Dunlap it_nv_to_inilist(nvlist_t *nvl, uint32_t *count, it_ini_t **inilist) 1247*a6d42e7dSPeter Dunlap { 1248*a6d42e7dSPeter Dunlap int ret = 0; 1249*a6d42e7dSPeter Dunlap it_ini_t *inip; 1250*a6d42e7dSPeter Dunlap it_ini_t *prev = NULL; 1251*a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1252*a6d42e7dSPeter Dunlap nvlist_t *nvt; 1253*a6d42e7dSPeter Dunlap char *name; 1254*a6d42e7dSPeter Dunlap 1255*a6d42e7dSPeter Dunlap if (!inilist || !count) { 1256*a6d42e7dSPeter Dunlap return (EINVAL); 1257*a6d42e7dSPeter Dunlap } 1258*a6d42e7dSPeter Dunlap 1259*a6d42e7dSPeter Dunlap *inilist = NULL; 1260*a6d42e7dSPeter Dunlap *count = 0; 1261*a6d42e7dSPeter Dunlap 1262*a6d42e7dSPeter Dunlap if (!nvl) { 1263*a6d42e7dSPeter Dunlap /* nothing to do */ 1264*a6d42e7dSPeter Dunlap return (0); 1265*a6d42e7dSPeter Dunlap } 1266*a6d42e7dSPeter Dunlap 1267*a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 1268*a6d42e7dSPeter Dunlap name = nvpair_name(nvp); 1269*a6d42e7dSPeter Dunlap 1270*a6d42e7dSPeter Dunlap ret = nvpair_value_nvlist(nvp, &nvt); 1271*a6d42e7dSPeter Dunlap if (ret != 0) { 1272*a6d42e7dSPeter Dunlap /* invalid entry? */ 1273*a6d42e7dSPeter Dunlap continue; 1274*a6d42e7dSPeter Dunlap } 1275*a6d42e7dSPeter Dunlap 1276*a6d42e7dSPeter Dunlap ret = it_nv_to_ini(nvt, name, &inip); 1277*a6d42e7dSPeter Dunlap if (ret != 0) { 1278*a6d42e7dSPeter Dunlap break; 1279*a6d42e7dSPeter Dunlap } 1280*a6d42e7dSPeter Dunlap 1281*a6d42e7dSPeter Dunlap (*count)++; 1282*a6d42e7dSPeter Dunlap 1283*a6d42e7dSPeter Dunlap if (*inilist == NULL) { 1284*a6d42e7dSPeter Dunlap *inilist = inip; 1285*a6d42e7dSPeter Dunlap } else { 1286*a6d42e7dSPeter Dunlap prev->ini_next = inip; 1287*a6d42e7dSPeter Dunlap } 1288*a6d42e7dSPeter Dunlap prev = inip; 1289*a6d42e7dSPeter Dunlap } 1290*a6d42e7dSPeter Dunlap 1291*a6d42e7dSPeter Dunlap if (ret != 0) { 1292*a6d42e7dSPeter Dunlap it_ini_free_cmn(*inilist); 1293*a6d42e7dSPeter Dunlap *inilist = NULL; 1294*a6d42e7dSPeter Dunlap } 1295*a6d42e7dSPeter Dunlap 1296*a6d42e7dSPeter Dunlap return (ret); 1297*a6d42e7dSPeter Dunlap } 1298*a6d42e7dSPeter Dunlap 1299*a6d42e7dSPeter Dunlap /* 1300*a6d42e7dSPeter Dunlap * Convert a sockaddr to the string representation, suitable for 1301*a6d42e7dSPeter Dunlap * storing in an nvlist or printing out in a list. 1302*a6d42e7dSPeter Dunlap */ 1303*a6d42e7dSPeter Dunlap #ifndef _KERNEL 1304*a6d42e7dSPeter Dunlap int 1305*a6d42e7dSPeter Dunlap sockaddr_to_str(struct sockaddr_storage *sa, char **addr) 1306*a6d42e7dSPeter Dunlap { 1307*a6d42e7dSPeter Dunlap int ret; 1308*a6d42e7dSPeter Dunlap char buf[INET6_ADDRSTRLEN + 7]; /* addr : port */ 1309*a6d42e7dSPeter Dunlap char pbuf[7]; 1310*a6d42e7dSPeter Dunlap const char *bufp; 1311*a6d42e7dSPeter Dunlap struct sockaddr_in *sin; 1312*a6d42e7dSPeter Dunlap struct sockaddr_in6 *sin6; 1313*a6d42e7dSPeter Dunlap uint16_t port; 1314*a6d42e7dSPeter Dunlap 1315*a6d42e7dSPeter Dunlap if (!sa || !addr) { 1316*a6d42e7dSPeter Dunlap return (EINVAL); 1317*a6d42e7dSPeter Dunlap } 1318*a6d42e7dSPeter Dunlap 1319*a6d42e7dSPeter Dunlap buf[0] = '\0'; 1320*a6d42e7dSPeter Dunlap 1321*a6d42e7dSPeter Dunlap if (sa->ss_family == AF_INET) { 1322*a6d42e7dSPeter Dunlap sin = (struct sockaddr_in *)sa; 1323*a6d42e7dSPeter Dunlap bufp = inet_ntop(AF_INET, 1324*a6d42e7dSPeter Dunlap (const void *)&(sin->sin_addr.s_addr), 1325*a6d42e7dSPeter Dunlap buf, sizeof (buf)); 1326*a6d42e7dSPeter Dunlap if (bufp == NULL) { 1327*a6d42e7dSPeter Dunlap ret = errno; 1328*a6d42e7dSPeter Dunlap return (ret); 1329*a6d42e7dSPeter Dunlap } 1330*a6d42e7dSPeter Dunlap port = ntohs(sin->sin_port); 1331*a6d42e7dSPeter Dunlap } else if (sa->ss_family == AF_INET6) { 1332*a6d42e7dSPeter Dunlap (void) strlcat(buf, "[", sizeof (buf)); 1333*a6d42e7dSPeter Dunlap sin6 = (struct sockaddr_in6 *)sa; 1334*a6d42e7dSPeter Dunlap bufp = inet_ntop(AF_INET6, 1335*a6d42e7dSPeter Dunlap (const void *)&sin6->sin6_addr.s6_addr, 1336*a6d42e7dSPeter Dunlap &buf[1], (sizeof (buf) - 1)); 1337*a6d42e7dSPeter Dunlap if (bufp == NULL) { 1338*a6d42e7dSPeter Dunlap ret = errno; 1339*a6d42e7dSPeter Dunlap return (ret); 1340*a6d42e7dSPeter Dunlap } 1341*a6d42e7dSPeter Dunlap (void) strlcat(buf, "]", sizeof (buf)); 1342*a6d42e7dSPeter Dunlap port = ntohs(sin6->sin6_port); 1343*a6d42e7dSPeter Dunlap } else { 1344*a6d42e7dSPeter Dunlap return (EINVAL); 1345*a6d42e7dSPeter Dunlap } 1346*a6d42e7dSPeter Dunlap 1347*a6d42e7dSPeter Dunlap 1348*a6d42e7dSPeter Dunlap (void) snprintf(pbuf, sizeof (pbuf), ":%u", port); 1349*a6d42e7dSPeter Dunlap (void) strlcat(buf, pbuf, sizeof (buf)); 1350*a6d42e7dSPeter Dunlap 1351*a6d42e7dSPeter Dunlap *addr = strdup(buf); 1352*a6d42e7dSPeter Dunlap if (*addr == NULL) { 1353*a6d42e7dSPeter Dunlap return (ENOMEM); 1354*a6d42e7dSPeter Dunlap } 1355*a6d42e7dSPeter Dunlap 1356*a6d42e7dSPeter Dunlap return (0); 1357*a6d42e7dSPeter Dunlap } 1358*a6d42e7dSPeter Dunlap #endif /* !_KERNEL */ 1359*a6d42e7dSPeter Dunlap 1360*a6d42e7dSPeter Dunlap int 1361*a6d42e7dSPeter Dunlap it_array_to_portallist(char **arr, uint32_t count, uint32_t default_port, 1362*a6d42e7dSPeter Dunlap it_portal_t **portallist, uint32_t *list_count) 1363*a6d42e7dSPeter Dunlap { 1364*a6d42e7dSPeter Dunlap int ret = 0; 1365*a6d42e7dSPeter Dunlap int i; 1366*a6d42e7dSPeter Dunlap it_portal_t *portal; 1367*a6d42e7dSPeter Dunlap it_portal_t *prev = NULL; 1368*a6d42e7dSPeter Dunlap it_portal_t *tmp; 1369*a6d42e7dSPeter Dunlap 1370*a6d42e7dSPeter Dunlap if (!arr || !portallist || !list_count) { 1371*a6d42e7dSPeter Dunlap return (EINVAL); 1372*a6d42e7dSPeter Dunlap } 1373*a6d42e7dSPeter Dunlap 1374*a6d42e7dSPeter Dunlap *list_count = 0; 1375*a6d42e7dSPeter Dunlap *portallist = NULL; 1376*a6d42e7dSPeter Dunlap 1377*a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) { 1378*a6d42e7dSPeter Dunlap if (!arr[i]) { 1379*a6d42e7dSPeter Dunlap /* should never happen */ 1380*a6d42e7dSPeter Dunlap continue; 1381*a6d42e7dSPeter Dunlap } 1382*a6d42e7dSPeter Dunlap portal = iscsit_zalloc(sizeof (it_portal_t)); 1383*a6d42e7dSPeter Dunlap if (!portal) { 1384*a6d42e7dSPeter Dunlap ret = ENOMEM; 1385*a6d42e7dSPeter Dunlap break; 1386*a6d42e7dSPeter Dunlap } 1387*a6d42e7dSPeter Dunlap if (it_common_convert_sa(arr[i], 1388*a6d42e7dSPeter Dunlap &(portal->portal_addr), default_port) == NULL) { 1389*a6d42e7dSPeter Dunlap iscsit_free(portal, sizeof (it_portal_t)); 1390*a6d42e7dSPeter Dunlap ret = EINVAL; 1391*a6d42e7dSPeter Dunlap break; 1392*a6d42e7dSPeter Dunlap } 1393*a6d42e7dSPeter Dunlap 1394*a6d42e7dSPeter Dunlap /* make sure no duplicates */ 1395*a6d42e7dSPeter Dunlap tmp = *portallist; 1396*a6d42e7dSPeter Dunlap while (tmp) { 1397*a6d42e7dSPeter Dunlap if (it_sa_compare(&(tmp->portal_addr), 1398*a6d42e7dSPeter Dunlap &(portal->portal_addr)) == 0) { 1399*a6d42e7dSPeter Dunlap iscsit_free(portal, sizeof (it_portal_t)); 1400*a6d42e7dSPeter Dunlap portal = NULL; 1401*a6d42e7dSPeter Dunlap break; 1402*a6d42e7dSPeter Dunlap } 1403*a6d42e7dSPeter Dunlap tmp = tmp->next; 1404*a6d42e7dSPeter Dunlap } 1405*a6d42e7dSPeter Dunlap 1406*a6d42e7dSPeter Dunlap if (!portal) { 1407*a6d42e7dSPeter Dunlap continue; 1408*a6d42e7dSPeter Dunlap } 1409*a6d42e7dSPeter Dunlap 1410*a6d42e7dSPeter Dunlap /* 1411*a6d42e7dSPeter Dunlap * The first time through the loop, *portallist == NULL 1412*a6d42e7dSPeter Dunlap * because we assigned it to NULL above. Subsequently 1413*a6d42e7dSPeter Dunlap * prev will have been set. Therefor it's OK to put 1414*a6d42e7dSPeter Dunlap * lint override before prev->next assignment. 1415*a6d42e7dSPeter Dunlap */ 1416*a6d42e7dSPeter Dunlap if (*portallist == NULL) { 1417*a6d42e7dSPeter Dunlap *portallist = portal; 1418*a6d42e7dSPeter Dunlap } else { 1419*a6d42e7dSPeter Dunlap prev->next = portal; 1420*a6d42e7dSPeter Dunlap } 1421*a6d42e7dSPeter Dunlap 1422*a6d42e7dSPeter Dunlap prev = portal; 1423*a6d42e7dSPeter Dunlap (*list_count)++; 1424*a6d42e7dSPeter Dunlap } 1425*a6d42e7dSPeter Dunlap 1426*a6d42e7dSPeter Dunlap return (ret); 1427*a6d42e7dSPeter Dunlap } 1428*a6d42e7dSPeter Dunlap 1429*a6d42e7dSPeter Dunlap /* 1430*a6d42e7dSPeter Dunlap * Function: it_config_free_cmn() 1431*a6d42e7dSPeter Dunlap * 1432*a6d42e7dSPeter Dunlap * Free any resources associated with the it_config_t structure. 1433*a6d42e7dSPeter Dunlap * 1434*a6d42e7dSPeter Dunlap * Parameters: 1435*a6d42e7dSPeter Dunlap * cfg A C representation of the current iSCSI configuration 1436*a6d42e7dSPeter Dunlap */ 1437*a6d42e7dSPeter Dunlap void 1438*a6d42e7dSPeter Dunlap it_config_free_cmn(it_config_t *cfg) 1439*a6d42e7dSPeter Dunlap { 1440*a6d42e7dSPeter Dunlap if (!cfg) { 1441*a6d42e7dSPeter Dunlap return; 1442*a6d42e7dSPeter Dunlap } 1443*a6d42e7dSPeter Dunlap 1444*a6d42e7dSPeter Dunlap if (cfg->config_tgt_list) { 1445*a6d42e7dSPeter Dunlap it_tgt_free_cmn(cfg->config_tgt_list); 1446*a6d42e7dSPeter Dunlap } 1447*a6d42e7dSPeter Dunlap 1448*a6d42e7dSPeter Dunlap if (cfg->config_tpg_list) { 1449*a6d42e7dSPeter Dunlap it_tpg_free_cmn(cfg->config_tpg_list); 1450*a6d42e7dSPeter Dunlap } 1451*a6d42e7dSPeter Dunlap 1452*a6d42e7dSPeter Dunlap if (cfg->config_ini_list) { 1453*a6d42e7dSPeter Dunlap it_ini_free_cmn(cfg->config_ini_list); 1454*a6d42e7dSPeter Dunlap } 1455*a6d42e7dSPeter Dunlap 1456*a6d42e7dSPeter Dunlap if (cfg->config_global_properties) { 1457*a6d42e7dSPeter Dunlap nvlist_free(cfg->config_global_properties); 1458*a6d42e7dSPeter Dunlap } 1459*a6d42e7dSPeter Dunlap 1460*a6d42e7dSPeter Dunlap if (cfg->config_isns_svr_list) { 1461*a6d42e7dSPeter Dunlap it_portal_t *pp = cfg->config_isns_svr_list; 1462*a6d42e7dSPeter Dunlap it_portal_t *pp_next; 1463*a6d42e7dSPeter Dunlap 1464*a6d42e7dSPeter Dunlap while (pp) { 1465*a6d42e7dSPeter Dunlap pp_next = pp->next; 1466*a6d42e7dSPeter Dunlap iscsit_free(pp, sizeof (it_portal_t)); 1467*a6d42e7dSPeter Dunlap pp = pp_next; 1468*a6d42e7dSPeter Dunlap } 1469*a6d42e7dSPeter Dunlap } 1470*a6d42e7dSPeter Dunlap 1471*a6d42e7dSPeter Dunlap iscsit_free(cfg, sizeof (it_config_t)); 1472*a6d42e7dSPeter Dunlap } 1473*a6d42e7dSPeter Dunlap 1474*a6d42e7dSPeter Dunlap /* 1475*a6d42e7dSPeter Dunlap * Function: it_tgt_free_cmn() 1476*a6d42e7dSPeter Dunlap * 1477*a6d42e7dSPeter Dunlap * Frees an it_tgt_t structure. If tgt_next is not NULL, frees 1478*a6d42e7dSPeter Dunlap * all structures in the list. 1479*a6d42e7dSPeter Dunlap */ 1480*a6d42e7dSPeter Dunlap void 1481*a6d42e7dSPeter Dunlap it_tgt_free_cmn(it_tgt_t *tgt) 1482*a6d42e7dSPeter Dunlap { 1483*a6d42e7dSPeter Dunlap it_tgt_t *tgtp = tgt; 1484*a6d42e7dSPeter Dunlap it_tgt_t *next; 1485*a6d42e7dSPeter Dunlap 1486*a6d42e7dSPeter Dunlap if (!tgt) { 1487*a6d42e7dSPeter Dunlap return; 1488*a6d42e7dSPeter Dunlap } 1489*a6d42e7dSPeter Dunlap 1490*a6d42e7dSPeter Dunlap while (tgtp) { 1491*a6d42e7dSPeter Dunlap next = tgtp->tgt_next; 1492*a6d42e7dSPeter Dunlap 1493*a6d42e7dSPeter Dunlap if (tgtp->tgt_tpgt_list) { 1494*a6d42e7dSPeter Dunlap it_tpgt_free_cmn(tgtp->tgt_tpgt_list); 1495*a6d42e7dSPeter Dunlap } 1496*a6d42e7dSPeter Dunlap 1497*a6d42e7dSPeter Dunlap if (tgtp->tgt_properties) { 1498*a6d42e7dSPeter Dunlap nvlist_free(tgtp->tgt_properties); 1499*a6d42e7dSPeter Dunlap } 1500*a6d42e7dSPeter Dunlap 1501*a6d42e7dSPeter Dunlap iscsit_free(tgtp, sizeof (it_tgt_t)); 1502*a6d42e7dSPeter Dunlap 1503*a6d42e7dSPeter Dunlap tgtp = next; 1504*a6d42e7dSPeter Dunlap } 1505*a6d42e7dSPeter Dunlap } 1506*a6d42e7dSPeter Dunlap 1507*a6d42e7dSPeter Dunlap /* 1508*a6d42e7dSPeter Dunlap * Function: it_tpgt_free_cmn() 1509*a6d42e7dSPeter Dunlap * 1510*a6d42e7dSPeter Dunlap * Deallocates resources of an it_tpgt_t structure. If tpgt->next 1511*a6d42e7dSPeter Dunlap * is not NULL, frees all members of the list. 1512*a6d42e7dSPeter Dunlap */ 1513*a6d42e7dSPeter Dunlap void 1514*a6d42e7dSPeter Dunlap it_tpgt_free_cmn(it_tpgt_t *tpgt) 1515*a6d42e7dSPeter Dunlap { 1516*a6d42e7dSPeter Dunlap it_tpgt_t *tpgtp = tpgt; 1517*a6d42e7dSPeter Dunlap it_tpgt_t *next; 1518*a6d42e7dSPeter Dunlap 1519*a6d42e7dSPeter Dunlap if (!tpgt) { 1520*a6d42e7dSPeter Dunlap return; 1521*a6d42e7dSPeter Dunlap } 1522*a6d42e7dSPeter Dunlap 1523*a6d42e7dSPeter Dunlap while (tpgtp) { 1524*a6d42e7dSPeter Dunlap next = tpgtp->tpgt_next; 1525*a6d42e7dSPeter Dunlap 1526*a6d42e7dSPeter Dunlap iscsit_free(tpgtp, sizeof (it_tpgt_t)); 1527*a6d42e7dSPeter Dunlap 1528*a6d42e7dSPeter Dunlap tpgtp = next; 1529*a6d42e7dSPeter Dunlap } 1530*a6d42e7dSPeter Dunlap } 1531*a6d42e7dSPeter Dunlap 1532*a6d42e7dSPeter Dunlap /* 1533*a6d42e7dSPeter Dunlap * Function: it_tpg_free_cmn() 1534*a6d42e7dSPeter Dunlap * 1535*a6d42e7dSPeter Dunlap * Deallocates resources associated with an it_tpg_t structure. 1536*a6d42e7dSPeter Dunlap * If tpg->next is not NULL, frees all members of the list. 1537*a6d42e7dSPeter Dunlap */ 1538*a6d42e7dSPeter Dunlap void 1539*a6d42e7dSPeter Dunlap it_tpg_free_cmn(it_tpg_t *tpg) 1540*a6d42e7dSPeter Dunlap { 1541*a6d42e7dSPeter Dunlap it_tpg_t *tpgp = tpg; 1542*a6d42e7dSPeter Dunlap it_tpg_t *next; 1543*a6d42e7dSPeter Dunlap it_portal_t *portalp; 1544*a6d42e7dSPeter Dunlap it_portal_t *pnext; 1545*a6d42e7dSPeter Dunlap 1546*a6d42e7dSPeter Dunlap while (tpgp) { 1547*a6d42e7dSPeter Dunlap next = tpgp->tpg_next; 1548*a6d42e7dSPeter Dunlap 1549*a6d42e7dSPeter Dunlap portalp = tpgp->tpg_portal_list; 1550*a6d42e7dSPeter Dunlap 1551*a6d42e7dSPeter Dunlap while (portalp) { 1552*a6d42e7dSPeter Dunlap pnext = portalp->next; 1553*a6d42e7dSPeter Dunlap iscsit_free(portalp, sizeof (it_portal_t)); 1554*a6d42e7dSPeter Dunlap portalp = pnext; 1555*a6d42e7dSPeter Dunlap } 1556*a6d42e7dSPeter Dunlap 1557*a6d42e7dSPeter Dunlap iscsit_free(tpgp, sizeof (it_tpg_t)); 1558*a6d42e7dSPeter Dunlap 1559*a6d42e7dSPeter Dunlap tpgp = next; 1560*a6d42e7dSPeter Dunlap } 1561*a6d42e7dSPeter Dunlap } 1562*a6d42e7dSPeter Dunlap 1563*a6d42e7dSPeter Dunlap /* 1564*a6d42e7dSPeter Dunlap * Function: it_ini_free_cmn() 1565*a6d42e7dSPeter Dunlap * 1566*a6d42e7dSPeter Dunlap * Deallocates resources of an it_ini_t structure. If ini->next is 1567*a6d42e7dSPeter Dunlap * not NULL, frees all members of the list. 1568*a6d42e7dSPeter Dunlap */ 1569*a6d42e7dSPeter Dunlap void 1570*a6d42e7dSPeter Dunlap it_ini_free_cmn(it_ini_t *ini) 1571*a6d42e7dSPeter Dunlap { 1572*a6d42e7dSPeter Dunlap it_ini_t *inip = ini; 1573*a6d42e7dSPeter Dunlap it_ini_t *next; 1574*a6d42e7dSPeter Dunlap 1575*a6d42e7dSPeter Dunlap if (!ini) { 1576*a6d42e7dSPeter Dunlap return; 1577*a6d42e7dSPeter Dunlap } 1578*a6d42e7dSPeter Dunlap 1579*a6d42e7dSPeter Dunlap while (inip) { 1580*a6d42e7dSPeter Dunlap next = inip->ini_next; 1581*a6d42e7dSPeter Dunlap 1582*a6d42e7dSPeter Dunlap if (inip->ini_properties) { 1583*a6d42e7dSPeter Dunlap nvlist_free(inip->ini_properties); 1584*a6d42e7dSPeter Dunlap } 1585*a6d42e7dSPeter Dunlap 1586*a6d42e7dSPeter Dunlap iscsit_free(inip, sizeof (it_ini_t)); 1587*a6d42e7dSPeter Dunlap 1588*a6d42e7dSPeter Dunlap inip = next; 1589*a6d42e7dSPeter Dunlap } 1590*a6d42e7dSPeter Dunlap } 1591