aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-02-06 02:56:36 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-06 02:56:36 -0500
commitff491a7334acfd74e515c896632e37e401f52676 (patch)
tree0e3663706a706029d6fc749ef7f66cdd03925231 /drivers/scsi
parent612e244c12215f6f74973ea3b89bff96450dc530 (diff)
netlink: change return-value logic of netlink_broadcast()
Currently, netlink_broadcast() reports errors to the caller if no messages at all were delivered: 1) If, at least, one message has been delivered correctly, returns 0. 2) Otherwise, if no messages at all were delivered due to skb_clone() failure, return -ENOBUFS. 3) Otherwise, if there are no listeners, return -ESRCH. With this patch, the caller knows if the delivery of any of the messages to the listeners have failed: 1) If it fails to deliver any message (for whatever reason), return -ENOBUFS. 2) Otherwise, if all messages were delivered OK, returns 0. 3) Otherwise, if no listeners, return -ESRCH. In the current ctnetlink code and in Netfilter in general, we can add reliable logging and connection tracking event delivery by dropping the packets whose events were not successfully delivered over Netlink. Of course, this option would be settable via /proc as this approach reduces performance (in terms of filtered connections per seconds by a stateful firewall) but providing reliable logging and event delivery (for conntrackd) in return. This patch also changes some clients of netlink_broadcast() that may report ENOBUFS errors via printk. This error handling is not of any help. Instead, the userspace daemons that are listening to those netlink messages should resync themselves with the kernel-side if they hit ENOBUFS. BTW, netlink_broadcast() clients include those that call cn_netlink_send(), nlmsg_multicast() and genlmsg_multicast() since they internally call netlink_broadcast() and return its error value. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_transport_fc.c16
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c12
2 files changed, 6 insertions, 22 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 5f77417ed585..3ee4eb40abcf 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -533,12 +533,8 @@ fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
533 event->event_code = event_code; 533 event->event_code = event_code;
534 event->event_data = event_data; 534 event->event_data = event_data;
535 535
536 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 536 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
537 GFP_KERNEL); 537 GFP_KERNEL);
538 if (err && (err != -ESRCH)) /* filter no recipient errors */
539 /* nlmsg_multicast already kfree_skb'd */
540 goto send_fail;
541
542 return; 538 return;
543 539
544send_fail_skb: 540send_fail_skb:
@@ -607,12 +603,8 @@ fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
607 event->event_code = FCH_EVT_VENDOR_UNIQUE; 603 event->event_code = FCH_EVT_VENDOR_UNIQUE;
608 memcpy(&event->event_data, data_buf, data_len); 604 memcpy(&event->event_data, data_buf, data_len);
609 605
610 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 606 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
611 GFP_KERNEL); 607 GFP_KERNEL);
612 if (err && (err != -ESRCH)) /* filter no recipient errors */
613 /* nlmsg_multicast already kfree_skb'd */
614 goto send_vendor_fail;
615
616 return; 608 return;
617 609
618send_vendor_fail_skb: 610send_vendor_fail_skb:
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 75c9297694cb..2adfab8c11c1 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -966,15 +966,7 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt)
966static int 966static int
967iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) 967iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp)
968{ 968{
969 int rc; 969 return netlink_broadcast(nls, skb, 0, 1, gfp);
970
971 rc = netlink_broadcast(nls, skb, 0, 1, gfp);
972 if (rc < 0) {
973 printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
974 return rc;
975 }
976
977 return 0;
978} 970}
979 971
980static int 972static int
@@ -1207,7 +1199,7 @@ int iscsi_session_event(struct iscsi_cls_session *session,
1207 * the user and when the daemon is restarted it will handle it 1199 * the user and when the daemon is restarted it will handle it
1208 */ 1200 */
1209 rc = iscsi_broadcast_skb(skb, GFP_KERNEL); 1201 rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
1210 if (rc < 0) 1202 if (rc == -ESRCH)
1211 iscsi_cls_session_printk(KERN_ERR, session, 1203 iscsi_cls_session_printk(KERN_ERR, session,
1212 "Cannot notify userspace of session " 1204 "Cannot notify userspace of session "
1213 "event %u. Check iscsi daemon\n", 1205 "event %u. Check iscsi daemon\n",