Author: mav
Date: Mon Oct  5 10:37:20 2015
New Revision: 288770
URL: https://svnweb.freebsd.org/changeset/base/288770

Log:
  MFC r287940: Replicate initiators WWPNs and names between HA peers.

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/ctl/ctl.h
  stable/10/sys/cam/ctl/ctl_io.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c Mon Oct  5 10:36:28 2015        (r288769)
+++ stable/10/sys/cam/ctl/ctl.c Mon Oct  5 10:37:20 2015        (r288770)
@@ -656,14 +656,56 @@ ctl_isc_announce_port(struct ctl_port *p
        free(msg, M_CTL);
 }
 
+void
+ctl_isc_announce_iid(struct ctl_port *port, int iid)
+{
+       struct ctl_softc *softc = control_softc;
+       union ctl_ha_msg *msg;
+       int i, l;
+
+       if (port->targ_port < softc->port_min ||
+           port->targ_port >= softc->port_max ||
+           softc->ha_link != CTL_HA_LINK_ONLINE)
+               return;
+       mtx_lock(&softc->ctl_lock);
+       i = sizeof(msg->iid);
+       l = 0;
+       if (port->wwpn_iid[iid].name)
+               l = strlen(port->wwpn_iid[iid].name) + 1;
+       i += l;
+       msg = malloc(i, M_CTL, M_NOWAIT);
+       if (msg == NULL) {
+               mtx_unlock(&softc->ctl_lock);
+               return;
+       }
+       bzero(&msg->iid, sizeof(msg->iid));
+       msg->hdr.msg_type = CTL_MSG_IID_SYNC;
+       msg->hdr.nexus.targ_port = port->targ_port;
+       msg->hdr.nexus.initid = iid;
+       msg->iid.in_use = port->wwpn_iid[iid].in_use;
+       msg->iid.name_len = l;
+       msg->iid.wwpn = port->wwpn_iid[iid].wwpn;
+       if (port->wwpn_iid[iid].name)
+               strlcpy(msg->iid.data, port->wwpn_iid[iid].name, l);
+       mtx_unlock(&softc->ctl_lock);
+       ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg->iid, i, M_NOWAIT);
+       free(msg, M_CTL);
+}
+
 static void
 ctl_isc_ha_link_up(struct ctl_softc *softc)
 {
        struct ctl_port *port;
        struct ctl_lun *lun;
+       int i;
 
-       STAILQ_FOREACH(port, &softc->port_list, links)
+       STAILQ_FOREACH(port, &softc->port_list, links) {
                ctl_isc_announce_port(port);
+               for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
+                       if (port->wwpn_iid[i].in_use)
+                               ctl_isc_announce_iid(port, i);
+               }
+       }
        STAILQ_FOREACH(lun, &softc->lun_list, links)
                ctl_isc_announce_lun(lun);
 }
@@ -674,6 +716,7 @@ ctl_isc_ha_link_down(struct ctl_softc *s
        struct ctl_port *port;
        struct ctl_lun *lun;
        union ctl_io *io;
+       int i;
 
        mtx_lock(&softc->ctl_lock);
        STAILQ_FOREACH(lun, &softc->lun_list, links) {
@@ -698,6 +741,11 @@ ctl_isc_ha_link_down(struct ctl_softc *s
                    port->targ_port < softc->port_max)
                        continue;
                port->status &= ~CTL_PORT_STATUS_ONLINE;
+               for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
+                       port->wwpn_iid[i].in_use = 0;
+                       free(port->wwpn_iid[i].name, M_CTL);
+                       port->wwpn_iid[i].name = NULL;
+               }
        }
        mtx_unlock(&softc->ctl_lock);
 }
@@ -910,6 +958,29 @@ ctl_isc_port_sync(struct ctl_softc *soft
        mtx_unlock(&softc->ctl_lock);
 }
 
