Author: mav
Date: Fri Sep 18 12:08:00 2015
New Revision: 287957
URL: https://svnweb.freebsd.org/changeset/base/287957

Log:
  Kill HA link and shutdown the threads on shutdown.

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl_ha.c
  head/sys/cam/ctl/ctl_ha.h

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c      Fri Sep 18 10:44:25 2015        (r287956)
+++ head/sys/cam/ctl/ctl.c      Fri Sep 18 12:08:00 2015        (r287957)
@@ -1581,13 +1581,12 @@ ctl_shutdown(void)
        softc = (struct ctl_softc *)control_softc;
 
        if (softc->is_single == 0) {
+               ctl_ha_msg_shutdown(softc);
                if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL)
-                   != CTL_HA_STATUS_SUCCESS) {
-                       printf("ctl_shutdown: ctl_ha_msg_deregister failed.\n");
-               }
-               if (ctl_ha_msg_shutdown(softc) != CTL_HA_STATUS_SUCCESS) {
-                       printf("ctl_shutdown: ctl_ha_msg_shutdown failed.\n");
-               }
+                   != CTL_HA_STATUS_SUCCESS)
+                       printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
+               if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
+                       printf("%s: ctl_ha_msg_destroy failed.\n", __func__);
                ctl_frontend_deregister(&ha_frontend);
        }
 

Modified: head/sys/cam/ctl/ctl_ha.c
==============================================================================
--- head/sys/cam/ctl/ctl_ha.c   Fri Sep 18 10:44:25 2015        (r287956)
+++ head/sys/cam/ctl/ctl_ha.c   Fri Sep 18 12:08:00 2015        (r287957)
@@ -155,6 +155,8 @@ struct ha_softc {
        int              ha_receiving;
        int              ha_wakeup;
        int              ha_disconnect;
+       int              ha_shutdown;
+       eventhandler_tag ha_shutdown_eh;
        TAILQ_HEAD(, ctl_ha_dt_req) ha_dts;
 } ha_softc;
 
@@ -568,10 +570,12 @@ ctl_ha_conn_thread(void *arg)
        int error;
 
        while (1) {
-               if (softc->ha_disconnect) {
+               if (softc->ha_disconnect || softc->ha_shutdown) {
                        ctl_ha_close(softc);
                        ctl_ha_lclose(softc);
                        softc->ha_disconnect = 0;
+                       if (softc->ha_shutdown)
+                               break;
                } else if (softc->ha_so != NULL &&
                    (softc->ha_so->so_error ||
                     softc->ha_so->so_rcv.sb_state & SBS_CANTRCVMORE))
@@ -614,6 +618,11 @@ ctl_ha_conn_thread(void *arg)
                softc->ha_wakeup = 0;
                mtx_unlock(&softc->ha_lock);
        }
+       mtx_lock(&softc->ha_lock);
+       softc->ha_shutdown = 2;
+       wakeup(&softc->ha_wakeup);
+       mtx_unlock(&softc->ha_lock);
+       kthread_exit();
 }
 
 static int
@@ -936,6 +945,8 @@ ctl_ha_msg_init(struct ctl_softc *ctl_so
                mtx_destroy(&softc->ha_lock);
                return (CTL_HA_STATUS_ERROR);
        }
+       softc->ha_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
+           ctl_ha_msg_shutdown, ctl_softc, SHUTDOWN_PRI_FIRST);
        SYSCTL_ADD_PROC(&ctl_softc->sysctl_ctx,
            SYSCTL_CHILDREN(ctl_softc->sysctl_tree),
            OID_AUTO, "ha_peer", CTLTYPE_STRING | CTLFLAG_RWTUN,
@@ -949,14 +960,40 @@ ctl_ha_msg_init(struct ctl_softc *ctl_so
        return (CTL_HA_STATUS_SUCCESS);
 };
 
-ctl_ha_status
+void
 ctl_ha_msg_shutdown(struct ctl_softc *ctl_softc)
 {
        struct ha_softc *softc = &ha_softc;
 
-       if (ctl_ha_msg_deregister(CTL_HA_CHAN_DATA) != CTL_HA_STATUS_SUCCESS) {
-               printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
+       /* Disconnect and shutdown threads. */
+       mtx_lock(&softc->ha_lock);
+       if (softc->ha_shutdown < 2) {
+               softc->ha_shutdown = 1;
+               softc->ha_wakeup = 1;
+               wakeup(&softc->ha_wakeup);
+               while (softc->ha_shutdown < 2) {
+                       msleep(&softc->ha_wakeup, &softc->ha_lock, 0,
+                           "shutdown", hz);
+               }
        }
+       mtx_unlock(&softc->ha_lock);
+};
+
+ctl_ha_status
+ctl_ha_msg_destroy(struct ctl_softc *ctl_softc)
+{
+       struct ha_softc *softc = &ha_softc;
+
+       if (softc->ha_shutdown_eh != NULL) {
+               EVENTHANDLER_DEREGISTER(shutdown_pre_sync,
+                   softc->ha_shutdown_eh);
+               softc->ha_shutdown_eh = NULL;
+       }
+
+       ctl_ha_msg_shutdown(ctl_softc); /* Just in case. */
+
+       if (ctl_ha_msg_deregister(CTL_HA_CHAN_DATA) != CTL_HA_STATUS_SUCCESS)
+               printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
 
        mtx_destroy(&softc->ha_lock);
        return (CTL_HA_STATUS_SUCCESS);

Modified: head/sys/cam/ctl/ctl_ha.h
==============================================================================
--- head/sys/cam/ctl/ctl_ha.h   Fri Sep 18 10:44:25 2015        (r287956)
+++ head/sys/cam/ctl/ctl_ha.h   Fri Sep 18 12:08:00 2015        (r287957)
@@ -109,7 +109,8 @@ struct ctl_ha_dt_req {
 
 struct ctl_softc;
 ctl_ha_status ctl_ha_msg_init(struct ctl_softc *softc);
-ctl_ha_status ctl_ha_msg_shutdown(struct ctl_softc *softc);
+void ctl_ha_msg_shutdown(struct ctl_softc *softc);
+ctl_ha_status ctl_ha_msg_destroy(struct ctl_softc *softc);
 
 typedef void (*ctl_evt_handler)(ctl_ha_channel channel, ctl_ha_event event,
                                int param);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to