diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-15 02:11:31 -0600 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2010-01-15 02:24:02 -0600 |
commit | bb0cb72219e13e25a8c13c05268cd7c346b8e5ca (patch) | |
tree | 8621b6ec0ddc4a378fd61ec8ad6ebbc680c8d023 /utils | |
parent | ec1de7f9aec063e1435c413be7f5e83bad862289 (diff) | |
download | open-iscsi-bb0cb72219e13e25a8c13c05268cd7c346b8e5ca.tar.gz |
ibft boot: fix dev to iface matching
This fixes a regression from
492eca19715a0c3aa096cff76cb34bb8339a39c1
We cannot just match by MAC because the bnx2i card uses
seperate MACs for the iscsi and net interfaces. OTOH, we
cannot just follow the sysfs links, because the ibft
implemenation may not provide the pci linking info.
So this adds back get_iface_from_device, but also keeps
the use of the common net helper. The commit still did
some cleanup since there were multiple match my MAC functions.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/fwparam_ibft/fwparam_ibft_sysfs.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/utils/fwparam_ibft/fwparam_ibft_sysfs.c b/utils/fwparam_ibft/fwparam_ibft_sysfs.c index b782f5a..9a2cb7d 100644 --- a/utils/fwparam_ibft/fwparam_ibft_sysfs.c +++ b/utils/fwparam_ibft/fwparam_ibft_sysfs.c @@ -80,6 +80,84 @@ static int find_sysfs_dirs(const char *fpath, const struct stat *sb, return 0; } + +static int get_iface_from_device(char *id, struct boot_context *context) +{ + char dev_dir[FILENAMESZ]; + int rc = ENODEV; + DIR *dirfd; + struct dirent *dent; + + memset(dev_dir, 0, FILENAMESZ); + snprintf(dev_dir, FILENAMESZ, IBFT_SYSFS_ROOT"/%s/device", id); + + if (!file_exist(dev_dir)) + return 0; + + dirfd = opendir(dev_dir); + if (!dirfd) + return errno; + + while ((dent = readdir(dirfd))) { + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..") || + strncmp(dent->d_name, "net:", 4)) + continue; + + if (!strncmp(dent->d_name, "net:", 4)) { + if ((strlen(dent->d_name) - 4) > + (sizeof(context->iface) - 1)) { + rc = EINVAL; + printf("Net device %s too big for iface " + "buffer.\n", dent->d_name); + break; + } + + if (sscanf(dent->d_name, "net:%s", context->iface) != 1) + rc = EINVAL; + rc = 0; + break; + } else { + printf("Could not read ethernet to net link.\n"); + rc = EOPNOTSUPP; + break; + } + } + + closedir(dirfd); + + if (rc != ENODEV) + return rc; + + /* If not found try again with newer kernel networkdev sysfs layout */ + strlcat(dev_dir, "/net", FILENAMESZ); + + if (!file_exist(dev_dir)) + return rc; + + dirfd = opendir(dev_dir); + if (!dirfd) + return errno; + + while ((dent = readdir(dirfd))) { + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) + continue; + + /* Take the first "regular" directory entry */ + if (strlen(dent->d_name) > (sizeof(context->iface) - 1)) { + rc = EINVAL; + printf("Net device %s too big for iface buffer.\n", + dent->d_name); + break; + } + + strcpy(context->iface, dent->d_name); + rc = 0; + break; + } + + closedir(dirfd); + return rc; +} /* * Routines to fill in the context values. @@ -93,9 +171,20 @@ static int fill_nic_context(char *id, struct boot_context *context) if (rc) return rc; - rc = net_get_dev_from_hwaddress(context->mac, context->iface); - if (rc) - return rc; + /* + * Some offload cards like bnx2i use different MACs for the net and + * iscsi functions, so we have to follow the sysfs links. + * + * Other ibft implementations may not be tied to a pci function, + * so there will not be any device/net link, so we drop down to + * the MAC matching. + */ + rc = get_iface_from_device(id, context); + if (rc) { + rc = net_get_dev_from_hwaddress(context->mac, context->iface); + if (rc) + return rc; + } sysfs_get_str(id, IBFT_SUBSYS, "ip-addr", context->ipaddr, sizeof(context->ipaddr)); |