+static void
+ctl_isc_iid_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
+{
+       struct ctl_port *port;
+       int iid;
+
+       port = softc->ctl_ports[msg->hdr.nexus.targ_port];
+       if (port == NULL) {
+               printf("%s: Received IID for unknown port %d\n",
+                   __func__, msg->hdr.nexus.targ_port);
+               return;
+       }
+       iid = msg->hdr.nexus.initid;
+       port->wwpn_iid[iid].in_use = msg->iid.in_use;
+       port->wwpn_iid[iid].wwpn = msg->iid.wwpn;
+       free(port->wwpn_iid[iid].name, M_CTL);
+       if (msg->iid.name_len) {
+               port->wwpn_iid[iid].name = strndup(&msg->iid.data[0],
+                   msg->iid.name_len, M_CTL);
+       } else
+               port->wwpn_iid[iid].name = NULL;
+}
+
 /*
  * ISC (Inter Shelf Communication) event handler.  Events from the HA
  * subsystem come in here.
@@ -1185,6 +1256,9 @@ ctl_isc_event_handler(ctl_ha_channel cha
                case CTL_MSG_LUN_SYNC:
                        ctl_isc_lun_sync(softc, msg, param);
                        break;
+               case CTL_MSG_IID_SYNC:
+                       ctl_isc_iid_sync(softc, msg, param);
+                       break;
                default:
                        printf("Received HA message of unknown type %d\n",
                            msg->hdr.msg_type);
@@ -1599,6 +1673,7 @@ ctl_remove_initiator(struct ctl_port *po
        port->wwpn_iid[iid].in_use--;
        port->wwpn_iid[iid].last_use = time_uptime;
        mtx_unlock(&softc->ctl_lock);
+       ctl_isc_announce_iid(port, iid);
 
        return (0);
 }
@@ -1714,6 +1789,7 @@ take:
        port->wwpn_iid[iid].wwpn = wwpn;
        port->wwpn_iid[iid].in_use++;
        mtx_unlock(&softc->ctl_lock);
+       ctl_isc_announce_iid(port, iid);
 
        return (iid);
 }

Modified: stable/10/sys/cam/ctl/ctl.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl.h Mon Oct  5 10:36:28 2015        (r288769)
+++ stable/10/sys/cam/ctl/ctl.h Mon Oct  5 10:37:20 2015        (r288770)
@@ -191,6 +191,7 @@ void ctl_clr_ua_allluns(struct ctl_softc
 
 void ctl_isc_announce_lun(struct ctl_lun *lun);
 void ctl_isc_announce_port(struct ctl_port *port);
+void ctl_isc_announce_iid(struct ctl_port *port, int iid);
 
 /*
  * KPI to manipulate LUN/port options

Modified: stable/10/sys/cam/ctl/ctl_io.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_io.h      Mon Oct  5 10:36:28 2015        
(r288769)
+++ stable/10/sys/cam/ctl/ctl_io.h      Mon Oct  5 10:37:20 2015        
(r288770)
@@ -197,6 +197,7 @@ typedef enum {
        CTL_MSG_UA,                     /* Set/clear UA on secondary. */
        CTL_MSG_PORT_SYNC,              /* Information about port. */
        CTL_MSG_LUN_SYNC,               /* Information about LUN. */
+       CTL_MSG_IID_SYNC,               /* Information about initiator. */
        CTL_MSG_FAILOVER                /* Fake, never sent though the wire */
 } ctl_msg_type;
 
@@ -502,6 +503,17 @@ struct ctl_ha_msg_lun_pr_key {
        uint64_t                pr_key;
 };
 
+/*
+ * Used for CTL_MSG_IID_SYNC.
+ */
+struct ctl_ha_msg_iid {
+       struct ctl_ha_msg_hdr   hdr;
+       int                     in_use;
+       int                     name_len;
+       uint64_t                wwpn;
+       uint8_t                 data[];
+};
+
 union ctl_ha_msg {
        struct ctl_ha_msg_hdr   hdr;
        struct ctl_ha_msg_task  task;
@@ -511,6 +523,7 @@ union ctl_ha_msg {
        struct ctl_ha_msg_ua    ua;
        struct ctl_ha_msg_port  port;
        struct ctl_ha_msg_lun   lun;
+       struct ctl_ha_msg_iid   iid;
 };
 
 
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to