changeset 9895:adcf72c91c4f

6818210 Remove fcadm create-fcoe-ports subcommand and implement the function in fcoeconfig
author Kevin Yu <Kevin.Yu@Sun.COM>
date Thu, 18 Jun 2009 10:55:44 +0800
parents 42b0c48b08a4
children e800509e1335
files usr/src/cmd/Makefile usr/src/cmd/Makefile.check usr/src/cmd/fcinfo/Makefile usr/src/cmd/fcinfo/fcinfo.c usr/src/cmd/fcinfo/fcinfo.h usr/src/cmd/fcinfo/fcoe_config.xml usr/src/cmd/fcinfo/fcoeadm.c usr/src/cmd/fcinfo/fcoeconfig usr/src/cmd/fcoesvc/Makefile usr/src/cmd/fcoesvc/fcoe_target.xml usr/src/cmd/fcoesvc/fcoetsvc.c usr/src/lib/libfcoe/Makefile.com usr/src/lib/libfcoe/common/libfcoe.c usr/src/lib/libfcoe/common/libfcoe.h usr/src/lib/libfcoe/common/mapfile-vers usr/src/pkgdefs/SUNWfcprtr/prototype_com usr/src/tools/scripts/bfu.sh usr/src/uts/common/io/fcoe/fcoe.c usr/src/uts/common/io/fcoe/fcoe_fc.c usr/src/uts/common/io/fcoe/fcoe_fc.h
diffstat 20 files changed, 889 insertions(+), 715 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/Makefile	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/Makefile	Thu Jun 18 10:55:44 2009 +0800
@@ -152,6 +152,7 @@
 	factor		\
 	false		\
 	fcinfo		\
+	fcoesvc		\
 	fdetach		\
 	fdformat	\
 	fdisk		\
--- a/usr/src/cmd/Makefile.check	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/Makefile.check	Thu Jun 18 10:55:44 2009 +0800
@@ -41,6 +41,7 @@
 	drd				\
 	dumpadm				\
 	fcinfo				\
+	fcoesvc				\
 	fm				\
 	intrd				\
 	iscsid				\
--- a/usr/src/cmd/fcinfo/Makefile	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/fcinfo/Makefile	Thu Jun 18 10:55:44 2009 +0800
@@ -30,9 +30,7 @@
 PROG = fcinfo
 ROOT_PROG_LINK = $(ROOTUSRSBIN)/fcadm
 MANIFEST = npiv_config.xml
-MANIFEST += fcoe_config.xml
 SVCMETHOD = npivconfig
-SVCMETHOD += fcoeconfig
 PRODUCT = $(PROG)
 
 $(ROOT_PROG_LINK) := FILEMODE = 0555
--- a/usr/src/cmd/fcinfo/fcinfo.c	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/fcinfo/fcinfo.c	Thu Jun 18 10:55:44 2009 +0800
@@ -53,7 +53,6 @@
 static int fcoeAdmCreatePortFunc(int, char **, cmdOptions_t *, void *);
 static int fcoeListPortsFunc(int, char **, cmdOptions_t *, void *);
 static int fcoeAdmDeletePortFunc(int, char **, cmdOptions_t *, void *);
-static int fcoeAdmCreatePortListFunc(int, char **, cmdOptions_t *, void *);
 static char *getExecBasename(char *);
 
 /*
@@ -122,9 +121,6 @@
 	{"list-fcoe-ports",
 	    fcoeListPortsFunc, "t", NULL, NULL,
 		OPERAND_NONE, NULL},
-	{"create-fcoe-ports",
-	    fcoeAdmCreatePortListFunc, "t", NULL, NULL,
-		OPERAND_NONE, NULL},
 	{NULL, 0, NULL, NULL, NULL, 0, NULL, NULL}
 };
 
@@ -243,17 +239,6 @@
 }
 
 /*
- * Pass in options/arguments, rest of arguments
- */
-/*ARGSUSED*/
-static int
-fcoeAdmCreatePortListFunc(int objects, char *argv[], cmdOptions_t *options,
-    void *addArgs)
-{
-	return (fcoe_adm_create_portlist(options));
-}
-
-/*
  * input:
  *  execFullName - exec name of program (argv[0])
  *
--- a/usr/src/cmd/fcinfo/fcinfo.h	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/fcinfo/fcinfo.h	Thu Jun 18 10:55:44 2009 +0800
@@ -89,24 +89,6 @@
 #define	NPIV_PG_NAME	"npiv-port-list"
 #define	NPIV_PORT_LIST	"port_list"
 
-#define	FCOE_SCF_ADD		0
-#define	FCOE_SCF_REMOVE		1
-
-#define	FCOE_SUCCESS			0
-#define	FCOE_ERROR			1
-#define	FCOE_ERROR_NOT_FOUND		2
-#define	FCOE_ERROR_EXISTS		3
-#define	FCOE_ERROR_SERVICE_NOT_FOUND	4
-#define	FCOE_ERROR_NOMEM		5
-#define	FCOE_ERROR_MEMBER_NOT_FOUND	6
-#define	FCOE_ERROR_BUSY			7
-
-#define	FCOE_PORT_LIST_LENGTH	255
-
-#define	FCOE_SERVICE	"network/fcoe_config"
-#define	FCOE_PG_NAME	"fcoe-port-list-pg"
-#define	FCOE_PORT_LIST	"port_list_p"
-
 /* flags that are needed to be passed into processHBA */
 #define	PRINT_LINKSTAT	    0x00000001	/* print link statistics information */
 #define	PRINT_SCSI_TARGET   0x00000010	/* print Scsi target information */
@@ -169,7 +151,6 @@
     cmdOptions_t *options);
 int fcoe_adm_delete_port(int objects, char *argv[]);
 int fcoe_adm_list_ports(cmdOptions_t *options);
-int fcoe_adm_create_portlist(cmdOptions_t *options);
 
 
 #ifdef	__cplusplus
--- a/usr/src/cmd/fcinfo/fcoe_config.xml	Wed Jun 17 15:32:10 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-
-<!--
-
-CDDL HEADER START
-
-The contents of this file are subject to the terms of the
-Common Development and Distribution License (the "License").
-You may not use this file except in compliance with the License.
-
-You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-or http://www.opensolaris.org/os/licensing.
-See the License for the specific language governing permissions
-and limitations under the License.
-
-When distributing Covered Code, include this CDDL HEADER in each
-file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-If applicable, add the following below this CDDL HEADER, with the
-fields enclosed by brackets "[]" replaced with your own identifying
-information: Portions Copyright [yyyy] [name of copyright owner]
-
-CDDL HEADER END
-
-Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-Use is subject to license terms.
-
-
-Service manifests for the FCOE configure
-
-
--->
-
-<!--
-
--->
-
-<service_bundle type='manifest' name='SUNWfcprt:fcoe_config'>
-
-<service
-	name='network/fcoe_config'
-	type='service'
-	version='1'>
-
-	<create_default_instance enabled='true' />
-
-	<single_instance/>
-
-	<dependency
-		name='fcoesysevent'
-		grouping='require_all'
-		restart_on='none'
-		type='service'>
-		<service_fmri value='svc:/system/sysevent' />
-	</dependency>
-
-	<dependent
-		name='fcoe-filesystem'
-		grouping='require_all'
-		restart_on='none'>
-		<service_fmri value='svc:/system/filesystem/local' />
-	</dependent>
-
-	<dependent
-		name='fcoe-fc'
-		grouping='require_all'
-		restart_on='none'>
-		<service_fmri value='svc:/system/device/fc-fabric' />
-	</dependent>
-
-	<exec_method
-		type='method'
-		name='start'
-		exec='/lib/svc/method/fcoeconfig'
-		timeout_seconds='1200'>
-	</exec_method>
-
-	<exec_method
-		type='method'
-		name='stop'
-		exec=':true'
-		timeout_seconds='60'>
-	</exec_method>
-
-	<property_group name='startd' type='framework'>
-		<propval name='duration' type='astring'
-			value='transient' />
-	</property_group>
-
-	<stability value='Unstable' />
-
-</service>
-
-</service_bundle>
--- a/usr/src/cmd/fcinfo/fcoeadm.c	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/cmd/fcinfo/fcoeadm.c	Thu Jun 18 10:55:44 2009 +0800
@@ -33,22 +33,10 @@
 #include <stddef.h>
 #include <strings.h>
 #include <libfcoe.h>
