aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl/ctl_ha.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2015-09-18 12:08:00 +0000
committerAlexander Motin <mav@FreeBSD.org>2015-09-18 12:08:00 +0000
commit59bb97a9347b3dd655f636d29f530ae453bee310 (patch)
tree5f43d443f1565836c67eb493acb4730c985d8376 /sys/cam/ctl/ctl_ha.c
parent1c69dbd09866e1ea976155618efcf8f78941a30a (diff)
downloadsrc-59bb97a9347b3dd655f636d29f530ae453bee310.tar.gz
src-59bb97a9347b3dd655f636d29f530ae453bee310.zip
Kill HA link and shutdown the threads on shutdown.
Notes
Notes: svn path=/head/; revision=287957
Diffstat (limited to 'sys/cam/ctl/ctl_ha.c')
-rw-r--r--sys/cam/ctl/ctl_ha.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c
index 952e92a8493f..13cb2e1ed660 100644
--- a/sys/cam/ctl/ctl_ha.c
+++ b/sys/cam/ctl/ctl_ha.c
@@ -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_softc)
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_softc)
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);