On 02/04/2013 08:32 AM, Osier Yang wrote: > This finds the parent for vHBA by iterating over all the HBA > which supports vport_ops capability on the host, and return > the first one which is online, not saturated (vports in use > is less than max_vports). > --- > docs/formatstorage.html.in | 3 +- > src/libvirt_private.syms | 1 + > src/storage/storage_backend_scsi.c | 10 +++-- > src/util/virutil.c | 83 ++++++++++++++++++++++++++++++++++++ > src/util/virutil.h | 2 + > 5 files changed, 93 insertions(+), 6 deletions(-) > > diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in > index af42fed..7315865 100644 > --- a/docs/formatstorage.html.in > +++ b/docs/formatstorage.html.in > @@ -99,8 +99,7 @@ > <code>wwpn</code> (<span class="since">1.0.2</span>) indicates > the (v)HBA. The optional attribute <code>parent</code> > (<span class="since">1.0.2</span>) specifies the parent device of > - the (v)HBA. It's optional for HBA, but required for vHBA. > - <span class="since">Since 0.6.2</span></dd> > + the (v)HBA. <span class="since">Since 0.6.2</span></dd> The silent scream :-) > <dt><code>host</code></dt> > <dd>Provides the source for pools backed by storage from a > remote server. Will be used in combination with a <code>directory</code> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 7334e15..759d630 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -1841,6 +1841,7 @@ virFileStripSuffix; > virFileUnlock; > virFileWaitForDevices; > virFileWriteStr; > +virFindFCHostCapableVport; > virFindFileInPath; > virFormatIntDecimal; > virGetDeviceID; > diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c > index a9b96a3..59abeb0 100644 > --- a/src/storage/storage_backend_scsi.c > +++ b/src/storage/storage_backend_scsi.c > @@ -646,10 +646,12 @@ createVport(virStoragePoolSourceAdapter adapter) > adapter.data.fchost.wwpn)) > return 0; > > - if (!adapter.data.fchost.parent) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("'parent' for vHBA must be specified")); > - return -1; > + if (!adapter.data.fchost.parent && > + !(adapter.data.fchost.parent = virFindFCHostCapableVport(NULL))) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("'parent' for vHBA not specified, and " > + "cannot find one on this host")); > + return -1; > } > > if ((parent_host = getHostNumber(adapter.data.fchost.parent)) < 0) > diff --git a/src/util/virutil.c b/src/util/virutil.c > index 3073337..b9a6166 100644 > --- a/src/util/virutil.c > +++ b/src/util/virutil.c > @@ -3555,6 +3555,82 @@ cleanup: > VIR_FREE(wwpn_buf); > return ret; > } > + > +# define PORT_STATE_ONLINE "Online" > + > +/* virFindFCHostCapableVport: > + * > + * Iterate over the sysfs and find out the first online HBA which > + * supports vport, and not saturated,. > + */ > +char * > +virFindFCHostCapableVport(const char *sysfs_prefix) > +{ > + const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; > + DIR *dir = NULL; > + struct dirent *entry = NULL; > + char *max_vports = NULL; > + char *vports = NULL; > + char *state = NULL; > + char *ret = NULL; > + > + if (!(dir = opendir(prefix))) { > + virReportSystemError(errno, > + _("Failed to opendir path '%s'"), > + prefix); > + return NULL; > + } > + > + while ((entry = readdir(dir))) { > + if (STREQ(entry->d_name, ".") || STREQ(entry->d_name, "..")) > + continue; > + > + int host; uint32_t? To be consistent with other comments. > + > + ignore_value(sscanf(entry->d_name, "host%d", &host)); Why ignore_value()? If == -1, then host is undefined - could be something that results in the following being successful.. > + if (!virIsCapableVport(NULL, host)) > + continue; > + > + if (virReadFCHost(NULL, host, "port_state", &state) < 0) { > + VIR_DEBUG("Failed to read port_state for host%d", host); > + continue; > + } > + > + /* Skip the not online FC host */ > + if (!STREQ(state, PORT_STATE_ONLINE)) { > + VIR_FREE(state); > + continue; > + } > + VIR_FREE(state); > + > + if (virReadFCHost(NULL, host, "max_npiv_vports", &max_vports) < 0) { > + VIR_DEBUG("Failed to read max_npiv_vports for host%d", host); VIR_FREE(max_vports); > + continue; > + } > + > + if (virReadFCHost(NULL, host, "npiv_vports_inuse", &vports) < 0) { > + VIR_DEBUG("Failed to read npiv_vports_inuse for host%d", host); > + VIR_FREE(max_vports); VIR_FREE(vports); > + continue; > + } So do we document somewhere that the FC Host must have these two attributes defined for us to consider using them? > + > + if ((strlen(max_vports) > strlen(vports)) || > + ((strlen(max_vports) == strlen(vports)) && Why not just one ">=" > + strcmp(max_vports, vports) > 0)) { > + ret = strdup(entry->d_name); > + goto cleanup; > + } What is being tested? The name or the value? I didn't go back to look at what virReadFCHost() provides, but I do see there is a patch: https://www.redhat.com/archives/libvir-list/2013-January/msg00947.html that will convert the string to the number and compare using that. There's possible some code reuse that could make this and that patch a whole lot easier. > + > + VIR_FREE(max_vports); > + VIR_FREE(vports); > + } > + > +cleanup: > + closedir(dir); > + VIR_FREE(max_vports); > + VIR_FREE(vports); > + return ret; > +} > #else > int > virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, > @@ -3600,4 +3676,11 @@ virGetFCHostNameByWWN(const char *sysfs_prefix ATTRIBUTE_UNUSED, > return NULL; > } > > +char * > +virFindFCHostCapableVport(const char *sysfs_prefix ATTRIBUTE_UNUSED) > +{ > + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); > + return NULL; > +} > + > #endif /* __linux__ */ > diff --git a/src/util/virutil.h b/src/util/virutil.h > index 78b50a8..3a68134 100644 > --- a/src/util/virutil.h > +++ b/src/util/virutil.h > @@ -320,4 +320,6 @@ char * virGetFCHostNameByWWN(const char *sysfs_prefix, > const char *wwpn) > ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); > > +char * virFindFCHostCapableVport(const char *sysfs_prefix ); > + > #endif /* __VIR_UTIL_H__ */ > John -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list