-#include <libscf.h>
 #include <syslog.h>
 
 static const char *FCOE_DRIVER_PATH	= "/devices/fcoe:admin";
 
-static char *
-WWN2str(char *buf, FCOE_PORT_WWN *wwn) {
-	int j;
-	unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
-	buf[0] = '\0';
-	for (j = 0; j < 16; j += 2) {
-		sprintf(&buf[j], "%02X", (int)*pc++);
-	}
-	return (buf);
-}
-
 static int
 isValidWWN(char *wwn)
 {
@@ -110,375 +98,6 @@
 	    attr->mac_promisc == 1 ? "On" : "Off");
 }
 
-/*
- * Initialize scf fcoe service access
- * handle - returned handle
- * service - returned service handle
- */
-static int
-fcoe_cfg_scf_init(scf_handle_t **handle, scf_service_t **service)
-{
-	scf_scope_t	*scope = NULL;
-	int		ret;
-
-	if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
-		syslog(LOG_ERR, "scf_handle_create failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto err;
-	}
-
-	if (scf_handle_bind(*handle) == -1) {
-		syslog(LOG_ERR, "scf_handle_bind failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto err;
-	}
-
-	if ((*service = scf_service_create(*handle)) == NULL) {
-		syslog(LOG_ERR, "scf_service_create failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto err;
-	}
-
-	if ((scope = scf_scope_create(*handle)) == NULL) {
-		syslog(LOG_ERR, "scf_scope_create failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto err;
-	}
-
-	if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
-		syslog(LOG_ERR, "scf_handle_get_scope failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto err;
-	}
-
-	if (scf_scope_get_service(scope, FCOE_SERVICE, *service) == -1) {
-		syslog(LOG_ERR, "scf_scope_get_service failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR_SERVICE_NOT_FOUND;
-		goto err;
-	}
-
-	scf_scope_destroy(scope);
-
-	return (FCOE_SUCCESS);
-
-err:
-	if (*handle != NULL) {
-		scf_handle_destroy(*handle);
-	}
-	if (*service != NULL) {
-		scf_service_destroy(*service);
-		*service = NULL;
-	}
-	if (scope != NULL) {
-		scf_scope_destroy(scope);
-	}
-	return (ret);
-}
-
-
-static int
-fcoe_adm_add_remove_scf_entry(char *mac_name,
-    char *pwwn, char *nwwn,
-    int is_target, int is_promiscuous, int addRemoveFlag)
-{
-	scf_handle_t	*handle = NULL;
-	scf_service_t	*svc = NULL;
-	scf_propertygroup_t	*pg = NULL;
-	scf_transaction_t	*tran = NULL;
-	scf_transaction_entry_t	*entry = NULL;
-	scf_property_t	*prop = NULL;
-	scf_value_t	*valueLookup = NULL;
-	scf_iter_t	*valueIter = NULL;
-	scf_value_t	**valueSet = NULL;
-	int	ret = FCOE_SUCCESS;
-	boolean_t	createProp = B_FALSE;
-	int	lastAlloc = 0;
-	char	buf[FCOE_PORT_LIST_LENGTH] = {0};
-	char	memberName[FCOE_PORT_LIST_LENGTH] = {0};
-	boolean_t	found = B_FALSE;
-	int	i = 0;
-	int	valueArraySize = 0;
-	int	commitRet;
-
-	sprintf(memberName, "%s:%s:%s:%d:%d", mac_name, pwwn, nwwn,
-	    is_target, is_promiscuous);
-
-	ret = fcoe_cfg_scf_init(&handle, &svc);
-	if (ret != FCOE_SUCCESS) {
-		goto out;
-	}
-
-	if (((pg = scf_pg_create(handle)) == NULL) ||
-	    ((tran = scf_transaction_create(handle)) == NULL) ||
-	    ((entry = scf_entry_create(handle)) == NULL) ||
-	    ((prop = scf_property_create(handle)) == NULL) ||
-	    ((valueIter = scf_iter_create(handle)) == NULL)) {
-		ret = FCOE_ERROR;
-		goto out;
-	}
-
-	/* get property group or create it */
-	if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) {
-		if ((scf_error() == SCF_ERROR_NOT_FOUND)) {
-			if (scf_service_add_pg(svc, FCOE_PG_NAME,
-			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
-				syslog(LOG_ERR, "add pg failed - %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-			} else {
-				createProp = B_TRUE;
-			}
-		} else {
-			syslog(LOG_ERR, "get pg failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-		}
-		if (ret != FCOE_SUCCESS) {
-			goto out;
-		}
-	}
-
-	/* to make sure property exists */
-	if (createProp == B_FALSE) {
-		if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
-			if ((scf_error() == SCF_ERROR_NOT_FOUND)) {
-				createProp = B_TRUE;
-			} else {
-				syslog(LOG_ERR, "get property failed - %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-				goto out;
-			}
-		}
-	}
-
-	/* Begin the transaction */
-	if (scf_transaction_start(tran, pg) == -1) {
-		syslog(LOG_ERR, "start transaction failed - %s",
-		    scf_strerror(scf_error()));
-		ret = FCOE_ERROR;
-		goto out;
-	}
-
-	valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
-	    * (lastAlloc = PORT_LIST_ALLOC));
-	if (valueSet == NULL) {
-		ret = FCOE_ERROR_NOMEM;
-		goto out;
-	}
-
-	if (createProp) {
-		if (scf_transaction_property_new(tran, entry, FCOE_PORT_LIST,
-		    SCF_TYPE_USTRING) == -1) {
-			if (scf_error() == SCF_ERROR_EXISTS) {
-				ret = FCOE_ERROR_EXISTS;
-			} else {
-				syslog(LOG_ERR,
-				    "transaction property new failed - %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-			}
-			goto out;
-		}
-	} else {
-		if (scf_transaction_property_change(tran, entry,
-		    FCOE_PORT_LIST, SCF_TYPE_USTRING) == -1) {
-			syslog(LOG_ERR,
-			    "transaction property change failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-
-		if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
-			syslog(LOG_ERR, "get property failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-
-		valueLookup = scf_value_create(handle);
-		if (valueLookup == NULL) {
-			syslog(LOG_ERR, "scf value alloc failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-
-		if (scf_iter_property_values(valueIter, prop) == -1) {
-			syslog(LOG_ERR, "iter value failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-
-		while (scf_iter_next_value(valueIter, valueLookup) == 1) {
-			char *macnameIter = NULL;
-			char buftmp[FCOE_PORT_LIST_LENGTH] = {0};
-
-			bzero(buf, sizeof (buf));
-			if (scf_value_get_ustring(valueLookup,
-			    buf, MAXNAMELEN) == -1) {
-				syslog(LOG_ERR, "iter value failed- %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-				break;
-			}
-			strcpy(buftmp, buf);
-			macnameIter = strtok(buftmp, ":");
-			if (bcmp(macnameIter, mac_name,
-			    strlen(mac_name)) == 0) {
-				if (addRemoveFlag == FCOE_SCF_ADD) {
-					ret = FCOE_ERROR_EXISTS;
-					break;
-				} else {
-					found = B_TRUE;
-					continue;
-				}
-			}
-
-			valueSet[i] = scf_value_create(handle);
-			if (valueSet[i] == NULL) {
-				syslog(LOG_ERR, "scf value alloc failed - %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-				break;
-			}
-
-			if (scf_value_set_ustring(valueSet[i], buf) == -1) {
-				syslog(LOG_ERR, "set value failed 1- %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-				break;
-			}
-
-			if (scf_entry_add_value(entry, valueSet[i]) == -1) {
-				syslog(LOG_ERR, "add value failed - %s",
-				    scf_strerror(scf_error()));
-				ret = FCOE_ERROR;
-				break;
-			}
-
-			i++;
-
-			if (i >= lastAlloc) {
-				lastAlloc += PORT_LIST_ALLOC;
-				valueSet = realloc(valueSet,
-				    sizeof (*valueSet) * lastAlloc);
-				if (valueSet == NULL) {
-					ret = FCOE_ERROR;
-					break;
-				}
-			}
-		}
-	}
-
-	valueArraySize = i;
-	if (!found && (addRemoveFlag == FCOE_SCF_REMOVE)) {
-		ret = FCOE_ERROR_MEMBER_NOT_FOUND;
-	}
-	if (ret != FCOE_SUCCESS) {
-		goto out;
-	}
-
-	if (addRemoveFlag == FCOE_SCF_ADD) {
-		/*
-		 * Now create the new entry
-		 */
-		valueSet[i] = scf_value_create(handle);
-		if (valueSet[i] == NULL) {
-			syslog(LOG_ERR, "scf value alloc failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		} else {
-			valueArraySize++;
-		}
-
-		/*
-		 * Set the new member name
-		 */
-		if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
-			syslog(LOG_ERR, "set value failed 2- %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-
-		/*
-		 * Add the new member
-		 */
-		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
-			syslog(LOG_ERR, "add value failed - %s",
-			    scf_strerror(scf_error()));
-			ret = FCOE_ERROR;
-			goto out;
-		}
-	}
-
-	if ((commitRet = scf_transaction_commit(tran)) != 1) {
-		syslog(LOG_ERR, "transaction commit failed - %s",
-		    scf_strerror(scf_error()));
-		if (commitRet == 0) {
-			ret = FCOE_ERROR_BUSY;
-		} else {
-			ret = FCOE_ERROR;
-		}
-		goto out;
-	}
-
-out:
-	/*
-	 * Free resources
-	 */
-	if (handle != NULL) {
-		scf_handle_destroy(handle);
-	}
-	if (svc != NULL) {
-		scf_service_destroy(svc);
-	}
-	if (pg != NULL) {
-		scf_pg_destroy(pg);
-	}
-	if (tran != NULL) {
-		scf_transaction_destroy(tran);
-	}
-	if (entry != NULL) {
-		scf_entry_destroy(entry);
-	}
-	if (prop != NULL) {
-		scf_property_destroy(prop);
-	}
-	if (valueIter != NULL) {
-		scf_iter_destroy(valueIter);
-	}
-	if (valueLookup != NULL) {
-		scf_value_destroy(valueLookup);
-	}
-
-	/*
-	 * Free valueSet scf resources
-	 */
-	if (valueArraySize > 0) {
-		for (i = 0; i < valueArraySize; i++) {
-			scf_value_destroy(valueSet[i]);
-		}
-	}
-	/*
-	 * Now free the pointer array to the resources
-	 */
-	if (valueSet != NULL) {
-		free(valueSet);
-	}
-
-	return (ret);
-}
 
 int
 fcoe_adm_create_port(int objects, char *argv[],
@@ -629,7 +248,7 @@
 
 		case FCOE_STATUS_ERROR_GET_LINKINFO:
 			fprintf(stderr,
-			    gettext("Error: Failed to get link infomation "
+			    gettext("Error: Failed to get link information "
 			    "for %s\n"), macLinkName);
 			break;
 
@@ -640,17 +259,6 @@
 		}
 		return (1);
 	} else {
-		char cpwwn[17], cnwwn[17];
-
-		WWN2str(cpwwn, &pwwn);
-		WWN2str(cnwwn, &nwwn);
-
-		fcoe_adm_add_remove_scf_entry((char *)macLinkName,
-		    cpwwn,
-		    cnwwn,
-		    createtgt,
-		    promiscuous,
-		    FCOE_SCF_ADD);
 		return (0);
 	}
 }
@@ -722,12 +330,6 @@
 		}
 		return (1);
 	} else {
-		fcoe_adm_add_remove_scf_entry((char *)macLinkName,
-		    "",
-		    "",
-		    0,
-		    0,
-		    FCOE_SCF_REMOVE);
 		return (0);
 	}
 }
@@ -822,141 +424,3 @@
 	return (ret);
 
 }
-
-int
-fcoe_adm_create_portlist(cmdOptions_t *options)
-{
-	scf_handle_t	*handle = NULL;
-	scf_service_t	*svc = NULL;
-	scf_propertygroup_t	*pg = NULL;
-	scf_transaction_t	*tran = NULL;
-	scf_transaction_entry_t	*entry = NULL;
-	scf_property_t		*prop = NULL;
-	scf_value_t	*valueLookup = NULL;
-	scf_iter_t	*valueIter = NULL;
-	char		buf[FCOE_PORT_LIST_LENGTH] = {0};
-	int		commitRet;
-	int		create_target = 0, create_initiator = 0;
-
-	/* Check what type of port list will be created */
-	for (; options->optval; options++) {
-		switch (options->optval) {
-		case 'i':
-			create_initiator = 1;
-			break;
-		case 't':
-			create_target = 1;
-			break;
-		default:
-			fprintf(stderr, gettext("Error: Illegal option: %c\n"),
-			    options->optval);
-			return (1);
-		}
-	}
-
-	if (create_initiator == 0 && create_target == 0) {
-		create_initiator = 1;
-		create_target = 1;
-	}
-
-	commitRet = fcoe_cfg_scf_init(&handle, &svc);
-	if (commitRet != FCOE_SUCCESS) {
-		goto out;
-	}
-
-	if (((pg = scf_pg_create(handle)) == NULL) ||
-	    ((tran = scf_transaction_create(handle)) == NULL) ||
-	    ((entry = scf_entry_create(handle)) == NULL) ||
-	    ((prop = scf_property_create(handle)) == NULL) ||
-	    ((valueIter = scf_iter_create(handle)) == NULL)) {
-		goto out;
-	}
-
-	/* get property group or create it */
-	if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) {
-		goto out;
-	}
-
-	if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
-		syslog(LOG_ERR, "get property failed - %s",
-		    scf_strerror(scf_error()));
-		goto out;
-	}
-
-	valueLookup = scf_value_create(handle);
-	if (valueLookup == NULL) {
-		syslog(LOG_ERR, "scf value alloc failed - %s",
-		    scf_strerror(scf_error()));
-		goto out;
-	}
-
-	if (scf_iter_property_values(valueIter, prop) == -1) {
-		syslog(LOG_ERR, "iter value failed - %s",
-		    scf_strerror(scf_error()));
-		goto out;
-	}
-	while (scf_iter_next_value(valueIter, valueLookup) == 1) {
-		uint8_t *macLinkName = NULL;
-		char *remainder = NULL;
-		FCOE_PORT_WWN pwwn, nwwn;
-		uint64_t	nodeWWN, portWWN;
-		int is_target, is_promiscuous;
-
-		bzero(buf, sizeof (buf));
-		bzero(&pwwn, sizeof (pwwn));
-		bzero(&nwwn, sizeof (nwwn));
-		if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
-			syslog(LOG_ERR, "iter value failed - %s",
-			    scf_strerror(scf_error()));
-			break;
-		}
-		macLinkName = (uint8_t *)strtok(buf, ":");
-		remainder = strtok(NULL, "#");
-		sscanf(remainder, "%016llx:%016llx:%d:%d",
-		    &portWWN, &nodeWWN, &is_target, &is_promiscuous);
-		if ((!create_target && is_target) ||
-		    (!create_initiator && !is_target)) {
-			continue;
-		}
-
-		nodeWWN = htonll(nodeWWN);
-		memcpy(&nwwn, &nodeWWN, sizeof (nodeWWN));
-		portWWN = htonll(portWWN);
-		memcpy(&pwwn, &portWWN, sizeof (portWWN));
-
-		FCOE_CreatePort(macLinkName,
-		    is_target ? FCOE_PORTTYPE_TARGET : FCOE_PORTTYPE_INITIATOR,
-		    pwwn, nwwn, is_promiscuous);
-	}
-
-out:
-	/*
-	 * Free resources
-	 */
-	if (handle != NULL) {
-		scf_handle_destroy(handle);
-	}
-	if (svc != NULL) {
-		scf_service_destroy(svc);
-	}
-	if (pg != NULL) {
-		scf_pg_destroy(pg);
-	}
-	if (tran != NULL) {
-		scf_transaction_destroy(tran);
-	}
-	if (entry != NULL) {
-		scf_entry_destroy(entry);
-	}
-	if (prop != NULL) {
-		scf_property_destroy(prop);
-	}
-	if (valueIter != NULL) {
-		scf_iter_destroy(valueIter);
-	}
-	if (valueLookup != NULL) {
-		scf_value_destroy(valueLookup);
-	}
-
-	return (0);
-}
--- a/usr/src/cmd/fcinfo/fcoeconfig	Wed Jun 17 15:32:10 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#!/sbin/sh
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-#
-# This script is used to reconfigure fabric device(s) which were configured
-# prior to boot.  The luxadm command used below is an expert level command
-# and has a restrictive usage for boot time reconfiguration of fabric
-# devices.
-#
-# DO NOT USE the command for any other purpose.
-#
-
-/usr/sbin/fcadm create-fcoe-ports
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fcoesvc/Makefile	Thu Jun 18 10:55:44 2009 +0800
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROG =	svc-fcoet
+
+include ../Makefile.cmd
+
+COMMONBASE = ../../common
+
+LOCAL_OBJS = fcoetsvc.o
+LOCAL_SRCS =	$(LOCAL_OBJS:%.o=%.c)
+OBJS =	$(LOCAL_OBJS)
+SRCS = $(LOCAL_SRCS)
+
+LDLIBS += -lfcoe
+
+MANIFEST    = fcoe_target.xml
+SVCMETHOD   = svc-fcoet
+
+ROOTMANIFESTDIR	= $(ROOTSVCSYSTEM)
+$(ROOTSVCSYSTEM)/fcoe_target.xml	:= OWNER = root
+$(ROOTSVCSYSTEM)/fcoe_target.xml	:= GROUP = bin
+$(ROOTSVCSYSTEM)/fcoe_target.xml	:= FILEMODE = 0444
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+	$(POST_PROCESS)
+
+install: all $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+check:	$(CHKMANIFEST)
+	$(CSTYLE) -pPc $(SRCS:%=%)
+
+cmdparse.o:
+	    $(COMPILE.c) -o $@
+	    $(POST_PROCESS_O)
+
+clean:
+	$(RM) $(OBJS)
+
+lint:	lint_SRCS
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fcoesvc/fcoe_target.xml	Thu Jun 18 10:55:44 2009 +0800
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+
+<!--
+
+CDDL HEADER START
+
+The contents of this file are subject to the terms of the
+Common Development and Distribution License (the "License").
+You may not use this file except in compliance with the License.
+
+You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+or http://www.opensolaris.org/os/licensing.
+See the License for the specific language governing permissions
+and limitations under the License.
+
+When distributing Covered Code, include this CDDL HEADER in each
+file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+If applicable, add the following below this CDDL HEADER, with the
+fields enclosed by brackets "[]" replaced with your own identifying
+information: Portions Copyright [yyyy] [name of copyright owner]
+
+CDDL HEADER END
+
+Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+Use is subject to license terms.
+
+Service manifests for the FCoE target configuration
+-->
+
+<!--
+	system/fcoe_target - Export FCoE target port services
+-->
+
+<service_bundle type='manifest' name='SUNWfcprtr:fcoe_target'>
+
+<service
+	name='system/fcoe_target'
+	type='service'
+	version='1'>
+
+	<create_default_instance enabled='true' />
+
+	<single_instance/>
+
+	<dependency name = 'network'
+		grouping='require_any'
+		restart_on='error'
+		type='service'>
+		<service_fmri value='svc:/milestone/network'/>
+	</dependency>
+
+	<dependency name = 'stmf'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/system/stmf:default'/>
+	</dependency>
+
+	<exec_method
+		type='method'
+		name='start'
+		exec='/lib/svc/method/svc-fcoet'
+		timeout_seconds='600'>
+		<method_context>
+			<method_credential
+			user='root'
+			group='root'
+			privileges='basic,sys_devices'
+			/>
+		</method_context>
+	</exec_method>
+
+	<exec_method
+		type='method'
+		name='stop'
+		exec=':true'
+		timeout_seconds='60'>
+		<method_context>
+			<method_credential
+			user='root'
+			group='root'
+			privileges='basic,sys_devices'
+			/>
+		</method_context>
+	</exec_method>
+
+	<property_group name='startd' type='framework'>
+		<propval name='duration' type='astring'
+			value='transient' />
+	</property_group>
+
+	<stability value='Evolving' />
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+				fcoe target service
+			</loctext>
+		</common_name>
+		<documentation>
+			<manpage title='fcadm' section='1M'
+				manpath='/usr/share/man' />
+		</documentation>
+	</template>
+
+</service>
+
+</service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fcoesvc/fcoetsvc.c	Thu Jun 18 10:55:44 2009 +0800
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <libfcoe.h>
+#include <locale.h>
+
+int
+main()
+{
+	FCOE_STATUS	status;
+	PFCOE_SMF_PORT_LIST portlist = NULL;
+	PFCOE_SMF_PORT_INSTANCE port = NULL;
+	int i;
+	int ret = 0;
+
+	(void) setlocale(LC_ALL, "");
+
+	status = FCOE_LoadConfig(FCOE_PORTTYPE_TARGET, &portlist);
+
+	if (status != FCOE_STATUS_OK) {
+		ret = 1;
+	} else if (portlist == NULL) {
+		return (0);
+	} else {
+		for (i = 0; i < portlist->port_num; i++) {
+			port = &portlist->ports[i];
+			if (port->port_type == FCOE_PORTTYPE_TARGET) {
+				(void) FCOE_CreatePort(port->mac_link_name,
+				    port->port_type,
+				    port->port_pwwn,
+				    port->port_nwwn,
+				    port->mac_promisc);
+			}
+		}
+		ret = 0;
+	}
+
+	if (portlist != NULL) {
+		free(portlist);
+	}
+	return (ret);
+} /* end main */
--- a/usr/src/lib/libfcoe/Makefile.com	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/lib/libfcoe/Makefile.com	Thu Jun 18 10:55:44 2009 +0800
@@ -37,7 +37,7 @@
 INCS +=		-I$(SRCDIR)
 INCS +=		-I$(SRC)/uts/common/sys/fcoe
 
-LDLIBS +=	-lc -ldladm
+LDLIBS +=	-lc -ldladm -lscf
 C99MODE=	-xc99=%all
 C99LMODE=	-Xc99=%all
 CPPFLAGS +=	$(INCS) -D_REENTRANT
--- a/usr/src/lib/libfcoe/common/libfcoe.c	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/lib/libfcoe/common/libfcoe.c	Thu Jun 18 10:55:44 2009 +0800
@@ -39,6 +39,8 @@
 #include <libfcoe.h>
 #include <libdllink.h>
 #include <fcoeio.h>
+#include <libscf.h>
+#include <inttypes.h>
 
 #define	FCOE_DEV_PATH	 "/devices/fcoe:admin"
 
@@ -71,6 +73,16 @@
 	return (ret);
 }
 
+static void
+WWN2str(char *buf, FCOE_PORT_WWN *wwn) {
+	int j;
+	unsigned char *pc = (unsigned char *)&(wwn->wwn[0]);
+	buf[0] = '\0';
+	for (j = 0; j < 16; j += 2) {
+		(void) sprintf(&buf[j], "%02X", (int)*pc++);
+	}
+}
+
 static int
 isWWNZero(FCOE_PORT_WWN portwwn)
 {
@@ -85,6 +97,378 @@
 	return (1);
 }
 
+/*
+ * Initialize scf fcoe service access
+ * handle - returned handle
+ * service - returned service handle
+ */
+static int
+fcoe_cfg_scf_init(scf_handle_t **handle, scf_service_t **service, int is_target)
+{
+	scf_scope_t	*scope = NULL;
+	int		ret;
+
+	if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
+		syslog(LOG_ERR, "scf_handle_create failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto err;
+	}
+
+	if (scf_handle_bind(*handle) == -1) {
+		syslog(LOG_ERR, "scf_handle_bind failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto err;
+	}
+
+	if ((*service = scf_service_create(*handle)) == NULL) {
+		syslog(LOG_ERR, "scf_service_create failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto err;
+	}
+
+	if ((scope = scf_scope_create(*handle)) == NULL) {
+		syslog(LOG_ERR, "scf_scope_create failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto err;
+	}
+
+	if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
+		syslog(LOG_ERR, "scf_handle_get_scope failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto err;
+	}
+
+	if (scf_scope_get_service(scope,
+	    is_target ? FCOE_TARGET_SERVICE: FCOE_INITIATOR_SERVICE,
+	    *service) == -1) {
+		syslog(LOG_ERR, "scf_scope_get_service failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR_SERVICE_NOT_FOUND;
+		goto err;
+	}
+
+	scf_scope_destroy(scope);
+
+	return (FCOE_SUCCESS);
+
+err:
+	if (*handle != NULL) {
+		scf_handle_destroy(*handle);
+	}
+	if (*service != NULL) {
+		scf_service_destroy(*service);
+		*service = NULL;
+	}
+	if (scope != NULL) {
+		scf_scope_destroy(scope);
+	}
+	return (ret);
+}
+
+static int
+fcoe_add_remove_scf_entry(char *mac_name,
+    char *pwwn, char *nwwn,
+    int is_target, int is_promiscuous, int addRemoveFlag)
+{
+	scf_handle_t	*handle = NULL;
+	scf_service_t	*svc = NULL;
+	scf_propertygroup_t	*pg = NULL;
+	scf_transaction_t	*tran = NULL;
+	scf_transaction_entry_t	*entry = NULL;
+	scf_property_t	*prop = NULL;
+	scf_value_t	*valueLookup = NULL;
+	scf_iter_t	*valueIter = NULL;
+	scf_value_t	**valueSet = NULL;
+	int	ret = FCOE_SUCCESS;
+	boolean_t	createProp = B_FALSE;
+	int	lastAlloc = 0;
+	char	buf[FCOE_PORT_LIST_LENGTH] = {0};
+	char	memberName[FCOE_PORT_LIST_LENGTH] = {0};
+	boolean_t	found = B_FALSE;
+	int	i = 0;
+	int	valueArraySize = 0;
+	int	commitRet;
+	int portListAlloc = 100;
+
+	(void) snprintf(memberName, FCOE_PORT_LIST_LENGTH,
+	    "%s:%s:%s:%d:%d", mac_name, pwwn, nwwn,
+	    is_target, is_promiscuous);
+
+	ret = fcoe_cfg_scf_init(&handle, &svc, is_target);
+	if (ret != FCOE_SUCCESS) {
+		goto out;
+	}
+
+	if (((pg = scf_pg_create(handle)) == NULL) ||
+	    ((tran = scf_transaction_create(handle)) == NULL) ||
+	    ((entry = scf_entry_create(handle)) == NULL) ||
+	    ((prop = scf_property_create(handle)) == NULL) ||
+	    ((valueIter = scf_iter_create(handle)) == NULL)) {
+		ret = FCOE_ERROR;
+		goto out;
+	}
+
+	/* get property group or create it */
+	if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) {
+		if ((scf_error() == SCF_ERROR_NOT_FOUND)) {
+			if (scf_service_add_pg(svc, FCOE_PG_NAME,
+			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
+				syslog(LOG_ERR, "add pg failed - %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+			} else {
+				createProp = B_TRUE;
+			}
+		} else {
+			syslog(LOG_ERR, "get pg failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+		}
+		if (ret != FCOE_SUCCESS) {
+			goto out;
+		}
+	}
+
+	/* to make sure property exists */
+	if (createProp == B_FALSE) {
+		if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
+			if ((scf_error() == SCF_ERROR_NOT_FOUND)) {
+				createProp = B_TRUE;
+			} else {
+				syslog(LOG_ERR, "get property failed - %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+				goto out;
+			}
+		}
+	}
+
+	/* Begin the transaction */
+	if (scf_transaction_start(tran, pg) == -1) {
+		syslog(LOG_ERR, "start transaction failed - %s",
+		    scf_strerror(scf_error()));
+		ret = FCOE_ERROR;
+		goto out;
+	}
+
+	valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
+	    * (lastAlloc = portListAlloc));
+	if (valueSet == NULL) {
+		ret = FCOE_ERROR_NOMEM;
+		goto out;
+	}
+
+	if (createProp) {
+		if (scf_transaction_property_new(tran, entry, FCOE_PORT_LIST,
+		    SCF_TYPE_USTRING) == -1) {
+			if (scf_error() == SCF_ERROR_EXISTS) {
+				ret = FCOE_ERROR_EXISTS;
+			} else {
+				syslog(LOG_ERR,
+				    "transaction property new failed - %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+			}
+			goto out;
+		}
+	} else {
+		if (scf_transaction_property_change(tran, entry,
+		    FCOE_PORT_LIST, SCF_TYPE_USTRING) == -1) {
+			syslog(LOG_ERR,
+			    "transaction property change failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+
+		if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
+			syslog(LOG_ERR, "get property failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+
+		valueLookup = scf_value_create(handle);
+		if (valueLookup == NULL) {
+			syslog(LOG_ERR, "scf value alloc failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+
+		if (scf_iter_property_values(valueIter, prop) == -1) {
+			syslog(LOG_ERR, "iter value failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+
+		while (scf_iter_next_value(valueIter, valueLookup) == 1) {
+			char *macnameIter = NULL;
+			char buftmp[FCOE_PORT_LIST_LENGTH] = {0};
+
+			bzero(buf, sizeof (buf));
+			if (scf_value_get_ustring(valueLookup,
+			    buf, MAXNAMELEN) == -1) {
+				syslog(LOG_ERR, "iter value failed- %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+				break;
+			}
+			(void) strcpy(buftmp, buf);
+			macnameIter = strtok(buftmp, ":");
+			if (strcmp(macnameIter, mac_name) == 0) {
+				if (addRemoveFlag == FCOE_SCF_ADD) {
+					ret = FCOE_ERROR_EXISTS;
+					break;
+				} else {
+					found = B_TRUE;
+					continue;
+				}
+			}
+
+			valueSet[i] = scf_value_create(handle);
+			if (valueSet[i] == NULL) {
+				syslog(LOG_ERR, "scf value alloc failed - %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+				break;
+			}
+
+			if (scf_value_set_ustring(valueSet[i], buf) == -1) {
+				syslog(LOG_ERR, "set value failed 1- %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+				break;
+			}
+
+			if (scf_entry_add_value(entry, valueSet[i]) == -1) {
+				syslog(LOG_ERR, "add value failed - %s",
+				    scf_strerror(scf_error()));
+				ret = FCOE_ERROR;
+				break;
+			}
+
+			i++;
+
+			if (i >= lastAlloc) {
+				lastAlloc += portListAlloc;
+				valueSet = realloc(valueSet,
+				    sizeof (*valueSet) * lastAlloc);
+				if (valueSet == NULL) {
+					ret = FCOE_ERROR;
+					break;
+				}
+			}
+		}
+	}
+
+	valueArraySize = i;
+	if (!found && (addRemoveFlag == FCOE_SCF_REMOVE)) {
+		ret = FCOE_ERROR_MEMBER_NOT_FOUND;
+	}
+	if (ret != FCOE_SUCCESS) {
+		goto out;
+	}
+
+	if (addRemoveFlag == FCOE_SCF_ADD) {
+		/*
+		 * Now create the new entry
+		 */
+		valueSet[i] = scf_value_create(handle);
+		if (valueSet[i] == NULL) {
+			syslog(LOG_ERR, "scf value alloc failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		} else {
+			valueArraySize++;
+		}
+
+		/*
+		 * Set the new member name
+		 */
+		if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
+			syslog(LOG_ERR, "set value failed 2- %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+
+		/*
+		 * Add the new member
+		 */
+		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
+			syslog(LOG_ERR, "add value failed - %s",
+			    scf_strerror(scf_error()));
+			ret = FCOE_ERROR;
+			goto out;
+		}
+	}
+
+	if ((commitRet = scf_transaction_commit(tran)) != 1) {
+		syslog(LOG_ERR, "transaction commit failed - %s",
+		    scf_strerror(scf_error()));
+		if (commitRet == 0) {
+			ret = FCOE_ERROR_BUSY;
+		} else {
+			ret = FCOE_ERROR;
+		}
+		goto out;
+	}
+
+out:
+	/*
+	 * Free resources
+	 */
+	if (handle != NULL) {
+		scf_handle_destroy(handle);
+	}
+	if (svc != NULL) {
+		scf_service_destroy(svc);
+	}
+	if (pg != NULL) {
+		scf_pg_destroy(pg);
+	}
+	if (tran != NULL) {
+		scf_transaction_destroy(tran);
+	}
+	if (entry != NULL) {
+		scf_entry_destroy(entry);
+	}
+	if (prop != NULL) {
+		scf_property_destroy(prop);
+	}
+	if (valueIter != NULL) {
+		scf_iter_destroy(valueIter);
+	}
+	if (valueLookup != NULL) {
+		scf_value_destroy(valueLookup);
+	}
+
+	/*
+	 * Free valueSet scf resources
+	 */
+	if (valueArraySize > 0) {
+		for (i = 0; i < valueArraySize; i++) {
+			scf_value_destroy(valueSet[i]);
+		}
+	}
+	/*
+	 * Now free the pointer array to the resources
+	 */
+	if (valueSet != NULL) {
+		free(valueSet);
+	}
+
+	return (ret);
+}
+
 FCOE_STATUS
 FCOE_CreatePort(
 	const FCOE_UINT8		*macLinkName,
@@ -93,7 +477,7 @@
 	FCOE_PORT_WWN		nwwn,
 	FCOE_UINT8		promiscuous)
 {
-	FCOE_STATUS		status = FCOE_STATUS_OK;
+	FCOE_STATUS		status;
 	int			fcoe_fd;
 	fcoeio_t		fcoeio;
 	fcoeio_create_port_param_t	param;
@@ -118,6 +502,12 @@
 	if (dladm_name2info(handle, (const char *)macLinkName,
 	    &linkid, NULL, &class, NULL) != DLADM_STATUS_OK) {
 		dladm_close(handle);
+		(void) fcoe_add_remove_scf_entry((char *)macLinkName,
+		    "",
+		    "",
+		    portType,
+		    0,
+		    FCOE_SCF_REMOVE);
 		return (FCOE_STATUS_ERROR_GET_LINKINFO);
 	}
 	dladm_close(handle);
@@ -204,6 +594,17 @@
 			status = FCOE_STATUS_ERROR;
 		}
 	} else {
+		char cpwwn[17], cnwwn[17];
+
+		WWN2str(cpwwn, &pwwn);
+		WWN2str(cnwwn, &nwwn);
+
+		(void) fcoe_add_remove_scf_entry((char *)macLinkName,
+		    cpwwn,
+		    cnwwn,
+		    portType,
+		    promiscuous,
+		    FCOE_SCF_ADD);
 		status = FCOE_STATUS_OK;
 	}
 	(void) close(fcoe_fd);
@@ -219,6 +620,8 @@
 	dladm_handle_t		handle;
 	datalink_id_t		linkid;
 	fcoeio_delete_port_param_t fc_del_port;
+	uint64_t	is_target = 0;
+	int		io_ret = 0;
 
 	if (macLinkName == NULL) {
 		return (FCOE_STATUS_ERROR_INVAL_ARG);
@@ -249,10 +652,13 @@
 
 	/* only 4 bytes here, need to change */
 	fcoeio.fcoeio_ilen = sizeof (fcoeio_delete_port_param_t);
-	fcoeio.fcoeio_xfer = FCOEIO_XFER_WRITE;
+	fcoeio.fcoeio_olen = sizeof (uint64_t);
+	fcoeio.fcoeio_xfer = FCOEIO_XFER_RW;
 	fcoeio.fcoeio_ibuf = (uintptr_t)&fc_del_port;
+	fcoeio.fcoeio_obuf = (uintptr_t)&is_target;
 
-	if (ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio) != 0) {
+	io_ret = ioctl(fcoe_fd, FCOEIO_CMD, &fcoeio);
+	if (io_ret != 0) {
 		switch (fcoeio.fcoeio_status) {
 		case FCOEIOE_INVAL_ARG:
 			status = FCOE_STATUS_ERROR_INVAL_ARG;
@@ -278,8 +684,29 @@
 			status = FCOE_STATUS_ERROR;
 		}
 	} else {
+		(void) fcoe_add_remove_scf_entry((char *)macLinkName,
+		    "",
+		    "",
+		    is_target,
+		    0,
+		    FCOE_SCF_REMOVE);
 		status = FCOE_STATUS_OK;
 	}
+
+	if (io_ret == FCOEIOE_MAC_NOT_FOUND) {
+		(void) fcoe_add_remove_scf_entry((char *)macLinkName,
+		    "",
+		    "",
+		    0,
+		    0,
+		    FCOE_SCF_REMOVE);
+		(void) fcoe_add_remove_scf_entry((char *)macLinkName,
+		    "",
+		    "",
+		    1,
+		    0,
+		    FCOE_SCF_REMOVE);
+	}
 	(void) close(fcoe_fd);
 	return (status);
 }
@@ -344,6 +771,8 @@
 				retry++;
 			default:
 				status = FCOE_STATUS_ERROR;
+				(void) close(fcoe_fd);
+				return (status);
 			}
 		} else {
 			status = FCOE_STATUS_OK;
@@ -396,3 +825,148 @@
 	(void) close(fcoe_fd);
 	return (status);
 }
+
+FCOE_STATUS FCOE_LoadConfig(
+	FCOE_UINT8		portType,
+    FCOE_SMF_PORT_LIST **portlist)
+{
+	scf_handle_t	*handle = NULL;
+	scf_service_t	*svc = NULL;
+	scf_propertygroup_t	*pg = NULL;
+	scf_transaction_t	*tran = NULL;
+	scf_transaction_entry_t	*entry = NULL;
+	scf_property_t		*prop = NULL;
+	scf_value_t	*valueLookup = NULL;
+	scf_iter_t	*valueIter = NULL;
+	char		buf[FCOE_PORT_LIST_LENGTH] = {0};
+	int		commitRet;
+	FCOE_UINT32	portIndex;
+	int		bufsize, retry;
+	int		size = 10; /* default first attempt */
+	int		pg_or_prop_not_found = 0;
+
+	commitRet = fcoe_cfg_scf_init(&handle, &svc, portType);
+	if (commitRet != FCOE_SUCCESS) {
+		goto out;
+	}
+
+	if (((pg = scf_pg_create(handle)) == NULL) ||
+	    ((tran = scf_transaction_create(handle)) == NULL) ||
+	    ((entry = scf_entry_create(handle)) == NULL) ||
+	    ((prop = scf_property_create(handle)) == NULL) ||
+	    ((valueIter = scf_iter_create(handle)) == NULL)) {
+		goto out;
+	}
+
+	if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) {
+		pg_or_prop_not_found = 1;
+		goto out;
+	}
+
+	if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) {
+		pg_or_prop_not_found = 1;
+		goto out;
+	}
+
+	valueLookup = scf_value_create(handle);
+	if (valueLookup == NULL) {
+		syslog(LOG_ERR, "scf value alloc failed - %s",
+		    scf_strerror(scf_error()));
+		goto out;
+	}
+
+	portIndex = 0;
+
+	do {
+		if (scf_iter_property_values(valueIter, prop) == -1) {
+			syslog(LOG_ERR, "iter value failed - %s",
+			    scf_strerror(scf_error()));
+			goto out;
+		}
+
+		retry = 0;
+		bufsize = sizeof (FCOE_SMF_PORT_INSTANCE) * (size - 1) +
+		    sizeof (FCOE_SMF_PORT_LIST);
+		*portlist = (PFCOE_SMF_PORT_LIST)malloc(bufsize);
+
+		while (scf_iter_next_value(valueIter, valueLookup) == 1) {
+			uint8_t *macLinkName = NULL;
+			char *remainder = NULL;
+			uint64_t	nodeWWN, portWWN;
+			int is_target, is_promiscuous;
+
+			bzero(buf, sizeof (buf));
+			if (scf_value_get_ustring(valueLookup, buf,
+			    MAXNAMELEN) == -1) {
+				syslog(LOG_ERR, "iter value failed - %s",
+				    scf_strerror(scf_error()));
+				break;
+			}
+			macLinkName = (uint8_t *)strtok(buf, ":");
+			remainder = strtok(NULL, "#");
+			(void) sscanf(remainder,
+			    "%016" PRIx64 ":%016" PRIx64 ":%d:%d",
+			    &portWWN, &nodeWWN, &is_target, &is_promiscuous);
+
+			if (portIndex >= size) {
+				free(*portlist);
+				retry = 1;
+				size *= 2;
+				break;
+			} else {
+				PFCOE_SMF_PORT_INSTANCE pi =
+				    &(*portlist)->ports[portIndex++];
+				(void) strcpy((char *)pi->mac_link_name,
+				    (char *)macLinkName);
+				pi->port_type = is_target ?
+				    FCOE_PORTTYPE_TARGET:
+				    FCOE_PORTTYPE_INITIATOR;
+				portWWN = htonll(portWWN);
+				nodeWWN = htonll(nodeWWN);
+				(void) memcpy(&pi->port_pwwn, &portWWN,
+				    sizeof (FCOE_PORT_WWN));
+				(void) memcpy(&pi->port_nwwn, &nodeWWN,
+				    sizeof (FCOE_PORT_WWN));
+				pi->mac_promisc = is_promiscuous;
+			}
+		}
+
+		(*portlist)->port_num = portIndex;
+	} while (retry == 1);
+
+	return (FCOE_STATUS_OK);
+out:
+	/*
+	 * Free resources
+	 */
+	if (handle != NULL) {
+		scf_handle_destroy(handle);
+	}
+	if (svc != NULL) {
+		scf_service_destroy(svc);
+	}
+	if (pg != NULL) {
+		scf_pg_destroy(pg);
+	}
+	if (tran != NULL) {
+		scf_transaction_destroy(tran);
+	}
+	if (entry != NULL) {
+		scf_entry_destroy(entry);
+	}
+	if (prop != NULL) {
+		scf_property_destroy(prop);
+	}
+	if (valueIter != NULL) {
+		scf_iter_destroy(valueIter);
+	}
+	if (valueLookup != NULL) {
+		scf_value_destroy(valueLookup);
+	}
+
+	if (pg_or_prop_not_found == 1) {
+		return (FCOE_STATUS_OK);
+	} else {
+		return (FCOE_STATUS_ERROR);
+	}
+}
--- a/usr/src/lib/libfcoe/common/libfcoe.h	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/lib/libfcoe/common/libfcoe.h	Thu Jun 18 10:55:44 2009 +0800
@@ -37,12 +37,31 @@
 #endif
 
 /*
- * FCOE Port Type
+ * FCoE Port Type
  */
 #define	FCOE_PORTTYPE_INITIATOR		0
 #define	FCOE_PORTTYPE_TARGET		1
 
 #define	FCOE_MAX_MAC_NAME_LEN		32
+
+#define	FCOE_SCF_ADD		0
+#define	FCOE_SCF_REMOVE		1
+
+#define	FCOE_SUCCESS			0
+#define	FCOE_ERROR			1
+#define	FCOE_ERROR_EXISTS		2
+#define	FCOE_ERROR_SERVICE_NOT_FOUND	3
+#define	FCOE_ERROR_NOMEM		4
+#define	FCOE_ERROR_MEMBER_NOT_FOUND	5
+#define	FCOE_ERROR_BUSY			6
+
+#define	FCOE_TARGET_SERVICE	"system/fcoe_target"
+#define	FCOE_INITIATOR_SERVICE	"system/fcoe_initiator"
+#define	FCOE_PG_NAME	"fcoe-port-list-pg"
+#define	FCOE_PORT_LIST	"port_list_p"
+
+#define	FCOE_PORT_LIST_LENGTH	255
+
 typedef unsigned char	FCOE_UINT8;
 typedef		 char	FCOE_INT8;
 typedef unsigned short	FCOE_UINT16;
@@ -88,6 +107,25 @@
 } FCOE_PORT_ATTRIBUTE, *PFCOE_PORT_ATTRIBUTE;
 
 /*
+ * FCoE port instance in smf repository
+ */
+typedef struct fcoe_smf_port_instance {
+	FCOE_UINT8	mac_link_name[MAXLINKNAMELEN];
+	FCOE_UINT8	port_type;
+	FCOE_PORT_WWN	port_pwwn;
+	FCOE_PORT_WWN	port_nwwn;
+	FCOE_UINT8	mac_promisc;
+} FCOE_SMF_PORT_INSTANCE, *PFCOE_SMF_PORT_INSTANCE;
+
+/*
+ * FCoE port instance list
+ */
+typedef struct fcoe_smf_port_list {
+	FCOE_UINT32	port_num;
+	FCOE_SMF_PORT_INSTANCE	ports[1];
+} FCOE_SMF_PORT_LIST, *PFCOE_SMF_PORT_LIST;
+
+/*
  * macLinkName: mac name with maximum lenth 32
  * portType: 0 (Initiator)/ 1(Target)
  * pwwn: Port WWN
@@ -114,6 +152,14 @@
     FCOE_PORT_ATTRIBUTE	**portlist
 );
 
+/*
+ * Make sure to free the memory pointed by portlist
+ */
+FCOE_STATUS FCOE_LoadConfig(
+    FCOE_UINT8		portType,
+    FCOE_SMF_PORT_LIST **portlist
+);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/lib/libfcoe/common/mapfile-vers	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/lib/libfcoe/common/mapfile-vers	Thu Jun 18 10:55:44 2009 +0800
@@ -42,6 +42,7 @@
 	FCOE_CreatePort;
 	FCOE_DeletePort;
 	FCOE_GetPortList;
+	FCOE_LoadConfig;
 
     local:
 	*;
--- a/usr/src/pkgdefs/SUNWfcprtr/prototype_com	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/pkgdefs/SUNWfcprtr/prototype_com	Thu Jun 18 10:55:44 2009 +0800
@@ -44,10 +44,11 @@
 d none var/svc 755 root sys
 d none var/svc/manifest 755 root sys
 d none var/svc/manifest/network 0755 root sys
+d none var/svc/manifest/system 0755 root sys
 f manifest var/svc/manifest/network/npiv_config.xml 0444 root sys
-f manifest var/svc/manifest/network/fcoe_config.xml 0444 root sys
+f manifest var/svc/manifest/system/fcoe_target.xml 0444 root sys
 d none lib 755 root bin
 d none lib/svc 755 root bin
 d none lib/svc/method 755 root bin
 f none lib/svc/method/npivconfig 0555 root bin
-f none lib/svc/method/fcoeconfig 0555 root bin
+f none lib/svc/method/svc-fcoet 0555 root bin
--- a/usr/src/tools/scripts/bfu.sh	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/tools/scripts/bfu.sh	Thu Jun 18 10:55:44 2009 +0800
@@ -306,13 +306,13 @@
 	lib/svc/method/fc-fabric
 	lib/svc/method/iscsi-initiator
 	lib/svc/method/npivconfig
-	lib/svc/method/fcoeconfig
 	lib/svc/method/sf880dr
 	lib/svc/method/svc-cvcd
 	lib/svc/method/svc-dcs
 	lib/svc/method/svc-drd
 	lib/svc/method/svc-dscp
 	lib/svc/method/svc-dumpadm
+	lib/svc/method/svc-fcoet
 	lib/svc/method/svc-intrd
 	lib/svc/method/svc-hal
 	lib/svc/method/svc-labeld
@@ -364,7 +364,6 @@
 	var/log/pool
 	var/svc/manifest/network/iscsi/iscsi-initiator.xml
 	var/svc/manifest/network/npiv_config.xml
-	var/svc/manifest/network/fcoe_config.xml
 	var/svc/manifest/network/rpc/mdcomm.xml
 	var/svc/manifest/network/rpc/meta.xml
 	var/svc/manifest/network/rpc/metamed.xml
@@ -383,6 +382,7 @@
 	var/svc/manifest/system/device/devices-audio.xml
 	var/svc/manifest/system/device/devices-fc-fabric.xml
 	var/svc/manifest/system/dumpadm.xml
+	var/svc/manifest/system/fcoe_target.xml
 	var/svc/manifest/system/filesystem/rmvolmgr.xml
 	var/svc/manifest/system/fmd.xml
 	var/svc/manifest/system/hal.xml
@@ -1476,6 +1476,7 @@
 	var/svc/manifest/network/datalink.xml
 	var/svc/manifest/network/datalink-init.xml
 	var/svc/manifest/network/iscsi_initiator.xml
+	var/svc/manifest/network/fcoe_config.xml
 "
 
 # smf services whose manifests have been renamed
@@ -1498,6 +1499,7 @@
 	lib/svc/method/svc-kdc.slave
 	lib/svc/share/krb_include.sh
 	lib/svc/method/iscsid
+	lib/svc/method/fcoeconfig
 "
 
 smf_cleanup () {
--- a/usr/src/uts/common/io/fcoe/fcoe.c	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/uts/common/io/fcoe/fcoe.c	Thu Jun 18 10:55:44 2009 +0800
@@ -765,9 +765,11 @@
 	case FCOEIO_DELETE_FCOE_PORT: {
 		fcoeio_delete_port_param_t *del_port_param =
 		    (fcoeio_delete_port_param_t *)ibuf;
+		uint64_t *is_target = (uint64_t *)obuf;
 
 		if (fcoeio->fcoeio_ilen < sizeof (fcoeio_delete_port_param_t) ||
-		    fcoeio->fcoeio_xfer != FCOEIO_XFER_WRITE) {
+		    fcoeio->fcoeio_olen != sizeof (uint64_t) ||
+		    fcoeio->fcoeio_xfer != FCOEIO_XFER_RW) {
 			fcoeio->fcoeio_status = FCOEIOE_INVAL_ARG;
 			ret = EINVAL;
 			break;
@@ -775,7 +777,7 @@
 
 		mutex_enter(&ss->ss_ioctl_mutex);
 		ret = fcoe_delete_port(ss->ss_dip, fcoeio,
-		    del_port_param->fdp_mac_linkid);
+		    del_port_param->fdp_mac_linkid, is_target);
 		if (ret != 0) {
 			FCOE_LOG("fcoe",
 			    "fcoe_delete_port failed: %d", ret);
--- a/usr/src/uts/common/io/fcoe/fcoe_fc.c	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/uts/common/io/fcoe/fcoe_fc.c	Thu Jun 18 10:55:44 2009 +0800
@@ -453,7 +453,8 @@
 }
 
 int
-fcoe_delete_port(dev_info_t *parent, fcoeio_t *fcoeio, datalink_id_t linkid)
+fcoe_delete_port(dev_info_t *parent, fcoeio_t *fcoeio, datalink_id_t linkid,
+    uint64_t *is_target)
 {
 	int		 rval = 0;
 	fcoe_mac_t	*mac;
@@ -464,6 +465,8 @@
 		return (EINVAL);
 	}
 
+	*is_target = EPORT_CLT_TYPE(&mac->fm_eport);
+
 	if ((mac->fm_flags & FCOE_MAC_FLAG_ENABLED) != FCOE_MAC_FLAG_ENABLED) {
 		fcoeio->fcoeio_status = FCOEIOE_ALREADY;
 		return (EALREADY);
--- a/usr/src/uts/common/io/fcoe/fcoe_fc.h	Wed Jun 17 15:32:10 2009 -0700
+++ b/usr/src/uts/common/io/fcoe/fcoe_fc.h	Thu Jun 18 10:55:44 2009 +0800
@@ -36,7 +36,8 @@
 extern void fcoe_mac_notify_link_up(void *);
 extern void fcoe_mac_notify_link_down(void *);
 extern int fcoe_create_port(dev_info_t *, fcoe_mac_t *, int);
-extern int fcoe_delete_port(dev_info_t *, fcoeio_t *, datalink_id_t);
+extern int fcoe_delete_port(dev_info_t *, fcoeio_t *,
+    datalink_id_t, uint64_t *is_target);
 
 #endif	/* _KERNEL */