mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
[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: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
ffbfe92533
commit
790f39a2d5
1 changed files with 27 additions and 11 deletions
|
@ -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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue