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:
Bart Van Assche
2020-06-06 16:27:41 +00:00
parent c647d76ef2
commit c51cf132e1
5 changed files with 68 additions and 17 deletions
+21 -8
View File
@@ -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;
}
+3
View File
@@ -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
+1 -1
View File
@@ -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)) {
+17
View File
@@ -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
View File
@@ -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);
}