mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-17 12:46:27 +00:00
iscsi-scst: Add network namespace support
This patch makes it possible to run the SCST iSCSI target software inside
a Docker container that uses another network namespace than the default.
See also https://github.com/bvanassche/scst/issues/24 .
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9002 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -25,6 +25,9 @@
|
||||
#include "iscsi_trace_flag.h"
|
||||
#include "iscsi.h"
|
||||
|
||||
struct net *iscsi_net_ns;
|
||||
EXPORT_SYMBOL(iscsi_net_ns);
|
||||
|
||||
/* See also commit 2d4bc93368f5 ("netlink: extended ACK reporting") */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
|
||||
struct netlink_ext_ack;
|
||||
@@ -191,6 +194,8 @@ out_unlock:
|
||||
|
||||
int __init event_init(void)
|
||||
{
|
||||
iscsi_net_ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22))
|
||||
nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv,
|
||||
THIS_MODULE);
|
||||
@@ -198,7 +203,7 @@ int __init event_init(void)
|
||||
nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL,
|
||||
THIS_MODULE);
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
|
||||
nl = netlink_kernel_create(&init_net, NETLINK_ISCSI_SCST, 1,
|
||||
nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST, 1,
|
||||
event_recv_skb, NULL, THIS_MODULE);
|
||||
#else
|
||||
{
|
||||
@@ -207,18 +212,24 @@ int __init event_init(void)
|
||||
.groups = 1,
|
||||
};
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
|
||||
nl = netlink_kernel_create(&init_net, NETLINK_ISCSI_SCST,
|
||||
nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST,
|
||||
THIS_MODULE, &cfg);
|
||||
#else
|
||||
nl = netlink_kernel_create(&init_net, NETLINK_ISCSI_SCST, &cfg);
|
||||
nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST,
|
||||
&cfg);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (!nl) {
|
||||
PRINT_ERROR("%s", "netlink_kernel_create() failed");
|
||||
return -ENOMEM;
|
||||
} else
|
||||
return 0;
|
||||
if (!nl)
|
||||
goto drop_ns;
|
||||
|
||||
return 0;
|
||||
|
||||
drop_ns:
|
||||
PRINT_ERROR("%s", "netlink_kernel_create() failed");
|
||||
kobj_ns_drop(KOBJ_NS_TYPE_NET, iscsi_net_ns);
|
||||
iscsi_net_ns = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void event_exit(void)
|
||||
@@ -229,4 +240,6 @@ void event_exit(void)
|
||||
#else
|
||||
netlink_kernel_release(nl);
|
||||
#endif
|
||||
kobj_ns_drop(KOBJ_NS_TYPE_NET, iscsi_net_ns);
|
||||
iscsi_net_ns = NULL;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#define iscsi_sense_unexpected_unsolicited_data ABORTED_COMMAND, 0x0C, 0x0C
|
||||
#define iscsi_sense_incorrect_amount_of_data ABORTED_COMMAND, 0x0C, 0x0D
|
||||
|
||||
struct net;
|
||||
|
||||
struct iscsi_sess_params {
|
||||
int initial_r2t;
|
||||
int immediate_data;
|
||||
@@ -666,6 +668,7 @@ static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu)
|
||||
}
|
||||
|
||||
extern struct scst_tgt_template iscsi_template;
|
||||
extern struct net *iscsi_net_ns;
|
||||
|
||||
/*
|
||||
* Skip this command if result is true. Must be called under
|
||||
|
||||
@@ -1812,7 +1812,7 @@ struct isert_portal *isert_portal_create(void)
|
||||
cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP,
|
||||
IB_QPT_RC);
|
||||
#else
|
||||
cm_id = rdma_create_id(&init_net, isert_cm_evt_handler, portal,
|
||||
cm_id = rdma_create_id(iscsi_net_ns, isert_cm_evt_handler, portal,
|
||||
RDMA_PS_TCP, IB_QPT_RC);
|
||||
#endif
|
||||
if (IS_ERR(cm_id)) {
|
||||
|
||||
@@ -792,6 +792,23 @@ enum umh_wait {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* <linux/kobject_ns.h> */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
/*
|
||||
* See also commit a685e08987d1 ("Delay struct net freeing while there's a
|
||||
* sysfs instance refering to it") # v3.0.
|
||||
*/
|
||||
static inline void *kobj_ns_grab_current(enum kobj_ns_type type)
|
||||
{
|
||||
return &init_net;
|
||||
}
|
||||
|
||||
static inline void kobj_ns_drop(enum kobj_ns_type type, void *ns)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <linux/kref.h> */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) && \
|
||||
|
||||
+26
-8
@@ -179,6 +179,7 @@ static const enum scst_exec_context srpt_send_context = SCST_CONTEXT_DIRECT;
|
||||
|
||||
static struct ib_client srpt_client;
|
||||
static struct scst_tgt_template srpt_template;
|
||||
static struct net *srpt_net_ns;
|
||||
static struct rdma_cm_id *rdma_cm_id;
|
||||
|
||||
static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
@@ -4679,6 +4680,8 @@ static int __init srpt_init_module(void)
|
||||
goto out_unregister_target;
|
||||
}
|
||||
|
||||
srpt_net_ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
|
||||
|
||||
if (rdma_cm_port) {
|
||||
struct sockaddr_in addr;
|
||||
|
||||
@@ -4690,38 +4693,48 @@ static int __init srpt_init_module(void)
|
||||
rdma_cm_id = rdma_create_id(srpt_rdma_cm_handler, NULL,
|
||||
RDMA_PS_TCP, IB_QPT_RC);
|
||||
#else
|
||||
rdma_cm_id = rdma_create_id(&init_net, srpt_rdma_cm_handler,
|
||||
rdma_cm_id = rdma_create_id(srpt_net_ns, srpt_rdma_cm_handler,
|
||||
NULL, RDMA_PS_TCP, IB_QPT_RC);
|
||||
#endif
|
||||
if (IS_ERR(rdma_cm_id)) {
|
||||
ret = PTR_ERR(rdma_cm_id);
|
||||
rdma_cm_id = NULL;
|
||||
pr_err("RDMA/CM ID creation failed\n");
|
||||
goto out_unregister_client;
|
||||
goto drop_ns;
|
||||
}
|
||||
|
||||
/* We will listen on any RDMA device. */
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = cpu_to_be16(rdma_cm_port);
|
||||
if (rdma_bind_addr(rdma_cm_id, (void *)&addr)) {
|
||||
ret = rdma_bind_addr(rdma_cm_id, (void *)&addr);
|
||||
if (ret) {
|
||||
pr_err("Binding RDMA/CM ID to port %u failed\n",
|
||||
rdma_cm_port);
|
||||
goto out_unregister_client;
|
||||
goto destroy_id;
|
||||
}
|
||||
|
||||
if (rdma_listen(rdma_cm_id, 128)) {
|
||||
ret = rdma_listen(rdma_cm_id, 128);
|
||||
if (ret) {
|
||||
pr_err("rdma_listen() failed\n");
|
||||
goto out_unregister_client;
|
||||
goto destroy_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister_client:
|
||||
destroy_id:
|
||||
if (rdma_cm_id)
|
||||
rdma_destroy_id(rdma_cm_id);
|
||||
|
||||
drop_ns:
|
||||
kobj_ns_drop(KOBJ_NS_TYPE_NET, srpt_net_ns);
|
||||
srpt_net_ns = NULL;
|
||||
ib_unregister_client(&srpt_client);
|
||||
|
||||
out_unregister_target:
|
||||
scst_unregister_target_template(&srpt_template);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -4732,7 +4745,12 @@ static void __exit srpt_cleanup_module(void)
|
||||
|
||||
if (rdma_cm_id)
|
||||
rdma_destroy_id(rdma_cm_id);
|
||||
|
||||
kobj_ns_drop(KOBJ_NS_TYPE_NET, srpt_net_ns);
|
||||
srpt_net_ns = NULL;
|
||||
|
||||
ib_unregister_client(&srpt_client);
|
||||
|
||||
scst_unregister_target_template(&srpt_template);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user