Commit 790f39a2 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] iscsi: support mutiple daemons

Patch from david.somayajulu@qlogic.com and cleaned up by Tomo.

qla4xxx is going to have a different daemon so this patch
just routes the events to the right daemon.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ffbfe925
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define ISCSI_HOST_ATTRS 0 #define ISCSI_HOST_ATTRS 0
struct iscsi_internal { struct iscsi_internal {
int daemon_pid;
struct scsi_transport_template t; struct scsi_transport_template t;
struct iscsi_transport *iscsi_transport; struct iscsi_transport *iscsi_transport;
struct list_head list; struct list_head list;
...@@ -145,7 +146,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, ...@@ -145,7 +146,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
NULL); NULL);
static struct sock *nls; static struct sock *nls;
static int daemon_pid;
static DEFINE_MUTEX(rx_queue_mutex); static DEFINE_MUTEX(rx_queue_mutex);
struct mempool_zone { struct mempool_zone {
...@@ -572,13 +572,13 @@ mempool_zone_get_skb(struct mempool_zone *zone) ...@@ -572,13 +572,13 @@ mempool_zone_get_skb(struct mempool_zone *zone)
} }
static int static int
iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
{ {
unsigned long flags; unsigned long flags;
int rc; int rc;
skb_get(skb); skb_get(skb);
rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT); rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
if (rc < 0) { if (rc < 0) {
mempool_free(skb, zone->pool); mempool_free(skb, zone->pool);
printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
...@@ -600,9 +600,14 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, ...@@ -600,9 +600,14 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
struct sk_buff *skb; struct sk_buff *skb;
struct iscsi_uevent *ev; struct iscsi_uevent *ev;
char *pdu; char *pdu;
struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
data_size); data_size);
priv = iscsi_if_transport_lookup(conn->transport);
if (!priv)
return -EINVAL;
mempool_zone_complete(conn->z_pdu); mempool_zone_complete(conn->z_pdu);
skb = mempool_zone_get_skb(conn->z_pdu); skb = mempool_zone_get_skb(conn->z_pdu);
...@@ -613,7 +618,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, ...@@ -613,7 +618,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
return -ENOMEM; return -ENOMEM;
} }
nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
ev = NLMSG_DATA(nlh); ev = NLMSG_DATA(nlh);
memset(ev, 0, sizeof(*ev)); memset(ev, 0, sizeof(*ev));
ev->transport_handle = iscsi_handle(conn->transport); ev->transport_handle = iscsi_handle(conn->transport);
...@@ -626,7 +631,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, ...@@ -626,7 +631,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
return iscsi_unicast_skb(conn->z_pdu, skb); return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
} }
EXPORT_SYMBOL_GPL(iscsi_recv_pdu); EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
...@@ -635,8 +640,13 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ...@@ -635,8 +640,13 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct sk_buff *skb; struct sk_buff *skb;
struct iscsi_uevent *ev; struct iscsi_uevent *ev;
struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev)); int len = NLMSG_SPACE(sizeof(*ev));
priv = iscsi_if_transport_lookup(conn->transport);
if (!priv)
return;
mempool_zone_complete(conn->z_error); mempool_zone_complete(conn->z_error);
skb = mempool_zone_get_skb(conn->z_error); skb = mempool_zone_get_skb(conn->z_error);
...@@ -646,7 +656,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ...@@ -646,7 +656,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
return; return;
} }
nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
ev = NLMSG_DATA(nlh); ev = NLMSG_DATA(nlh);
ev->transport_handle = iscsi_handle(conn->transport); ev->transport_handle = iscsi_handle(conn->transport);
ev->type = ISCSI_KEVENT_CONN_ERROR; ev->type = ISCSI_KEVENT_CONN_ERROR;
...@@ -656,7 +666,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ...@@ -656,7 +666,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
ev->r.connerror.cid = conn->cid; ev->r.connerror.cid = conn->cid;
ev->r.connerror.sid = iscsi_conn_get_sid(conn); ev->r.connerror.sid = iscsi_conn_get_sid(conn);
iscsi_unicast_skb(conn->z_error, skb); iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid);
dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
error); error);
...@@ -686,7 +696,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, ...@@ -686,7 +696,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
nlh->nlmsg_flags = flags; nlh->nlmsg_flags = flags;
memcpy(NLMSG_DATA(nlh), payload, size); memcpy(NLMSG_DATA(nlh), payload, size);
return iscsi_unicast_skb(z_reply, skb); return iscsi_unicast_skb(z_reply, skb, pid);
} }
static int static int
...@@ -698,12 +708,17 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) ...@@ -698,12 +708,17 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
struct iscsi_cls_conn *conn; struct iscsi_cls_conn *conn;
struct nlmsghdr *nlhstat; struct nlmsghdr *nlhstat;
struct iscsi_uevent *evstat; struct iscsi_uevent *evstat;
struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev) + int len = NLMSG_SPACE(sizeof(*ev) +
sizeof(struct iscsi_stats) + sizeof(struct iscsi_stats) +
sizeof(struct iscsi_stats_custom) * sizeof(struct iscsi_stats_custom) *
ISCSI_STATS_CUSTOM_MAX); ISCSI_STATS_CUSTOM_MAX);
int err = 0; int err = 0;
priv = iscsi_if_transport_lookup(transport);
if (!priv)
return -EINVAL;
conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid); conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
if (!conn) if (!conn)
return -EEXIST; return -EEXIST;
...@@ -720,7 +735,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) ...@@ -720,7 +735,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
return -ENOMEM; return -ENOMEM;
} }
nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0, nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0,
(len - sizeof(*nlhstat)), 0); (len - sizeof(*nlhstat)), 0);
evstat = NLMSG_DATA(nlhstat); evstat = NLMSG_DATA(nlhstat);
memset(evstat, 0, sizeof(*evstat)); memset(evstat, 0, sizeof(*evstat));
...@@ -746,7 +761,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) ...@@ -746,7 +761,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
skb_trim(skbstat, NLMSG_ALIGN(actual_size)); skb_trim(skbstat, NLMSG_ALIGN(actual_size));
nlhstat->nlmsg_len = actual_size; nlhstat->nlmsg_len = actual_size;
err = iscsi_unicast_skb(conn->z_pdu, skbstat); err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
} while (err < 0 && err != -ECONNREFUSED); } while (err < 0 && err != -ECONNREFUSED);
return err; return err;
...@@ -981,6 +996,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -981,6 +996,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (!try_module_get(transport->owner)) if (!try_module_get(transport->owner))
return -EINVAL; return -EINVAL;
priv->daemon_pid = NETLINK_CREDS(skb)->pid;
switch (nlh->nlmsg_type) { switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION: case ISCSI_UEVENT_CREATE_SESSION:
err = iscsi_if_create_session(priv, ev); err = iscsi_if_create_session(priv, ev);
...@@ -1073,7 +1090,6 @@ iscsi_if_rx(struct sock *sk, int len) ...@@ -1073,7 +1090,6 @@ iscsi_if_rx(struct sock *sk, int len)
skb_pull(skb, skb->len); skb_pull(skb, skb->len);
goto free_skb; goto free_skb;
} }
daemon_pid = NETLINK_CREDS(skb)->pid;
while (skb->len >= NLMSG_SPACE(0)) { while (skb->len >= NLMSG_SPACE(0)) {
int err; int err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment