1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte /*
22*a7949318SReed * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23fcf3ce44SJohn Forte * Use is subject to license terms.
24fcf3ce44SJohn Forte */
25fcf3ce44SJohn Forte
26fcf3ce44SJohn Forte #include <libscf.h>
27fcf3ce44SJohn Forte #include <stdio.h>
28fcf3ce44SJohn Forte #include <stdlib.h>
29fcf3ce44SJohn Forte #include <errno.h>
30fcf3ce44SJohn Forte #include <syslog.h>
31fcf3ce44SJohn Forte #include <strings.h>
32fcf3ce44SJohn Forte #include <ctype.h>
33fcf3ce44SJohn Forte #include <fcinfo.h>
34fcf3ce44SJohn Forte
35fcf3ce44SJohn Forte
36fcf3ce44SJohn Forte #define FCADM_RETRY_TIMES 10
37fcf3ce44SJohn Forte #define FCADM_SLEEP_TIME 1
38fcf3ce44SJohn Forte
39fcf3ce44SJohn Forte static char *
WWN2str(char * buf,HBA_WWN * wwn)40fcf3ce44SJohn Forte WWN2str(char *buf, HBA_WWN *wwn) {
41fcf3ce44SJohn Forte int j;
42fcf3ce44SJohn Forte unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
43fcf3ce44SJohn Forte buf[0] = '\0';
44fcf3ce44SJohn Forte for (j = 0; j < 16; j += 2) {
45fcf3ce44SJohn Forte sprintf(&buf[j], "%02X", (int)*pc++);
46fcf3ce44SJohn Forte }
47fcf3ce44SJohn Forte return (buf);
48fcf3ce44SJohn Forte }
49fcf3ce44SJohn Forte
50fcf3ce44SJohn Forte static int
isValidWWN(char * wwn)51fcf3ce44SJohn Forte isValidWWN(char *wwn)
52fcf3ce44SJohn Forte {
53fcf3ce44SJohn Forte int index;
54fcf3ce44SJohn Forte
55fcf3ce44SJohn Forte if (wwn == NULL) {
56fcf3ce44SJohn Forte return (0);
57fcf3ce44SJohn Forte }
58fcf3ce44SJohn Forte
59fcf3ce44SJohn Forte if (strlen(wwn) != 16) {
60fcf3ce44SJohn Forte return (0);
61fcf3ce44SJohn Forte }
62fcf3ce44SJohn Forte
63fcf3ce44SJohn Forte for (index = 0; index < 16; index++) {
64fcf3ce44SJohn Forte if (isxdigit(wwn[index])) {
65fcf3ce44SJohn Forte continue;
66fcf3ce44SJohn Forte }
67fcf3ce44SJohn Forte return (0);
68fcf3ce44SJohn Forte }
69fcf3ce44SJohn Forte return (1);
70fcf3ce44SJohn Forte }
71fcf3ce44SJohn Forte
72fcf3ce44SJohn Forte
73fcf3ce44SJohn Forte /*
74fcf3ce44SJohn Forte * Initialize scf stmf service access
75fcf3ce44SJohn Forte * handle - returned handle
76fcf3ce44SJohn Forte * service - returned service handle
77fcf3ce44SJohn Forte */
78fcf3ce44SJohn Forte static int
cfgInit(scf_handle_t ** handle,scf_service_t ** service)79fcf3ce44SJohn Forte cfgInit(scf_handle_t **handle, scf_service_t **service)
80fcf3ce44SJohn Forte {
81fcf3ce44SJohn Forte scf_scope_t *scope = NULL;
82fcf3ce44SJohn Forte int ret;
83fcf3ce44SJohn Forte
84fcf3ce44SJohn Forte if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
85fcf3ce44SJohn Forte /* log error */
86fcf3ce44SJohn Forte ret = NPIV_ERROR;
87fcf3ce44SJohn Forte goto err;
88fcf3ce44SJohn Forte }
89fcf3ce44SJohn Forte
90fcf3ce44SJohn Forte if (scf_handle_bind(*handle) == -1) {
91fcf3ce44SJohn Forte /* log error */
92fcf3ce44SJohn Forte ret = NPIV_ERROR;
93fcf3ce44SJohn Forte goto err;
94fcf3ce44SJohn Forte }
95fcf3ce44SJohn Forte
96fcf3ce44SJohn Forte if ((*service = scf_service_create(*handle)) == NULL) {
97fcf3ce44SJohn Forte /* log error */
98fcf3ce44SJohn Forte ret = NPIV_ERROR;
99fcf3ce44SJohn Forte goto err;
100fcf3ce44SJohn Forte }
101fcf3ce44SJohn Forte
102fcf3ce44SJohn Forte if ((scope = scf_scope_create(*handle)) == NULL) {
103fcf3ce44SJohn Forte /* log error */
104fcf3ce44SJohn Forte ret = NPIV_ERROR;
105fcf3ce44SJohn Forte goto err;
106fcf3ce44SJohn Forte }
107fcf3ce44SJohn Forte
108fcf3ce44SJohn Forte if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
109fcf3ce44SJohn Forte /* log error */
110fcf3ce44SJohn Forte ret = NPIV_ERROR;
111fcf3ce44SJohn Forte goto err;
112fcf3ce44SJohn Forte }
113fcf3ce44SJohn Forte
114fcf3ce44SJohn Forte if (scf_scope_get_service(scope, NPIV_SERVICE, *service) == -1) {
115fcf3ce44SJohn Forte /* log error */
116fcf3ce44SJohn Forte ret = NPIV_ERROR_SERVICE_NOT_FOUND;
117fcf3ce44SJohn Forte goto err;
118fcf3ce44SJohn Forte }
119fcf3ce44SJohn Forte
120fcf3ce44SJohn Forte scf_scope_destroy(scope);
121fcf3ce44SJohn Forte
122fcf3ce44SJohn Forte return (NPIV_SUCCESS);
123fcf3ce44SJohn Forte
124fcf3ce44SJohn Forte err:
125fcf3ce44SJohn Forte if (*handle != NULL) {
126fcf3ce44SJohn Forte scf_handle_destroy(*handle);
127fcf3ce44SJohn Forte }
128fcf3ce44SJohn Forte if (*service != NULL) {
129fcf3ce44SJohn Forte scf_service_destroy(*service);
130fcf3ce44SJohn Forte *service = NULL;
131fcf3ce44SJohn Forte }
132fcf3ce44SJohn Forte if (scope != NULL) {
133fcf3ce44SJohn Forte scf_scope_destroy(scope);
134fcf3ce44SJohn Forte }
135fcf3ce44SJohn Forte return (ret);
136fcf3ce44SJohn Forte }
137fcf3ce44SJohn Forte
138fcf3ce44SJohn Forte static int
npivAddRemoveNPIVEntry(char * ppwwn,char * vnwwn,char * vpwwn,int vindex,int addRemoveFlag)139fcf3ce44SJohn Forte npivAddRemoveNPIVEntry(char *ppwwn, char *vnwwn,
140fcf3ce44SJohn Forte char *vpwwn, int vindex, int addRemoveFlag) {
141fcf3ce44SJohn Forte scf_handle_t *handle = NULL;
142fcf3ce44SJohn Forte scf_service_t *svc = NULL;
143fcf3ce44SJohn Forte scf_propertygroup_t *pg = NULL;
144fcf3ce44SJohn Forte scf_transaction_t *tran = NULL;
145fcf3ce44SJohn Forte scf_transaction_entry_t *entry = NULL;
146fcf3ce44SJohn Forte scf_property_t *prop = NULL;
147fcf3ce44SJohn Forte scf_value_t *valueLookup = NULL;
148fcf3ce44SJohn Forte scf_iter_t *valueIter = NULL;
149fcf3ce44SJohn Forte scf_value_t **valueSet = NULL;
150fcf3ce44SJohn Forte int ret = NPIV_SUCCESS;
151fcf3ce44SJohn Forte boolean_t createProp = B_FALSE;
152fcf3ce44SJohn Forte int lastAlloc = 0;
153fcf3ce44SJohn Forte char buf[NPIV_PORT_LIST_LENGTH] = {0};
154fcf3ce44SJohn Forte char memberName[NPIV_PORT_LIST_LENGTH] = {0};
155fcf3ce44SJohn Forte boolean_t found = B_FALSE;
156fcf3ce44SJohn Forte int i = 0;
157fcf3ce44SJohn Forte int valueArraySize = 0;
158fcf3ce44SJohn Forte int commitRet;
159fcf3ce44SJohn Forte
160fcf3ce44SJohn Forte if (vnwwn) {
161fcf3ce44SJohn Forte sprintf(memberName, "%s:%s:%s:%d", ppwwn, vpwwn, vnwwn, vindex);
162fcf3ce44SJohn Forte } else {
163fcf3ce44SJohn Forte sprintf(memberName, "%s:%s", ppwwn, vpwwn);
164fcf3ce44SJohn Forte }
165fcf3ce44SJohn Forte
166fcf3ce44SJohn Forte ret = cfgInit(&handle, &svc);
167fcf3ce44SJohn Forte if (ret != NPIV_SUCCESS) {
168fcf3ce44SJohn Forte goto out;
169fcf3ce44SJohn Forte }
170fcf3ce44SJohn Forte
171fcf3ce44SJohn Forte if (((pg = scf_pg_create(handle)) == NULL) ||
172fcf3ce44SJohn Forte ((tran = scf_transaction_create(handle)) == NULL) ||
173fcf3ce44SJohn Forte ((entry = scf_entry_create(handle)) == NULL) ||
174fcf3ce44SJohn Forte ((prop = scf_property_create(handle)) == NULL) ||
175fcf3ce44SJohn Forte ((valueIter = scf_iter_create(handle)) == NULL)) {
176fcf3ce44SJohn Forte ret = NPIV_ERROR;
177fcf3ce44SJohn Forte goto out;
178fcf3ce44SJohn Forte }
179fcf3ce44SJohn Forte
180fcf3ce44SJohn Forte /* get property group or create it */
181fcf3ce44SJohn Forte if (scf_service_get_pg(svc, NPIV_PG_NAME, pg) == -1) {
182fcf3ce44SJohn Forte if ((scf_error() == SCF_ERROR_NOT_FOUND) &&
183fcf3ce44SJohn Forte (addRemoveFlag == NPIV_ADD)) {
184fcf3ce44SJohn Forte if (scf_service_add_pg(svc, NPIV_PG_NAME,
185fcf3ce44SJohn Forte SCF_GROUP_APPLICATION, 0, pg) == -1) {
186fcf3ce44SJohn Forte syslog(LOG_ERR, "add pg failed - %s",
187fcf3ce44SJohn Forte scf_strerror(scf_error()));
188fcf3ce44SJohn Forte ret = NPIV_ERROR;
189fcf3ce44SJohn Forte } else {
190fcf3ce44SJohn Forte createProp = B_TRUE;
191fcf3ce44SJohn Forte }
192fcf3ce44SJohn Forte } else if (scf_error() == SCF_ERROR_NOT_FOUND) {
193fcf3ce44SJohn Forte ret = NPIV_ERROR_NOT_FOUND;
194fcf3ce44SJohn Forte } else {
195fcf3ce44SJohn Forte syslog(LOG_ERR, "get pg failed - %s",
196fcf3ce44SJohn Forte scf_strerror(scf_error()));
197fcf3ce44SJohn Forte ret = NPIV_ERROR;
198fcf3ce44SJohn Forte }
199fcf3ce44SJohn Forte if (ret != NPIV_SUCCESS) {
200fcf3ce44SJohn Forte goto out;
201fcf3ce44SJohn Forte }
202fcf3ce44SJohn Forte }
203fcf3ce44SJohn Forte
204fcf3ce44SJohn Forte /* Begin the transaction */
205fcf3ce44SJohn Forte if (scf_transaction_start(tran, pg) == -1) {
206fcf3ce44SJohn Forte syslog(LOG_ERR, "start transaction failed - %s",
207fcf3ce44SJohn Forte scf_strerror(scf_error()));
208fcf3ce44SJohn Forte ret = NPIV_ERROR;
209fcf3ce44SJohn Forte goto out;
210fcf3ce44SJohn Forte }
211fcf3ce44SJohn Forte
212fcf3ce44SJohn Forte valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
213fcf3ce44SJohn Forte * (lastAlloc = PORT_LIST_ALLOC));
214fcf3ce44SJohn Forte if (valueSet == NULL) {
215fcf3ce44SJohn Forte ret = NPIV_ERROR_NOMEM;
216fcf3ce44SJohn Forte goto out;
217fcf3ce44SJohn Forte }
218fcf3ce44SJohn Forte
219fcf3ce44SJohn Forte if (createProp) {
220fcf3ce44SJohn Forte if (scf_transaction_property_new(tran, entry, NPIV_PORT_LIST,
221fcf3ce44SJohn Forte SCF_TYPE_USTRING) == -1) {
222fcf3ce44SJohn Forte if (scf_error() == SCF_ERROR_EXISTS) {
223fcf3ce44SJohn Forte ret = NPIV_ERROR_EXISTS;
224fcf3ce44SJohn Forte } else {
225fcf3ce44SJohn Forte syslog(LOG_ERR,
226fcf3ce44SJohn Forte "transaction property new failed - %s",
227fcf3ce44SJohn Forte scf_strerror(scf_error()));
228fcf3ce44SJohn Forte ret = NPIV_ERROR;
229fcf3ce44SJohn Forte }
230fcf3ce44SJohn Forte goto out;
231fcf3ce44SJohn Forte }
232fcf3ce44SJohn Forte } else {
233fcf3ce44SJohn Forte if (scf_transaction_property_change(tran, entry,
234fcf3ce44SJohn Forte NPIV_PORT_LIST, SCF_TYPE_USTRING) == -1) {
235fcf3ce44SJohn Forte syslog(LOG_ERR,
236fcf3ce44SJohn Forte "transaction property change failed - %s",
237fcf3ce44SJohn Forte scf_strerror(scf_error()));
238fcf3ce44SJohn Forte ret = NPIV_ERROR;
239fcf3ce44SJohn Forte goto out;
240fcf3ce44SJohn Forte }
241fcf3ce44SJohn Forte
242fcf3ce44SJohn Forte if (scf_pg_get_property(pg, NPIV_PORT_LIST, prop) == -1) {
243fcf3ce44SJohn Forte syslog(LOG_ERR, "get property failed - %s",
244fcf3ce44SJohn Forte scf_strerror(scf_error()));
245fcf3ce44SJohn Forte ret = NPIV_ERROR;
246fcf3ce44SJohn Forte goto out;
247fcf3ce44SJohn Forte }
248fcf3ce44SJohn Forte
249fcf3ce44SJohn Forte valueLookup = scf_value_create(handle);
250fcf3ce44SJohn Forte if (valueLookup == NULL) {
251fcf3ce44SJohn Forte syslog(LOG_ERR, "scf value alloc failed - %s",
252fcf3ce44SJohn Forte scf_strerror(scf_error()));
253fcf3ce44SJohn Forte ret = NPIV_ERROR;
254fcf3ce44SJohn Forte goto out;
255fcf3ce44SJohn Forte }
256fcf3ce44SJohn Forte
257fcf3ce44SJohn Forte if (scf_iter_property_values(valueIter, prop) == -1) {
258fcf3ce44SJohn Forte syslog(LOG_ERR, "iter value failed - %s",
259fcf3ce44SJohn Forte scf_strerror(scf_error()));
260fcf3ce44SJohn Forte ret = NPIV_ERROR;
261fcf3ce44SJohn Forte goto out;
262fcf3ce44SJohn Forte }
263fcf3ce44SJohn Forte
264fcf3ce44SJohn Forte while (scf_iter_next_value(valueIter, valueLookup) == 1) {
265fcf3ce44SJohn Forte bzero(buf, sizeof (buf));
266fcf3ce44SJohn Forte if (scf_value_get_ustring(valueLookup,
267fcf3ce44SJohn Forte buf, MAXNAMELEN) == -1) {
268fcf3ce44SJohn Forte syslog(LOG_ERR, "iter value failed - %s",
269fcf3ce44SJohn Forte scf_strerror(scf_error()));
270fcf3ce44SJohn Forte ret = NPIV_ERROR;
271fcf3ce44SJohn Forte break;
272fcf3ce44SJohn Forte }
273fcf3ce44SJohn Forte
274fcf3ce44SJohn Forte if ((strlen(buf) >= strlen(memberName)) &&
275fcf3ce44SJohn Forte bcmp(buf, memberName, strlen(memberName)) == 0) {
276fcf3ce44SJohn Forte if (addRemoveFlag == NPIV_ADD) {
277fcf3ce44SJohn Forte ret = NPIV_ERROR_EXISTS;
278fcf3ce44SJohn Forte break;
279fcf3ce44SJohn Forte } else {
280fcf3ce44SJohn Forte found = B_TRUE;
281fcf3ce44SJohn Forte continue;
282fcf3ce44SJohn Forte }
283fcf3ce44SJohn Forte }
284fcf3ce44SJohn Forte
285fcf3ce44SJohn Forte valueSet[i] = scf_value_create(handle);
286fcf3ce44SJohn Forte if (valueSet[i] == NULL) {
287fcf3ce44SJohn Forte syslog(LOG_ERR, "scf value alloc failed - %s",
288fcf3ce44SJohn Forte scf_strerror(scf_error()));
289fcf3ce44SJohn Forte ret = NPIV_ERROR;
290fcf3ce44SJohn Forte break;
291fcf3ce44SJohn Forte }
292fcf3ce44SJohn Forte
293fcf3ce44SJohn Forte if (scf_value_set_ustring(valueSet[i], buf) == -1) {
294fcf3ce44SJohn Forte syslog(LOG_ERR, "set value failed - %s",
295fcf3ce44SJohn Forte scf_strerror(scf_error()));
296fcf3ce44SJohn Forte ret = NPIV_ERROR;
297fcf3ce44SJohn Forte break;
298fcf3ce44SJohn Forte }
299fcf3ce44SJohn Forte
300fcf3ce44SJohn Forte if (scf_entry_add_value(entry, valueSet[i]) == -1) {
301fcf3ce44SJohn Forte syslog(LOG_ERR, "add value failed - %s",
302fcf3ce44SJohn Forte scf_strerror(scf_error()));
303fcf3ce44SJohn Forte ret = NPIV_ERROR;
304fcf3ce44SJohn Forte break;
305fcf3ce44SJohn Forte }
306fcf3ce44SJohn Forte
307fcf3ce44SJohn Forte i++;
308fcf3ce44SJohn Forte
309fcf3ce44SJohn Forte if (i >= lastAlloc) {
310fcf3ce44SJohn Forte lastAlloc += PORT_LIST_ALLOC;
311fcf3ce44SJohn Forte valueSet = realloc(valueSet,
312fcf3ce44SJohn Forte sizeof (*valueSet) * lastAlloc);
313fcf3ce44SJohn Forte if (valueSet == NULL) {
314fcf3ce44SJohn Forte ret = NPIV_ERROR;
315fcf3ce44SJohn Forte break;
316fcf3ce44SJohn Forte }
317fcf3ce44SJohn Forte }
318fcf3ce44SJohn Forte }
319fcf3ce44SJohn Forte }
320fcf3ce44SJohn Forte
321fcf3ce44SJohn Forte valueArraySize = i;
322fcf3ce44SJohn Forte if (!found && (addRemoveFlag == NPIV_REMOVE)) {
323fcf3ce44SJohn Forte ret = NPIV_ERROR_MEMBER_NOT_FOUND;
324fcf3ce44SJohn Forte }
325fcf3ce44SJohn Forte if (ret != NPIV_SUCCESS) {
326fcf3ce44SJohn Forte goto out;
327fcf3ce44SJohn Forte }
328fcf3ce44SJohn Forte
329fcf3ce44SJohn Forte if (addRemoveFlag == NPIV_ADD) {
330fcf3ce44SJohn Forte /*
331fcf3ce44SJohn Forte * Now create the new entry
332fcf3ce44SJohn Forte */
333fcf3ce44SJohn Forte valueSet[i] = scf_value_create(handle);
334fcf3ce44SJohn Forte if (valueSet[i] == NULL) {
335fcf3ce44SJohn Forte syslog(LOG_ERR, "scf value alloc failed - %s",
336fcf3ce44SJohn Forte scf_strerror(scf_error()));
337fcf3ce44SJohn Forte ret = NPIV_ERROR;
338fcf3ce44SJohn Forte goto out;
339fcf3ce44SJohn Forte } else {
340fcf3ce44SJohn Forte valueArraySize++;
341fcf3ce44SJohn Forte }
342fcf3ce44SJohn Forte
343fcf3ce44SJohn Forte /*
344fcf3ce44SJohn Forte * Set the new member name
345fcf3ce44SJohn Forte */
346fcf3ce44SJohn Forte if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
347fcf3ce44SJohn Forte syslog(LOG_ERR, "set value failed - %s",
348fcf3ce44SJohn Forte scf_strerror(scf_error()));
349fcf3ce44SJohn Forte ret = NPIV_ERROR;
350fcf3ce44SJohn Forte goto out;
351fcf3ce44SJohn Forte }
352fcf3ce44SJohn Forte
353fcf3ce44SJohn Forte /*
354fcf3ce44SJohn Forte * Add the new member
355fcf3ce44SJohn Forte */
356fcf3ce44SJohn Forte if (scf_entry_add_value(entry, valueSet[i]) == -1) {
357fcf3ce44SJohn Forte syslog(LOG_ERR, "add value failed - %s",
358fcf3ce44SJohn Forte scf_strerror(scf_error()));
359fcf3ce44SJohn Forte ret = NPIV_ERROR;
360fcf3ce44SJohn Forte goto out;
361fcf3ce44SJohn Forte }
362fcf3ce44SJohn Forte }
363fcf3ce44SJohn Forte
364fcf3ce44SJohn Forte if ((commitRet = scf_transaction_commit(tran)) != 1) {
365fcf3ce44SJohn Forte syslog(LOG_ERR, "transaction commit failed - %s",
366fcf3ce44SJohn Forte scf_strerror(scf_error()));
367fcf3ce44SJohn Forte if (commitRet == 0) {
368fcf3ce44SJohn Forte ret = NPIV_ERROR_BUSY;
369fcf3ce44SJohn Forte } else {
370fcf3ce44SJohn Forte ret = NPIV_ERROR;
371fcf3ce44SJohn Forte }
372fcf3ce44SJohn Forte goto out;
373fcf3ce44SJohn Forte }
374fcf3ce44SJohn Forte
375fcf3ce44SJohn Forte out:
376fcf3ce44SJohn Forte /*
377fcf3ce44SJohn Forte * Free resources
378fcf3ce44SJohn Forte */
379fcf3ce44SJohn Forte if (handle != NULL) {
380fcf3ce44SJohn Forte scf_handle_destroy(handle);
381fcf3ce44SJohn Forte }
382fcf3ce44SJohn Forte if (svc != NULL) {
383fcf3ce44SJohn Forte scf_service_destroy(svc);
384fcf3ce44SJohn Forte }
385fcf3ce44SJohn Forte if (pg != NULL) {
386fcf3ce44SJohn Forte scf_pg_destroy(pg);
387fcf3ce44SJohn Forte }
388fcf3ce44SJohn Forte if (tran != NULL) {
389fcf3ce44SJohn Forte scf_transaction_destroy(tran);
390fcf3ce44SJohn Forte }
391fcf3ce44SJohn Forte if (entry != NULL) {
392fcf3ce44SJohn Forte scf_entry_destroy(entry);
393fcf3ce44SJohn Forte }
394fcf3ce44SJohn Forte if (prop != NULL) {
395fcf3ce44SJohn Forte scf_property_destroy(prop);
396fcf3ce44SJohn Forte }
397fcf3ce44SJohn Forte if (valueIter != NULL) {
398fcf3ce44SJohn Forte scf_iter_destroy(valueIter);
399fcf3ce44SJohn Forte }
400fcf3ce44SJohn Forte if (valueLookup != NULL) {
401fcf3ce44SJohn Forte scf_value_destroy(valueLookup);
402fcf3ce44SJohn Forte }
403fcf3ce44SJohn Forte
404fcf3ce44SJohn Forte /*
405fcf3ce44SJohn Forte * Free valueSet scf resources
406fcf3ce44SJohn Forte */
407fcf3ce44SJohn Forte if (valueArraySize > 0) {
408fcf3ce44SJohn Forte for (i = 0; i < valueArraySize; i++) {
409fcf3ce44SJohn Forte scf_value_destroy(valueSet[i]);
410fcf3ce44SJohn Forte }
411fcf3ce44SJohn Forte }
412fcf3ce44SJohn Forte /*
413fcf3ce44SJohn Forte * Now free the pointer array to the resources
414fcf3ce44SJohn Forte */
415fcf3ce44SJohn Forte if (valueSet != NULL) {
416fcf3ce44SJohn Forte free(valueSet);
417fcf3ce44SJohn Forte }
418fcf3ce44SJohn Forte
419fcf3ce44SJohn Forte return (ret);
420fcf3ce44SJohn Forte }
421fcf3ce44SJohn Forte
422fcf3ce44SJohn Forte static int
retrieveNPIVAttrs(HBA_HANDLE handle,HBA_WWN portWWN,HBA_PORTNPIVATTRIBUTES * npivattrs,HBA_UINT32 * portIndex)423fcf3ce44SJohn Forte retrieveNPIVAttrs(HBA_HANDLE handle, HBA_WWN portWWN,
424fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES *npivattrs, HBA_UINT32 *portIndex) {
425fcf3ce44SJohn Forte HBA_STATUS status;
426fcf3ce44SJohn Forte HBA_ADAPTERATTRIBUTES attrs;
427fcf3ce44SJohn Forte HBA_PORTATTRIBUTES portattrs;
428fcf3ce44SJohn Forte int portCtr;
429fcf3ce44SJohn Forte int times = 0;
430fcf3ce44SJohn Forte
431fcf3ce44SJohn Forte /* argument checking */
432fcf3ce44SJohn Forte if (npivattrs == NULL || portIndex == NULL) {
433fcf3ce44SJohn Forte return (1);
434fcf3ce44SJohn Forte }
435fcf3ce44SJohn Forte
436fcf3ce44SJohn Forte memset(&attrs, 0, sizeof (HBA_ADAPTERATTRIBUTES));
437fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, &attrs);
438fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
439fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) &&
440fcf3ce44SJohn Forte times++ < 130) {
441fcf3ce44SJohn Forte status = HBA_GetAdapterAttributes(handle, &attrs);
442fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) {
443fcf3ce44SJohn Forte break;
444fcf3ce44SJohn Forte }
445fcf3ce44SJohn Forte (void) sleep(1);
446fcf3ce44SJohn Forte }
447fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
448fcf3ce44SJohn Forte return (1);
449fcf3ce44SJohn Forte }
450fcf3ce44SJohn Forte
451fcf3ce44SJohn Forte memset(&portattrs, 0, sizeof (HBA_PORTATTRIBUTES));
452fcf3ce44SJohn Forte for (portCtr = 0; portCtr < attrs.NumberOfPorts; portCtr++) {
453fcf3ce44SJohn Forte status = HBA_GetAdapterPortAttributes(handle,
454fcf3ce44SJohn Forte portCtr, &portattrs);
455fcf3ce44SJohn Forte times = 0;
456fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
457fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) &&
458fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) {
459fcf3ce44SJohn Forte status = HBA_GetAdapterPortAttributes(handle,
460fcf3ce44SJohn Forte portCtr, &portattrs);
461fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) {
462fcf3ce44SJohn Forte break;
463fcf3ce44SJohn Forte }
464fcf3ce44SJohn Forte (void) sleep(1);
465fcf3ce44SJohn Forte }
466fcf3ce44SJohn Forte
467fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
468fcf3ce44SJohn Forte return (1);
469fcf3ce44SJohn Forte }
470fcf3ce44SJohn Forte
471fcf3ce44SJohn Forte if (memcmp(portWWN.wwn, portattrs.PortWWN.wwn,
472fcf3ce44SJohn Forte sizeof (portattrs.PortWWN.wwn)) == 0) {
473fcf3ce44SJohn Forte break;
474fcf3ce44SJohn Forte }
475fcf3ce44SJohn Forte }
476fcf3ce44SJohn Forte if (portCtr >= attrs.NumberOfPorts) {
477fcf3ce44SJohn Forte *portIndex = 0;
478fcf3ce44SJohn Forte return (1);
479fcf3ce44SJohn Forte }
480fcf3ce44SJohn Forte *portIndex = portCtr;
481fcf3ce44SJohn Forte
482fcf3ce44SJohn Forte status = Sun_HBA_GetPortNPIVAttributes(handle, portCtr, npivattrs);
483fcf3ce44SJohn Forte times = 0;
484fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
485fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) &&
486fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) {
487fcf3ce44SJohn Forte status = Sun_HBA_GetPortNPIVAttributes(handle,
488fcf3ce44SJohn Forte portCtr, npivattrs);
489fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) {
490fcf3ce44SJohn Forte break;
491fcf3ce44SJohn Forte }
492fcf3ce44SJohn Forte (void) sleep(1);
493fcf3ce44SJohn Forte }
494fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
495fcf3ce44SJohn Forte return (1);
496fcf3ce44SJohn Forte }
497fcf3ce44SJohn Forte
498fcf3ce44SJohn Forte return (0);
499fcf3ce44SJohn Forte }
500fcf3ce44SJohn Forte
501fcf3ce44SJohn Forte
502fcf3ce44SJohn Forte int
fc_util_delete_npivport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)503fcf3ce44SJohn Forte fc_util_delete_npivport(int wwnCount, char **wwn_argv,
504fcf3ce44SJohn Forte cmdOptions_t *options)
505fcf3ce44SJohn Forte {
506fcf3ce44SJohn Forte uint64_t physicalportWWN, virtualportWWN;
507fcf3ce44SJohn Forte HBA_WWN portWWN, vportWWN;
508fcf3ce44SJohn Forte HBA_STATUS status;
509fcf3ce44SJohn Forte HBA_HANDLE handle;
510fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES npivattrs;
511fcf3ce44SJohn Forte HBA_UINT32 portIndex;
512fcf3ce44SJohn Forte char pwwn[17];
513fcf3ce44SJohn Forte int times;
514fcf3ce44SJohn Forte
515fcf3ce44SJohn Forte if (wwnCount != 1) {
516fcf3ce44SJohn Forte fprintf(stderr,
517fcf3ce44SJohn Forte gettext("Invalid Parameter\n"));
518fcf3ce44SJohn Forte return (1);
519fcf3ce44SJohn Forte }
520fcf3ce44SJohn Forte
521fcf3ce44SJohn Forte for (; options->optval; options++) {
522fcf3ce44SJohn Forte switch (options->optval) {
523fcf3ce44SJohn Forte case 'p':
524fcf3ce44SJohn Forte if (!isValidWWN(options->optarg)) {
525fcf3ce44SJohn Forte fprintf(stderr,
526fcf3ce44SJohn Forte gettext("Invalid Port WWN\n"));
527fcf3ce44SJohn Forte return (1);
528fcf3ce44SJohn Forte }
529fcf3ce44SJohn Forte sscanf(options->optarg, "%016llx", &virtualportWWN);
530fcf3ce44SJohn Forte break;
531fcf3ce44SJohn Forte default:
532fcf3ce44SJohn Forte return (1);
533fcf3ce44SJohn Forte }
534fcf3ce44SJohn Forte }
535fcf3ce44SJohn Forte
536fcf3ce44SJohn Forte if (!isValidWWN(wwn_argv[0])) {
537fcf3ce44SJohn Forte fprintf(stderr,
538fcf3ce44SJohn Forte gettext("Invalid Physical Port WWN\n"));
539fcf3ce44SJohn Forte return (1);
540fcf3ce44SJohn Forte }
541fcf3ce44SJohn Forte
542fcf3ce44SJohn Forte if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
543fcf3ce44SJohn Forte fprintf(stderr,
544fcf3ce44SJohn Forte gettext("Failed to load FC-HBA common library\n"));
545fcf3ce44SJohn Forte printStatus(status);
546fcf3ce44SJohn Forte fprintf(stderr, "\n");
547fcf3ce44SJohn Forte return (1);
548fcf3ce44SJohn Forte }
549fcf3ce44SJohn Forte sscanf(wwn_argv[0], "%016llx", &physicalportWWN);
550fcf3ce44SJohn Forte physicalportWWN = htonll(physicalportWWN);
551fcf3ce44SJohn Forte memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
552fcf3ce44SJohn Forte
553fcf3ce44SJohn Forte virtualportWWN = htonll(virtualportWWN);
554fcf3ce44SJohn Forte memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
555fcf3ce44SJohn Forte
556fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, portWWN);
557fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
558fcf3ce44SJohn Forte fprintf(stderr,
559fcf3ce44SJohn Forte gettext("Error: HBA port %s: not found\n"),
560fcf3ce44SJohn Forte wwn_argv[0]);
561fcf3ce44SJohn Forte HBA_FreeLibrary();
562fcf3ce44SJohn Forte return (1);
563fcf3ce44SJohn Forte }
564fcf3ce44SJohn Forte
565fcf3ce44SJohn Forte /* Get physical port NPIV attributes */
566fcf3ce44SJohn Forte if (retrieveNPIVAttrs(handle, portWWN, &npivattrs, &portIndex) == 0) {
567fcf3ce44SJohn Forte /* Check port NPIV attributes */
568fcf3ce44SJohn Forte if (npivattrs.MaxNumberOfNPIVPorts == 0) {
569fcf3ce44SJohn Forte fprintf(stderr,
570fcf3ce44SJohn Forte gettext("Error: NPIV not Supported\n"));
571fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
572fcf3ce44SJohn Forte HBA_FreeLibrary();
573fcf3ce44SJohn Forte return (1);
574fcf3ce44SJohn Forte }
575fcf3ce44SJohn Forte
576fcf3ce44SJohn Forte /* Delete a virtual port */
577fcf3ce44SJohn Forte status = Sun_HBA_DeleteNPIVPort(handle, portIndex,
578fcf3ce44SJohn Forte vportWWN);
579fcf3ce44SJohn Forte times = 0;
580fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
581fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) &&
582fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) {
583fcf3ce44SJohn Forte (void) sleep(1);
584fcf3ce44SJohn Forte status = Sun_HBA_DeleteNPIVPort(handle, portIndex,
585fcf3ce44SJohn Forte vportWWN);
586fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) {
587fcf3ce44SJohn Forte break;
588fcf3ce44SJohn Forte }
589fcf3ce44SJohn Forte }
590fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
591fcf3ce44SJohn Forte fprintf(stderr,
592fcf3ce44SJohn Forte gettext("Error: failed to delete a npiv port\n"));
593fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
594fcf3ce44SJohn Forte HBA_FreeLibrary();
595fcf3ce44SJohn Forte return (1);
596fcf3ce44SJohn Forte }
597fcf3ce44SJohn Forte } else {
598fcf3ce44SJohn Forte fprintf(stderr,
599fcf3ce44SJohn Forte gettext("Error: failed to get port NPIV attributes\n"));
600fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
601fcf3ce44SJohn Forte HBA_FreeLibrary();
602fcf3ce44SJohn Forte return (1);
603fcf3ce44SJohn Forte }
604fcf3ce44SJohn Forte
605fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
606fcf3ce44SJohn Forte HBA_FreeLibrary();
607fcf3ce44SJohn Forte
608fcf3ce44SJohn Forte WWN2str(pwwn, &vportWWN);
609fcf3ce44SJohn Forte npivAddRemoveNPIVEntry(wwn_argv[0],
610fcf3ce44SJohn Forte NULL, pwwn, 0, NPIV_REMOVE);
611fcf3ce44SJohn Forte
612fcf3ce44SJohn Forte return (0);
613fcf3ce44SJohn Forte }
614fcf3ce44SJohn Forte
615fcf3ce44SJohn Forte int
fc_util_create_npivport(int wwnCount,char ** wwn_argv,cmdOptions_t * options)616fcf3ce44SJohn Forte fc_util_create_npivport(int wwnCount,
617fcf3ce44SJohn Forte char **wwn_argv, cmdOptions_t *options)
618fcf3ce44SJohn Forte {
619fcf3ce44SJohn Forte uint64_t physicalportWWN, virtualnodeWWN, virtualportWWN;
620fcf3ce44SJohn Forte HBA_WWN portWWN, vnodeWWN, vportWWN;
621fcf3ce44SJohn Forte HBA_STATUS status;
622fcf3ce44SJohn Forte HBA_HANDLE handle;
623fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES npivattrs;
624fcf3ce44SJohn Forte HBA_UINT32 portIndex;
625fcf3ce44SJohn Forte HBA_UINT32 npivportIndex = 0;
626fcf3ce44SJohn Forte char nwwn[17], pwwn[17];
627fcf3ce44SJohn Forte int randomflag = 0;
628fcf3ce44SJohn Forte int times;
629fcf3ce44SJohn Forte
630fcf3ce44SJohn Forte if (wwnCount != 1) {
631fcf3ce44SJohn Forte fprintf(stderr,
632fcf3ce44SJohn Forte gettext("Invalid Parameter\n"));
633fcf3ce44SJohn Forte return (1);
634fcf3ce44SJohn Forte }
635fcf3ce44SJohn Forte
636fcf3ce44SJohn Forte for (; options->optval; options++) {
637fcf3ce44SJohn Forte switch (options->optval) {
638fcf3ce44SJohn Forte case 'p':
639fcf3ce44SJohn Forte if (!isValidWWN(options->optarg)) {
640fcf3ce44SJohn Forte fprintf(stderr,
641fcf3ce44SJohn Forte gettext("Invalid Port WWN\n"));
642fcf3ce44SJohn Forte return (1);
643fcf3ce44SJohn Forte }
644fcf3ce44SJohn Forte sscanf(options->optarg, "%016llx", &virtualportWWN);
645fcf3ce44SJohn Forte randomflag++;
646fcf3ce44SJohn Forte break;
647fcf3ce44SJohn Forte case 'n':
648fcf3ce44SJohn Forte if (!isValidWWN(options->optarg)) {
649fcf3ce44SJohn Forte fprintf(stderr,
650fcf3ce44SJohn Forte gettext("Invalid Node WWN\n"));
651fcf3ce44SJohn Forte return (1);
652fcf3ce44SJohn Forte }
653fcf3ce44SJohn Forte sscanf(options->optarg, "%016llx", &virtualnodeWWN);
654fcf3ce44SJohn Forte randomflag++;
655fcf3ce44SJohn Forte break;
656fcf3ce44SJohn Forte default:
657fcf3ce44SJohn Forte return (1);
658fcf3ce44SJohn Forte }
659fcf3ce44SJohn Forte }
660fcf3ce44SJohn Forte
661fcf3ce44SJohn Forte if (!isValidWWN(wwn_argv[0])) {
662fcf3ce44SJohn Forte fprintf(stderr,
663fcf3ce44SJohn Forte gettext("Invalid Physical Port WWN\n"));
664fcf3ce44SJohn Forte wwnCount = 0;
665fcf3ce44SJohn Forte return (1);
666fcf3ce44SJohn Forte }
667fcf3ce44SJohn Forte
668fcf3ce44SJohn Forte if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
669fcf3ce44SJohn Forte fprintf(stderr,
670fcf3ce44SJohn Forte gettext("Failed to load FC-HBA common library\n"));
671fcf3ce44SJohn Forte printStatus(status);
672fcf3ce44SJohn Forte fprintf(stderr, "\n");
673fcf3ce44SJohn Forte return (1);
674fcf3ce44SJohn Forte }
675fcf3ce44SJohn Forte
676fcf3ce44SJohn Forte sscanf(wwn_argv[0], "%016llx", &physicalportWWN);
677fcf3ce44SJohn Forte physicalportWWN = htonll(physicalportWWN);
678fcf3ce44SJohn Forte memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
679fcf3ce44SJohn Forte
680fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, portWWN);
681fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
682fcf3ce44SJohn Forte fprintf(stderr,
683fcf3ce44SJohn Forte gettext("Error: HBA port %s: not found\n"),
684fcf3ce44SJohn Forte wwn_argv[0]);
685fcf3ce44SJohn Forte HBA_FreeLibrary();
686fcf3ce44SJohn Forte return (1);
687fcf3ce44SJohn Forte }
688fcf3ce44SJohn Forte
689fcf3ce44SJohn Forte if (randomflag != 2) {
690fcf3ce44SJohn Forte status = Sun_HBA_AdapterCreateWWN(handle, 0,
691fcf3ce44SJohn Forte &vnodeWWN, &vportWWN, NULL, HBA_CREATE_WWN_RANDOM);
692fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
693fcf3ce44SJohn Forte fprintf(stderr,
694fcf3ce44SJohn Forte gettext("Error: Fail to get Random WWN\n"));
695fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
696fcf3ce44SJohn Forte HBA_FreeLibrary();
697fcf3ce44SJohn Forte return (1);
698fcf3ce44SJohn Forte }
699fcf3ce44SJohn Forte } else {
700fcf3ce44SJohn Forte virtualnodeWWN = htonll(virtualnodeWWN);
701fcf3ce44SJohn Forte memcpy(vnodeWWN.wwn, &virtualnodeWWN, sizeof (virtualnodeWWN));
702fcf3ce44SJohn Forte virtualportWWN = htonll(virtualportWWN);
703fcf3ce44SJohn Forte memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
704fcf3ce44SJohn Forte }
705fcf3ce44SJohn Forte
706fcf3ce44SJohn Forte if (memcmp(vnodeWWN.wwn, vportWWN.wwn, 8) == 0) {
707fcf3ce44SJohn Forte fprintf(stderr,
708fcf3ce44SJohn Forte gettext("Error: Port WWN is same as Node WWN\n"));
709fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
710fcf3ce44SJohn Forte HBA_FreeLibrary();
711fcf3ce44SJohn Forte return (1);
712fcf3ce44SJohn Forte }
713fcf3ce44SJohn Forte
714fcf3ce44SJohn Forte /* Get physical port NPIV attributes */
715fcf3ce44SJohn Forte if (retrieveNPIVAttrs(handle, portWWN, &npivattrs, &portIndex) == 0) {
716fcf3ce44SJohn Forte /* Check port NPIV attributes */
717fcf3ce44SJohn Forte if (npivattrs.MaxNumberOfNPIVPorts == 0) {
718fcf3ce44SJohn Forte fprintf(stderr,
719fcf3ce44SJohn Forte gettext("Error: NPIV not Supported\n"));
720fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
721fcf3ce44SJohn Forte HBA_FreeLibrary();
722fcf3ce44SJohn Forte return (1);
723fcf3ce44SJohn Forte }
724fcf3ce44SJohn Forte if (npivattrs.MaxNumberOfNPIVPorts ==
725fcf3ce44SJohn Forte npivattrs.NumberOfNPIVPorts) {
726fcf3ce44SJohn Forte fprintf(stderr,
727fcf3ce44SJohn Forte gettext("Error: Can not create more NPIV port\n"));
728fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
729fcf3ce44SJohn Forte HBA_FreeLibrary();
730fcf3ce44SJohn Forte return (1);
731fcf3ce44SJohn Forte }
732fcf3ce44SJohn Forte
733fcf3ce44SJohn Forte /* Create a virtual port */
734fcf3ce44SJohn Forte status = Sun_HBA_CreateNPIVPort(handle, portIndex,
735fcf3ce44SJohn Forte vnodeWWN, vportWWN, &npivportIndex);
736fcf3ce44SJohn Forte times = 0;
737fcf3ce44SJohn Forte while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
738fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) &&
739fcf3ce44SJohn Forte times++ < HBA_MAX_RETRIES) {
740fcf3ce44SJohn Forte (void) sleep(1);
741fcf3ce44SJohn Forte status = Sun_HBA_CreateNPIVPort(handle, portIndex,
742fcf3ce44SJohn Forte vnodeWWN, vportWWN, &npivportIndex);
743fcf3ce44SJohn Forte if (status == HBA_STATUS_OK) {
744fcf3ce44SJohn Forte break;
745fcf3ce44SJohn Forte }
746fcf3ce44SJohn Forte }
747fcf3ce44SJohn Forte
748fcf3ce44SJohn Forte if (status != HBA_STATUS_OK) {
749fcf3ce44SJohn Forte fprintf(stderr,
750fcf3ce44SJohn Forte gettext("Error: failed to create a npiv port\n"));
751fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
752fcf3ce44SJohn Forte HBA_FreeLibrary();
753fcf3ce44SJohn Forte return (1);
754fcf3ce44SJohn Forte }
755fcf3ce44SJohn Forte } else {
756fcf3ce44SJohn Forte fprintf(stderr,
757fcf3ce44SJohn Forte gettext("Error: failed to get port NPIV attributes\n"));
758fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
759fcf3ce44SJohn Forte HBA_FreeLibrary();
760fcf3ce44SJohn Forte return (1);
761fcf3ce44SJohn Forte }
762fcf3ce44SJohn Forte
763fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
764fcf3ce44SJohn Forte HBA_FreeLibrary();
765fcf3ce44SJohn Forte
766fcf3ce44SJohn Forte WWN2str(nwwn, &vnodeWWN);
767fcf3ce44SJohn Forte WWN2str(pwwn, &vportWWN);
768fcf3ce44SJohn Forte npivAddRemoveNPIVEntry(wwn_argv[0],
769fcf3ce44SJohn Forte nwwn, pwwn, npivportIndex, NPIV_ADD);
770fcf3ce44SJohn Forte
771fcf3ce44SJohn Forte return (0);
772fcf3ce44SJohn Forte }
773fcf3ce44SJohn Forte
774fcf3ce44SJohn Forte int
create_npivport(char * ppwwn_str,char * vnwwn_str,char * vpwwn_str,int vindex)775fcf3ce44SJohn Forte create_npivport(char *ppwwn_str, char *vnwwn_str,
776fcf3ce44SJohn Forte char *vpwwn_str, int vindex)
777fcf3ce44SJohn Forte {
778fcf3ce44SJohn Forte uint64_t physicalportWWN, virtualnodeWWN, virtualportWWN;
779fcf3ce44SJohn Forte HBA_WWN portWWN, vnodeWWN, vportWWN;
780fcf3ce44SJohn Forte HBA_STATUS status;
781fcf3ce44SJohn Forte HBA_HANDLE handle;
782fcf3ce44SJohn Forte HBA_PORTNPIVATTRIBUTES npivattrs;
783fcf3ce44SJohn Forte HBA_UINT32 portIndex;
784fcf3ce44SJohn Forte HBA_UINT32 npivportIndex;
785fcf3ce44SJohn Forte int times = 0;
786fcf3ce44SJohn Forte
787fcf3ce44SJohn Forte sscanf(ppwwn_str, "%016llx", &physicalportWWN);
788fcf3ce44SJohn Forte physicalportWWN = htonll(physicalportWWN);
789fcf3ce44SJohn Forte memcpy(portWWN.wwn, &physicalportWWN, sizeof (physicalportWWN));
790fcf3ce44SJohn Forte sscanf(vnwwn_str, "%016llx", &virtualnodeWWN);
791fcf3ce44SJohn Forte virtualnodeWWN = htonll(virtualnodeWWN);
792fcf3ce44SJohn Forte memcpy(vnodeWWN.wwn, &virtualnodeWWN, sizeof (virtualnodeWWN));
793fcf3ce44SJohn Forte sscanf(vpwwn_str, "%016llx", &virtualportWWN);
794fcf3ce44SJohn Forte virtualportWWN = htonll(virtualportWWN);
795fcf3ce44SJohn Forte memcpy(vportWWN.wwn, &virtualportWWN, sizeof (virtualportWWN));
796fcf3ce44SJohn Forte npivportIndex = vindex;
797fcf3ce44SJohn Forte
798fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, portWWN);
799fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
800fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) {
801fcf3ce44SJohn Forte (void) sleep(FCADM_SLEEP_TIME);
802fcf3ce44SJohn Forte status = HBA_OpenAdapterByWWN(&handle, portWWN);
803fcf3ce44SJohn Forte if (times++ > FCADM_RETRY_TIMES) {
804fcf3ce44SJohn Forte return (1);
805fcf3ce44SJohn Forte }
806fcf3ce44SJohn Forte }
807fcf3ce44SJohn Forte
808fcf3ce44SJohn Forte /* Get physical port NPIV attributes */
809fcf3ce44SJohn Forte if (retrieveNPIVAttrs(handle, portWWN,
810fcf3ce44SJohn Forte &npivattrs, &portIndex) == 0) {
811fcf3ce44SJohn Forte /* Check port NPIV attributes */
812fcf3ce44SJohn Forte if (npivattrs.MaxNumberOfNPIVPorts == 0) {
813fcf3ce44SJohn Forte goto failed;
814fcf3ce44SJohn Forte }
815fcf3ce44SJohn Forte if (npivattrs.MaxNumberOfNPIVPorts ==
816fcf3ce44SJohn Forte npivattrs.NumberOfNPIVPorts) {
817fcf3ce44SJohn Forte goto failed;
818fcf3ce44SJohn Forte }
819fcf3ce44SJohn Forte
820fcf3ce44SJohn Forte /* Create a virtual port */
821fcf3ce44SJohn Forte status = Sun_HBA_CreateNPIVPort(handle, portIndex,
822fcf3ce44SJohn Forte vnodeWWN, vportWWN, &npivportIndex);
823fcf3ce44SJohn Forte times = 0;
824fcf3ce44SJohn Forte while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
825fcf3ce44SJohn Forte status == HBA_STATUS_ERROR_BUSY) {
826fcf3ce44SJohn Forte (void) sleep(FCADM_SLEEP_TIME);
827fcf3ce44SJohn Forte status = Sun_HBA_CreateNPIVPort(handle, portIndex,
828fcf3ce44SJohn Forte vnodeWWN, vportWWN, &npivportIndex);
829fcf3ce44SJohn Forte if (times++ > FCADM_RETRY_TIMES) {
830fcf3ce44SJohn Forte goto failed;
831fcf3ce44SJohn Forte }
832fcf3ce44SJohn Forte }
833fcf3ce44SJohn Forte }
834fcf3ce44SJohn Forte
835fcf3ce44SJohn Forte failed:
836fcf3ce44SJohn Forte HBA_CloseAdapter(handle);
837fcf3ce44SJohn Forte
838fcf3ce44SJohn Forte return (0);
839fcf3ce44SJohn Forte }
840fcf3ce44SJohn Forte
841fcf3ce44SJohn Forte int
fc_util_create_portlist()842fcf3ce44SJohn Forte fc_util_create_portlist()
843fcf3ce44SJohn Forte {
844fcf3ce44SJohn Forte scf_handle_t *handle = NULL;
845fcf3ce44SJohn Forte scf_service_t *svc = NULL;
846fcf3ce44SJohn Forte scf_propertygroup_t *pg = NULL;
847fcf3ce44SJohn Forte scf_transaction_t *tran = NULL;
848fcf3ce44SJohn Forte scf_transaction_entry_t *entry = NULL;
849fcf3ce44SJohn Forte scf_property_t *prop = NULL;
850fcf3ce44SJohn Forte scf_value_t *valueLookup = NULL;
851fcf3ce44SJohn Forte scf_iter_t *valueIter = NULL;
852fcf3ce44SJohn Forte char buf[NPIV_PORT_LIST_LENGTH] = {0};
853fcf3ce44SJohn Forte int commitRet;
854fcf3ce44SJohn Forte
855fcf3ce44SJohn Forte commitRet = cfgInit(&handle, &svc);
856fcf3ce44SJohn Forte if (commitRet != NPIV_SUCCESS) {
857fcf3ce44SJohn Forte goto out;
858fcf3ce44SJohn Forte }
859fcf3ce44SJohn Forte
860fcf3ce44SJohn Forte if (((pg = scf_pg_create(handle)) == NULL) ||
861fcf3ce44SJohn Forte ((tran = scf_transaction_create(handle)) == NULL) ||
862fcf3ce44SJohn Forte ((entry = scf_entry_create(handle)) == NULL) ||
863fcf3ce44SJohn Forte ((prop = scf_property_create(handle)) == NULL) ||
864fcf3ce44SJohn Forte ((valueIter = scf_iter_create(handle)) == NULL)) {
865fcf3ce44SJohn Forte goto out;
866fcf3ce44SJohn Forte }
867fcf3ce44SJohn Forte
868fcf3ce44SJohn Forte /* get property group or create it */
869fcf3ce44SJohn Forte if (scf_service_get_pg(svc, NPIV_PG_NAME, pg) == -1) {
870fcf3ce44SJohn Forte goto out;
871fcf3ce44SJohn Forte }
872fcf3ce44SJohn Forte
873fcf3ce44SJohn Forte if (scf_pg_get_property(pg, NPIV_PORT_LIST, prop) == -1) {
874fcf3ce44SJohn Forte syslog(LOG_ERR, "get property failed - %s",
875fcf3ce44SJohn Forte scf_strerror(scf_error()));
876fcf3ce44SJohn Forte goto out;
877fcf3ce44SJohn Forte }
878fcf3ce44SJohn Forte
879fcf3ce44SJohn Forte valueLookup = scf_value_create(handle);
880fcf3ce44SJohn Forte if (valueLookup == NULL) {
881fcf3ce44SJohn Forte syslog(LOG_ERR, "scf value alloc failed - %s",
882fcf3ce44SJohn Forte scf_strerror(scf_error()));
883fcf3ce44SJohn Forte goto out;
884fcf3ce44SJohn Forte }
885fcf3ce44SJohn Forte
886fcf3ce44SJohn Forte if (scf_iter_property_values(valueIter, prop) == -1) {
887fcf3ce44SJohn Forte syslog(LOG_ERR, "iter value failed - %s",
888fcf3ce44SJohn Forte scf_strerror(scf_error()));
889fcf3ce44SJohn Forte goto out;
890fcf3ce44SJohn Forte }
891fcf3ce44SJohn Forte
892fcf3ce44SJohn Forte if (HBA_LoadLibrary() != HBA_STATUS_OK) {
893fcf3ce44SJohn Forte goto out;
894fcf3ce44SJohn Forte }
895fcf3ce44SJohn Forte HBA_GetNumberOfAdapters();
896fcf3ce44SJohn Forte
897fcf3ce44SJohn Forte while (scf_iter_next_value(valueIter, valueLookup) == 1) {
898fcf3ce44SJohn Forte char ppwwn[17] = {0};
899fcf3ce44SJohn Forte char vnwwn[17] = {0};
900fcf3ce44SJohn Forte char vpwwn[17] = {0};
901fcf3ce44SJohn Forte int vindex = 0;
902fcf3ce44SJohn Forte
903fcf3ce44SJohn Forte bzero(buf, sizeof (buf));
904fcf3ce44SJohn Forte if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
905fcf3ce44SJohn Forte syslog(LOG_ERR, "iter value failed - %s",
906fcf3ce44SJohn Forte scf_strerror(scf_error()));
907fcf3ce44SJohn Forte break;
908fcf3ce44SJohn Forte }
909fcf3ce44SJohn Forte
910fcf3ce44SJohn Forte sscanf(buf, "%16s:%16s:%16s:%d", ppwwn, vpwwn, vnwwn, &vindex);
911fcf3ce44SJohn Forte create_npivport(ppwwn, vnwwn, vpwwn, vindex);
912fcf3ce44SJohn Forte }
913fcf3ce44SJohn Forte
914fcf3ce44SJohn Forte HBA_FreeLibrary();
915fcf3ce44SJohn Forte out:
916fcf3ce44SJohn Forte /*
917fcf3ce44SJohn Forte * Free resources
918fcf3ce44SJohn Forte */
919fcf3ce44SJohn Forte if (handle != NULL) {
920fcf3ce44SJohn Forte scf_handle_destroy(handle);
921fcf3ce44SJohn Forte }
922fcf3ce44SJohn Forte if (svc != NULL) {
923fcf3ce44SJohn Forte scf_service_destroy(svc);
924fcf3ce44SJohn Forte }
925fcf3ce44SJohn Forte if (pg != NULL) {
926fcf3ce44SJohn Forte scf_pg_destroy(pg);
927fcf3ce44SJohn Forte }
928fcf3ce44SJohn Forte if (tran != NULL) {
929fcf3ce44SJohn Forte scf_transaction_destroy(tran);
930fcf3ce44SJohn Forte }
931fcf3ce44SJohn Forte if (entry != NULL) {
932fcf3ce44SJohn Forte scf_entry_destroy(entry);
933fcf3ce44SJohn Forte }
934fcf3ce44SJohn Forte if (prop != NULL) {
935fcf3ce44SJohn Forte scf_property_destroy(prop);
936fcf3ce44SJohn Forte }
937fcf3ce44SJohn Forte if (valueIter != NULL) {
938fcf3ce44SJohn Forte scf_iter_destroy(valueIter);
939fcf3ce44SJohn Forte }
940fcf3ce44SJohn Forte if (valueLookup != NULL) {
941fcf3ce44SJohn Forte scf_value_destroy(valueLookup);
942fcf3ce44SJohn Forte }
943fcf3ce44SJohn Forte
944fcf3ce44SJohn Forte return (0);
945fcf3ce44SJohn Forte }
946*a7949318SReed
947*a7949318SReed /* ARGSUSED */
948*a7949318SReed int
fc_util_force_lip(int objects,char * argv[])949*a7949318SReed fc_util_force_lip(int objects, char *argv[])
950*a7949318SReed {
951*a7949318SReed uint64_t hbaWWN;
952*a7949318SReed HBA_WWN myWWN;
953*a7949318SReed HBA_HANDLE handle;
954*a7949318SReed HBA_STATUS status;
955*a7949318SReed int rval = 0;
956*a7949318SReed
957*a7949318SReed if ((status = HBA_LoadLibrary()) != HBA_STATUS_OK) {
958*a7949318SReed fprintf(stderr, gettext("Failed to load FC-HBA library\n"));
959*a7949318SReed printStatus(status);
960*a7949318SReed fprintf(stderr, "\n");
961*a7949318SReed return (1);
962*a7949318SReed }
963*a7949318SReed
964*a7949318SReed sscanf(argv[0], "%016llx", &hbaWWN);
965*a7949318SReed hbaWWN = htonll(hbaWWN);
966*a7949318SReed memcpy(myWWN.wwn, &hbaWWN, sizeof (hbaWWN));
967*a7949318SReed
968*a7949318SReed /*
969*a7949318SReed * Try target mode first
970*a7949318SReed */
971*a7949318SReed if ((status = Sun_HBA_OpenTgtAdapterByWWN(&handle, myWWN)) !=
972*a7949318SReed HBA_STATUS_OK) {
973*a7949318SReed /*
974*a7949318SReed * Continue to try initiator mode
975*a7949318SReed */
976*a7949318SReed if ((status = HBA_OpenAdapterByWWN(&handle, myWWN)) !=
977*a7949318SReed HBA_STATUS_OK) {
978*a7949318SReed fprintf(stderr, gettext("Error: HBA %s not found\n"),
979*a7949318SReed argv[0]);
980*a7949318SReed return (0);
981*a7949318SReed }
982*a7949318SReed }
983*a7949318SReed
984*a7949318SReed status = Sun_HBA_ForceLip(handle, &rval);
985*a7949318SReed if ((status != HBA_STATUS_OK) || (rval != 0)) {
986*a7949318SReed fprintf(stderr, gettext("Error: Failed to reinitialize the "
987*a7949318SReed "link of HBA %s\n"), argv[0]);
988*a7949318SReed }
989*a7949318SReed
990*a7949318SReed return (0);
991*a7949318SReed }
992