HACK start with smb_transport_direct...
authorStefan Metzmacher <metze@samba.org>
Fri, 10 Aug 2012 13:36:16 +0000 (15:36 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 18 Sep 2012 03:10:21 +0000 (05:10 +0200)
libcli/smb/smb_transport_direct.c [new file with mode: 0644]
libcli/smb/wscript
wscript

diff --git a/libcli/smb/smb_transport_direct.c b/libcli/smb/smb_transport_direct.c
new file mode 100644 (file)
index 0000000..c8c0fc8
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+   Unix SMB/CIFS implementation.
+   Infrastructure for SMB-Direct RDMA as transport
+   Copyright (C) Stefan Metzmacher 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include <tevent.h>
+#include "../util/tevent_ntstatus.h"
+#include "../lib/tsocket/tsocket.h"
+
+#ifdef SMB_TRANSPORT_ENABLE_RDMA
+#include <rdma/rdma_cma_abi.h>
+#include <rdma/rdma_cma.h>
+#include <infiniband/verbs.h>
+
+struct smb_direct_transport {
+       struct {
+               struct rdma_cm_id *cm_id;
+               struct rdma_event_channel *cm_channel;
+               struct tevent_fd *fde_channel;
+               enum rdma_cm_event_type expected_event;
+               struct rdma_cm_event *cm_event;
+       } rdma;
+};
+
+static int smb_direct_transport_destructor(struct smb_direct_transport *t);
+
+static struct smb_direct_transport *smb_direct_transport_create(TALLOC_CTX *mem_ctx)
+{
+       struct smb_direct_transport *t;
+       int ret;
+
+       t = talloc_zero(mem_ctx, struct smb_direct_transport);
+       if (t == NULL) {
+               return NULL;
+       }
+       talloc_set_destructor(t, smb_direct_transport_destructor);
+
+       t->rdma.cm_channel = rdma_create_event_channel();
+       if (t->rdma.cm_channel == NULL) {
+               talloc_free(t);
+               return NULL;
+       }
+
+#if RDMA_USER_CM_MAX_ABI_VERSION >= 2
+       ret = rdma_create_id(t->rdma.cm_channel,
+                            &t->rdma.cm_id,
+                            t, RDMA_PS_TCP);
+#else
+       ret = rdma_create_id(t->rdma.cm_channel,
+                            &t->rdma.cm_id,
+                            t);
+#endif
+       if (ret != 0) {
+               talloc_free(t);
+               return NULL;
+       }
+
+       return t;
+}
+
+static int smb_direct_transport_destructor(struct smb_direct_transport *t)
+{
+       TALLOC_FREE(t->rdma.fde_channel);
+
+       if (t->rdma.cm_event != NULL) {
+               rdma_ack_cm_event(t->rdma.cm_event);
+               t->rdma.cm_event = NULL;
+       }
+
+       if (t->rdma.cm_id != NULL) {
+               rdma_destroy_id(t->rdma.cm_id);
+               t->rdma.cm_id = NULL;
+       }
+
+       if (t->rdma.cm_channel != NULL) {
+               rdma_destroy_event_channel(t->rdma.cm_channel);
+               t->rdma.cm_channel = NULL;
+       }
+
+       return 0;
+}
+
+struct smb_direct_rdma_connect_state {
+       struct smb_direct_transport *t;
+};
+
+static struct tevent_req *smb_direct_rdma_connect_send(TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct smb_direct_transport *transport,
+                                       struct tsocket_address *local_addr,
+                                       struct tsocket_address *remote_addr)
+{
+       struct tevent_req *req;
+       struct smb_direct_rdma_connect_state *state;
+       int ret;
+       struct sockaddr *src_addr, *dst_addr;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_direct_rdma_connect_state);
+       if (!req) {
+               return NULL;
+       }
+       state->t = transport;
+
+/*
+ * ret = smb_direct_transport_setup_ev(transport, ev);
+       if (ret != 0) {
+
+       }
+*/
+       ret = rdma_resolve_addr(state->t->rdma.cm_id,
+                               src_addr, dst_addr,
+                               5000);
+       if (ret != 0) {
+       }
+       state->t->rdma.expected_event = RDMA_CM_EVENT_ADDR_RESOLVED;
+
+       return req;
+}
+
+static void smb_direct_rdma_connect_handler(struct tevent_context *ev,
+                                           struct tevent_fd *fde,
+                                           uint16_t flags,
+                                           void *private_data)
+{
+       struct tevent_req *req =
+               talloc_get_type_abort(private_data,
+               struct tevent_req);
+       struct smb_direct_rdma_connect_state *state =
+               tevent_req_data(req,
+               struct smb_direct_rdma_connect_state);
+       int ret;
+
+       ret = rdma_get_cm_event(state->t->rdma.cm_channel,
+                               &state->t->rdma.cm_event);
+       if (ret != 0) {
+
+       }
+
+       if (state->t->rdma.cm_event->status != 0) {
+
+       }
+
+       if (state->t->rdma.cm_event->event != state->t->rdma.expected_event) {
+
+       }
+
+       switch (state->t->rdma.cm_event->event) {
+       case RDMA_CM_EVENT_ADDR_RESOLVED:
+               ret = rdma_resolve_route(state->t->rdma.cm_id, 5000);
+               if (ret != 0) {
+
+               }
+               break;
+       case RDMA_CM_EVENT_ADDR_ERROR:
+               break;
+       case RDMA_CM_EVENT_ROUTE_RESOLVED:
+
+       case RDMA_CM_EVENT_ROUTE_ERROR:
+       case RDMA_CM_EVENT_CONNECT_REQUEST:
+       case RDMA_CM_EVENT_CONNECT_RESPONSE:
+       case RDMA_CM_EVENT_CONNECT_ERROR:
+       case RDMA_CM_EVENT_UNREACHABLE:
+       case RDMA_CM_EVENT_REJECTED:
+       case RDMA_CM_EVENT_ESTABLISHED:
+       case RDMA_CM_EVENT_DISCONNECTED:
+       case RDMA_CM_EVENT_DEVICE_REMOVAL:
+       case RDMA_CM_EVENT_MULTICAST_JOIN:
+       case RDMA_CM_EVENT_MULTICAST_ERROR:
+       case RDMA_CM_EVENT_ADDR_CHANGE:
+       case RDMA_CM_EVENT_TIMEWAIT_EXIT:
+               //error
+               break;
+       }
+
+       if (state->t->rdma.cm_event != NULL) {
+               rdma_ack_cm_event(state->t->rdma.cm_event);
+               state->t->rdma.cm_event = NULL;
+       }
+}
+
+static NTSTATUS smb_transport_direct_rdma_connect_recv(struct tevent_req *req)
+{
+       struct smb_direct_rdma_connect_state *state =
+               tevent_req_data(req,
+               struct smb_direct_rdma_connect_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       tevent_req_received(req);
+       return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+#endif /* SMB_TRANSPORT_ENABLE_RDMA */
index ae65d684df10701847eaff3faedaac32c1c1272b..5b12e115ad9f76186f66817899bcb6eef2033a4d 100755 (executable)
@@ -1,12 +1,33 @@
 #!/usr/bin/env python
 
 
+def set_options(opt):
+    return
+
+def configure(conf):
+    rdma = conf.CHECK_FUNCS_IN('rdma_connect', 'rdmacm',
+                               headers='rdma/rdma_cma.h')
+
+    ibverbs = conf.CHECK_FUNCS_IN('ibv_create_qp', 'ibverbs',
+                                  headers='infiniband/verbs.h')
+
+    hdrs = conf.CHECK_HEADERS('''
+                              rdma/rdma_cma_abi.h
+                              rdma/rdma_cma.h
+                              infiniband/verbs.h
+                              ''',
+                              together=True)
+
+    if rdma and ibverbs and hdrs:
+        conf.DEFINE('SMB_TRANSPORT_ENABLE_RDMA', 1)
+
 def build(bld):
     bld.SAMBA_LIBRARY('smb_transport',
         source='''
             read_smb.c
+            smb_transport_direct.c
         ''',
-        deps='errors LIBASYNC_REQ',
+        deps='errors LIBASYNC_REQ rdmacm ibverbs',
         public_deps='talloc tevent samba-util',
         private_library=True,
         public_headers='''
diff --git a/wscript b/wscript
index 4f823102dd5cf31131d6331671ae614e9fdd3ceb..707da37b2a56d485257b94b39c6bea6b9c2c008b 100755 (executable)
--- a/wscript
+++ b/wscript
@@ -43,6 +43,7 @@ def set_options(opt):
     opt.RECURSE('lib/nss_wrapper')
     opt.RECURSE('lib/socket_wrapper')
     opt.RECURSE('lib/uid_wrapper')
+    opt.RECURSE('libcli/smb')
     opt.RECURSE('pidl')
     opt.RECURSE('source3')
     opt.RECURSE('lib/util')
@@ -140,6 +141,7 @@ def configure(conf):
     conf.RECURSE('lib/subunit/c')
     conf.RECURSE('libcli/smbreadline')
     conf.RECURSE('lib/crypto')
+    conf.RECURSE('libcli/smb')
     conf.RECURSE('pidl')
     conf.RECURSE('selftest')
     conf.RECURSE('source3')