[Pkg-iscsi-maintainers] [SCM] Debian Open-iSCSI Packaging branch, upstream-mnc, updated. 2.0-872-193-gde2c0e7

Mike Christie michaelc at cs.wisc.edu
Sat Apr 7 15:43:53 UTC 2012


The following commit has been merged in the upstream-mnc branch:
commit c4aee089c879ee51c93d9cb48cd7a521efc667b2
Author: Mike Christie <michaelc at cs.wisc.edu>
Date:   Thu Oct 6 04:16:03 2011 -0500

    iscsi tools: fix netlink msg setup
    
    This fixes a regression added in
    deef9e20c2f1b107760b5b4c29289de77fcdc39f
    and fixes a alignment issue with the new iface netconfig support.
    
    The regression was added when we changed how we sent
    the netlink message header and data from one blob to
    iovecs. The nlmsg_len was not tracking the header
    so the kernel was misreading how much data it had to read.
    This would lead to iscsiadm hanging because logins were
    not getting completed.
    
    This also fixes a issue where the data was not padded
    so when sending multiple params the params would not
    start at nice boundaries and could cause unaligned access
    errors.

diff --git a/usr/iface.c b/usr/iface.c
index 9c70d09..a42efff 100644
--- a/usr/iface.c
+++ b/usr/iface.c
@@ -41,6 +41,7 @@
 #include "fw_context.h"
 #include "sysdeps.h"
 #include "iscsi_err.h"
+#include "iscsi_netlink.h"
 
 /*
  * Default ifaces for use with transports that do not bind to hardware
@@ -1145,14 +1146,16 @@ static int iface_fill_port(struct iovec *iov, struct iface_rec *iface,
 	int len;
 	struct iscsi_iface_param_info *net_param;
 	uint16_t port = 3260;
+	struct nlattr *attr;
 
-	len = sizeof(struct iscsi_iface_param_info) + 2;
-	iov->iov_base = calloc(len, sizeof(char));
-	if (!(iov->iov_base))
+	len = sizeof(struct iscsi_iface_param_info) + sizeof(port);
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_PORT, len);
+	if (!iov->iov_base)
 		return 1;
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_PORT;
 	net_param->iface_type = iface_type;
 	net_param->iface_num = iface->iface_num;
@@ -1170,14 +1173,16 @@ static int iface_fill_mtu(struct iovec *iov, struct iface_rec *iface,
 	int len;
 	struct iscsi_iface_param_info *net_param;
 	uint16_t mtu = 0;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 2;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_MTU, len);
 	if (!(iov->iov_base))
 		return 1;
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_MTU;
 	net_param->iface_type = iface_type;
 	net_param->iface_num = iface->iface_num;
@@ -1195,14 +1200,16 @@ static int iface_fill_vlan_id(struct iovec *iov, struct iface_rec *iface,
 	int len;
 	struct iscsi_iface_param_info *net_param;
 	uint16_t vlan = 0;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 2;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_VLAN_ID, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_VLAN_ID;
 	net_param->iface_type = iface_type;
 	net_param->iface_num = iface->iface_num;
@@ -1226,14 +1233,16 @@ static int iface_fill_vlan_state(struct iovec *iov, struct iface_rec *iface,
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_VLAN_ENABLED, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_VLAN_ENABLED;
 	net_param->iface_type = iface_type;
 	net_param->iface_num = iface->iface_num;
@@ -1252,14 +1261,16 @@ static int iface_fill_net_state(struct iovec *iov, struct iface_rec *iface,
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IFACE_ENABLE, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_IFACE_ENABLE;
 	net_param->iface_type = iface_type;
 	net_param->iface_num = iface->iface_num;
@@ -1277,14 +1288,16 @@ static int iface_fill_net_bootproto(struct iovec *iov, struct iface_rec *iface)
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV4_BOOTPROTO, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_IPV4_BOOTPROTO;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV4;
 	net_param->iface_num = iface->iface_num;
@@ -1302,14 +1315,16 @@ static int iface_fill_net_autocfg(struct iovec *iov, struct iface_rec *iface)
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV6;
 	net_param->param_type = ISCSI_NET_PARAM;
@@ -1331,14 +1346,17 @@ static int iface_fill_linklocal_autocfg(struct iovec *iov,
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG,
+					len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV6;
 	net_param->param_type = ISCSI_NET_PARAM;
@@ -1357,14 +1375,17 @@ static int iface_fill_router_autocfg(struct iovec *iov, struct iface_rec *iface)
 {
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 1;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG,
+					len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV6;
 	net_param->param_type = ISCSI_NET_PARAM;
@@ -1385,14 +1406,16 @@ static int iface_fill_net_ipv4_addr(struct iovec *iov, struct iface_rec *iface,
 	int rc = 1;
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 4;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(param, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = param;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV4;
 	net_param->iface_num = iface->iface_num;
@@ -1439,14 +1462,16 @@ static int iface_fill_net_ipv6_addr(struct iovec *iov, struct iface_rec *iface,
 	int rc;
 	int len;
 	struct iscsi_iface_param_info *net_param;
+	struct nlattr *attr;
 
 	len = sizeof(struct iscsi_iface_param_info) + 16;
-	iov->iov_base = calloc(len, sizeof(char));
+	iov->iov_base = iscsi_nla_alloc(param, len);
 	if (!(iov->iov_base))
 		return 1;
 
-	iov->iov_len = len;
-	net_param = (struct iscsi_iface_param_info *)(iov->iov_base);
+	attr = iov->iov_base;
+	iov->iov_len = NLA_ALIGN(attr->nla_len);
+	net_param = (struct iscsi_iface_param_info *)ISCSI_NLA_DATA(attr);
 	net_param->param = param;
 	net_param->iface_type = ISCSI_IFACE_TYPE_IPV6;
 	net_param->iface_num = iface->iface_num;
diff --git a/usr/iscsi_timer.h b/usr/iscsi_netlink.h
similarity index 54%
copy from usr/iscsi_timer.h
copy to usr/iscsi_netlink.h
index 13e8368..25b41db 100644
--- a/usr/iscsi_timer.h
+++ b/usr/iscsi_netlink.h
@@ -1,7 +1,7 @@
 /*
- * iSCSI timer
+ * iSCSI Netlink attr helpers
  *
- * Copyright (C) 2002 Cisco Systems, Inc.
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -15,14 +15,19 @@
  *
  * See the file COPYING included with this distribution for more details.
  */
