commit ac38eee2083821eb29d098227ad044c950d115e4 Author: Mike Christie Date: Sun Aug 14 22:14:04 2011 -0500 iscsi tools: fix default iface binding setup If a driver supports multiple ifaces only one is getting auto created. This modifies the default iface setup code so that it creates a iface per kernel iface or a iface per host if kernel ifaces are not supported. diff --git a/usr/iface.c b/usr/iface.c index 5d5f7bf..9c70d09 100644 --- a/usr/iface.c +++ b/usr/iface.c @@ -424,12 +424,61 @@ int iface_get_by_net_binding(struct iface_rec *pattern, return ISCSI_ERR_NO_OBJS_FOUND; } +static int iface_get_iptype(struct iface_rec *iface) +{ + if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) + return ISCSI_IFACE_TYPE_IPV6; + else + return ISCSI_IFACE_TYPE_IPV4; +} + +static int iface_setup_binding_from_kern_iface(void *data, + struct iface_rec *kern_iface) +{ + struct host_info *hinfo = data; + struct iface_rec iface; + + if (!strlen(hinfo->iface.hwaddress)) { + log_error("Invalid offload iSCSI host %u. Missing " + "hwaddress. Try upgrading %s driver.\n", + hinfo->host_no, hinfo->iface.transport_name); + return 0; + } + + memset(&iface, 0, sizeof(struct iface_rec)); + strcpy(iface.hwaddress, hinfo->iface.hwaddress); + strcpy(iface.transport_name, hinfo->iface.transport_name); + + if (kern_iface) { + iface.iface_num = kern_iface->iface_num; + + snprintf(iface.name, sizeof(iface.name), "%s.%s.%s.%u", + kern_iface->transport_name, + kern_iface->hwaddress, + iface_get_iptype(kern_iface) == ISCSI_IFACE_TYPE_IPV4 ? + "ipv4" : "ipv6", kern_iface->iface_num); + } else { + snprintf(iface.name, sizeof(iface.name), "%s.%s", + hinfo->iface.transport_name, hinfo->iface.hwaddress); + } + + if (iface_conf_read(&iface)) { + /* not found so create it */ + if (iface_conf_write(&iface)) { + log_error("Could not create default iface conf %s.", + iface.name); + /* fall through - will not be persistent */ + } + } + + return 0; +} + static int __iface_setup_host_bindings(void *data, struct host_info *hinfo) { struct iface_rec *def_iface; - struct iface_rec iface; struct iscsi_transport *t; - int i = 0; + int i = 0, nr_found; t = iscsi_sysfs_get_transport_by_hba(hinfo->host_no); if (!t) @@ -441,26 +490,12 @@ static int __iface_setup_host_bindings(void *data, struct host_info *hinfo) return 0; } - if (iface_get_by_net_binding(&hinfo->iface, &iface) == - ISCSI_ERR_NO_OBJS_FOUND) { - /* Must be a new port */ - if (!strlen(hinfo->iface.hwaddress)) { - log_error("Invalid offload iSCSI host %u. Missing " - "hwaddress. Try upgrading %s driver.\n", - hinfo->host_no, t->name); - return 0; - } - - memset(&iface, 0, sizeof(struct iface_rec)); - strcpy(iface.hwaddress, hinfo->iface.hwaddress); - strcpy(iface.transport_name, hinfo->iface.transport_name); - snprintf(iface.name, sizeof(iface.name), "%s.%s", - t->name, hinfo->iface.hwaddress); - if (iface_conf_write(&iface)) - log_error("Could not create default iface conf %s.", - iface.name); - /* fall through - will not be persistent */ - } + nr_found = 0; + iscsi_sysfs_for_each_iface_on_host(hinfo, hinfo->host_no, + &nr_found, + iface_setup_binding_from_kern_iface); + if (!nr_found) + iface_setup_binding_from_kern_iface(hinfo, NULL); return 0; } @@ -843,7 +878,6 @@ int iface_setup_from_boot_context(struct iface_rec *iface, memset(iface->name, 0, sizeof(iface->name)); snprintf(iface->name, sizeof(iface->name), "%s.%s", iface->transport_name, context->mac); - strlcpy(iface->hwaddress, context->mac, sizeof(iface->hwaddress)); strlcpy(iface->ipaddress, context->ipaddr, @@ -921,9 +955,7 @@ static int __iface_get_param_count(void *data, struct iface_rec *iface) if (strcmp(iface_params->primary->hwaddress, iface->hwaddress)) return 0; - if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) - iptype = ISCSI_IFACE_TYPE_IPV6; - + iptype = iface_get_iptype(iface); if (iptype == ISCSI_IFACE_TYPE_IPV4) { if (strcmp(iface->state, "disable")) { @@ -1466,12 +1498,10 @@ static int __iface_build_net_config(void *data, struct iface_rec *iface) if (strcmp(net_config->primary->hwaddress, iface->hwaddress)) return 0; - if (strcmp(iface->bootproto, "dhcp") && !strstr(iface->ipaddress, ".")) - iptype = ISCSI_IFACE_TYPE_IPV6; - /* start at 2, because 0 is for nlmsghdr and 1 for event */ iov = net_config->iovs + 2; + iptype = iface_get_iptype(iface); if (iptype == ISCSI_IFACE_TYPE_IPV4) { if (!strcmp(iface->state, "disable")) { if (!iface_fill_net_state(&iov[net_config->count], diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c index 995549e..961cefd 100644 --- a/usr/iscsi_sysfs.c +++ b/usr/iscsi_sysfs.c @@ -425,9 +425,10 @@ uint32_t iscsi_sysfs_get_host_no_from_hwinfo(struct iface_rec *iface, int *rc) static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no, char *session, char *iface_kern_id) { + uint32_t tmp_host_no, iface_num; char host_id[NAME_SIZE]; struct iscsi_transport *t; - int ret; + int ret, iface_type; t = iscsi_sysfs_get_transport_by_hba(host_no); if (!t) @@ -582,6 +583,10 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no, &iface->vlan_id); sysfs_get_uint8(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan_priority", &iface->vlan_priority); + + if (sscanf(iface_kern_id, "ipv%d-iface-%u-%u", &iface_type, + &tmp_host_no, &iface_num) == 3) + iface->iface_num = iface_num; done: if (ret) return ISCSI_ERR_SYSFS_LOOKUP;