xref: /illumos-gate/usr/src/cmd/fcinfo/fcadm-list.c (revision a7949318)
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