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