Currently fcoemon create and destroy operations while DCB not
operational are very misleading and un-deterministic, for
instance on DCB required interface after FCoE APP is disabled
and then:-

- creating interface after deleting it, results  in
  internal error after long wait.

  #[root@vinit upstream]# fcoeadm -c eth1.172
  fcoeadm: Internal error

- creating again results in different error as.

  #fcoeadm -c eth1.172
   fcoeadm: Connection already created on interface eth1.172

- deleting after "Connection already created" error on last
  create, results in no action.

  #fcoeadm -d eth1.172-fcoe
  fcoeadm: No action was taken

- deleting interface first time succeeds but second delete fails
with misleading prints as "No action was taken"

This patch fixes these inconsistent behaviors, it adds new
error code to prints out reason of creation failures due to
DCB being not ready. However allows successful deletion while
DCB not ready.

Also returns "no connection created on the interface"
error on attempt to delete again on the previously already deleted
interface or failed creation due DCB being not ready.

This patch also cleanups return error code handling by
have it processed at one place and freeing sock_reply there
since currently some places sock_reply is not freed after
responding with error code and does reply processing at multiple
places.

Checkpatch warnings on not using -ve errno are pre-existing
with this patch and these should be fixed separately with all
its pre-existing uses.

Signed-off-by: Vasu Dev <vasu....@intel.com>
Tested-by: Marcus Dennis <marcusx.e.den...@intel.com>
---

 fcoeadm.c            |    4 ++++
 fcoemon.c            |   54 ++++++++++++++++++++++++--------------------------
 include/fcoe_utils.h |    1 +
 3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/fcoeadm.c b/fcoeadm.c
index 795b12a..6f3e6ae 100644
--- a/fcoeadm.c
+++ b/fcoeadm.c
@@ -464,6 +464,10 @@ err:
                        FCOE_LOG_ERR("Connection to fcoemon timed out\n");
                        break;
 
+               case EDCBNOTRDY:
+                       FCOE_LOG_ERR("DCB not ready on the DCB required i/f\n");
+                       break;
+
                case EHBAAPIERR:
                        FCOE_LOG_ERR("libHBAAPI or libhbalinux error\n");
                        break;
diff --git a/fcoemon.c b/fcoemon.c
index 42ed61d..ad80ced 100644
--- a/fcoemon.c
+++ b/fcoemon.c
@@ -154,7 +154,7 @@ static void fcm_dcbd_rx(void *);
 static void fcm_dcbd_event(char *, size_t);
 static void fcm_dcbd_cmd_resp(char *, cmd_status);
 static void fcm_netif_advance(struct fcm_netif *);
-static void fcm_fcoe_action(struct fcm_netif *, struct fcoe_port *);
+static int fcm_fcoe_action(struct fcm_netif *, struct fcoe_port *);
 static void fcp_set_next_action(struct fcoe_port *, enum fcp_action);
 static enum fcoe_status fcm_fcoe_if_action(char *, char *);
 
@@ -2568,7 +2568,7 @@ int fcm_start_vlan_disc(struct fcoe_port *p)
  *         action = 2      Create the FCoE interface
  *         action = 3      Reset the interface
  */
-static void fcm_fcoe_action(struct fcm_netif *ff, struct fcoe_port *p)
+static int fcm_fcoe_action(struct fcm_netif *ff, struct fcoe_port *p)
 {
        struct fcoe_port *vp;
        char *ifname = p->ifname;
@@ -2631,10 +2631,8 @@ static void fcm_fcoe_action(struct fcm_netif *ff, struct 
fcoe_port *p)
        case FCP_RESET_IF:
                FCM_LOG_DBG("OP: RESET %s\n", p->ifname);
 
-               if (strlen(p->fchost) <= 0)  {
-                       fcm_cli_reply(p->sock_reply, ENOFCHOST);
-                       return;
-               }
+               if (strlen(p->fchost) <= 0)
+                       return ENOFCHOST;
 
                sprintf(path, "%s/%s/issue_lip", SYSFS_FCHOST, p->fchost);
                FCM_LOG_DBG("OP: RESET %s\n", path);
@@ -2642,10 +2640,8 @@ static void fcm_fcoe_action(struct fcm_netif *ff, struct 
fcoe_port *p)
                break;
        case FCP_SCAN_IF:
                FCM_LOG_DBG("OP: SCAN %s\n", p->ifname);
-               if (strlen(p->fchost) <= 0)  {
-                       fcm_cli_reply(p->sock_reply, ENOFCHOST);
-                       return;
-               }
+               if (strlen(p->fchost) <= 0)
+                       return ENOFCHOST;
 
                sprintf(path, "%s/%s/device/scsi_host/%s/scan",
                        SYSFS_FCHOST, p->fchost, p->fchost);
@@ -2657,17 +2653,12 @@ static void fcm_fcoe_action(struct fcm_netif *ff, 
struct fcoe_port *p)
                rc = fcm_start_vlan_disc(p);
                break;
        default:
-               return;
+               return rc;
                break;
        }
 