-#ifndef ISCSI_TIMER_H
-#define ISCSI_TIMER_H
 
-struct timeval;
+#ifndef ISCSI_NLA_H
+#define ISCSI_NLA_H
 
-extern void iscsi_timer_clear(struct timeval *timer);
-extern void iscsi_timer_set(struct timeval *timer, int seconds);
-extern int iscsi_timer_expired(struct timeval *timer);
-extern int iscsi_timer_msecs_until(struct timeval *timer);
+#include <linux/netlink.h>
+
+struct iovec;
+
+#define ISCSI_NLA_HDRLEN	((int) NLA_ALIGN(sizeof(struct nlattr)))
+#define ISCSI_NLA_DATA(nla)	((void *)((char*)(nla) + ISCSI_NLA_HDRLEN))
+#define ISCSI_NLA_LEN(len) 	((len) + NLA_ALIGN(ISCSI_NLA_HDRLEN))
+#define ISCSI_NLA_TOTAL_LEN(len) (NLA_ALIGN(ISCSI_NLA_LEN(len)))
+
+extern struct nlattr *iscsi_nla_alloc(uint16_t type, uint16_t len);
 
 #endif
diff --git a/usr/netlink.c b/usr/netlink.c
index 801ee6f..08c08d8 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -38,6 +38,7 @@
 #include "initiator.h"
 #include "iscsi_sysfs.h"
 #include "transport.h"
+#include "iscsi_netlink.h"
 
 static int ctrl_fd;
 static struct sockaddr_nl src_addr, dest_addr;
@@ -63,6 +64,19 @@ static int ctldev_handle(void);
 
 #define NLM_SETPARAM_DEFAULT_MAX (NI_MAXHOST + 1 + sizeof(struct iscsi_uevent))
 
+struct nlattr *iscsi_nla_alloc(uint16_t type, uint16_t len)
+{
+	struct nlattr *attr;
+
+	attr = calloc(1, ISCSI_NLA_TOTAL_LEN(len));
+	if (!attr)
+		return NULL; 
+
+	attr->nla_len = ISCSI_NLA_LEN(len);
+	attr->nla_type = type;
+	return attr;
+}
+
 static int
 kread(char *data, int count)
 {
@@ -185,7 +199,7 @@ kwritev(enum iscsi_uevent_e type, struct iovec *iovp, int count)
 	for (i = 1; i < count; i++)
 		datalen += iovp[i].iov_len;
 
-	nlh->nlmsg_len = NLMSG_ALIGN(datalen);
+	nlh->nlmsg_len = datalen + sizeof(*nlh);
 	nlh->nlmsg_pid = getpid();
 	nlh->nlmsg_flags = 0;
 	nlh->nlmsg_type = type;

-- 
Debian Open-iSCSI Packaging



More information about the Pkg-iscsi-maintainers mailing list