Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:PowerPC
open-fcoe
fcoe-utils-beta2-update
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fcoe-utils-beta2-update of Package open-fcoe
diff -Pur --exclude=.git fcoe-utils/configure.ac fcoe-utils-tip/configure.ac --- fcoe-utils/configure.ac 2010-01-08 15:43:45.067000276 -0800 +++ fcoe-utils-tip/configure.ac 2010-01-08 12:15:27.545000527 -0800 @@ -1,4 +1,4 @@ -AC_INIT([fcoe-utils], [1.0.7], [devel@open-fcoe.org]) +AC_INIT([fcoe-utils], [1.0.9], [devel@open-fcoe.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC @@ -19,6 +19,6 @@ [PKG_CHECK_MODULES([DCBD], [dcbd]) AC_SUBST([DCBD_CFLAGS])]) -AC_CONFIG_FILES([Makefile fcoeplumb fcoe-utils.spec]) +AC_CONFIG_FILES([Makefile fcoeplumb fcoe-utils.spec fcoe_utils.h]) AC_OUTPUT diff -Pur --exclude=.git fcoe-utils/etc/initd/initd.fedora fcoe-utils-tip/etc/initd/initd.fedora --- fcoe-utils/etc/initd/initd.fedora 2010-01-08 16:56:17.511000544 -0800 +++ fcoe-utils-tip/etc/initd/initd.fedora 2010-01-08 12:15:27.548000527 -0800 @@ -118,31 +118,14 @@ fi } -validate_link_flow_control() -{ - ifname=$1 - - retry_count=1 - while true - do - TX_STATUS=`ethtool -a $ifname 2>&1 | awk '/TX:/{print $2}'` - RX_STATUS=`ethtool -a $ifname 2>&1 | awk '/RX:/{print $2}'` - - if [ "$TX_STATUS" = "on" ] && [ "$RX_STATUS" = "on" ]; then - return 0 - fi - - ethtool -A $ifname rx on tx on - [ $retry_count -eq 0 ] && return 0 - retry_count=$(($retry_count-1)) - usleep 500000 - done - $LOGGER "Warning: Failed to bring up link flow control of $ifname." - return 1 -} - service_start() { + pidof $FCOEMON + if [ $? -eq 0 ]; then + $LOGGER "Warning: daemon already running." + return + fi + rm -f /var/run/fcoemon.* modprobe -q libfc @@ -158,22 +141,6 @@ pidof $FCOEMON [ $? -eq 0 ] && kill -TERM `pidof $FCOEMON` - for ifcfg_file in `ls $CONFIG_DIR/cfg-eth*` - do - ifname=`basename $ifcfg_file | cut -d"-" -f2` - . $ifcfg_file - [ "$FCOE_ENABLE" != "yes" ] && - [ "$FCOE_ENABLE" != "YES" ] && continue - if [ "$DCB_REQUIRED" != "yes" ] && - [ "$DCB_REQUIRED" != "YES" ]; then - STATUS=`$FCOEADM -i $ifname 2>&1 | \ - awk '/Symbolic Name:/{print $6}'` - if [ "$STATUS" = "$ifname" ]; then - $FCOEADM -d $ifname - fi - fi - done - retry_count=5 while true do diff -Pur --exclude=.git fcoe-utils/etc/initd/initd.suse fcoe-utils-tip/etc/initd/initd.suse --- fcoe-utils/etc/initd/initd.suse 2010-01-08 15:43:45.069000342 -0800 +++ fcoe-utils-tip/etc/initd/initd.suse 2010-01-08 12:15:27.548000527 -0800 @@ -189,42 +189,7 @@ startup_fcoe_modules - HAS_DCB_IF="false" - for ifcfg_file in `ls $CONFIG_DIR/cfg-eth*` - do - ifname=`basename $ifcfg_file | cut -d"-" -f2` - . $ifcfg_file - [ "$FCOE_ENABLE" != "yes" ] && - [ "$FCOE_ENABLE" != "YES" ] && continue - - if [ "$DCB_REQUIRED" != "yes" ] && - [ "$DCB_REQUIRED" != "YES" ]; then - # - # DCB is not required, we nee to validate the - # link flow control of the Ethernet port - # - validate_link_flow_control $ifname - [ $? -ne 0 ] && continue - # - # Create the FCoE interface - # - $FCOEADM -c $ifname - else - # - # Configure the DCB for the Ethernet - # port if DCB is required - # - HAS_DCB_IF="true" - fi - done - - # - # If DCB-required Ethernet port exists, then start the fcoemon - # daemon to create the FCoE interfaces for these ports. - # - if [ "$HAS_DCB_IF" = "true" ]; then - startproc -l ${LOG_FILE} -p ${PID_FILE} ${FCOEMON} ${FCOEMON_OPTS} - fi + startproc -l ${LOG_FILE} -p ${PID_FILE} ${FCOEMON} ${FCOEMON_OPTS} rc_status -v return @@ -235,22 +200,6 @@ checkproc $FCOEMON [ $? -eq 0 ] && killproc -TERM $FCOEMON - for ifcfg_file in `ls $CONFIG_DIR/cfg-eth*` - do - ifname=`basename $ifcfg_file | cut -d"-" -f2` - . $ifcfg_file - [ "$FCOE_ENABLE" != "yes" ] && - [ "$FCOE_ENABLE" != "YES" ] && continue - if [ "$DCB_REQUIRED" != "yes" ] && - [ "$DCB_REQUIRED" != "YES" ]; then - STATUS=`$FCOEADM -i $ifname 2>&1 | \ - awk '/Symbolic Name:/{print $6}'` - if [ "$STATUS" = "$ifname" ]; then - $FCOEADM -d $ifname - fi - fi - done - retry_count=5 while true do diff -Pur --exclude=.git fcoe-utils/fcoeadm.c fcoe-utils-tip/fcoeadm.c --- fcoe-utils/fcoeadm.c 2010-01-08 16:56:55.791000544 -0800 +++ fcoe-utils-tip/fcoeadm.c 2010-01-08 12:15:27.550000527 -0800 @@ -17,17 +17,17 @@ * Maintained at www.Open-FCoE.org */ -#include <stdio.h> -#include <stdlib.h> +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include <libgen.h> -#include <errno.h> -#include <getopt.h> -#include <dirent.h> +#include <paths.h> +#include "fcoe_utils.h" #include "fcoeadm.h" #include "fcoe_clif.h" -static char *fcoeadm_version = \ - "fcoeadm v1.0.9\n Copyright (c) 2009, Intel Corporation.\n"; +static char *fcoeadm_version = +"fcoeadm v" FCOE_UTILS_VERSION "\n Copyright (c) 2009, Intel Corporation.\n"; #define CMD_RESPONSE_TIMEOUT 5 @@ -49,12 +49,6 @@ struct clif *clif_conn; -enum { /* Match the values in fcoemon */ - FCOEADM_CREATE = 1, - FCOEADM_DESTROY, - FCOEADM_RESET, -}; - static void fcoeadm_help(void) { printf("%s\n", fcoeadm_version); @@ -71,81 +65,42 @@ } /* - * Open and close to check if directory exists - */ -static int fcoeadm_checkdir(char *dir) -{ - DIR *d = NULL; - - if (!dir) - return -EINVAL; - /* check if we have sysfs */ - d = opendir(dir); - if (!d) - return -EINVAL; - closedir(d); - return 0; -} - -/* * TODO - check this ifname before performing any action */ static int fcoeadm_check(char *ifname) { char path[256]; + int fd; + int status = 0; /* check if we have sysfs */ - if (fcoeadm_checkdir(SYSFS_MOUNT)) { + if (fcoeclif_checkdir(SYSFS_MOUNT)) { fprintf(stderr, "%s: Sysfs mount point %s not found!\n", progname, SYSFS_MOUNT); - return -EINVAL; - } - /* check fcoe module */ - if (fcoeadm_checkdir(SYSFS_FCOE)) { - fprintf(stderr, - "%s: Please make sure FCoE driver module is loaded!\n", - progname); - return -EINVAL; + status = -EINVAL; } + /* check target interface */ if (!ifname) { fprintf(stderr, "%s: Invalid interface name!\n", progname); - return -EINVAL; + status = -EINVAL; } sprintf(path, "%s/%s", SYSFS_NET, ifname); - if (fcoeadm_checkdir(path)) { + if (fcoeclif_checkdir(path)) { fprintf(stderr, "%s: Interface %s not found!\n", progname, ifname); - return -EINVAL; + status = -EINVAL; } - return 0; -} - -static int fcoeadm_print_response(char *rbuf, int rlen, - char *device_name, int cmd) -{ - fprintf(stdout, "Command :\t"); - switch (cmd) { - case FCOEADM_CREATE: - fprintf(stdout, "FCOEADM CREATE\n"); - break; - case FCOEADM_RESET: - fprintf(stdout, "FCOEADM RESET\n"); - break; - case FCOEADM_DESTROY: - fprintf(stdout, "FCOEADM DELETE\n"); - break; - default: - fprintf(stderr, "BAD COMMAND\n"); + fd = open(CLIF_PID_FILE, O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + fprintf(stderr, + "%s: fcoemon was not running!\n", progname); + status = -EINVAL; } - fprintf(stdout, "Port Name:\t%s\n", device_name); - - fprintf(stdout, "Status :\t%s\n", atoi(rbuf) ? "FAIL" : "SUCCESS"); - - return 0; + return status; } static int fcoeadm_clif_request(const struct clif_data *cmd, size_t cmd_len, @@ -213,7 +168,7 @@ } rbuf[len] = '\0'; - ret = fcoeadm_print_response(rbuf, len, s, cmd); + ret = atoi(rbuf); free(data); return ret; @@ -242,9 +197,6 @@ int flen; static int counter; - if (ifname == NULL) - return NULL; - flen = strlen(FCM_SRV_DIR) + strlen(ifname) + 2; fcmon_file = malloc(flen); if (fcmon_file == NULL) @@ -317,7 +269,6 @@ clif_conn = fcoeadm_open_cli(clif_ifname); if (clif_conn) { - fprintf(stdout, "Connection established.\n"); break; } else { fprintf(stderr, "Failed to connect to fcoemon.\n"); @@ -345,7 +296,7 @@ progname, ifname); return -EINVAL; } - return fcoeadm_action(FCOEADM_CREATE, ifname); + return fcoeadm_action(FCOE_CREATE_CMD, ifname); } /* @@ -359,7 +310,7 @@ progname, ifname); return -EINVAL; } - return fcoeadm_action(FCOEADM_DESTROY, ifname); + return fcoeadm_action(FCOE_DESTROY_CMD, ifname); } /* @@ -367,7 +318,7 @@ */ static int fcoeadm_reset(char *ifname) { - return fcoeadm_action(FCOEADM_RESET, ifname); + return fcoeadm_action(FCOE_RESET_CMD, ifname); } /* @@ -540,7 +491,7 @@ sizeof(opt_info->ifname)); } if (strnlen(opt_info->ifname, IFNAMSIZ - 1)) { - if (fcoeadm_validate_interface( + if (fcoeclif_validate_interface( opt_info->ifname, fchost, FCHOSTBUFLEN)) goto done; @@ -570,7 +521,7 @@ sizeof(opt_info->ifname)); } if (strnlen(opt_info->ifname, IFNAMSIZ - 1)) { - if (fcoeadm_validate_interface( + if (fcoeclif_validate_interface( opt_info->ifname, fchost, FCHOSTBUFLEN)) goto done; @@ -601,7 +552,7 @@ strncpy(opt_info->ifname, optarg, sizeof(opt_info->ifname)); if (strnlen(opt_info->ifname, IFNAMSIZ - 1)) { - if (fcoeadm_validate_interface( + if (fcoeclif_validate_interface( opt_info->ifname, fchost, FCHOSTBUFLEN)) goto done; diff -Pur --exclude=.git fcoe-utils/fcoeadm.h fcoe-utils-tip/fcoeadm.h --- fcoe-utils/fcoeadm.h 2010-01-08 16:56:55.792000544 -0800 +++ fcoe-utils-tip/fcoeadm.h 2010-01-08 12:15:27.550000527 -0800 @@ -49,9 +49,6 @@ #include "fc_types.h" #include "fc_scsi.h" -#define __USE_GNU -#include <string.h> - #define FCOE_MAX_LUN 255 struct opt_info { @@ -72,8 +69,7 @@ /** * struct clif - Internal structure for client interface library * - * This structure is used by the fcmon and fcoeadm client interface - * libraryto store internal data. + * This structure is used by fcoeadm client interface to store internal data. */ struct clif { int s; diff -Pur --exclude=.git fcoe-utils/fcoe_clif.c fcoe-utils-tip/fcoe_clif.c --- fcoe-utils/fcoe_clif.c 2010-01-08 16:56:55.790000544 -0800 +++ fcoe-utils-tip/fcoe_clif.c 2010-01-08 12:15:27.549000527 -0800 @@ -17,6 +17,9 @@ * Maintained at www.Open-FCoE.org */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -26,15 +29,12 @@ #include <errno.h> #include "fcoe_clif.h" -static char *fcoeadm_read(const char *path) +static char *fcoeclif_read(const char *path) { FILE *fp; char *buf; int size = 512; - if (!path) - return NULL; - buf = malloc(size); if (!buf) return NULL; @@ -52,22 +52,16 @@ return NULL; } -static int fcoeadm_check_fchost(const char *ifname, const char *dname) +static int fcoeclif_check_fchost(const char *ifname, const char *dname) { char *buf; char path[512]; - if (!ifname) - return -EINVAL; - - if (!dname) - return -EINVAL; - if (dname[0] == '.') return -EINVAL; sprintf(path, "%s/%s/symbolic_name", SYSFS_FCHOST, dname); - buf = fcoeadm_read(path); + buf = fcoeclif_read(path); if (!buf) return -EINVAL; @@ -79,24 +73,18 @@ return 0; } -static int fcoeadm_find_fchost(char *ifname, char *fchost, int len) +static int fcoeclif_find_fchost(char *ifname, char *fchost, int len) { int n, dname_len; int found = 0; struct dirent **namelist; - if (!ifname) - return -EINVAL; - - if ((!fchost) || (len <= 0)) - return -EINVAL; - memset(fchost, 0, len); n = scandir(SYSFS_FCHOST, &namelist, 0, alphasort); if (n > 0) { while (n--) { /* check symbolic name */ - if (!fcoeadm_check_fchost(ifname, + if (!fcoeclif_check_fchost(ifname, namelist[n]->d_name)) { dname_len = strnlen(namelist[n]->d_name, len); if (dname_len != len) { @@ -126,12 +114,33 @@ /* * Validate an existing instance for an FC interface */ -int fcoeadm_validate_interface(char *ifname, char *fchost, int len) +int fcoeclif_validate_interface(char *ifname, char *fchost, int len) { - if (!fcoeadm_find_fchost(ifname, fchost, len)) { + if ((!ifname) || (!fchost) || (len <= 0)) + return -EINVAL; + + if (!fcoeclif_find_fchost(ifname, fchost, len)) { fprintf(stderr, "No fc_host found for %s\n", ifname); return -EINVAL; } return 0; } + + +/* + * Open and close to check if directory exists + */ +int fcoeclif_checkdir(char *dir) +{ + DIR *d = NULL; + + if (!dir) + return -EINVAL; + /* check if we have sysfs */ + d = opendir(dir); + if (!d) + return -EINVAL; + closedir(d); + return 0; +} diff -Pur --exclude=.git fcoe-utils/fcoe_clif.h fcoe-utils-tip/fcoe_clif.h --- fcoe-utils/fcoe_clif.h 2010-01-08 16:56:55.790000544 -0800 +++ fcoe-utils-tip/fcoe_clif.h 2010-01-08 12:15:27.549000527 -0800 @@ -20,16 +20,15 @@ #ifndef _FCOE_CLIF_H_ #define _FCOE_CLIF_H_ -#define FCM_SRV_DIR "/var/run/fcm" -#define CLIF_IFNAME "fcm_clif" -#define MAX_MSGBUF 512 -#define FCHOSTBUFLEN 64 #define SYSFS_MOUNT "/sys" #define SYSFS_NET SYSFS_MOUNT "/class/net" #define SYSFS_FCHOST SYSFS_MOUNT "/class/fc_host" #define SYSFS_FCOE SYSFS_MOUNT "/module/fcoe/parameters" -#define FCOE_CREATE SYSFS_FCOE "/create" -#define FCOE_DESTROY SYSFS_FCOE "/destroy" +#define FCM_SRV_DIR "/var/run/fcm" +#define CLIF_IFNAME "fcm_clif" +#define FCHOSTBUFLEN 64 +#define MAX_MSGBUF 512 +#define CLIF_PID_FILE _PATH_VARRUN "fcoemon.pid" enum clif_status { CLI_SUCCESS = 0, @@ -37,6 +36,12 @@ CLI_NO_ACTION }; +enum { + FCOE_CREATE_CMD = 1, + FCOE_DESTROY_CMD, + FCOE_RESET_CMD, +}; + /* * Description of fcoemon and fcoeadm socket data structure interface */ @@ -45,5 +50,6 @@ char ifname[IFNAMSIZ]; }; -int fcoeadm_validate_interface(char *ifname, char *fchost, int len); +int fcoeclif_validate_interface(char *ifname, char *fchost, int len); +int fcoeclif_checkdir(char *dir); #endif /* _FCOE_CLIF_H_ */ diff -Pur --exclude=.git fcoe-utils/fcoemon.c fcoe-utils-tip/fcoemon.c --- fcoe-utils/fcoemon.c 2010-01-08 16:56:55.793000544 -0800 +++ fcoe-utils-tip/fcoemon.c 2010-01-08 12:15:27.551000527 -0800 @@ -56,6 +56,7 @@ #include "net_types.h" #include "fc_types.h" +#include "fcoe_utils.h" #include "fcoemon_utils.h" #include "fcoemon.h" #include "fcoe_clif.h" @@ -75,7 +76,6 @@ #define VLAN_DIR "/proc/net/vlan" #define CLIF_NAME_PATH _PATH_VARRUN "dcbd/clif" -#define CLIF_PID_FILE _PATH_VARRUN "fcoemon.pid" #define CLIF_LOCAL_SUN_PATH _PATH_TMP "fcoemon.dcbd.%d" #define DCBD_CONNECT_TIMEOUT (10 * 1000 * 1000) /* 10 seconds */ #define DCBD_CONNECT_RETRY_TIMEOUT (1 * 1000 * 1000) /* 1 seconds */ @@ -84,8 +84,11 @@ #define FCM_PING_REQ_LEN 1 /* byte-length of dcbd PING request */ #define FCM_PING_RSP_LEN 8 /* byte-length of dcbd PING response */ -static char *fcoemon_version = \ - "fcoemon v1.0.8\n Copyright (c) 2009, Intel Corporation.\n"; +#define FCOE_CREATE SYSFS_FCOE "/create" +#define FCOE_DESTROY SYSFS_FCOE "/destroy" + +static char *fcoemon_version = +"fcoemon v" FCOE_UTILS_VERSION "\n Copyright (c) 2009, Intel Corporation.\n"; enum fcm_srv_status { fcm_success = 0, @@ -95,7 +98,6 @@ static struct fcm_srv_data *srv_data; - /* * fcoe service configuration data * Note: These information are read in from the fcoe service @@ -153,7 +155,7 @@ char *fcm_dcbd_cmd = CONFIG_DIR "/scripts/fcoeplumb"; /* Debugging routine */ -static void print_errors(char *buf, int errors); +static void print_errors(int errors); struct fcm_netif_head fcm_netif_head = TAILQ_HEAD_INITIALIZER(fcm_netif_head); @@ -323,6 +325,7 @@ rc = fcm_read_config_variable(file, val, sizeof(val), fp, "FCOE_ENABLE"); if (rc < 0) { + FCM_LOG("%s invalid format for FCOE_ENABLE setting"); fclose(fp); free(next); continue; @@ -335,6 +338,7 @@ rc = fcm_read_config_variable(file, val, sizeof(val), fp, "DCB_REQUIRED"); if (rc < 0) { + FCM_LOG("%s invalid format for DCB_REQUIRED setting"); fclose(fp); free(next); continue; @@ -366,7 +370,7 @@ * NULL - if not found */ static struct fcoe_port *fcm_find_next_fcoe_port(struct fcoe_port *p, - char *ifname) + char *ifname) { struct fcoe_port *np; @@ -390,17 +394,25 @@ } static struct fcoe_port *fcm_find_fcoe_port(char *ifname, - enum fcoeport_ifname t) + enum fcoeport_ifname t) { struct fcoe_port *p; char *fp_ifname; p = fcoe_config.port; while (p) { - if (t == FCP_CFG_IFNAME) + switch (t) { + case FCP_CFG_IFNAME: fp_ifname = p->ifname; - else + break; + case FCP_REAL_IFNAME: fp_ifname = p->real_ifname; + break; + default: + FCM_LOG("unhandled interface type [%d] for %s", + t, ifname); + return NULL; + } if (!strncmp(ifname, fp_ifname, IFNAMSIZ)) return p; @@ -552,17 +564,66 @@ ff->response_pending = 0; } +static void update_fcoe_port_state(struct fcoe_port *p, unsigned int type, + u_int8_t operstate, enum fcoeport_ifname t) +{ + struct fcm_netif *ff = NULL; + + if (type != RTM_DELLINK) { + ff = fcm_netif_lookup_create(p->real_ifname); + if (!ff) + return; + + /* Only set the ff_operstate field of the network interface + * element if this routine is being called for the real + * network interface, or, if the interface is a VLAN, if the + * network interface element has not been intialized and the + * VLAN operstate is up (if VLAN is up, then real interface is + * up). + */ + if ((t == FCP_REAL_IFNAME) || + ((t == FCP_CFG_IFNAME) && + (ff->ff_operstate == IF_OPER_UNKNOWN) && + (operstate == IF_OPER_UP))) + ff->ff_operstate = operstate; + + if (!p->fcoe_enable) { + p->action = FCP_DESTROY_IF; + return; + } + + if (operstate == IF_OPER_UP) { + if (p->dcb_required) { + /* If DCB is required, do not start the dcbd + * query sequence if this routine is being + * called for a real interface and the FCoE + * interface is configured on a VLAN. + */ + if ((t == FCP_REAL_IFNAME) && + strncmp(p->ifname, p->real_ifname, + IFNAMSIZ)) + fcm_dcbd_state_set(ff, FCD_INIT); + else + fcm_dcbd_state_set(ff, + FCD_GET_DCB_STATE); + } else { + p->action = FCP_CREATE_IF; + } + } + } else { + p->action = FCP_DESTROY_IF; + } +} + void fcm_process_link_msg(struct ifinfomsg *ip, int len, unsigned type) { struct fcoe_port *p; - struct fcm_netif *ff = NULL; struct rtattr *ap; char ifname[IFNAMSIZ]; char real_dev[IFNAMSIZ]; u_int8_t operstate; u_int64_t mac; int is_vlan; - int dcb_required_cnt; mac = is_vlan = 0; operstate = IF_OPER_UNKNOWN; @@ -608,101 +669,28 @@ /* try to find the real device name */ real_dev[0] = '\0'; - if (type != RTM_DELLINK) { - fcm_vlan_dev_real_dev(ifname, real_dev); - if (strlen(real_dev)) { - strncpy(p->real_ifname, real_dev, - strlen(real_dev)+1); - ff = fcm_netif_lookup_create(real_dev); - if (!ff) - return; - } - - if (operstate == IF_OPER_UP) { - /* if ff was just created, initialize - * operstate to the value of the VLAN - * interface. Since the VLAN interface - * is up, the underlying real interface - * should be up too. - */ - if (ff->ff_operstate == IF_OPER_UNKNOWN) - ff->ff_operstate = operstate; - - if (p->fcoe_enable) { - if (p->dcb_required) - fcm_dcbd_state_set(ff, - FCD_GET_DCB_STATE); - else - p->action = FCP_CREATE_IF; - } - } - if (!p->fcoe_enable) - p->action = FCP_DESTROY_IF; - } else { - p->action = FCP_DESTROY_IF; - } + fcm_vlan_dev_real_dev(ifname, real_dev); + if (strlen(real_dev)) + strncpy(p->real_ifname, real_dev, strlen(real_dev)+1); + update_fcoe_port_state(p, type, operstate, FCP_CFG_IFNAME); p->last_msg_type = type; } else { - /* there is an fcoe port configured to use this real netif. - * make sure structures are up to date. - */ - if (p && type != RTM_DELLINK) { + /* the ifname is not a VLAN. handle the case where it has + * an FCoE interface configured on it. + */ + if (p) { strncpy(p->real_ifname, ifname, strlen(ifname)+1); - ff = fcm_netif_lookup_create(ifname); - if (!ff) - return; - ff->ff_operstate = operstate; - if (p->fcoe_enable) { - if (!p->dcb_required && operstate == IF_OPER_UP) - p->action = FCP_CREATE_IF; - if (p->dcb_required && operstate != IF_OPER_UP) - fcm_dcbd_state_set(ff, FCD_INIT); - } else { - p->action = FCP_DESTROY_IF; - } - } else if (p && type == RTM_DELLINK) { - p->action = FCP_DESTROY_IF; - } else if (p && !p->fcoe_enable) { - p->action = FCP_DESTROY_IF; + update_fcoe_port_state(p, type, operstate, + FCP_REAL_IFNAME); } - if (!ff) - ff = fcm_netif_lookup(ifname); - if (ff) - ff->ff_operstate = operstate; - - /* scan for all fcoe port's which use this netif as a - * real netif. - */ + /* handle all FCoE ports which are on VLANs over this + * ifname. + */ p = fcm_find_fcoe_port(ifname, FCP_REAL_IFNAME); - dcb_required_cnt = 0; while (p) { - ff = fcm_netif_lookup_create(ifname); - if (!ff) - break; - ff->ff_operstate = operstate; - - if (p->fcoe_enable && p->last_msg_type != RTM_DELLINK) { - if (operstate == IF_OPER_UP) { - if (p->dcb_required) { - fcm_dcbd_state_set(ff, - FCD_GET_DCB_STATE); - dcb_required_cnt++; - } else if (!dcb_required_cnt) { - fcm_dcbd_state_set(ff, - FCD_INIT); - } - } else { - if (p->dcb_required) - fcm_dcbd_state_set(ff, - FCD_INIT); - if (type == RTM_DELLINK) - p->action = FCP_DESTROY_IF; - } - } else { - p->action = FCP_DESTROY_IF; - } - + update_fcoe_port_state(p, type, operstate, + FCP_REAL_IFNAME); p = fcm_find_next_fcoe_port(p, ifname); } } @@ -819,7 +807,6 @@ return 0; } - static void fcm_fcoe_init(void) { if (fcm_read_config_files()) @@ -1138,7 +1125,7 @@ * past the interface name. */ static struct fcm_netif *fcm_dcbd_get_port(char **msgp, size_t len_off, - size_t len_len, size_t len) + size_t len_len, size_t len) { struct fcm_netif *ff; u_int32_t if_len; @@ -1261,7 +1248,7 @@ * FCP_DESTROY_IF - if the dcb netif should not support fcoe interface * FCP_WAIT - if dcb criteria is inconclusive */ -static int validate_dcbd_info(struct fcm_netif *ff) +static enum fcp_action validate_dcbd_info(struct fcm_netif *ff) { int errors = 0; int dcbon; @@ -1334,7 +1321,7 @@ /* The dcbd state does not match the create or destroy criteria. * Log possible problems. - */ + */ if (dcbon && !ff->ff_app_info.willing) { FCM_LOG_DEV(ff, "WARNING: FCoE willing mode is false\n"); errors++; @@ -1345,7 +1332,7 @@ } if (dcbon && !ff->ff_app_info.op_mode) { FCM_LOG_DEV(ff, "WARNING: FCoE operational mode is false\n"); - print_errors("", ff->ff_app_info.op_error); + print_errors(ff->ff_app_info.op_error); errors++; } if (dcbon && !ff->ff_pfc_info.enable) { @@ -1356,9 +1343,14 @@ FCM_LOG_DEV(ff, "WARNING: PFC advertise mode is false\n"); errors++; } + if (dcbon && !ff->ff_app_info.op_mode) { + FCM_LOG_DEV(ff, "WARNING: APP:0 operational mode is false\n"); + print_errors(ff->ff_app_info.op_error); + errors++; + } if (dcbon && !ff->ff_pfc_info.op_mode) { FCM_LOG_DEV(ff, "WARNING: PFC operational mode is false\n"); - print_errors("", ff->ff_pfc_info.op_error); + print_errors(ff->ff_pfc_info.op_error); errors++; } if (dcbon && !(ff->ff_pfc_info.u.pfcup & ff->ff_app_info.u.appcfg)) { @@ -1459,7 +1451,7 @@ fcm_dcbd_state_set(ff, FCD_ERROR); } else { if (val && fcoe_config.debug) - print_errors("", val); + print_errors(val); switch (ff->ff_dcbd_state) { case FCD_GET_PFC_OPER: @@ -1492,18 +1484,6 @@ } } -/** - * fcm_dcbd_get_peer() - Response handler for get peer command - * @ff: fcoe port structure - * @resp: response buffer - * @cp: response buffer pointer, points past the interface name - * @st: status - */ -static void fcm_dcbd_get_peer(struct fcm_netif *ff, char *resp, char *cp) -{ - return; -} - /* * Handle command response. * Response buffer points past command code character in response. @@ -1554,7 +1534,7 @@ /* * check that dcbd response matches the current dcbd state. - */ + */ state = ff->ff_dcbd_state; if (((cmd == CMD_GET_CONFIG) && ((state == FCD_GET_DCB_STATE && feature == FEATURE_DCB) || @@ -1586,10 +1566,6 @@ fcm_dcbd_get_oper(ff, resp, cp); break; - case CMD_GET_PEER: - fcm_dcbd_get_peer(ff, resp, cp); - break; - default: FCM_LOG_DEV_DBG(ff, "Unknown cmd 0x%x in response: resp %s", cmd, resp); @@ -1631,7 +1607,7 @@ /* * Check if the FCoE ports which use the interface on which the * dcbd event arrived are configured to require dcb. - */ + */ p = fcm_find_fcoe_port(ff->ifname, FCP_REAL_IFNAME); while (p) { @@ -1754,7 +1730,7 @@ break; case FCP_RESET_IF: FCM_LOG_DBG("OP: RESET\n"); - if (fcoeadm_validate_interface(ifname, fchost, FCHOSTBUFLEN)) { + if (fcoeclif_validate_interface(ifname, fchost, FCHOSTBUFLEN)) { fcm_cli_reply(p->sock_reply, CLI_FAIL); return; } @@ -1827,9 +1803,8 @@ if (rc < 0) FCM_LOG_ERR(errno, "fork error"); else if (rc == 0) { /* child process */ - execlp(fcm_dcbd_cmd, fcm_dcbd_cmd, p->ifname, - p->real_ifname, qos_arg, qos, debug, syslog, - (char *)NULL); + execlp(fcm_dcbd_cmd, fcm_dcbd_cmd, p->real_ifname, + qos_arg, qos, debug, syslog, (char *)NULL); } exit(1); @@ -1972,13 +1947,13 @@ /* * Perform pending actions (dcbd queries) on network interfaces. - */ + */ TAILQ_FOREACH(ff, &fcm_netif_head, ff_list) fcm_netif_advance(ff); /* * Perform actions on FCoE ports - */ + */ i = 0; p = fcoe_config.port; while (p) { @@ -2006,6 +1981,7 @@ { printf("%s\n", fcoemon_version); printf("Usage: %s\n" + "\t [-e|--exec <exec>]\n" "\t [-f|--foreground]\n" "\t [-d|--debug]\n" "\t [-s|--syslog]\n" @@ -2384,6 +2360,9 @@ fcoe_config.use_syslog = 1; enable_syslog(1); break; + case 'e': + fcm_dcbd_cmd = optarg; + break; case 'v': printf("%s\n", fcoemon_version); return 0; @@ -2439,6 +2418,13 @@ exit(1); } fcm_pidfile_create(); + + /* check fcoe module */ + if (fcoeclif_checkdir(SYSFS_FCOE)) { + FCM_LOG_ERR(errno, "make sure FCoE driver module is loaded!"); + exit(1); + } + fcm_fcoe_init(); fcm_link_init(); /* NETLINK_ROUTE protocol */ fcm_dcbd_init(); @@ -2459,73 +2445,48 @@ /******************************************************* * The following are debug routines * *******************************************************/ +static void add_msg_to_buf(char *buf, int maxlen, char *msg, char *prefix) +{ + int len = strlen(buf); -static void print_errors(char *buf, int errors) + if (len + strlen(msg) + strlen(prefix) < maxlen) + sprintf(buf+len, "%s%s", prefix, msg); +} + +static void print_errors(int errors) { - char msg[80]; - int len, j; - int flag = 0; + char msg[256]; + int cnt = 0; memset(msg, 0, sizeof(msg)); - len = sprintf(msg, "0x%02x - ", errors); + sprintf(msg, "0x%02x - ", errors); - if (!errors) { - j = sprintf(msg + len, "none\n"); - FCM_LOG("%s %s", buf, msg); - return; - } + if (errors & 0x01) + add_msg_to_buf(msg, sizeof(msg), "mismatch with peer", + (cnt++) ? ", " : ""); - if (errors & 0x01) { - flag++; - j = sprintf(msg + len, "mismatch with peer"); - len += j; - } + if (errors & 0x02) + add_msg_to_buf(msg, sizeof(msg), "local configuration error", + (cnt++) ? ", " : ""); - if (errors & 0x02) { - if (flag++) { - j = sprintf(msg + len, ", "); - len += j; - } - j = sprintf(msg + len, "local configuration error"); - len += j; - } + if (errors & 0x04) + add_msg_to_buf(msg, sizeof(msg), "multiple TLV's received", + (cnt++) ? ", " : ""); - if (errors & 0x04) { - if (flag++) { - j = sprintf(msg + len, ", "); - len += j; - } - j = sprintf(msg + len, "multiple TLV's received"); - len += j; - } + if (errors & 0x08) + add_msg_to_buf(msg, sizeof(msg), "peer error", + (cnt++) ? ", " : ""); - if (errors & 0x08) { - if (flag++) { - j = sprintf(msg + len, ", "); - len += j; - } - j = sprintf(msg + len, "peer error"); - len += j; - } + if (errors & 0x10) + add_msg_to_buf(msg, sizeof(msg), "multiple LLDP neighbors", + (cnt++) ? ", " : ""); - if (errors & 0x10) { - if (flag++) { - j = sprintf(msg + len, ", "); - len += j; - } - j = sprintf(msg + len, "multiple LLDP neighbors"); - len += j; - } + if (errors & 0x20) + add_msg_to_buf(msg, sizeof(msg), "peer feature not present", + (cnt++) ? ", " : ""); - if (errors & 0x20) { - j = len; - if (flag++) { - j = sprintf(msg + len, ", "); - len += j; - } - j = sprintf(msg + len, "peer feature not present"); - len += j; - } + if (!errors) + add_msg_to_buf(msg, sizeof(msg), "none", ""); - FCM_LOG("%s %s\n", buf, msg); + FCM_LOG("%s\n", msg); } diff -Pur --exclude=.git fcoe-utils/fcoeplumb.in fcoe-utils-tip/fcoeplumb.in --- fcoe-utils/fcoeplumb.in 2010-01-08 16:56:55.795000544 -0800 +++ fcoe-utils-tip/fcoeplumb.in 2010-01-08 12:15:27.553000527 -0800 @@ -22,8 +22,8 @@ usage() { echo usage: $cmdname \ - '<ifname real_ifname> [--reset | --create | --destroy] [--debug] [--syslog]' \ - '[--qos-disable | --qos-enable <pri>[,<pri>]...]' >&2 + '[--debug] [--syslog]' \ + '[<ethX> --qos-disable | --qos-enable <pri>[,<pri>]...]' >&2 exit 1 } @@ -207,22 +207,20 @@ [ ${DEBUG_LOGGING} ] && $LOGGER "fcoeplumb arguments: ($*)" -ifname=$1 -shift -real_ifname=$1 +net_ifname=$1 shift while [ "$#" -ge 1 ] do case "$1" in - --reset | -r) - cmd=reset - ;; - --create | -c) - cmd=create + --qos-enable) + [ "$#" -lt 2 ] && usage + qos_list=$2 + shift ;; - --destroy | -d) - cmd=destroy + --qos-disable) + [[ "$2" =~ ^[0-9]+$ ]] && shift + qos_list="disable" ;; --debug) DEBUG_LOGGING=1 @@ -232,15 +230,6 @@ USE_SYSLOG=1 config_logging ;; - --qos-enable) - [ "$#" -lt 2 ] && usage - qos_list=$2 - shift - ;; - --qos-disable) - [[ "$2" =~ ^[0-9]+$ ]] && shift - qos_list="disable" - ;; *) echo "$cmdname: unknown parameter '$1'" >&2 usage @@ -252,19 +241,21 @@ # This must be the first to do after parsing the command arguments! # Notice that the filter ID is used in find_skbedit_filter(), # add_skbedit_filter(), replace_skbedit_filter(). -fcoe_filter_id=`get_filter_id $real_ifname $FCOE_FILTER_KEY` -fip_filter_id=`get_filter_id $real_ifname $FIP_FILTER_KEY` +fcoe_filter_id=`get_filter_id $net_ifname $FCOE_FILTER_KEY` +fip_filter_id=`get_filter_id $net_ifname $FIP_FILTER_KEY` if [ "$qos_list" == "disable" ]; then # Remove the FCoE filters - find_skbedit_filter $real_ifname $FCOE_ETHERTYPE $fcoe_filter_id + find_skbedit_filter $net_ifname $FCOE_ETHERTYPE $fcoe_filter_id found_filter=$? - [ $found_filter -le 7 ] && delete_skbedit_filter $real_ifname $found_filter $FCOE_ETHERTYPE $fcoe_filter_id + [ $found_filter -le 7 ] && delete_skbedit_filter $net_ifname \ + $found_filter $FCOE_ETHERTYPE $fcoe_filter_id # Remove the FIP filters - find_skbedit_filter $real_ifname $FIP_ETHERTYPE $fip_filter_id + find_skbedit_filter $net_ifname $FIP_ETHERTYPE $fip_filter_id found_filter=$? - [ $found_filter -le 7 ] && delete_skbedit_filter $real_ifname $found_filter $FIP_ETHERTYPE $fip_filter_id + [ $found_filter -le 7 ] && delete_skbedit_filter $net_ifname \ + $found_filter $FIP_ETHERTYPE $fip_filter_id elif [ -n $qos_list ]; then # @@ -287,7 +278,6 @@ *) echo "$cmdname: bad QOS value '$1'" >&2 usage - ;; esac if [ -z "$QOS_BEST" ]; then @@ -302,7 +292,7 @@ # If the best QOS is not found, do nothing. [ -z "$QOS_BEST" ] && exit 0 - [ ${DEBUG_LOGGING} ] && $LOGGER "$real_ifname - Choosing QOS '$QOS_BEST'" + [ ${DEBUG_LOGGING} ] && $LOGGER "$net_ifname - Choosing QOS '$QOS_BEST'" # # Setup the traffic classifier for FCoE @@ -310,45 +300,49 @@ # qos_queue=`expr $QOS_BEST` - find_multiq_qdisc $real_ifname + find_multiq_qdisc $net_ifname found_qdisc=$? if [ $found_qdisc -eq 1 ]; then # Adjust the FCoE filter - [ ${DEBUG_LOGGING} ] && $LOGGER "$real_ifname: Qdisc is found" - find_skbedit_filter $real_ifname $FCOE_ETHERTYPE $fcoe_filter_id + [ ${DEBUG_LOGGING} ] && $LOGGER "$net_ifname: Qdisc is found" + find_skbedit_filter $net_ifname $FCOE_ETHERTYPE $fcoe_filter_id found_filter=$? if [ $found_filter -gt 7 ]; then - add_skbedit_filter $real_ifname $qdisc_id $qos_queue \ + add_skbedit_filter $net_ifname $qdisc_id $qos_queue \ $FCOE_ETHERTYPE $fcoe_filter_id elif [ $found_filter -ne $qos_queue ]; then [ ${DEBUG_LOGGING} ] && $LOGGER \ - "$real_ifname: Filter is found and QOS is different" - replace_skbedit_filter $real_ifname $qos_queue $FCOE_ETHERTYPE $fcoe_filter_id + "$net_ifname: Filter is found and QOS is different" + replace_skbedit_filter $net_ifname $qos_queue \ + $FCOE_ETHERTYPE $fcoe_filter_id else [ ${DEBUG_LOGGING} ] && $LOGGER \ - "$real_ifname: Filter is found and is identical" + "$net_ifname: Filter is found and is identical" fi # Adjust the FIP filter - [ ${DEBUG_LOGGING} ] && $LOGGER "$real_ifname: Qdisc is found" - find_skbedit_filter $real_ifname $FIP_ETHERTYPE $fip_filter_id + [ ${DEBUG_LOGGING} ] && $LOGGER "$net_ifname: Qdisc is found" + find_skbedit_filter $net_ifname $FIP_ETHERTYPE $fip_filter_id found_filter=$? if [ $found_filter -gt 7 ]; then - add_skbedit_filter $real_ifname $qdisc_id $qos_queue \ + add_skbedit_filter $net_ifname $qdisc_id $qos_queue \ $FIP_ETHERTYPE $fip_filter_id elif [ $found_filter -ne $qos_queue ]; then [ ${DEBUG_LOGGING} ] && $LOGGER \ - "$ifname: Filter is found and QOS is different" - replace_skbedit_filter $real_ifname $qos_queue $FIP_ETHERTYPE $fip_filter_id + "$net_ifname: Filter is found and QOS is different" + replace_skbedit_filter $net_ifname $qos_queue \ + $FIP_ETHERTYPE $fip_filter_id else [ ${DEBUG_LOGGING} ] && $LOGGER \ - "$real_ifname: Filter is found and is identical" + "$net_ifname: Filter is found and is identical" fi else - add_multiq_qdisc $real_ifname $qdisc_id - add_skbedit_filter $real_ifname $qdisc_id $qos_queue $FCOE_ETHERTYPE $fcoe_filter_id - add_skbedit_filter $real_ifname $qdisc_id $qos_queue $FIP_ETHERTYPE $fip_filter_id + add_multiq_qdisc $net_ifname $qdisc_id + add_skbedit_filter $net_ifname $qdisc_id $qos_queue \ + $FCOE_ETHERTYPE $fcoe_filter_id + add_skbedit_filter $net_ifname $qdisc_id $qos_queue \ + $FIP_ETHERTYPE $fip_filter_id fi fi diff -Pur --exclude=.git fcoe-utils/fcoe_utils.h.in fcoe-utils-tip/fcoe_utils.h.in --- fcoe-utils/fcoe_utils.h.in 1969-12-31 16:00:00.000000000 -0800 +++ fcoe-utils-tip/fcoe_utils.h.in 2010-01-08 12:15:27.549000527 -0800 @@ -0,0 +1,6 @@ +#ifndef _FCOE_UTILS_H_ +#define _FCOE_UTILS_H_ + +#define FCOE_UTILS_VERSION "@VERSION@" + +#endif /* _FCOE_UTILS_H_ */ diff -Pur --exclude=.git fcoe-utils/fcrls.c fcoe-utils-tip/fcrls.c --- fcoe-utils/fcrls.c 1969-12-31 16:00:00.000000000 -0800 +++ fcoe-utils-tip/fcrls.c 2010-01-08 12:15:27.553000527 -0800 @@ -0,0 +1,507 @@ +/* + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <dirent.h> +#include <stdarg.h> +#include <stdbool.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <linux/types.h> +typedef __u8 u8; +typedef __u16 u16; +typedef __u32 u32; +typedef __u64 u64; +#include <linux/bsg.h> +#include <scsi/sg.h> +#include <scsi/fc/fc_els.h> +#include <scsi/scsi_bsg_fc.h> + +#define ntoh24(n) (u32) ((n)[0] << 16 | (n)[1] << 8 | (n)[2]) +#define hton24(h) { (h) >> 16 & 0xff, (h) >> 8 & 0xff, (h) & 0xff } + +#define SYSFS_FC_RPORTS "/sys/class/fc_remote_ports" + +struct rport_info { + int host_no; + int channel; + u32 number; + u32 port_id; + bool found; + bool online; +}; + +struct fcoe_fc_els_lesb { + __be32 lesb_link_fail; /* link failure count */ + __be32 lesb_vlink_fail; /* virtual link failure count */ + __be32 lesb_miss_fka; /* missing FIP keep-alive count */ + __be32 lesb_symb_err; /* symbol error during carrier count */ + __be32 lesb_err_block; /* errored block count */ + __be32 lesb_fcs_error; /* frame check sequence error count */ +} __attribute__((__packed__)); + +union rls_acc { + struct fc_els_lesb fs3; + struct fcoe_fc_els_lesb bb5; +} __attribute__((__packed__)); + +struct rls_rjt { + u8 er_resv; + u8 er_reason; + u8 er_explan; + u8 er_vendor; +} __attribute__((__packed__)); + +struct rls_rsp { + u8 rls_cmd; + u8 rls_resv[3]; + union rls_acc acc; + struct rls_rjt rjt; +} __attribute__((__packed__)); + +static char *rjt_reason[] = { + [1] = "Invalid command code", + [2] = "Invalid version level", + [3] = "Logical error", + [4] = "Invalid CT_IU size", + [5] = "Logical busy", + [7] = "Protocol error", + [9] = "Unable to perform command request", + [0xB] = "Command not supported", + [0xD] = "Server not available", + [0xE] = "Session could not be established", + [0xFF] = "Vendor specific", + [0x100] = "N/A", +}; + +static char *rjt_explan[] = { + [0] = "No additional explanation", + [1] = "Port Identifier not registered", + [2] = "Port Name not registered", + [3] = "Node Name not registered", + [4] = "Class of Service not registered", + [6] = "Initial Process Associator not registered", + [7] = "FC-4 Types not registered", + [8] = "Symbolic Port Name not registered", + [9] = "Symbolic Node Name not registered", + [0xA] = "Port Type not registered", + [0xC] = "Fabric Port Name not registered", + [0xD] = "Hard Address not registered", + [0xF] = "FC-4 Features not registered", + [0x10] = "Access denied", + [0x11] = "Unacceptable Port Identifier", + [0x12] = "Data base empty", + [0x13] = "No object registered in the specified scope", + [0x14] = "Domain ID not present", + [0x15] = "Port number not present", + [0x16] = "No device attached", + [0x17] = "invalid OX_ID-RX_ID combination", + [0x19] = "Request already in progress", + [0x1e] = "N_Port login required", + [0x29] = "insufficient resources", + [0x2a] = "unable to supply requested data", + [0x2c] = "Request not supported", + [0x2d] = "Invalid payload length", + [0x44] = "Invalid Port/Node_Name", + [0x46] = "Login Extension not supported", + [0x48] = "Authentication required", + [0x50] = "Periodic Scan Value not allowed", + [0x51] = "Periodic Scanning not supported", + [0x60] = "MAC addressing mode not supported", + [0x61] = "Proposed MAC address incorrectly formed", + [0xf0] = "Authorization Exception", + [0xf1] = "Authentication Exception", + [0xf2] = "Data base full", + [0xf3] = "Data base empty", + [0xf4] = "Processing request", + [0xf5] = "Unable to verify connection", + [0xf6] = "Devices not in a common zone", + [0x100] = "N/A", + +}; + +enum commands { + NONE = 0, + RLS_PORT, + RLS_FCID, + RLS_QUIET, + RLS_HELP, +}; + +/* RLS_QUIET */ +static bool quiet; + +/* : - has arg + * :: - has optional arg + * ; - arg is long opt + */ +static const struct option lopt[] = { + { "port", required_argument, NULL, RLS_PORT }, + { "fcid", required_argument, NULL, RLS_FCID }, + { "quiet", no_argument, NULL, RLS_QUIET }, + { "help", no_argument, NULL, RLS_HELP }, + { NULL, 0, NULL, 0 }, +}; + +static const char *lopt_usage[] = { + "rport bsg name, e.g., rport-7:0-1.", + "rport port FC_ID, e.g., 0xce000d.", + "disable verbose output.", + "print useage information.", + NULL, +}; + +#define bsg_error(format...) \ +({ \ + fprintf(stderr, "ERROR: " format); \ +}) + +#define bsg_debug(format...) \ +({ \ + if (!quiet) \ + printf("DEBUG: " format); \ +}) + +static char *els_rjt2str(int type, int code) +{ + char **str; + + str = (type == 0) ? rjt_reason : rjt_explan; + + if (code > 0xff) + code = 0x100; + + if (!str[code]) + code = 0x100; + + return str[code]; +} + +static int els_print_lesb(struct fcoe_fc_els_lesb *lesb) +{ + printf("RLS request accepted (LS_ACC), dumping status counters:\n" + "\tLink Failure Count = %u\n" + "\tVirtual Link Failure Count = %u\n" + "\tMissed Discovery Advertisement Count = %u\n" + "\tSymbol Error During Carrier Count = %u\n" + "\tErrored Block Count = %u\n" + "\tFrame Check Sequence Error Count = %u\n", + ntohl(lesb->lesb_link_fail), + ntohl(lesb->lesb_vlink_fail), + ntohl(lesb->lesb_miss_fka), + ntohl(lesb->lesb_symb_err), + ntohl(lesb->lesb_err_block), + ntohl(lesb->lesb_fcs_error)); + + return 0; +} + +static int els_print_rjt(struct rls_rjt *rjt) +{ + printf("RLS request rejected (LS_RJT), check reason code below:\n" + "\tReason Code = 0x%02x, %s.\n" + "\tExplain Code = 0x%02x, %s.\n", + rjt->er_reason, els_rjt2str(0, rjt->er_reason), + rjt->er_explan, els_rjt2str(1, rjt->er_explan)); + if (rjt->er_reason == ELS_RJT_VENDOR) + printf("\tVendor Code = 0x%02x (check with your vendor).\n", + rjt->er_vendor); + return 0; +} + +static int bsg_rport_els(int bsg, u8 els_code, void *req, int req_len, + void *rsp, int rsp_len) +{ + int rc; + char sense[96]; + struct fc_bsg_reply *reply = (struct fc_bsg_reply *)sense; + struct fc_bsg_request cdb = { + .msgcode = FC_BSG_RPT_ELS, + .rqst_data.r_els = { + .els_code = els_code, + } + }; + + struct sg_io_v4 sgio = { + .guard = 'Q', + .protocol = BSG_PROTOCOL_SCSI, + .subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT, + .request_len = sizeof(cdb), + .request = (u64)((long)&cdb), + .dout_xfer_len = req_len, + .dout_xferp = (u64)((long)req), + .din_xfer_len = rsp_len, + .din_xferp = (u64)((long)rsp), + .max_response_len = sizeof(sense), + .response = (u64)((long)&sense), + .timeout = 1000, + }; + memset(sense, 0, sizeof(sense)); + rc = ioctl(bsg, SG_IO, &sgio); + bsg_debug("ioctl returned %d: bsg_reply result=%d\n", + rc, reply->result); + return rc; +} + +static int bsg_rport_els_rls(int bsg, struct rport_info *rpi) +{ + int rc = EOPNOTSUPP; + struct fc_els_rls rls = { + .rls_cmd = ELS_RLS, + .rls_port_id = hton24(rpi->port_id), + }; + struct rls_rsp rsp; + + memset(&rsp, 0, sizeof(rsp)); + rc = bsg_rport_els(bsg, ELS_RLS, &rls, sizeof(rls), &rsp, sizeof(rsp)); + if (rc) { + bsg_error("bsg_rport_els(ELS_RLS) failed\n"); + return rc; + } + if (rsp.rls_cmd == ELS_LS_ACC) + return els_print_lesb(&rsp.acc.bb5); + + if (rsp.rls_cmd == ELS_LS_RJT) + return els_print_rjt(&rsp.rjt); + + bsg_error("Unknow response!\n"); + return EIO; +} + +static int rport_getid(struct rport_info *rpi) +{ + FILE *f; + char rp_sysfs[256]; + + if (rpi->found) + return 0; + snprintf(rp_sysfs, sizeof(rp_sysfs), "%s/rport-%d:%d-%d/port_id", + SYSFS_FC_RPORTS, rpi->host_no, rpi->channel, rpi->number); + f = fopen(rp_sysfs, "ro"); + if (!f) { + bsg_error("failed to fopen(%s)!\n", rp_sysfs); + return ENODEV; + } + if (1 != fscanf(f, "0x%6x", &rpi->port_id)) { + bsg_error("failed to fscanf(%s)\n", rp_sysfs); + fclose(f); + return ENODEV; + } + if (rpi->port_id & 0xff000000) { + bsg_error("rport %s:invalid fcid 0x%x\n", rp_sysfs, + rpi->port_id); + rpi->port_id = 0; + fclose(f); + return ENODEV; + } + fclose(f); + return 0; +} + +/* + * parse a string in format of rport-%d:%d-%d, and get the + * corresponding rport info. + * rport-%d:%d-%d + */ +static int rport_parse(const char *s, struct rport_info *rpi) +{ + if (!s) + return EINVAL; + memset(rpi, 0, sizeof(*rpi)); + if (3 != sscanf(s, "rport-%d:%d-%d", &rpi->host_no, &rpi->channel, + &rpi->number)) + return ENODEV; + if (rport_getid(rpi)) + return ENODEV; + return 0; +} + +#define RPORT_ONLINE "Online" +static int rport_check_state(struct rport_info *rpi) +{ + FILE *f; + char rp_sysfs[256]; + char rp_state[256]; + + rpi->online = false; + if (!rpi->found) + return EINVAL; + + snprintf(rp_sysfs, sizeof(rp_sysfs), "%s/rport-%d:%d-%d/port_state", + SYSFS_FC_RPORTS, rpi->host_no, rpi->channel, rpi->number); + + f = fopen(rp_sysfs, "ro"); + if (!f) { + bsg_error("failed to fopen(%s)!\n", rp_sysfs); + return ENODEV; + } + if (!fgets(rp_state, sizeof(rp_state), f)) { + bsg_error("failed to fgets(%s)!\n", rp_sysfs); + fclose(f); + return ENODEV; + } + if (strncmp(rp_state, RPORT_ONLINE, strlen(RPORT_ONLINE))) { + bsg_error("rport 0x%x %s:must be %s\n", rpi->port_id, + rp_state, RPORT_ONLINE); + fclose(f); + return ENODEV; + } + rpi->online = true; + fclose(f); + return 0; +} +/* locate rport by fcid */ +static int rport_find(struct rport_info *rpi) +{ + int n; + struct dirent **namelist; + struct rport_info rpii; + + if (rpi->found) + return 0; + + if (!rpi->port_id) + return ENODEV; + + n = scandir(SYSFS_FC_RPORTS, &namelist, 0, alphasort); + if (n < 0) { + bsg_error("failed to scandir %s\n", SYSFS_FC_RPORTS); + return ENODEV; + } + while (n--) { + if (namelist[n]->d_type != DT_DIR) + goto free_name; + if (rport_parse(namelist[n]->d_name, &rpii)) + goto free_name; + if (rpi->port_id != rpii.port_id) + goto free_name; + rpii.found = true; + memcpy(rpi, &rpii, sizeof(rpii)); + bsg_debug("found rport 0x%06x as rport-%d:%d-%d\n", + rpi->port_id, rpi->host_no, rpi->channel, + rpi->number); +free_name: + free(namelist[n]); + } + free(namelist); + return 0; +} + +static void bsg_usage(int status) +{ + int i, n; + + if (status) + bsg_error("Failed! %s (Errno %d)!\n", strerror(status), status); + + n = sizeof(lopt)/sizeof(struct option) - 1; + printf("Usage: fcrls\n"); + for (i = 0; i < n; i++) + printf("\t--%s: %s\n", lopt[i].name, lopt_usage[i]); + exit(status); +} + + +int main(int argc, char *argv[]) +{ + int rc = ENODEV; + int opt; + int bsg_dev; + char *endptr; + char *bsg_name = NULL; + struct rport_info rpi; + + rpi.found = false; + while ((opt = getopt_long(argc, argv, "", lopt, NULL)) != -1) { + switch (opt) { + case RLS_PORT: + if (rport_parse(optarg, &rpi)) { + bsg_error("%s format incorrect, must be:" + "rport-host:channel-number\n", optarg); + bsg_usage(EINVAL); + } + rpi.found = true; + goto out_rls; + case RLS_FCID: + rpi.found = false; + rpi.port_id = strtoull(optarg, &endptr, 16); + if (*endptr != '\0') { + bsg_error("%s has no valid FCID\n", optarg); + bsg_usage(EINVAL); + } + if (rport_find(&rpi)) { + bsg_error("%s is not a rport\n", optarg); + bsg_usage(ENODEV); + } + goto out_rls; + case RLS_QUIET: + quiet = true; + break; + case RLS_HELP: + bsg_usage(0); + break; + } + } +out_rls: + /* bsg device name */ + if (!rpi.found) + bsg_usage(ENODEV); + + if (asprintf(&bsg_name, "/dev/bsg/rport-%d:%d-%d", + rpi.host_no, rpi.channel, rpi.number) < 0) { + rc = ENOMEM; + bsg_error("not enough memory!\n"); + goto out_error; + } + /* open bsg device */ + bsg_dev = open(bsg_name, O_RDWR); + if (bsg_dev < 0) { + bsg_error("failed to open %s!\n", bsg_name); + goto out_free; + } + /* check port state */ + if (rport_check_state(&rpi) || (!rpi.online)) { + bsg_error("rport 0x%x is not online!\n", rpi.port_id); + goto out_close; + } + /* send rls */ + rc = bsg_rport_els_rls(bsg_dev, &rpi); + if (rc) { + bsg_error("Faild to bsg_rport_els_rls\n"); + goto out_close; + } + rc = 0; + +out_close: + close(bsg_dev); +out_free: + free(bsg_name); +out_error: + return rc; +} diff -Pur --exclude=.git fcoe-utils/fipvlan.c fcoe-utils-tip/fipvlan.c --- fcoe-utils/fipvlan.c 2010-01-08 15:43:45.071000396 -0800 +++ fcoe-utils-tip/fipvlan.c 2010-01-08 12:15:27.553000527 -0800 @@ -36,6 +36,7 @@ #include <arpa/inet.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include "fcoe_utils.h" #include "fip.h" #include "log.h" #include "list.h" @@ -45,7 +46,6 @@ /* global configuration */ char *exe; -#define VERSION_STR "0.5" struct iff { int ifindex; @@ -532,7 +532,7 @@ help(0); break; case 'v': - printf("%s version %s\n", exe, VERSION_STR); + printf("%s version %s\n", exe, FCOE_UTILS_VERSION); exit(0); break; default: diff -Pur --exclude=.git fcoe-utils/.gitignore fcoe-utils-tip/.gitignore --- fcoe-utils/.gitignore 2010-01-08 15:43:45.066000267 -0800 +++ fcoe-utils-tip/.gitignore 2010-01-08 12:15:27.543000528 -0800 @@ -15,12 +15,16 @@ # other autoconf generated files fcoe-utils.spec fcoeplumb +fcoe_utils.h # compile generated files *.o fcoeadm fcoemon fipvlan +fcping +fcnsq +fcrls etc/initd/fcoe # build.sh generated files diff -Pur --exclude=.git fcoe-utils/Makefile.am fcoe-utils-tip/Makefile.am --- fcoe-utils/Makefile.am 2010-01-08 16:56:55.788000544 -0800 +++ fcoe-utils-tip/Makefile.am 2010-01-08 12:15:27.544000527 -0800 @@ -1,5 +1,5 @@ ## target programs, to be built and installed in $(prefix)/sbin -sbin_PROGRAMS = fcoeadm fcping fipvlan fcnsq +sbin_PROGRAMS = fcoeadm fcping fipvlan fcnsq fcrls if WITH_DCB sbin_PROGRAMS += fcoemon endif @@ -12,7 +12,7 @@ ## rules for building fcoeadm ## only listed sources get packaged, so must list all headers too -fcoeadm_SOURCES = fcoeadm_display.c fcoeadm.c fcoeadm.h \ +fcoeadm_SOURCES = fcoeadm_display.c fcoeadm.c fcoeadm.h fcoe_utils.h \ include/fc_scsi.h include/fc_types.h include/net_types.h fcoe_clif.c fcoe_clif.h ## fcoeadm uses HBAAPI, so get the right flags for compiling and linking @@ -30,7 +30,8 @@ ## rules for building fcoemon ## only listed sources get packaged, so must list all headers too fcoemon_SOURCES = fcoemon_utils.c fcoemon.c fcoemon.h fcoemon_utils.h \ -include/fc_scsi.h include/fc_types.h include/net_types.h fcoe_clif.c fcoe_clif.h +fcoe_utils.h include/fc_scsi.h include/fc_types.h include/net_types.h \ +fcoe_clif.c fcoe_clif.h ## fcoemon needs headers from dcbd, get the right include path for them fcoemon_CFLAGS = $(DCBD_CFLAGS) @@ -38,7 +39,8 @@ ## rules for building fipvlan ## only listed sources get packaged, so must list all headers too -fipvlan_SOURCES = fipvlan.c include/fip.h log.c include/log.h include/list.h +fipvlan_SOURCES = fipvlan.c fcoe_utils.h include/fip.h \ +log.c include/log.h include/list.h ## install configuration file in $(prefix)/etc/fcoe fcoe_configdir = ${sysconfdir}/fcoe
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor