aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-05-18 21:31:39 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-05-20 10:35:51 -0400
commit790f39a2d5f03623b027f340b945f135d006ceba (patch)
tree5a591a6c7952d758d0f9a8d7874020cc3d4f8571
parentffbfe92533810bf1bb76fd275400825ef8898ed9 (diff)
[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>
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 44adafac861f..5569fdcfd621 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -36,6 +36,7 @@
36#define ISCSI_HOST_ATTRS 0 36#define ISCSI_HOST_ATTRS 0
37 37
38struct iscsi_internal { 38struct iscsi_internal {
39 int daemon_pid;
39 struct scsi_transport_template t; 40 struct scsi_transport_template t;
40 struct iscsi_transport *iscsi_transport; 41 struct iscsi_transport *iscsi_transport;
41 struct list_head list; 42 struct list_head list;
@@ -145,7 +146,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
145 NULL); 146 NULL);
146 147
147static struct sock *nls; 148static struct sock *nls;
148static int daemon_pid;
149static DEFINE_MUTEX(rx_queue_mutex); 149static DEFINE_MUTEX(rx_queue_mutex);
150 150
151struct mempool_zone { 151struct mempool_zone {
@@ -572,13 +572,13 @@ mempool_zone_get_skb(struct mempool_zone *zone)
572} 572}
573 573
574static int 574static int
575iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) 575iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
576{ 576{
577 unsigned long flags; 577 unsigned long flags;
578 int rc; 578 int rc;
579 579
580 skb_get(skb); 580 skb_get(skb);
581 rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT); 581 rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
582 if (rc < 0) { 582 if (rc < 0) {
583 mempool_free(skb, zone->pool); 583 mempool_free(skb, zone->pool);
584 printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); 584 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 struct sk_buff *skb; 600 struct sk_buff *skb;
601 struct iscsi_uevent *ev; 601 struct iscsi_uevent *ev;
602 char *pdu; 602 char *pdu;
603 struct iscsi_internal *priv;
603 int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + 604 int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
604 data_size); 605 data_size);
605 606
607 priv = iscsi_if_transport_lookup(conn->transport);
608 if (!priv)
609 return -EINVAL;
610
606 mempool_zone_complete(conn->z_pdu); 611 mempool_zone_complete(conn->z_pdu);
607 612
608 skb = mempool_zone_get_skb(conn->z_pdu); 613 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 return -ENOMEM; 618 return -ENOMEM;
614 } 619 }
615 620
616 nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 621 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
617 ev = NLMSG_DATA(nlh); 622 ev = NLMSG_DATA(nlh);
618 memset(ev, 0, sizeof(*ev)); 623 memset(ev, 0, sizeof(*ev));
619 ev->transport_handle = iscsi_handle(conn->transport); 624 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 memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); 631 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
627 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); 632 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
628 633
629 return iscsi_unicast_skb(conn->z_pdu, skb); 634 return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
630} 635}
631EXPORT_SYMBOL_GPL(iscsi_recv_pdu); 636EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
632 637
@@ -635,8 +640,13 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
635 struct nlmsghdr *nlh; 640 struct nlmsghdr *nlh;
636 struct sk_buff *skb; 641 struct sk_buff *skb;
637 struct iscsi_uevent *ev; 642 struct iscsi_uevent *ev;
643 struct iscsi_internal *priv;
638 int len = NLMSG_SPACE(sizeof(*ev)); 644 int len = NLMSG_SPACE(sizeof(*ev));
639 645
646 priv = iscsi_if_transport_lookup(conn->transport);
647 if (!priv)
648 return;
649
640 mempool_zone_complete(conn->z_error); 650 mempool_zone_complete(conn->z_error);
641 651
642 skb = mempool_zone_get_skb(conn->z_error); 652 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 return; 656 return;
647 } 657 }
648 658
649 nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); 659 nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
650 ev = NLMSG_DATA(nlh); 660 ev = NLMSG_DATA(nlh);
651 ev->transport_handle = iscsi_handle(conn->transport); 661 ev->transport_handle = iscsi_handle(conn->transport);
652 ev->type = ISCSI_KEVENT_CONN_ERROR; 662 ev->type = ISCSI_KEVENT_CONN_ERROR;
@@ -656,7 +666,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
656 ev->r.connerror.cid = conn->cid; 666 ev->r.connerror.cid = conn->cid;
657 ev->r.connerror.sid = iscsi_conn_get_sid(conn); 667 ev->r.connerror.sid = iscsi_conn_get_sid(conn);
658 668
659 iscsi_unicast_skb(conn->z_error, skb); 669 iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid);
660 670
661 dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", 671 dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
662 error); 672 error);
@@ -686,7 +696,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
686 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); 696 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
687 nlh->nlmsg_flags = flags; 697 nlh->nlmsg_flags = flags;
688 memcpy(NLMSG_DATA(nlh), payload, size); 698 memcpy(NLMSG_DATA(nlh), payload, size);
689 return iscsi_unicast_skb(z_reply, skb); 699 return iscsi_unicast_skb(z_reply, skb, pid);
690} 700}
691 701
692static int 702static int
@@ -698,12 +708,17 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
698 struct iscsi_cls_conn *conn; 708 struct iscsi_cls_conn *conn;
699 struct nlmsghdr *nlhstat; 709 struct nlmsghdr *nlhstat;
700 struct iscsi_uevent *evstat; 710 struct iscsi_uevent *evstat;
711 struct iscsi_internal *priv;
701 int len = NLMSG_SPACE(sizeof(*ev) + 712 int len = NLMSG_SPACE(sizeof(*ev) +
702 sizeof(struct iscsi_stats) + 713 sizeof(struct iscsi_stats) +
703 sizeof(struct iscsi_stats_custom) * 714 sizeof(struct iscsi_stats_custom) *
704 ISCSI_STATS_CUSTOM_MAX); 715 ISCSI_STATS_CUSTOM_MAX);
705 int err = 0; 716 int err = 0;
706 717
718 priv = iscsi_if_transport_lookup(transport);
719 if (!priv)
720 return -EINVAL;
721
707 conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid); 722 conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
708 if (!conn) 723 if (!conn)
709 return -EEXIST; 724 return -EEXIST;
@@ -720,7 +735,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
720 return -ENOMEM; 735 return -ENOMEM;
721 } 736 }
722 737
723 nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0, 738 nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0,
724 (len - sizeof(*nlhstat)), 0); 739 (len - sizeof(*nlhstat)), 0);
725 evstat = NLMSG_DATA(nlhstat); 740 evstat = NLMSG_DATA(nlhstat);
726 memset(evstat, 0, sizeof(*evstat)); 741 memset(evstat, 0, sizeof(*evstat));
@@ -746,7 +761,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
746 skb_trim(skbstat, NLMSG_ALIGN(actual_size)); 761 skb_trim(skbstat, NLMSG_ALIGN(actual_size));
747 nlhstat->nlmsg_len = actual_size; 762 nlhstat->nlmsg_len = actual_size;
748 763
749 err = iscsi_unicast_skb(conn->z_pdu, skbstat); 764 err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
750 } while (err < 0 && err != -ECONNREFUSED); 765 } while (err < 0 && err != -ECONNREFUSED);
751 766
752 return err; 767 return err;
@@ -981,6 +996,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
981 if (!try_module_get(transport->owner)) 996 if (!try_module_get(transport->owner))
982 return -EINVAL; 997 return -EINVAL;
983 998
999 priv->daemon_pid = NETLINK_CREDS(skb)->pid;
1000
984 switch (nlh->nlmsg_type) { 1001 switch (nlh->nlmsg_type) {
985 case ISCSI_UEVENT_CREATE_SESSION: 1002 case ISCSI_UEVENT_CREATE_SESSION:
986 err = iscsi_if_create_session(priv, ev); 1003 err = iscsi_if_create_session(priv, ev);
@@ -1073,7 +1090,6 @@ iscsi_if_rx(struct sock *sk, int len)
1073 skb_pull(skb, skb->len); 1090 skb_pull(skb, skb->len);
1074 goto free_skb; 1091 goto free_skb;
1075 } 1092 }
1076 daemon_pid = NETLINK_CREDS(skb)->pid;
1077 1093
1078 while (skb->len >= NLMSG_SPACE(0)) { 1094 while (skb->len >= NLMSG_SPACE(0)) {
1079 int err; 1095 int err;