diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/Makefile | 1 | ||||
-rw-r--r-- | usr/src/cmd/Makefile.check | 1 | ||||
-rw-r--r-- | usr/src/cmd/fcinfo/Makefile | 2 | ||||
-rw-r--r-- | usr/src/cmd/fcinfo/fcinfo.c | 15 | ||||
-rw-r--r-- | usr/src/cmd/fcinfo/fcinfo.h | 19 | ||||
-rw-r--r-- | usr/src/cmd/fcinfo/fcoeadm.c | 538 | ||||
-rw-r--r-- | usr/src/cmd/fcoesvc/Makefile (renamed from usr/src/cmd/fcinfo/fcoeconfig) | 55 | ||||
-rw-r--r-- | usr/src/cmd/fcoesvc/fcoe_target.xml (renamed from usr/src/cmd/fcinfo/fcoe_config.xml) | 69 | ||||
-rw-r--r-- | usr/src/cmd/fcoesvc/fcoetsvc.c | 64 | ||||
-rw-r--r-- | usr/src/lib/libfcoe/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/lib/libfcoe/common/libfcoe.c | 580 | ||||
-rw-r--r-- | usr/src/lib/libfcoe/common/libfcoe.h | 48 | ||||
-rw-r--r-- | usr/src/lib/libfcoe/common/mapfile-vers | 1 | ||||
-rw-r--r-- | usr/src/pkgdefs/SUNWfcprtr/prototype_com | 5 | ||||
-rw-r--r-- | usr/src/tools/scripts/bfu.sh | 6 | ||||
-rw-r--r-- | usr/src/uts/common/io/fcoe/fcoe.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/io/fcoe/fcoe_fc.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/io/fcoe/fcoe_fc.h | 3 |
18 files changed, 797 insertions, 623 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 143d2c1e83..e5dc179850 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -152,6 +152,7 @@ COMMON_SUBDIRS= \ factor \ false \ fcinfo \ + fcoesvc \ fdetach \ fdformat \ fdisk \ diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index aaeed0cb11..b6c3b8a7cc 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -41,6 +41,7 @@ MANIFEST_TOPDIRS= \ drd \ dumpadm \ fcinfo \ + fcoesvc \ fm \ intrd \ iscsid \ diff --git a/usr/src/cmd/fcinfo/Makefile b/usr/src/cmd/fcinfo/Makefile index 814e952fd5..a824667d71 100644 --- a/usr/src/cmd/fcinfo/Makefile +++ b/usr/src/cmd/fcinfo/Makefile @@ -30,9 +30,7 @@ COMMONBASE = ../../common 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 diff --git a/usr/src/cmd/fcinfo/fcinfo.c b/usr/src/cmd/fcinfo/fcinfo.c index 396647d9fb..8f94354c11 100644 --- a/usr/src/cmd/fcinfo/fcinfo.c +++ b/usr/src/cmd/fcinfo/fcinfo.c @@ -53,7 +53,6 @@ static int npivListRemotePortFunc(int, char **, cmdOptions_t *, void *); 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 @@ subCommandProps_t fcadmsubcommands[] = { {"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 @@ fcoeListPortsFunc(int objects, char *argv[], cmdOptions_t *options, } /* - * 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]) * diff --git a/usr/src/cmd/fcinfo/fcinfo.h b/usr/src/cmd/fcinfo/fcinfo.h index 00e61c28b5..d9a0f4c683 100644 --- a/usr/src/cmd/fcinfo/fcinfo.h +++ b/usr/src/cmd/fcinfo/fcinfo.h @@ -89,24 +89,6 @@ extern "C" { #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 @@ int fcoe_adm_create_port(int objects, char *argv[], 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 diff --git a/usr/src/cmd/fcinfo/fcoeadm.c b/usr/src/cmd/fcinfo/fcoeadm.c index 7b92f76673..c3ffe637b2 100644 --- a/usr/src/cmd/fcinfo/fcoeadm.c +++ b/usr/src/cmd/fcinfo/fcoeadm.c @@ -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 @@ printFCOEPortInfo(FCOE_PORT_ATTRIBUTE *attr) 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 @@ fcoe_adm_create_port(int objects, char *argv[], 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 @@ fcoe_adm_create_port(int objects, char *argv[], } 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 @@ fcoe_adm_delete_port(int objects, char *argv[]) } return (1); } else { - fcoe_adm_add_remove_scf_entry((char *)macLinkName, - "", - "", - 0, - 0, - FCOE_SCF_REMOVE); return (0); } } @@ -822,141 +424,3 @@ fcoe_adm_list_ports(cmdOptions_t *options) 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); -} diff --git a/usr/src/cmd/fcinfo/fcoeconfig b/usr/src/cmd/fcoesvc/Makefile index ba47b22c69..1dc31822fb 100644 --- a/usr/src/cmd/fcinfo/fcoeconfig +++ b/usr/src/cmd/fcoesvc/Makefile @@ -1,4 +1,3 @@ -#!/sbin/sh # # CDDL HEADER START # @@ -19,17 +18,53 @@ # # 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 +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 diff --git a/usr/src/cmd/fcinfo/fcoe_config.xml b/usr/src/cmd/fcoesvc/fcoe_target.xml index 10dcbc4f60..043882d944 100644 --- a/usr/src/cmd/fcinfo/fcoe_config.xml +++ b/usr/src/cmd/fcoesvc/fcoe_target.xml @@ -25,20 +25,17 @@ CDDL HEADER END Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. - -Service manifests for the FCOE configure - - +Service manifests for the FCoE target configuration --> <!-- - + system/fcoe_target - Export FCoE target port services --> -<service_bundle type='manifest' name='SUNWfcprt:fcoe_config'> +<service_bundle type='manifest' name='SUNWfcprtr:fcoe_target'> <service - name='network/fcoe_config' + name='system/fcoe_target' type='service' version='1'> @@ -46,33 +43,32 @@ Service manifests for the FCOE configure <single_instance/> - <dependency - name='fcoesysevent' - grouping='require_all' - restart_on='none' + <dependency name = 'network' + grouping='require_any' + restart_on='error' type='service'> - <service_fmri value='svc:/system/sysevent' /> + <service_fmri value='svc:/milestone/network'/> </dependency> - <dependent - name='fcoe-filesystem' + <dependency name = 'stmf' 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> + restart_on='none' + type='service'> + <service_fmri value='svc:/system/stmf:default'/> + </dependency> <exec_method type='method' name='start' - exec='/lib/svc/method/fcoeconfig' - timeout_seconds='1200'> + 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 @@ -80,6 +76,13 @@ Service manifests for the FCOE configure 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'> @@ -87,7 +90,19 @@ Service manifests for the FCOE configure value='transient' /> </property_group> - <stability value='Unstable' /> + <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> diff --git a/usr/src/cmd/fcoesvc/fcoetsvc.c b/usr/src/cmd/fcoesvc/fcoetsvc.c new file mode 100644 index 0000000000..12db8bd8cd --- /dev/null +++ b/usr/src/cmd/fcoesvc/fcoetsvc.c @@ -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 */ diff --git a/usr/src/lib/libfcoe/Makefile.com b/usr/src/lib/libfcoe/Makefile.com index 8c6c4c64dc..ed9f3d773d 100644 --- a/usr/src/lib/libfcoe/Makefile.com +++ b/usr/src/lib/libfcoe/Makefile.com @@ -37,7 +37,7 @@ SRCDIR = ../common 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 diff --git a/usr/src/lib/libfcoe/common/libfcoe.c b/usr/src/lib/libfcoe/common/libfcoe.c index a71c217a70..6e10527046 100644 --- a/usr/src/lib/libfcoe/common/libfcoe.c +++ b/usr/src/lib/libfcoe/common/libfcoe.c @@ -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 @@ openFcoe(int flag, int *fd) 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 @@ isWWNZero(FCOE_PORT_WWN portwwn) 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_CreatePort( 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 @@ FCOE_CreatePort( 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 @@ FCOE_CreatePort( 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 @@ FCOE_DeletePort(const FCOE_UINT8 *macLinkName) 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 @@ FCOE_DeletePort(const FCOE_UINT8 *macLinkName) /* 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 @@ FCOE_DeletePort(const FCOE_UINT8 *macLinkName) 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 @@ FCOE_GetPortList( retry++; default: status = FCOE_STATUS_ERROR; + (void) close(fcoe_fd); + return (status); } } else { status = FCOE_STATUS_OK; @@ -396,3 +825,148 @@ FCOE_GetPortList( (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); + } +} diff --git a/usr/src/lib/libfcoe/common/libfcoe.h b/usr/src/lib/libfcoe/common/libfcoe.h index 871022011c..622887693f 100644 --- a/usr/src/lib/libfcoe/common/libfcoe.h +++ b/usr/src/lib/libfcoe/common/libfcoe.h @@ -37,12 +37,31 @@ extern "C" { #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 @@ typedef struct fcoe_port_attr { } 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_STATUS FCOE_GetPortList( 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 diff --git a/usr/src/lib/libfcoe/common/mapfile-vers b/usr/src/lib/libfcoe/common/mapfile-vers index ba73d9e4dd..ef58a8431d 100644 --- a/usr/src/lib/libfcoe/common/mapfile-vers +++ b/usr/src/lib/libfcoe/common/mapfile-vers @@ -42,6 +42,7 @@ SUNWprivate { FCOE_CreatePort; FCOE_DeletePort; FCOE_GetPortList; + FCOE_LoadConfig; local: *; diff --git a/usr/src/pkgdefs/SUNWfcprtr/prototype_com b/usr/src/pkgdefs/SUNWfcprtr/prototype_com index 580312340a..b21cc9e92d 100644 --- a/usr/src/pkgdefs/SUNWfcprtr/prototype_com +++ b/usr/src/pkgdefs/SUNWfcprtr/prototype_com @@ -44,10 +44,11 @@ d none var 755 root sys 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 diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index e96b73be73..adf04b2f9b 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -306,13 +306,13 @@ superfluous_nonglobal_zone_files=" 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 @@ superfluous_nonglobal_zone_files=" 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 @@ superfluous_nonglobal_zone_files=" 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 @@ smf_obsolete_manifests=" 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 @@ smf_obsolete_methods=" lib/svc/method/svc-kdc.slave lib/svc/share/krb_include.sh lib/svc/method/iscsid + lib/svc/method/fcoeconfig " smf_cleanup () { diff --git a/usr/src/uts/common/io/fcoe/fcoe.c b/usr/src/uts/common/io/fcoe/fcoe.c index 677a29104f..372995df44 100644 --- a/usr/src/uts/common/io/fcoe/fcoe.c +++ b/usr/src/uts/common/io/fcoe/fcoe.c @@ -765,9 +765,11 @@ fcoe_iocmd(fcoe_soft_state_t *ss, intptr_t data, int mode) 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 @@ fcoe_iocmd(fcoe_soft_state_t *ss, intptr_t data, int mode) 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); diff --git a/usr/src/uts/common/io/fcoe/fcoe_fc.c b/usr/src/uts/common/io/fcoe/fcoe_fc.c index 68ec016134..268bd1c05f 100644 --- a/usr/src/uts/common/io/fcoe/fcoe_fc.c +++ b/usr/src/uts/common/io/fcoe/fcoe_fc.c @@ -453,7 +453,8 @@ fcoe_create_port(dev_info_t *parent, fcoe_mac_t *mac, int is_target) } 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 @@ fcoe_delete_port(dev_info_t *parent, fcoeio_t *fcoeio, datalink_id_t linkid) 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); diff --git a/usr/src/uts/common/io/fcoe/fcoe_fc.h b/usr/src/uts/common/io/fcoe/fcoe_fc.h index 51ee375130..58f01cad0c 100644 --- a/usr/src/uts/common/io/fcoe/fcoe_fc.h +++ b/usr/src/uts/common/io/fcoe/fcoe_fc.h @@ -36,7 +36,8 @@ extern fcoe_frame_t *fcoe_allocate_frame(fcoe_port_t *, uint32_t, void *); 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 */ |