diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-05-18 21:31:39 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-05-20 10:35:51 -0400 |
commit | 790f39a2d5f03623b027f340b945f135d006ceba (patch) | |
tree | 5a591a6c7952d758d0f9a8d7874020cc3d4f8571 | |
parent | ffbfe92533810bf1bb76fd275400825ef8898ed9 (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.c | 38 |
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 | ||
38 | struct iscsi_internal { | 38 | struct 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 | ||
147 | static struct sock *nls; | 148 | static struct sock *nls; |
148 | static int daemon_pid; | ||
149 | static DEFINE_MUTEX(rx_queue_mutex); | 149 | static DEFINE_MUTEX(rx_queue_mutex); |
150 | 150 | ||
151 | struct mempool_zone { | 151 | struct mempool_zone { |
@@ -572,13 +572,13 @@ mempool_zone_get_skb(struct mempool_zone *zone) | |||
572 | } | 572 | } |
573 | 573 | ||
574 | static int | 574 | static int |
575 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) | 575 | iscsi_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 | } |
631 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); | 636 | EXPORT_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 | ||
692 | static int | 702 | static 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; |