On 01/05/2012 08:38 PM, Mike Christie wrote:
> On 12/28/2011 02:36 AM, Mike Christie wrote:
>> On 12/22/2011 04:44 PM, pmullaney wrote:
>>> Hi all,
>>>
>>> Running into problems running under lxc. I am running iscsid in the
>>> container and when it
>>> attempts to connect to the netlink iscsi socket it is getting a
>>> connection refused(111) and
>>> the following in the log:
>>>
>>> sendmsg: bug? ctrl_fd 5
>>>
>>> which causes iscsid to exit.
>>>
>>> Any thoughts on what could be wrong?
>>>
>>
>> The iscsi netlink code never returns 111/ECONNREFUSED.
>>
>> It looks like the netlink code will return this when the netlink socket
>> is not setup.
>>
>
> Ok, I think we need to modify the iscsi netlink socket to support
> multiple namespaces.
>
> Have not been able to get this working in fedora 16 exactly, so this is
> just a guess based on looking at the code and git commits.
>
Here is a patch that should implement the needed functionality on the
netlink side. It is not optimal though, but should give us an idea if we
are on the right track.
--
You received this message because you are subscribed to the Google Groups
"open-iscsi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/open-iscsi?hl=en.
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index c1b172b..b09e02e 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -79,6 +79,14 @@ struct iscsi_internal {
struct transport_container session_cont;
};
+struct iscsi_nl_sock {
+ struct list_head list;
+ struct sock *sk;
+};
+
+static LIST_HEAD(iscsi_nl_sock_list);
+static DEFINE_SPINLOCK(iscsi_nl_sock_lock);
+
static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
static struct workqueue_struct *iscsi_eh_timer_workq;
@@ -599,7 +607,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
NULL,
NULL);
-static struct sock *nls;
static DEFINE_MUTEX(rx_queue_mutex);
static LIST_HEAD(sesslist);
@@ -1332,7 +1339,27 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
static int
iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
{
- return nlmsg_multicast(nls, skb, 0, group, gfp);
+ struct iscsi_nl_sock *nlsk;
+ struct sk_buff *cloned_skb;
+ int err, rc = 0;
+
+ spin_lock_bh(&iscsi_nl_sock_lock);
+ list_for_each_entry(nlsk, &iscsi_nl_sock_list, list) {
+ /* TODO change locking */
+ cloned_skb = skb_clone(skb, GFP_ATOMIC);
+ if (!cloned_skb) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ err = nlmsg_multicast(nlsk->sk, cloned_skb, 0, group,
+ GFP_ATOMIC);
+ if (err && !rc)
+ rc = err;
+ }
+ spin_unlock_bh(&iscsi_nl_sock_lock);
+ kfree_skb(skb);
+ return rc;
}
int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
@@ -2673,6 +2700,55 @@ int iscsi_unregister_transport(struct iscsi_transport *tt)
}
EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
+static int iscsi_pernet_init(struct net *net)
+{
+ struct iscsi_nl_sock *nlsk;
+
+ nlsk = kzalloc(sizeof(*nlsk), GFP_KERNEL);
+ if (!nlsk)
+ return -ENOMEM;
+
+ nlsk->sk = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1,
+ iscsi_if_rx, NULL, THIS_MODULE);
+ if (!nlsk->sk) {
+ printk(KERN_ERR "iscsi class: Could not create netlink "
+ "socket.\n");
+ kfree(nlsk);
+ return -ENODEV;
+ }
+
+ spin_lock_bh(&iscsi_nl_sock_lock);
+ list_add_tail(&nlsk->list, &iscsi_nl_sock_list);
+ spin_unlock_bh(&iscsi_nl_sock_lock);
+ return 0;
+}
+
+static void iscsi_pernet_exit(struct net *net)
+{
+ struct iscsi_nl_sock *nlsk;
+
+ spin_lock_bh(&iscsi_nl_sock_lock);
+ list_for_each_entry(nlsk, &iscsi_nl_sock_list, list) {
+ if (sock_net(nlsk->sk) == net)
+ goto found;
+ }
+
+ spin_unlock_bh(&iscsi_nl_sock_lock);
+ return;
+
+found:
+ list_del(&nlsk->list);
+ spin_unlock_bh(&iscsi_nl_sock_lock);
+
+ netlink_kernel_release(nlsk->sk);
+ kfree(nlsk);
+}
+
+static struct pernet_operations iscsi_pernet_ops = {
+ .init = iscsi_pernet_init,
+ .exit = iscsi_pernet_exit,
+};
+
static __init int iscsi_transport_init(void)
{
int err;
@@ -2706,21 +2782,18 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_conn_class;
- nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx,
- NULL, THIS_MODULE);
- if (!nls) {
- err = -ENOBUFS;
+ err = register_pernet_subsys(&iscsi_pernet_ops);
+ if (err)
goto unregister_session_class;
- }
iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh");
if (!iscsi_eh_timer_workq)
- goto release_nls;
+ goto unregister_pernet;
return 0;
-release_nls:
- netlink_kernel_release(nls);
+unregister_pernet:
+ unregister_pernet_subsys(&iscsi_pernet_ops);
unregister_session_class:
transport_class_unregister(&iscsi_session_class);
unregister_conn_class:
@@ -2739,7 +2812,7 @@ unregister_transport_class:
static void __exit iscsi_transport_exit(void)
{
destroy_workqueue(iscsi_eh_timer_workq);
- netlink_kernel_release(nls);
+ unregister_pernet_subsys(&iscsi_pernet_ops);
transport_class_unregister(&iscsi_connection_class);
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);