summaryrefslogtreecommitdiff
path: root/libopeniscsiusr
diff options
context:
space:
mode:
authorChris Leech <cleech@redhat.com>2018-06-13 08:09:07 -0700
committerChris Leech <cleech@redhat.com>2018-06-14 22:12:57 -0700
commit7ea1bf5da81ef0e70e0338e53caafab543eb8804 (patch)
tree10392103d3f33b62efe9b6ac1708f7f00af40dcd /libopeniscsiusr
parenta9a36675dc79ce00cdbfa436b247a198aba9ae30 (diff)
downloadopen-iscsi-7ea1bf5da81ef0e70e0338e53caafab543eb8804.tar.gz
libopeniscsiusr: hosts can have multiple ifaces
Both be2iscsi and qla4xxx export multiple iface ojbects in sysfs per host to represent the number of network configurations (ipv4/ipv6) that can be supported. Fix the libopeniscsiusr code to create and manage multiple offload iface records per host, as the old code did.
Diffstat (limited to 'libopeniscsiusr')
-rw-r--r--libopeniscsiusr/iface.c88
-rw-r--r--libopeniscsiusr/iface.h1
-rw-r--r--libopeniscsiusr/session.c3
-rw-r--r--libopeniscsiusr/sysfs.c37
-rw-r--r--libopeniscsiusr/sysfs.h10
5 files changed, 106 insertions, 33 deletions
diff --git a/libopeniscsiusr/iface.c b/libopeniscsiusr/iface.c
index 955395d..9ff765d 100644
--- a/libopeniscsiusr/iface.c
+++ b/libopeniscsiusr/iface.c
@@ -89,14 +89,14 @@ _iscsi_getter_func_gen(iscsi_iface, port_speed, const char *);
_iscsi_getter_func_gen(iscsi_iface, name, const char *);
int _iscsi_iface_get_from_sysfs(struct iscsi_context *ctx, uint32_t host_id,
- uint32_t sid, struct iscsi_iface **iface)
+ uint32_t sid, char *iface_kern_id,
+ struct iscsi_iface **iface)
{
int rc = LIBISCSI_OK;
char *sysfs_se_dir_path = NULL;
char *sysfs_sh_dir_path = NULL;
char *sysfs_scsi_host_dir_path = NULL;
char *sysfs_iface_dir_path = NULL;
- char iface_kern_id[PATH_MAX];
char proc_name[ISCSI_TRANSPORT_NAME_MAXLEN];
struct iscsi_iface **ifaces = NULL;
uint32_t iface_count = 0;
@@ -195,8 +195,7 @@ int _iscsi_iface_get_from_sysfs(struct iscsi_context *ctx, uint32_t host_id,
(*iface)->name,
sizeof((*iface)->name)/sizeof(char), "");
- rc = _iscsi_iface_kern_id_of_host_id(ctx, host_id, iface_kern_id);
- if (rc == LIBISCSI_OK) {
+ if (iface_kern_id != NULL) {
_good(_fill_hw_iface_from_sys(ctx, *iface, iface_kern_id),
rc, out);
} else {
@@ -268,6 +267,53 @@ out:
return rc;
}
+/* create all ifaces for a host from sysfs */
+int _iscsi_ifaces_get_from_sysfs(struct iscsi_context *ctx, uint32_t host_id,
+ struct iscsi_iface ***ifaces, uint32_t *iface_count)
+{
+ int rc = LIBISCSI_OK;
+ char **iface_kern_ids = NULL;
+ uint32_t i = 0;
+
+ assert(ctx != NULL);
+ assert(ifaces != NULL);
+
+ *ifaces = NULL;
+ *iface_count = 0;
+
+ _good(_iscsi_iface_kern_ids_of_host_id(ctx, host_id, &iface_kern_ids, iface_count),
+ rc, out);
+ if (*iface_count > 0) {
+ *ifaces = (struct iscsi_iface **) calloc(*iface_count,
+ sizeof(struct iscsi_iface *));
+ _alloc_null_check(ctx, *ifaces, rc, out);
+ for (i = 0; i < *iface_count; i++) {
+ _good(_iscsi_iface_get_from_sysfs(ctx, host_id, 0,
+ iface_kern_ids[i], &(*ifaces)[i]), rc, out);
+ }
+ } else {
+ /* if there's no iface exported in sysfs,
+ * we should still be able to create one record per host */
+ *ifaces = (struct iscsi_iface **) calloc(1, sizeof(struct iscsi_iface *));
+ _alloc_null_check(ctx, *ifaces, rc, out);
+ *iface_count = 1;
+ _good(_iscsi_iface_get_from_sysfs(ctx, host_id, 0, NULL, &(*ifaces)[0]), rc, out);
+ }
+out:
+ if (iface_kern_ids != NULL) {
+ for (i = 0; i < *iface_count; i++) {
+ free(iface_kern_ids[i]);
+ }
+ free(iface_kern_ids);
+ }
+ if (rc != LIBISCSI_OK) {
+ iscsi_ifaces_free(*ifaces, *iface_count);
+ *ifaces = NULL;
+ *iface_count = 0;
+ }
+ return rc;
+}
+
int iscsi_default_iface_setup(struct iscsi_context *ctx)
{
int rc = LIBISCSI_OK;
@@ -276,11 +322,13 @@ int iscsi_default_iface_setup(struct iscsi_context *ctx)
struct _eth_if **eifs = NULL;
uint32_t eif_count = 0;
uint32_t i = 0;
+ uint32_t n = 0;
size_t j = 0;
struct _iscsi_net_drv *ind = NULL;
uint32_t *hids = NULL;
uint32_t hid_count = 0;
- struct iscsi_iface *iface = NULL;
+ struct iscsi_iface **ifaces = NULL;
+ uint32_t iface_count = 0;
char path[PATH_MAX];
assert(ctx != NULL);
@@ -345,20 +393,30 @@ int iscsi_default_iface_setup(struct iscsi_context *ctx)
for (i = 0; i < hid_count; ++i) {
/* Create /etc/iscsi/ifaces/<iface_name> file if not found
*/
- _good(_iscsi_iface_get_from_sysfs(ctx, hids[i], 0, &iface),
- rc, out);
- if ( ! iscsi_is_default_iface(iface)) {
- snprintf(path, PATH_MAX, "%s/%s", IFACE_CONFIG_DIR,
- iface->name);
- if (access(path, F_OK) != 0)
- rc = _iface_conf_write(ctx, iface);
+ _good(_iscsi_ifaces_get_from_sysfs(ctx, hids[i], &ifaces, &iface_count),
+ rc, out);
+ for (n = 0; n < iface_count; n++) {
+ if ( ! iscsi_is_default_iface(ifaces[n])) {
+ snprintf(path, PATH_MAX, "%s/%s", IFACE_CONFIG_DIR,
+ ifaces[n]->name);
+ if (access(path, F_OK) != 0)
+ rc = _iface_conf_write(ctx, ifaces[n]);
+ }
+ iscsi_iface_free(ifaces[n]);
+ ifaces[n] = NULL;
+ if (rc != LIBISCSI_OK)
+ goto out;
}
- iscsi_iface_free(iface);
- if (rc != LIBISCSI_OK)
- goto out;
+ free(ifaces);
+ ifaces = NULL;
}
out:
+ if (ifaces != NULL) {
+ for (i = 0; i < iface_count; i++)
+ free(ifaces[i]);
+ free(ifaces);
+ }
_eth_ifs_free(eifs, eif_count);
free(hids);
return rc;
diff --git a/libopeniscsiusr/iface.h b/libopeniscsiusr/iface.h
index eaf1832..f20ea13 100644
--- a/libopeniscsiusr/iface.h
+++ b/libopeniscsiusr/iface.h
@@ -139,6 +139,7 @@ struct iscsi_iface {
__DLL_LOCAL int _iscsi_iface_get_from_sysfs(struct iscsi_context *ctx,
uint32_t host_id, uint32_t sid,
+ char *iface_kern_id,
struct iscsi_iface **iface);
__DLL_LOCAL bool _iface_is_valid(struct iscsi_iface *iface);
diff --git a/libopeniscsiusr/session.c b/libopeniscsiusr/session.c
index 4d9c57c..7056c36 100644
--- a/libopeniscsiusr/session.c
+++ b/libopeniscsiusr/session.c
@@ -229,7 +229,8 @@ int iscsi_session_get(struct iscsi_context *ctx, uint32_t sid,
_good(_iscsi_host_id_of_session(ctx, sid, &host_id), rc, out);
- _good(_iscsi_iface_get_from_sysfs(ctx, host_id, sid, &((*se)->iface)),
+ /* does this need to the correct iface_kern_id for the session? */
+ _good(_iscsi_iface_get_from_sysfs(ctx, host_id, sid, NULL, &((*se)->iface)),
rc, out);
out:
diff --git a/libopeniscsiusr/sysfs.c b/libopeniscsiusr/sysfs.c
index 22eaf44..689f716 100644
--- a/libopeniscsiusr/sysfs.c
+++ b/libopeniscsiusr/sysfs.c
@@ -454,8 +454,10 @@ bool _iscsi_transport_is_loaded(const char *transport_name)
return false;
}
-int _iscsi_iface_kern_id_of_host_id(struct iscsi_context *ctx,
- uint32_t host_id, char *iface_kern_id)
+int _iscsi_iface_kern_ids_of_host_id(struct iscsi_context *ctx,
+ uint32_t host_id,
+ char ***iface_kern_ids,
+ uint32_t *iface_count)
{
char *sysfs_sh_path = NULL;
char *dev_path = NULL;
@@ -463,6 +465,7 @@ int _iscsi_iface_kern_id_of_host_id(struct iscsi_context *ctx,
int rc = LIBISCSI_OK;
struct dirent **namelist = NULL;
int n = 0;
+ uint32_t i = 0;
sysfs_sh_path = malloc(PATH_MAX);
_alloc_null_check(ctx, sysfs_sh_path, rc, out);
@@ -485,24 +488,32 @@ int _iscsi_iface_kern_id_of_host_id(struct iscsi_context *ctx,
_good(_scandir(ctx, sysfs_iface_path, &namelist, &n), rc, out);
if (n == 0) {
- rc = LIBISCSI_ERR_SYSFS_LOOKUP;
+ /* this is OK, and needed for transport drivers like
+ * bnx2i and qedi */
+ rc = LIBISCSI_OK;
_debug(ctx, "No iSCSI interface for iSCSI host %" PRIu32,
host_id);
goto out;
}
- if (n != 1) {
- rc = LIBISCSI_ERR_SYSFS_LOOKUP;
- _debug(ctx, "Got unexpected(got %d, should be 1) file in "
- "folder %s", n, sysfs_iface_path);
- goto out;
+ *iface_count = n;
+ *iface_kern_ids = calloc(*iface_count, sizeof(char *));
+ _alloc_null_check(ctx, *iface_kern_ids, rc, out);
+ for (i = 0; i < *iface_count; i++) {
+ (*iface_kern_ids)[i] = strdup(namelist[i]->d_name);
+ _alloc_null_check(ctx, (*iface_kern_ids)[i], rc, out);
+ _debug(ctx, "Found iSCSI iface '%s' for iSCSI host %" PRIu32,
+ (*iface_kern_ids)[i], host_id);
}
-
- snprintf(iface_kern_id, PATH_MAX, "%s", namelist[0]->d_name);
- _debug(ctx, "Found iSCSI iface '%s' for iSCSI host %" PRIu32,
- iface_kern_id, host_id);
-
out:
+ if (rc != LIBISCSI_OK) {
+ for (i = 0; i < *iface_count; i++ ) {
+ free((*iface_kern_ids)[i]);
+ }
+ free(*iface_kern_ids);
+ *iface_kern_ids = NULL;
+ *iface_count = 0;
+ }
_scandir_free(namelist, n);
free(sysfs_sh_path);
free(dev_path);
diff --git a/libopeniscsiusr/sysfs.h b/libopeniscsiusr/sysfs.h
index e285537..768b989 100644
--- a/libopeniscsiusr/sysfs.h
+++ b/libopeniscsiusr/sysfs.h
@@ -67,11 +67,13 @@ __DLL_LOCAL int _iscsi_host_id_of_session(struct iscsi_context *ctx,
uint32_t sid, uint32_t *host_id);
/*
- * iface_kern_id should be char[PATH_MAX]
+ * iface_kern_id returns an allocated (char *)[iface_count]
+ * that needs to be freed by the caller
*/
-__DLL_LOCAL int _iscsi_iface_kern_id_of_host_id(struct iscsi_context *ctx,
- uint32_t host_id,
- char *iface_kern_id);
+__DLL_LOCAL int _iscsi_iface_kern_ids_of_host_id(struct iscsi_context *ctx,
+ uint32_t host_id,
+ char ***iface_kern_ids,
+ uint32_t *iface_count);
/*
* The memory of (uint32_t *sids) should be freed by free().