--- a/usr/src/uts/common/fs/nfs/nfs_server.c Thu Feb 05 11:59:59 2009 -0500
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c Thu Feb 05 10:03:55 2009 -0800
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -70,6 +70,7 @@
#include <rpc/auth_des.h>
#include <rpc/svc.h>
#include <rpc/xdr.h>
+#include <rpc/rpc_rdma.h>
#include <nfs/nfs.h>
#include <nfs/export.h>
@@ -552,6 +553,8 @@
{
int error;
rdma_xprt_group_t started_rdma_xprts;
+ rdma_stat stat;
+ int svc_state = 0;
/* Double check the vers min/max ranges */
if ((rsa->nfs_versmin > rsa->nfs_versmax) ||
@@ -580,15 +583,52 @@
started_rdma_xprts.rtg_count = 0;
started_rdma_xprts.rtg_listhead = NULL;
started_rdma_xprts.rtg_poolid = rsa->poolid;
+
+restart:
error = svc_rdma_kcreate(rsa->netid, &nfs_sct_rdma, rsa->poolid,
&started_rdma_xprts);
- if (error == 0) {
- mutex_enter(&rdma_wait_mutex);
- if (!cv_wait_sig(&rdma_wait_cv, &rdma_wait_mutex)) {
- rdma_stop(started_rdma_xprts);
+ svc_state = !error;
+
+ while (!error) {
+
+ /*
+ * wait till either interrupted by a signal on
+ * nfs service stop/restart or signalled by a
+ * rdma plugin attach/detatch.
+ */
+
+ stat = rdma_kwait();
+
+ /*
+ * stop services if running -- either on a HCA detach event
+ * or if the nfs service is stopped/restarted.
+ */
+
+ if ((stat == RDMA_HCA_DETACH || stat == RDMA_INTR) &&
+ svc_state) {
+ rdma_stop(&started_rdma_xprts);
+ svc_state = 0;
}
- mutex_exit(&rdma_wait_mutex);
+
+ /*
+ * nfs service stop/restart, break out of the
+ * wait loop and return;
+ */
+ if (stat == RDMA_INTR)
+ return (0);
+
+ /*
+ * restart stopped services on a HCA attach event
+ * (if not already running)
+ */
+
+ if ((stat == RDMA_HCA_ATTACH) && (svc_state == 0))
+ goto restart;
+
+ /*
+ * loop until a nfs service stop/restart
+ */
}
return (error);