-       if (p->sock_reply) {
-               fcm_cli_reply(p->sock_reply, rc);
-               free(p->sock_reply);
-               p->sock_reply = NULL;
-       }
-
        p->last_action = p->action;
+       return rc;
 }
 
 /*
@@ -2794,6 +2785,7 @@ static void fcm_handle_changes()
 {
        struct fcm_netif *ff;
        struct fcoe_port *p;
+       int rc;
 
        /*
         * Perform pending actions (dcbd queries) on network interfaces.
@@ -2808,19 +2800,25 @@ static void fcm_handle_changes()
        while (p) {
                ff = fcm_netif_lookup(p->real_ifname);
                if (!ff) {
-                       if (p->sock_reply) {
-                               fcm_cli_reply(p->sock_reply, ENOETHDEV);
-                               free(p->sock_reply);
-                               p->sock_reply = NULL;
-                               p->action = FCP_WAIT;
-                       }
+                       rc = ENOETHDEV;
+                       p->action = FCP_WAIT;
                        goto next_port;
                }
 
-               fcm_fcoe_action(ff, p);
+               rc = fcm_fcoe_action(ff, p);
 
-               fcp_set_next_action(p, FCP_WAIT);
 next_port:
+               if (p->sock_reply) {
+                       if (p->dcb_required && !ff->ff_enabled && rc == SUCCESS
+                           && p->action != FCP_DESTROY_IF) {
+                               rc = EDCBNOTRDY;
+                               p->fcoe_enable = 0;
+                       }
+                       fcm_cli_reply(p->sock_reply, rc);
+                       free(p->sock_reply);
+                       p->sock_reply = NULL;
+               }
+               fcp_set_next_action(p, FCP_WAIT);
                p = p->next;
        }
 }
@@ -3065,19 +3063,19 @@ static enum fcoe_status fcm_cli_destroy(char *ifname,
                        p->fcoe_enable = 0;
 
                        if (p->last_action == FCP_DESTROY_IF)
-                               return ENOACTION;
+                               return ENOFCOECONN;
 
                        fcp_set_next_action(p, FCP_DESTROY_IF);
                        p->sock_reply = *r;
                        return SUCCESS;
                } else {
                        /* no action needed */
-                       return ENOACTION;
+                       return ENOFCOECONN;
                }
        }
 
        FCM_LOG_ERR(errno, "%s is not in port list.\n", ifname);
-       return EFAIL;
+       return ENOFCOECONN;
 }
 
 static enum fcoe_status fcm_cli_action(char *ifname, int cmd,
diff --git a/include/fcoe_utils.h b/include/fcoe_utils.h
index ca3288c..a22df3c 100644
--- a/include/fcoe_utils.h
+++ b/include/fcoe_utils.h
@@ -71,6 +71,7 @@ enum fcoe_status {
        ENOETHDEV,    /* Not a valid Ethernet interface */
        ENOMONCONN,   /* Not connected to fcoemon */
        ECONNTMOUT,   /* Connection to fcoemon timed out */
+       EDCBNOTRDY,   /* DCB not ready while interface requires DCB */
        EHBAAPIERR,   /* Error using HBAAPI/libhbalinux */
 };
 

_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to