diff options
Diffstat (limited to 'libopeniscsiusr')
-rw-r--r-- | libopeniscsiusr/iface.c | 88 | ||||
-rw-r--r-- | libopeniscsiusr/iface.h | 1 | ||||
-rw-r--r-- | libopeniscsiusr/session.c | 3 | ||||
-rw-r--r-- | libopeniscsiusr/sysfs.c | 37 | ||||
-rw-r--r-- | libopeniscsiusr/sysfs.h | 10 |
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(). |