dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fcinfo / fcadm-list.c
bloba53188c0264ad49182f82b3b123b7cd4f7600980
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <libscf.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <syslog.h>
31 #include <strings.h>
32 #include <ctype.h>
33 #include <fcinfo.h>
36 #define FCADM_RETRY_TIMES 10
37 #define FCADM_SLEEP_TIME 1
39 static char *
40 WWN2str(char *buf, HBA_WWN *wwn) {
41 int j;
42 unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
43 buf[0] = '\0';
44 for (j = 0; j < 16; j += 2) {
45 sprintf(&buf[j], "%02X", (int)*pc++);
47 return (buf);
50 static int
51 isValidWWN(char *wwn)
53 int index;
55 if (wwn == NULL) {
56 return (0);
59 if (strlen(wwn) != 16) {
60 return (0);
63 for (index = 0; index < 16; index++) {
64 if (isxdigit(wwn[index])) {
65 continue;
67 return (0);
69 return (1);
74 * Initialize scf stmf service access
75 * handle - returned handle
76 * service - returned service handle
78 static int
79 cfgInit(scf_handle_t **handle, scf_service_t **service)
81 scf_scope_t *scope = NULL;
82 int ret;
84 if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
85 /* log error */
86 ret = NPIV_ERROR;
87 goto err;
90 if (scf_handle_bind(*handle) == -1) {
91 /* log error */
92 ret = NPIV_ERROR;
93 goto err;
96 if ((*service = scf_service_create(*handle)) == NULL) {
97 /* log error */
98 ret = NPIV_ERROR;
99 goto err;
102 if ((scope = scf_scope_create(*handle)) == NULL) {
103 /* log error */
104 ret = NPIV_ERROR;
105 goto err;
108 if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
109 /* log error */
110 ret = NPIV_ERROR;
111 goto err;
114 if (scf_scope_get_service(scope, NPIV_SERVICE, *service) == -1) {
115 /* log error */
116 ret = NPIV_ERROR_SERVICE_NOT_FOUND;
117 goto err;
120 scf_scope_destroy(scope);
122 return (NPIV_SUCCESS);
124 err:
125 if (*handle != NULL) {
126 scf_handle_destroy(*handle);
128 if (*service != NULL) {
129 scf_service_destroy(*service);
130 *service = NULL;
132 if (scope != NULL) {
133 scf_scope_destroy(scope);
135 return (ret);
138 static int
139 npivAddRemoveNPIVEntry(char *ppwwn, char *vnwwn,
140 char *vpwwn, int vindex, int addRemoveFlag) {
141 scf_handle_t *handle = NULL;
142 scf_service_t *svc = NULL;
143 scf_propertygroup_t *pg = NULL;
144 scf_transaction_t *tran = NULL;
145 scf_transaction_entry_t *entry = NULL;
146 scf_property_t *prop = NULL;
147 scf_value_t *valueLookup = NULL;
148 scf_iter_t *valueIter = NULL;
149 scf_value_t **valueSet = NULL;
150 int ret = NPIV_SUCCESS;
151 boolean_t createProp = B_FALSE;
152 int lastAlloc = 0;
153 char buf[NPIV_PORT_LIST_LENGTH] = {0};
154 char memberName[NPIV_PORT_LIST_LENGTH] = {0};
155 boolean_t found = B_FALSE;
156 int i = 0;
157 int valueArraySize = 0;
158 int commitRet;
160 if (vnwwn) {
161 sprintf(memberName, "%s:%s:%s:%d", ppwwn, vpwwn, vnwwn, vindex);
162 } else {
163 sprintf(memberName, "%s:%s", ppwwn, vpwwn);
166 ret = cfgInit(&handle, &svc);
167 if (ret != NPIV_SUCCESS) {
168 goto out;
171 if (((pg = scf_pg_create(handle)) == NULL) ||
172 ((tran = scf_transaction_create(handle)) == NULL) ||
173 ((entry = scf_entry_create(handle)) == NULL) ||
174 ((prop = scf_property_create(handle)) == NULL) ||
175 ((valueIter = scf_iter_create(handle)) == NULL)) {
176 ret = NPIV_ERROR;
177 goto out;
180 /* get property group or create it */
181 if (scf_service_get_pg(svc, NPIV_PG_NAME, pg) == -1) {
182 if ((scf_error() == SCF_ERROR_NOT_FOUND) &&
183 (addRemoveFlag == NPIV_ADD)) {
184 if (scf_service_add_pg(svc, NPIV_PG_NAME,
185 SCF_GROUP_APPLICATION, 0, pg) == -1) {
186 syslog(LOG_ERR, "add pg failed - %s",
187 scf_strerror(scf_error()));
188 ret = NPIV_ERROR;
189 } else {
190 createProp = B_TRUE;
192 } else if (scf_error() == SCF_ERROR_NOT_FOUND) {
193 ret = NPIV_ERROR_NOT_FOUND;
194 } else {
195 syslog(LOG_ERR, "get pg failed - %s",
196 scf_strerror(scf_error()));
197 ret = NPIV_ERROR;
199 if (ret != NPIV_SUCCESS) {
200 goto out;
204 /* Begin the transaction */
205 if (scf_transaction_start(tran, pg) == -1) {
206 syslog(LOG_ERR, "start transaction failed - %s",
207 scf_strerror(scf_error()));
208 ret = NPIV_ERROR;
209 goto out;
212 valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
213 * (lastAlloc = PORT_LIST_ALLOC));
214 if (valueSet == NULL) {
215 ret = NPIV_ERROR_NOMEM;
216 goto out;
219 if (createProp) {
220 if (scf_transaction_property_new(tran, entry, NPIV_PORT_LIST,
221 SCF_TYPE_USTRING) == -1) {
222 if (scf_error() == SCF_ERROR_EXISTS) {
223 ret = NPIV_ERROR_EXISTS;
224 } else {
225 syslog(LOG_ERR,
226 "transaction property new failed - %s",
227 scf_strerror(scf_error()));
228 ret = NPIV_ERROR;
230 goto out;
232 } else {
233 if (scf_transaction_property_change(tran, entry,
234 NPIV_PORT_LIST, SCF_TYPE_USTRING) == -1) {
235 syslog(LOG_ERR,
236 "transaction property change failed - %s",
237 scf_strerror(scf_error()));
238 ret = NPIV_ERROR;
239 goto out;
242 if (scf_pg_get_property(pg, NPIV_PORT_LIST, prop) == -1) {
243 syslog(LOG_ERR, "get property failed - %s",
244 scf_strerror(scf_error()));
245 ret = NPIV_ERROR;
246 goto out;
249 valueLookup = scf_value_create(handle);
250 if (valueLookup == NULL) {
251 syslog(LOG_ERR, "scf value alloc failed - %s",
252 scf_strerror(scf_error()));
253 ret = NPIV_ERROR;
254 goto out;
257 if (scf_iter_property_values(valueIter, prop) == -1) {
258 syslog(LOG_ERR, "iter value failed - %s",
259 scf_strerror(scf_error()));
260 ret = NPIV_ERROR;
261 goto out;
264 while (scf_iter_next_value(valueIter, valueLookup) == 1) {
265 bzero(buf, sizeof (buf));
266 if (scf_value_get_ustring(valueLookup,
267 buf, MAXNAMELEN) == -1) {
268 syslog(LOG_ERR, "iter value failed - %s",
269 scf_strerror(scf_error()));
270 ret = NPIV_ERROR;
271 break;
274 if ((strlen(buf) >= strlen(memberName)) &&
275 bcmp(buf, memberName, strlen(memberName)) == 0) {
276 if (addRemoveFlag == NPIV_ADD) {
277 ret = NPIV_ERROR_EXISTS;
278 break;
279 } else {
280 found = B_TRUE;
281 continue;
285 valueSet[i] = scf_value_create(handle);
286 if (valueSet[i] == NULL) {
287 syslog(LOG_ERR, "scf value alloc failed - %s",
288 scf_strerror(scf_error()));
289 ret = NPIV_ERROR;
290 break;
293 if (scf_value_set_ustring(valueSet[i], buf) == -1) {
294 syslog(LOG_ERR, "set value failed - %s",
295 scf_strerror(scf_error()));
296 ret = NPIV_ERROR;
297 break;
300 if (scf_entry_add_value(entry, valueSet[i]) == -1) {
301 syslog(LOG_ERR, "add value failed - %s",
302 scf_strerror(scf_error()));
303 ret = NPIV_ERROR;
304 break;
307 i++;
309 if (i >= lastAlloc) {
310 lastAlloc += PORT_LIST_ALLOC;
311 valueSet = reallocarray(valueSet, lastAlloc,
312 sizeof (*valueSet));
313 if (valueSet == NULL) {
314 ret = NPIV_ERROR;
315 break;
321 valueArraySize = i;
322 if (!found && (addRemoveFlag == NPIV_REMOVE)) {
323 ret = NPIV_ERROR_MEMBER_NOT_FOUND;
325 if (ret != NPIV_SUCCESS) {
326 goto out;
329 if (addRemoveFlag == NPIV_ADD) {
331 * Now create the new entry
333 valueSet[i] = scf_value_create(handle);
334 if (valueSet[i] == NULL) {
335 syslog(LOG_ERR, "scf value alloc failed - %s",
336 scf_strerror(scf_error()));
337 ret = NPIV_ERROR;
338 goto out;
339 } else {
340 valueArraySize++;
344 * Set the new member name
346 if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
347 syslog(LOG_ERR, "set value failed - %s",
348 scf_strerror(scf_error()));
349 ret = NPIV_ERROR;
350 goto out;
354 * Add the new member
356 if (scf_entry_add_value(entry, valueSet[i]) == -1) {
357 syslog(LOG_ERR, "add value failed - %s",
358 scf_strerror(scf_error()));
359 ret = NPIV_ERROR;
360 goto out;
364 if ((commitRet = scf_transaction_commit(tran)) != 1) {
365 syslog(LOG_ERR, "transaction commit failed - %s",
366 scf_strerror(scf_error()));
367 if (commitRet == 0) {
368 ret = NPIV_ERROR_BUSY;
369 } else {
370 ret = NPIV_ERROR;
372 goto out;
375 out:
377 * Free resources
379 if (handle != NULL) {
380 scf_handle_destroy(handle);
382 if (svc != NULL) {
383 scf_service_destroy(svc);
385 if (pg != NULL) {
386 scf_pg_destroy(pg);
388 if (tran != NULL) {
389 scf_transaction_destroy(tran);
391 if (entry != NULL) {
392 scf_entry_destroy(entry);
394 if (prop != NULL) {
395 scf_property_destroy(prop);
397 if (valueIter != NULL) {
398 scf_iter_destroy(valueIter);
400 if (valueLookup != NULL) {
401 scf_value_destroy(valueLookup);
405 * Free valueSet scf resources
407 if (valueArraySize > 0) {
408 for (i = 0; i < valueArraySize; i++) {
409 scf_value_destroy(valueSet[i]);
413 * Now free the pointer array to the resources
415 if (valueSet != NULL) {
416 free(valueSet);
419 return (ret);
422 static int
423 retrieveNPIVAttrs(HBA_HANDLE handle, HBA_WWN portWWN,
424 HBA_PORTNPIVATTRIBUTES *npivattrs, HBA_UINT32 *portIndex) {
425 HBA_STATUS status;
426 HBA_ADAPTERATTRIBUTES attrs;
427 HBA_PORTATTRIBUTES portattrs;
428 int portCtr;
429 int times = 0;
431 /* argument checking */
432 if (npivattrs == NULL || portIndex == NULL) {
433 return (1);
436 memset(&attrs, 0, sizeof (HBA_ADAPTERATTRIBUTES));
437 status = HBA_GetAdapterAttributes(handle, &attrs);
438 while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
439 status == HBA_STATUS_ERROR_BUSY) &&
440 times++ < 130) {
441 status = HBA_GetAdapterAttributes(handle, &attrs);
442 if (status == HBA_STATUS_OK) {
443 break;
445 (void) sleep(1);
447 if (status != HBA_STATUS_OK) {
448 return (1);
451 memset(&portattrs, 0, sizeof (HBA_PORTATTRIBUTES));
452 for (portCtr = 0; portCtr < attrs.NumberOfPorts; portCtr++) {
453 status = HBA_GetAdapterPortAttributes(handle,
454 portCtr, &portattrs);
455 times = 0;
456 while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
457 status == HBA_STATUS_ERROR_BUSY) &&
458 times++ < HBA_MAX_RETRIES) {
459 status = HBA_GetAdapterPortAttributes(handle,
460 portCtr, &portattrs);
461 if (status == HBA_STATUS_OK) {
462 break;
464 (void) sleep(1);
467 if (status != HBA_STATUS_OK) {
468 return (1);
471 if (memcmp(portWWN.wwn, portattrs.PortWWN.wwn,
472 sizeof (portattrs.PortWWN.wwn)) == 0) {
473 break;
476 if (portCtr >= attrs.NumberOfPorts) {
477 *portIndex = 0;
478 return (1);
480 *portIndex = portCtr;
482 status = Sun_HBA_GetPortNPIVAttributes(handle, portCtr, npivattrs);
483 times = 0;
484 while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
485 status == HBA_STATUS_ERROR_BUSY) &&
486 times++ < HBA_MAX_RETRIES) {
487 status = Sun_HBA_GetPortNPIVAttributes(handle,
488 portCtr, npivattrs);
489 if (status == HBA_STATUS_OK) {
490 break;
492 (void) sleep(1);
494 if (status != HBA_STATUS_OK) {
495 return (1);
498 return (0);
503 fc_util_delete_npivport(int wwnCount, char **wwn_argv,
504 cmdOptions_t *options)
506 uint64_t physicalportWWN, virtualportWWN;
507 HBA_WWN portWWN, vportWWN;
508 HBA_STATUS status;
509 HBA_HANDLE handle;
510 HBA_PORTNPIVATTRIBUTES npivattrs;
511 HBA_UINT32 portIndex;
512 char pwwn[17];
513 int times;
515 if (wwnCount != 1) {
516 fprintf(stderr,
517 gettext("Invalid Parameter\n"));
518 return (1);
521 for (; options->optval; options++) {
522 switch (options->optval) {
523 case 'p':
524 if (!isValidWWN(options->optarg)) {
525 fprintf(stderr,
526 gettext("Invalid Port WWN\n"));
527 return (1);
529 sscanf(options->optarg, "%016llx", &virtualportWWN);
530 break;
531 default:
532 return (1);
536 if (!isValidWWN(wwn_argv[0])) {
537 fprintf(stderr,
538 gettext("Invalid Physical Port WWN\n"));
539 return (1);
542 if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
543 fprintf(stderr,
544 gettext("Failed to load FC-HBA common library\n"));
545 printStatus(status);
546 fprintf(stderr, "\n");
547 return (1);
549 sscanf(wwn_argv[0], "%016llx", &physicalportWWN);
550 physicalportWWN = htonll(physicalportWWN);
551 memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
553 virtualportWWN = htonll(virtualportWWN);
554 memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
556 status = HBA_OpenAdapterByWWN(&handle, portWWN);
557 if (status != HBA_STATUS_OK) {
558 fprintf(stderr,
559 gettext("Error: HBA port %s: not found\n"),
560 wwn_argv[0]);
561 HBA_FreeLibrary();
562 return (1);
565 /* Get physical port NPIV attributes */
566 if (retrieveNPIVAttrs(handle, portWWN, &npivattrs, &portIndex) == 0) {
567 /* Check port NPIV attributes */
568 if (npivattrs.MaxNumberOfNPIVPorts == 0) {
569 fprintf(stderr,
570 gettext("Error: NPIV not Supported\n"));
571 HBA_CloseAdapter(handle);
572 HBA_FreeLibrary();
573 return (1);
576 /* Delete a virtual port */
577 status = Sun_HBA_DeleteNPIVPort(handle, portIndex,
578 vportWWN);
579 times = 0;
580 while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
581 status == HBA_STATUS_ERROR_BUSY) &&
582 times++ < HBA_MAX_RETRIES) {
583 (void) sleep(1);
584 status = Sun_HBA_DeleteNPIVPort(handle, portIndex,
585 vportWWN);
586 if (status == HBA_STATUS_OK) {
587 break;
590 if (status != HBA_STATUS_OK) {
591 fprintf(stderr,
592 gettext("Error: failed to delete a npiv port\n"));
593 HBA_CloseAdapter(handle);
594 HBA_FreeLibrary();
595 return (1);
597 } else {
598 fprintf(stderr,
599 gettext("Error: failed to get port NPIV attributes\n"));
600 HBA_CloseAdapter(handle);
601 HBA_FreeLibrary();
602 return (1);
605 HBA_CloseAdapter(handle);
606 HBA_FreeLibrary();
608 WWN2str(pwwn, &vportWWN);
609 npivAddRemoveNPIVEntry(wwn_argv[0],
610 NULL, pwwn, 0, NPIV_REMOVE);
612 return (0);
616 fc_util_create_npivport(int wwnCount,
617 char **wwn_argv, cmdOptions_t *options)
619 uint64_t physicalportWWN, virtualnodeWWN, virtualportWWN;
620 HBA_WWN portWWN, vnodeWWN, vportWWN;
621 HBA_STATUS status;
622 HBA_HANDLE handle;
623 HBA_PORTNPIVATTRIBUTES npivattrs;
624 HBA_UINT32 portIndex;
625 HBA_UINT32 npivportIndex = 0;
626 char nwwn[17], pwwn[17];
627 int randomflag = 0;
628 int times;
630 if (wwnCount != 1) {
631 fprintf(stderr,
632 gettext("Invalid Parameter\n"));
633 return (1);
636 for (; options->optval; options++) {
637 switch (options->optval) {
638 case 'p':
639 if (!isValidWWN(options->optarg)) {
640 fprintf(stderr,
641 gettext("Invalid Port WWN\n"));
642 return (1);
644 sscanf(options->optarg, "%016llx", &virtualportWWN);
645 randomflag++;
646 break;
647 case 'n':
648 if (!isValidWWN(options->optarg)) {
649 fprintf(stderr,
650 gettext("Invalid Node WWN\n"));
651 return (1);
653 sscanf(options->optarg, "%016llx", &virtualnodeWWN);
654 randomflag++;
655 break;
656 default:
657 return (1);
661 if (!isValidWWN(wwn_argv[0])) {
662 fprintf(stderr,
663 gettext("Invalid Physical Port WWN\n"));
664 wwnCount = 0;
665 return (1);
668 if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
669 fprintf(stderr,
670 gettext("Failed to load FC-HBA common library\n"));
671 printStatus(status);
672 fprintf(stderr, "\n");
673 return (1);
676 sscanf(wwn_argv[0], "%016llx", &physicalportWWN);
677 physicalportWWN = htonll(physicalportWWN);
678 memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
680 status = HBA_OpenAdapterByWWN(&handle, portWWN);
681 if (status != HBA_STATUS_OK) {
682 fprintf(stderr,
683 gettext("Error: HBA port %s: not found\n"),
684 wwn_argv[0]);
685 HBA_FreeLibrary();
686 return (1);
689 if (randomflag != 2) {
690 status = Sun_HBA_AdapterCreateWWN(handle, 0,
691 &vnodeWWN, &vportWWN, NULL, HBA_CREATE_WWN_RANDOM);
692 if (status != HBA_STATUS_OK) {
693 fprintf(stderr,
694 gettext("Error: Fail to get Random WWN\n"));
695 HBA_CloseAdapter(handle);
696 HBA_FreeLibrary();
697 return (1);
699 } else {
700 virtualnodeWWN = htonll(virtualnodeWWN);
701 memcpy(vnodeWWN.wwn, &virtualnodeWWN, sizeof (virtualnodeWWN));
702 virtualportWWN = htonll(virtualportWWN);
703 memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
706 if (memcmp(vnodeWWN.wwn, vportWWN.wwn, 8) == 0) {
707 fprintf(stderr,
708 gettext("Error: Port WWN is same as Node WWN\n"));
709 HBA_CloseAdapter(handle);
710 HBA_FreeLibrary();
711 return (1);
714 /* Get physical port NPIV attributes */
715 if (retrieveNPIVAttrs(handle, portWWN, &npivattrs, &portIndex) == 0) {
716 /* Check port NPIV attributes */
717 if (npivattrs.MaxNumberOfNPIVPorts == 0) {
718 fprintf(stderr,
719 gettext("Error: NPIV not Supported\n"));
720 HBA_CloseAdapter(handle);
721 HBA_FreeLibrary();
722 return (1);
724 if (npivattrs.MaxNumberOfNPIVPorts ==
725 npivattrs.NumberOfNPIVPorts) {
726 fprintf(stderr,
727 gettext("Error: Can not create more NPIV port\n"));
728 HBA_CloseAdapter(handle);
729 HBA_FreeLibrary();
730 return (1);
733 /* Create a virtual port */
734 status = Sun_HBA_CreateNPIVPort(handle, portIndex,
735 vnodeWWN, vportWWN, &npivportIndex);
736 times = 0;
737 while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
738 status == HBA_STATUS_ERROR_BUSY) &&
739 times++ < HBA_MAX_RETRIES) {
740 (void) sleep(1);
741 status = Sun_HBA_CreateNPIVPort(handle, portIndex,
742 vnodeWWN, vportWWN, &npivportIndex);
743 if (status == HBA_STATUS_OK) {
744 break;
748 if (status != HBA_STATUS_OK) {
749 fprintf(stderr,
750 gettext("Error: failed to create a npiv port\n"));
751 HBA_CloseAdapter(handle);
752 HBA_FreeLibrary();
753 return (1);
755 } else {
756 fprintf(stderr,
757 gettext("Error: failed to get port NPIV attributes\n"));
758 HBA_CloseAdapter(handle);
759 HBA_FreeLibrary();
760 return (1);
763 HBA_CloseAdapter(handle);
764 HBA_FreeLibrary();
766 WWN2str(nwwn, &vnodeWWN);
767 WWN2str(pwwn, &vportWWN);
768 npivAddRemoveNPIVEntry(wwn_argv[0],
769 nwwn, pwwn, npivportIndex, NPIV_ADD);
771 return (0);
775 create_npivport(char *ppwwn_str, char *vnwwn_str,
776 char *vpwwn_str, int vindex)
778 uint64_t physicalportWWN, virtualnodeWWN, virtualportWWN;
779 HBA_WWN portWWN, vnodeWWN, vportWWN;
780 HBA_STATUS status;
781 HBA_HANDLE handle;
782 HBA_PORTNPIVATTRIBUTES npivattrs;
783 HBA_UINT32 portIndex;
784 HBA_UINT32 npivportIndex;
785 int times = 0;
787 sscanf(ppwwn_str, "%016llx", &physicalportWWN);
788 physicalportWWN = htonll(physicalportWWN);
789 memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
790 sscanf(vnwwn_str, "%016llx", &virtualnodeWWN);
791 virtualnodeWWN = htonll(virtualnodeWWN);
792 memcpy(vnodeWWN.wwn, &virtualnodeWWN, sizeof (virtualnodeWWN));
793 sscanf(vpwwn_str, "%016llx", &virtualportWWN);
794 virtualportWWN = htonll(virtualportWWN);
795 memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
796 npivportIndex = vindex;
798 status = HBA_OpenAdapterByWWN(&handle, portWWN);
799 while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
800 status == HBA_STATUS_ERROR_BUSY) {
801 (void) sleep(FCADM_SLEEP_TIME);
802 status = HBA_OpenAdapterByWWN(&handle, portWWN);
803 if (times++ > FCADM_RETRY_TIMES) {
804 return (1);
808 /* Get physical port NPIV attributes */
809 if (retrieveNPIVAttrs(handle, portWWN,
810 &npivattrs, &portIndex) == 0) {
811 /* Check port NPIV attributes */
812 if (npivattrs.MaxNumberOfNPIVPorts == 0) {
813 goto failed;
815 if (npivattrs.MaxNumberOfNPIVPorts ==
816 npivattrs.NumberOfNPIVPorts) {
817 goto failed;
820 /* Create a virtual port */
821 status = Sun_HBA_CreateNPIVPort(handle, portIndex,
822 vnodeWWN, vportWWN, &npivportIndex);
823 times = 0;
824 while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
825 status == HBA_STATUS_ERROR_BUSY) {
826 (void) sleep(FCADM_SLEEP_TIME);
827 status = Sun_HBA_CreateNPIVPort(handle, portIndex,
828 vnodeWWN, vportWWN, &npivportIndex);
829 if (times++ > FCADM_RETRY_TIMES) {
830 goto failed;
835 failed:
836 HBA_CloseAdapter(handle);
838 return (0);
842 fc_util_create_portlist()
844 scf_handle_t *handle = NULL;
845 scf_service_t *svc = NULL;
846 scf_propertygroup_t *pg = NULL;
847 scf_transaction_t *tran = NULL;
848 scf_transaction_entry_t *entry = NULL;
849 scf_property_t *prop = NULL;
850 scf_value_t *valueLookup = NULL;
851 scf_iter_t *valueIter = NULL;
852 char buf[NPIV_PORT_LIST_LENGTH] = {0};
853 int commitRet;
855 commitRet = cfgInit(&handle, &svc);
856 if (commitRet != NPIV_SUCCESS) {
857 goto out;
860 if (((pg = scf_pg_create(handle)) == NULL) ||
861 ((tran = scf_transaction_create(handle)) == NULL) ||
862 ((entry = scf_entry_create(handle)) == NULL) ||
863 ((prop = scf_property_create(handle)) == NULL) ||
864 ((valueIter = scf_iter_create(handle)) == NULL)) {
865 goto out;
868 /* get property group or create it */
869 if (scf_service_get_pg(svc, NPIV_PG_NAME, pg) == -1) {
870 goto out;
873 if (scf_pg_get_property(pg, NPIV_PORT_LIST, prop) == -1) {
874 syslog(LOG_ERR, "get property failed - %s",
875 scf_strerror(scf_error()));
876 goto out;
879 valueLookup = scf_value_create(handle);
880 if (valueLookup == NULL) {
881 syslog(LOG_ERR, "scf value alloc failed - %s",
882 scf_strerror(scf_error()));
883 goto out;
886 if (scf_iter_property_values(valueIter, prop) == -1) {
887 syslog(LOG_ERR, "iter value failed - %s",
888 scf_strerror(scf_error()));
889 goto out;
892 if (HBA_LoadLibrary() != HBA_STATUS_OK) {
893 goto out;
895 HBA_GetNumberOfAdapters();
897 while (scf_iter_next_value(valueIter, valueLookup) == 1) {
898 char ppwwn[17] = {0};
899 char vnwwn[17] = {0};
900 char vpwwn[17] = {0};
901 int vindex = 0;
903 bzero(buf, sizeof (buf));
904 if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
905 syslog(LOG_ERR, "iter value failed - %s",
906 scf_strerror(scf_error()));
907 break;
910 sscanf(buf, "%16s:%16s:%16s:%d", ppwwn, vpwwn, vnwwn, &vindex);
911 create_npivport(ppwwn, vnwwn, vpwwn, vindex);
914 HBA_FreeLibrary();
915 out:
917 * Free resources
919 if (handle != NULL) {
920 scf_handle_destroy(handle);
922 if (svc != NULL) {
923 scf_service_destroy(svc);
925 if (pg != NULL) {
926 scf_pg_destroy(pg);
928 if (tran != NULL) {
929 scf_transaction_destroy(tran);
931 if (entry != NULL) {
932 scf_entry_destroy(entry);
934 if (prop != NULL) {
935 scf_property_destroy(prop);
937 if (valueIter != NULL) {
938 scf_iter_destroy(valueIter);
940 if (valueLookup != NULL) {
941 scf_value_destroy(valueLookup);
944 return (0);
947 /* ARGSUSED */
949 fc_util_force_lip(int objects, char *argv[])
951 uint64_t hbaWWN;
952 HBA_WWN myWWN;
953 HBA_HANDLE handle;
954 HBA_STATUS status;
955 int rval = 0;
957 if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
958 fprintf(stderr, gettext("Failed to load FC-HBA library\n"));
959 printStatus(status);
960 fprintf(stderr, "\n");
961 return (1);
964 sscanf(argv[0], "%016llx", &hbaWWN);
965 hbaWWN = htonll(hbaWWN);
966 memcpy(myWWN.wwn, &hbaWWN, sizeof (hbaWWN));
969 * Try target mode first
971 if ((status = Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN)) !=
972 HBA_STATUS_OK) {
974 * Continue to try initiator mode
976 if ((status = HBA_OpenAdapterByWWN(&handle, myWWN)) !=
977 HBA_STATUS_OK) {
978 fprintf(stderr, gettext("Error: HBA %s not found\n"),
979 argv[0]);
980 return (0);
984 status = Sun_HBA_ForceLip(handle, &rval);
985 if ((status != HBA_STATUS_OK) || (rval != 0)) {
986 fprintf(stderr, gettext("Error: Failed to reinitialize the "
987 "link of HBA %s\n"), argv[0]);
990 return (0);