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