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