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 open-iscsi@googlegroups.com. To unsubscribe from this group, send email to open-iscsi+unsubscr...@googlegroups.com. 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);