[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1431555167-23995-4-git-send-email-cleech@redhat.com>
Date: Wed, 13 May 2015 15:12:46 -0700
From: Chris Leech <cleech@...hat.com>
To: <open-iscsi@...glegroups.com>, <linux-scsi@...r.kernel.org>,
netdev@...r.kernel.org
Subject: [RFC PATCH 3/4] iscsi: make all netlink multicast namespace aware
Make use of the per-net netlink sockets. Responses are sent back on the
same socket/namespace the request was received on. Async events are
reported on the socket/namespace stored in the iscsi_cls_host associated
with the event.
---
drivers/scsi/scsi_transport_iscsi.c | 92 ++++++++++++++++++++++++-------------
1 file changed, 61 insertions(+), 31 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 2b146cb..4fdd4bf 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2424,8 +2424,8 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
}
static int
-iscsi_multicast_netns(struct net *net, struct sk_buff *skb,
- uint32_t group, gfp_t gfp)
+iscsi_multicast_skb(const struct net *net, struct sk_buff *skb,
+ uint32_t group, gfp_t gfp)
{
struct sock *nls;
struct iscsi_net *isn;
@@ -2435,12 +2435,6 @@ iscsi_multicast_netns(struct net *net, struct sk_buff *skb,
return nlmsg_multicast(nls, skb, 0, group, gfp);
}
-static int
-iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
-{
- return iscsi_multicast_netns(&init_net, skb, group, gfp);
-}
-
int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size)
{
@@ -2449,6 +2443,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
struct iscsi_uevent *ev;
char *pdu;
struct iscsi_internal *priv;
+ const struct net *netns;
int len = nlmsg_total_size(sizeof(*ev) + sizeof(struct iscsi_hdr) +
data_size);
@@ -2475,7 +2470,8 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
- return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
+ netns = iscsi_conn_net(conn);
+ return iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
}
EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
@@ -2486,6 +2482,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
struct nlmsghdr *nlh;
struct sk_buff *skb;
struct iscsi_uevent *ev;
+ const struct net *netns;
int len = nlmsg_total_size(sizeof(*ev) + data_size);
skb = alloc_skb(len, GFP_ATOMIC);
@@ -2510,7 +2507,8 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
memcpy((char *)ev + sizeof(*ev), data, data_size);
- return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC);
+ netns = iscsi_host_net(shost->shost_data);
+ return iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC);
}
EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
@@ -2520,6 +2518,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
struct sk_buff *skb;
struct iscsi_uevent *ev;
struct iscsi_internal *priv;
+ const struct net *netns;
int len = nlmsg_total_size(sizeof(*ev));
priv = iscsi_if_transport_lookup(conn->transport);
@@ -2541,7 +2540,8 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
ev->r.connerror.cid = conn->cid;
ev->r.connerror.sid = iscsi_conn_get_sid(conn);
- iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
+ netns = iscsi_conn_net(conn);
+ iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n",
error);
@@ -2555,6 +2555,7 @@ void iscsi_conn_login_event(struct iscsi_cls_conn *conn,
struct sk_buff *skb;
struct iscsi_uevent *ev;
struct iscsi_internal *priv;
+ const struct net *netns;
int len = nlmsg_total_size(sizeof(*ev));
priv = iscsi_if_transport_lookup(conn->transport);
@@ -2575,7 +2576,9 @@ void iscsi_conn_login_event(struct iscsi_cls_conn *conn,
ev->r.conn_login.state = state;
ev->r.conn_login.cid = conn->cid;
ev->r.conn_login.sid = iscsi_conn_get_sid(conn);
- iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
+
+ netns = iscsi_conn_net(conn);
+ iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn login (%d)\n",
state);
@@ -2586,11 +2589,17 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
enum iscsi_host_event_code code, uint32_t data_size,
uint8_t *data)
{
+ struct Scsi_Host *shost;
+ const struct net *netns;
struct nlmsghdr *nlh;
struct sk_buff *skb;
struct iscsi_uevent *ev;
int len = nlmsg_total_size(sizeof(*ev) + data_size);
+ shost = scsi_host_lookup(host_no);
+ if (!shost)
+ return;
+
skb = alloc_skb(len, GFP_NOIO);
if (!skb) {
printk(KERN_ERR "gracefully ignored host event (%d):%d OOM\n",
@@ -2609,7 +2618,9 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
if (data_size)
memcpy((char *)ev + sizeof(*ev), data, data_size);
- iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
+ netns = iscsi_host_net(shost->shost_data);
+ scsi_host_put(shost);
+ iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
}
EXPORT_SYMBOL_GPL(iscsi_post_host_event);
@@ -2617,11 +2628,17 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
uint32_t status, uint32_t pid, uint32_t data_size,
uint8_t *data)
{
+ struct Scsi_Host *shost;
+ const struct net *netns;
struct nlmsghdr *nlh;
struct sk_buff *skb;
struct iscsi_uevent *ev;
int len = nlmsg_total_size(sizeof(*ev) + data_size);
+ shost = scsi_host_lookup(host_no);
+ if (!shost)
+ return;
+
skb = alloc_skb(len, GFP_NOIO);
if (!skb) {
printk(KERN_ERR "gracefully ignored ping comp: OOM\n");
@@ -2638,13 +2655,15 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
ev->r.ping_comp.data_size = data_size;
memcpy((char *)ev + sizeof(*ev), data, data_size);
- iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
+ netns = iscsi_host_net(shost->shost_data);
+ scsi_host_put(shost);
+ iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
}
EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
static int
-iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
- void *payload, int size)
+iscsi_if_send_reply(const struct net *netns, uint32_t group, int seq, int type,
+ int done, int multi, void *payload, int size)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
@@ -2661,11 +2680,12 @@ iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
nlh->nlmsg_flags = flags;
memcpy(nlmsg_data(nlh), payload, size);
- return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
+ return iscsi_multicast_skb(netns, skb, group, GFP_ATOMIC);
}
static int
-iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+iscsi_if_get_stats(const struct net *netns, struct iscsi_transport *transport,
+ struct nlmsghdr *nlh)
{
struct iscsi_uevent *ev = nlmsg_data(nlh);
struct iscsi_stats *stats;
@@ -2722,7 +2742,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
skb_trim(skbstat, NLMSG_ALIGN(actual_size));
nlhstat->nlmsg_len = actual_size;
- err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID,
+ err = iscsi_multicast_skb(netns, skbstat, ISCSI_NL_GRP_ISCSID,
GFP_ATOMIC);
} while (err < 0 && err != -ECONNREFUSED);
@@ -2742,6 +2762,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
struct iscsi_uevent *ev;
struct sk_buff *skb;
struct nlmsghdr *nlh;
+ const struct net *netns;
int rc, len = nlmsg_total_size(sizeof(*ev));
priv = iscsi_if_transport_lookup(session->transport);
@@ -2786,7 +2807,8 @@ int iscsi_session_event(struct iscsi_cls_session *session,
* this will occur if the daemon is not up, so we just warn
* the user and when the daemon is restarted it will handle it
*/
- rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
+ netns = iscsi_sess_net(session);
+ rc = iscsi_multicast_skb(netns, skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
if (rc == -ESRCH)
iscsi_cls_session_printk(KERN_ERR, session,
"Cannot notify userspace of session "
@@ -3108,7 +3130,8 @@ iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
}
static int
-iscsi_get_chap(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+iscsi_get_chap(const struct net *netns, struct iscsi_transport *transport,
+ struct nlmsghdr *nlh)
{
struct iscsi_uevent *ev = nlmsg_data(nlh);
struct Scsi_Host *shost = NULL;
@@ -3167,7 +3190,7 @@ iscsi_get_chap(struct iscsi_transport *transport, struct nlmsghdr *nlh)
skb_trim(skbchap, NLMSG_ALIGN(actual_size));
nlhchap->nlmsg_len = actual_size;
- err = iscsi_multicast_skb(skbchap, ISCSI_NL_GRP_ISCSID,
+ err = iscsi_multicast_skb(netns, skbchap, ISCSI_NL_GRP_ISCSID,
GFP_KERNEL);
} while (err < 0 && err != -ECONNREFUSED);
@@ -3514,7 +3537,8 @@ exit_logout_sid:
}
static int
-iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+iscsi_get_host_stats(const struct net *netns, struct iscsi_transport *transport,
+ struct nlmsghdr *nlh)
{
struct iscsi_uevent *ev = nlmsg_data(nlh);
struct Scsi_Host *shost = NULL;
@@ -3574,8 +3598,8 @@ iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
skb_trim(skbhost_stats, NLMSG_ALIGN(actual_size));
nlhhost_stats->nlmsg_len = actual_size;
- err = iscsi_multicast_skb(skbhost_stats, ISCSI_NL_GRP_ISCSID,
- GFP_KERNEL);
+ err = iscsi_multicast_skb(netns, skbhost_stats,
+ ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
} while (err < 0 && err != -ECONNREFUSED);
exit_host_stats:
@@ -3585,7 +3609,8 @@ exit_host_stats:
static int
-iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+iscsi_if_recv_msg(const struct net *netns, struct sk_buff *skb,
+ struct nlmsghdr *nlh, uint32_t *group)
{
int err = 0;
struct iscsi_uevent *ev = nlmsg_data(nlh);
@@ -3708,7 +3733,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
err = -EINVAL;
break;
case ISCSI_UEVENT_GET_STATS:
- err = iscsi_if_get_stats(transport, nlh);
+ err = iscsi_if_get_stats(netns, transport, nlh);
break;
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
case ISCSI_UEVENT_TRANSPORT_EP_POLL:
@@ -3733,7 +3758,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
err = iscsi_send_ping(transport, ev);
break;
case ISCSI_UEVENT_GET_CHAP:
- err = iscsi_get_chap(transport, nlh);
+ err = iscsi_get_chap(netns, transport, nlh);
break;
case ISCSI_UEVENT_DELETE_CHAP:
err = iscsi_delete_chap(transport, ev);
@@ -3764,7 +3789,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
nlmsg_attrlen(nlh, sizeof(*ev)));
break;
case ISCSI_UEVENT_GET_HOST_STATS:
- err = iscsi_get_host_stats(transport, nlh);
+ err = iscsi_get_host_stats(netns, transport, nlh);
break;
default:
err = -ENOSYS;
@@ -3782,6 +3807,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
static void
iscsi_if_rx(struct sk_buff *skb)
{
+ struct sock *sk = skb->sk;
+ const struct net *netns = sock_net(sk);
+
mutex_lock(&rx_queue_mutex);
while (skb->len >= NLMSG_HDRLEN) {
int err;
@@ -3801,7 +3829,7 @@ iscsi_if_rx(struct sk_buff *skb)
if (rlen > skb->len)
rlen = skb->len;
- err = iscsi_if_recv_msg(skb, nlh, &group);
+ err = iscsi_if_recv_msg(netns, skb, nlh, &group);
if (err) {
ev->type = ISCSI_KEVENT_IF_ERROR;
ev->iferror = err;
@@ -3817,7 +3845,9 @@ iscsi_if_rx(struct sk_buff *skb)
break;
if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
break;
- err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
+ if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err)
+ break;
+ err = iscsi_if_send_reply(netns, group, nlh->nlmsg_seq,
nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
} while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
skb_pull(skb, rlen);
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists