summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/Makefile.check1
-rw-r--r--usr/src/cmd/fcinfo/Makefile2
-rw-r--r--usr/src/cmd/fcinfo/fcinfo.c15
-rw-r--r--usr/src/cmd/fcinfo/fcinfo.h19
-rw-r--r--usr/src/cmd/fcinfo/fcoeadm.c538
-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.c64
-rw-r--r--usr/src/lib/libfcoe/Makefile.com2
-rw-r--r--usr/src/lib/libfcoe/common/libfcoe.c580
-rw-r--r--usr/src/lib/libfcoe/common/libfcoe.h48
-rw-r--r--usr/src/lib/libfcoe/common/mapfile-vers1
-rw-r--r--usr/src/pkgdefs/SUNWfcprtr/prototype_com5
-rw-r--r--usr/src/tools/scripts/bfu.sh6
-rw-r--r--usr/src/uts/common/io/fcoe/fcoe.c6
-rw-r--r--usr/src/uts/common/io/fcoe/fcoe_fc.c5
-rw-r--r--usr/src/uts/common/io/fcoe/fcoe_fc.h3
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 */