[libvirt] [PATCH 4/5] virISCSIScanTargets: Honour iSCSI interface

John Ferlan jferlan at redhat.com
Mon Jul 2 23:38:02 UTC 2018



On 06/29/2018 11:01 AM, Michal Privoznik wrote:
> When scanning for targets, iSCSI might give different results
> depending on the interface used. This is basically just name of

assuming this means whether the initiatoriqn interface was used

> config file under /etc/iscsi/ifaces to use. The file contains
> initiator IQN thus different results claim.
> 

Strange to have activity here - was there a bz? Or something found by
the (I assume) GSoC project:

https://www.redhat.com/archives/libvir-list/2018-June/msg00249.html

Touching something that's been avoided for 8 years is always scary, but
if it's broken, then sure it ought to be fixed.

> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/storage/storage_backend_iscsi.c |  4 +-
>  src/util/viriscsi.c                 | 78 ++++++++++++++++++++++++++++++++++---
>  src/util/viriscsi.h                 |  1 +
>  tests/viriscsitest.c                |  2 +-
>  4 files changed, 77 insertions(+), 8 deletions(-)
> 

This patch fails to compile for me:

In file included from util/viriscsi.c:32:0:
util/viriscsi.c: In function 'virISCSIScanTargets':
util/virerror.h:187:5: error: this statement may fall through
[-Werror=implicit-fallthrough=]
     virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                          __FUNCTION__, __LINE__, __VA_ARGS__)
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
util/viriscsi.c:479:13: note: in expansion of macro 'virReportError'
             virReportError(VIR_ERR_OPERATION_FAILED,
             ^~~~~~~~~~~~~~
util/viriscsi.c:482:9: note: here
         case IQN_ERROR:
         ^~~~

> diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
> index 7871d1915b..3b9dddb4fd 100644
> --- a/src/storage/storage_backend_iscsi.c
> +++ b/src/storage/storage_backend_iscsi.c
> @@ -194,7 +194,9 @@ virStorageBackendISCSIFindPoolSources(const char *srcSpec,
>      if (!(portal = virStorageBackendISCSIPortal(source)))
>          goto cleanup;
>  
> -    if (virISCSIScanTargets(portal, &ntargets, &targets) < 0)
> +    if (virISCSIScanTargets(portal,
> +                            source->initiator.iqn,

NIT: This could go on the previous line

> +                            &ntargets, &targets) < 0)
>          goto cleanup;
>  
>      if (VIR_ALLOC_N(list.sources, ntargets) < 0)
> diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
> index 44788056fd..365669aac2 100644
> --- a/src/util/viriscsi.c
> +++ b/src/util/viriscsi.c
> @@ -40,6 +40,13 @@
>  VIR_LOG_INIT("util.iscsi");
>  
>  
> +static int
> +virISCSIScanTargetsInternal(const char *portal,
> +                            const char *ifacename,
> +                            size_t *ntargetsret,
> +                            char ***targetsret);
> +
> +
>  struct virISCSISessionData {
>      char *session;
>      const char *devpath;
> @@ -286,9 +293,10 @@ virISCSIConnection(const char *portal,
>               * iscsiadm doesn't let you send commands to the Interface IQN,
>               * unless you've first issued a 'sendtargets' command to the
>               * portal. Without the sendtargets all that is received is a
> -             * "iscsiadm: No records found"
> +             * "iscsiadm: No records found". However, we must ensure that
> +             * the command is issued over interface name we invented above.

"invented" - again is this the make sure it's issued over the
initiatoriqn interface?

>               */
> -            if (virISCSIScanTargets(portal, NULL, NULL) < 0)
> +            if (virISCSIScanTargetsInternal(portal, ifacename, NULL, NULL) < 0)
>                  goto cleanup;
>  
>              break;
> @@ -371,10 +379,11 @@ virISCSIGetTargets(char **const groups,
>  }
>  
>  
> -int
> -virISCSIScanTargets(const char *portal,
> -                    size_t *ntargetsret,
> -                    char ***targetsret)
> +static int
> +virISCSIScanTargetsInternal(const char *portal,
> +                            const char *ifacename,
> +                            size_t *ntargetsret,
> +                            char ***targetsret)
>  {
>      /**
>       *
> @@ -400,6 +409,12 @@ virISCSIScanTargets(const char *portal,
>                                               "--op", "nonpersistent",
>                                               NULL);
>  
> +    if (ifacename) {
> +        virCommandAddArgList(cmd,
> +                             "--interface", ifacename,
> +                             NULL);
> +    }
> +

Could just be one line to avoid the { }

>      memset(&list, 0, sizeof(list));
>  
>      if (virCommandRunRegex(cmd,
> @@ -425,6 +440,57 @@ virISCSIScanTargets(const char *portal,
>      return ret;
>  }
>  
> +
> +/**
> + * virISCSIScanTargets:
> + * @portal: iSCSI portal
> + * @initiatoriqn: Initiator IQN
> + * @ntargets: number of items in @targetsret array
> + * @targets: array of targets
> + *
> + * For given @portal issue sendtargets command. Optionally,
> + * @initiatoriqn can be set to override default configuration.
> + * The targets are stored into @targets array and the size of
> + * the array is stored into @ntargets.
> + *
> + * Returns: 0 on success,
> + *         -1 otherwise (with error reported)
> + */
> +int
> +virISCSIScanTargets(const char *portal,
> +                    const char *initiatoriqn,
> +                    size_t *ntargets,
> +                    char ***targets)
> +{
> +    char *ifacename = NULL;
> +    int ret = -1;
> +
> +    if (ntargets)
> +        *ntargets = 0;
> +    if (targets)
> +        *targets = NULL;
> +
> +    if (initiatoriqn) {
> +        switch ((virStorageBackendIQNFound(initiatoriqn, &ifacename))) {
> +        case IQN_FOUND:
> +            break;
> +
> +        case IQN_MISSING:
> +            virReportError(VIR_ERR_OPERATION_FAILED,
> +                           _("no iSCSI interface defined for IQN %s"),
> +                           initiatoriqn);

    ATTRIBUTE_FALLTHROUGH;

With a couple of adjustments and some more explanation why we're here -
as in what is failing in the current scheme,

Reviewed-by: John Ferlan <jferlan at redhat.com>

John

> +        case IQN_ERROR:
> +        default:
> +            return -1;
> +        }
> +    }
> +
> +    ret = virISCSIScanTargetsInternal(portal, ifacename, ntargets, targets);
> +    VIR_FREE(ifacename);
> +    return ret;
> +}
> +
> +
>  /*
>   * virISCSINodeNew:
>   * @portal: address for iSCSI target
> diff --git a/src/util/viriscsi.h b/src/util/viriscsi.h
> index a44beeaf67..31b589dbf9 100644
> --- a/src/util/viriscsi.h
> +++ b/src/util/viriscsi.h
> @@ -49,6 +49,7 @@ virISCSIRescanLUNs(const char *session)
>  
>  int
>  virISCSIScanTargets(const char *portal,
> +                    const char *initiatoriqn,
>                      size_t *ntargetsret,
>                      char ***targetsret)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
> diff --git a/tests/viriscsitest.c b/tests/viriscsitest.c
> index aa4ba57707..4bdb782e36 100644
> --- a/tests/viriscsitest.c
> +++ b/tests/viriscsitest.c
> @@ -145,7 +145,7 @@ testISCSIScanTargets(const void *data)
>  
>      virCommandSetDryRun(NULL, testIscsiadmCb, NULL);
>  
> -    if (virISCSIScanTargets(info->portal, &ntargets, &targets) < 0)
> +    if (virISCSIScanTargets(info->portal, NULL, &ntargets, &targets) < 0)
>          goto cleanup;
>  
>      if (info->nexpected != ntargets) {
> 




More information about the libvir-list mailing list