[libvirt] [PATCH 02/11] Refactor iSCSI driver code to facilitate future changes

Dave Allan dallan at redhat.com
Fri Nov 12 17:39:57 UTC 2010


On Fri, Nov 12, 2010 at 04:22:35PM +0000, Daniel P. Berrange wrote:
> The following series of patches are adding significant
> extra functionality to the iSCSI driver. THe current
> internal helper methods are not sufficiently flexible
> to cope with these changes. This patch refactors the
> code to avoid needing to have a virStoragePoolObjPtr
> instance as a parameter, instead passing individual
> target, portal and initiatoriqn parameters.

What's your motivation for removing the struct and passing the
parameters individually?  It's clearly not wrong, but why generate the
code churn if it's not required?

> It also removes hardcoding of port 3260 in the portal
> address, instead using the XML value if any.

ACK

> * src/storage/storage_backend_iscsi.c: Refactor internal
>   helper methods
> ---
>  src/storage/storage_backend_iscsi.c |  251 +++++++++++++++++------------------
>  1 files changed, 125 insertions(+), 126 deletions(-)
> 
> diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
> index 06a89ec..51f71af 100644
> --- a/src/storage/storage_backend_iscsi.c
> +++ b/src/storage/storage_backend_iscsi.c
> @@ -89,6 +89,27 @@ virStorageBackendISCSITargetIP(const char *hostname,
>      return 0;
>  }
>  
> +static char *
> +virStorageBackendISCSIPortal(virStoragePoolSourcePtr source)
> +{
> +    char ipaddr[NI_MAXHOST];
> +    char *portal;
> +
> +    if (virStorageBackendISCSITargetIP(source->host.name,
> +                                       ipaddr, sizeof(ipaddr)) < 0)
> +        return NULL;
> +
> +    if (virAsprintf(&portal, "%s:%d,1", ipaddr,
> +                    source->host.port ?
> +                    source->host.port : 3260) < 0) {
> +        virReportOOMError();
> +        return NULL;
> +    }
> +
> +    return portal;
> +}
> +
> +
>  static int
>  virStorageBackendISCSIExtractSession(virStoragePoolObjPtr pool,
>                                       char **const groups,
> @@ -156,7 +177,7 @@ virStorageBackendISCSISession(virStoragePoolObjPtr pool,
>  #define LINE_SIZE 4096
>  
>  static int
> -virStorageBackendIQNFound(virStoragePoolObjPtr pool,
> +virStorageBackendIQNFound(const char *initiatoriqn,
>                            char **ifacename)
>  {
>      int ret = IQN_MISSING, fd = -1;
> @@ -182,7 +203,7 @@ virStorageBackendIQNFound(virStoragePoolObjPtr pool,
>      if (virExec(prog, NULL, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
>          virStorageReportError(VIR_ERR_INTERNAL_ERROR,
>                                _("Failed to run '%s' when looking for existing interface with IQN '%s'"),
> -                              prog[0], pool->def->source.initiator.iqn);
> +                              prog[0], initiatoriqn);
>  
>          ret = IQN_ERROR;
>          goto out;
> @@ -215,7 +236,7 @@ virStorageBackendIQNFound(virStoragePoolObjPtr pool,
>          }
>          iqn++;
>  
> -        if (STREQ(iqn, pool->def->source.initiator.iqn)) {
> +        if (STREQ(iqn, initiatoriqn)) {
>              token = strtok_r(line, " ", &saveptr);
>              *ifacename = strdup(token);
>              if (*ifacename == NULL) {
> @@ -246,7 +267,7 @@ out:
>  
>  
>  static int
> -virStorageBackendCreateIfaceIQN(virStoragePoolObjPtr pool,
> +virStorageBackendCreateIfaceIQN(const char *initiatoriqn,
>                                  char **ifacename)
>  {
>      int ret = -1, exitstatus = -1;
> @@ -267,7 +288,7 @@ virStorageBackendCreateIfaceIQN(virStoragePoolObjPtr pool,
>      };
>  
>      VIR_DEBUG("Attempting to create interface '%s' with IQN '%s'",
> -              &temp_ifacename[0], pool->def->source.initiator.iqn);
> +              &temp_ifacename[0], initiatoriqn);
>  
>      /* Note that we ignore the exitstatus.  Older versions of iscsiadm
>       * tools returned an exit status of > 0, even if they succeeded.
> @@ -283,7 +304,7 @@ virStorageBackendCreateIfaceIQN(virStoragePoolObjPtr pool,
>      const char *const cmdargv2[] = {
>          ISCSIADM, "--mode", "iface", "--interface", &temp_ifacename[0],
>          "--op", "update", "--name", "iface.initiatorname", "--value",
> -        pool->def->source.initiator.iqn, NULL
> +        initiatoriqn, NULL
>      };
>  
>      /* Note that we ignore the exitstatus.  Older versions of iscsiadm tools
> @@ -292,19 +313,19 @@ virStorageBackendCreateIfaceIQN(virStoragePoolObjPtr pool,
>      if (virRun(cmdargv2, &exitstatus) < 0) {
>          virStorageReportError(VIR_ERR_INTERNAL_ERROR,
>                                _("Failed to run command '%s' to update iscsi interface with IQN '%s'"),
> -                              cmdargv2[0], pool->def->source.initiator.iqn);
> +                              cmdargv2[0], initiatoriqn);
>          goto out;
>      }
>  
>      /* Check again to make sure the interface was created. */
> -    if (virStorageBackendIQNFound(pool, ifacename) != IQN_FOUND) {
> +    if (virStorageBackendIQNFound(initiatoriqn, ifacename) != IQN_FOUND) {
>          VIR_DEBUG("Failed to find interface '%s' with IQN '%s' "
>                    "after attempting to create it",
> -                  &temp_ifacename[0], pool->def->source.initiator.iqn);
> +                  &temp_ifacename[0], initiatoriqn);
>          goto out;
>      } else {
>          VIR_DEBUG("Interface '%s' with IQN '%s' was created successfully",
> -                  *ifacename, pool->def->source.initiator.iqn);
> +                  *ifacename, initiatoriqn);
>      }
>  
>      ret = 0;
> @@ -316,82 +337,72 @@ out:
>  }
>  
>  
> +
>  static int
> -virStorageBackendISCSIConnectionIQN(virStoragePoolObjPtr pool,
> -                                    const char *portal,
> -                                    const char *action)
> +virStorageBackendISCSIConnection(const char *portal,
> +                                 const char *initiatoriqn,
> +                                 const char *target,
> +                                 const char **extraargv)
>  {
>      int ret = -1;
> +    const char *const baseargv[] = {
> +        ISCSIADM,
> +        "--mode", "node",
> +        "--portal", portal,
> +        "--targetname", target,
> +        NULL
> +    };
> +    int i;
> +    int nargs = 0;
>      char *ifacename = NULL;
> +    const char **cmdargv;
>  
> -    switch (virStorageBackendIQNFound(pool, &ifacename)) {
> -    case IQN_FOUND:
> -        VIR_DEBUG("ifacename: '%s'", ifacename);
> -        break;
> -    case IQN_MISSING:
> -        if (virStorageBackendCreateIfaceIQN(pool, &ifacename) != 0) {
> -            goto out;
> -        }
> -        break;
> -    case IQN_ERROR:
> -    default:
> -        goto out;
> -    }
> +    for (i = 0 ; baseargv[i] != NULL ; i++)
> +        nargs++;
> +    for (i = 0 ; extraargv[i] != NULL ; i++)
> +        nargs++;
> +    if (initiatoriqn)
> +        nargs += 2;
>  
> -    const char *const sendtargets[] = {
> -        ISCSIADM, "--mode", "discovery", "--type", "sendtargets", "--portal", portal, NULL
> -    };
> -    if (virRun(sendtargets, NULL) < 0) {
> -        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
> -                              _("Failed to run %s to get target list"),
> -                              sendtargets[0]);
> -        goto out;
> +    if (VIR_ALLOC_N(cmdargv, nargs+1) < 0) {
> +        virReportOOMError();
> +        return -1;
>      }
>  
> -    const char *const cmdargv[] = {
> -        ISCSIADM, "--mode", "node", "--portal", portal,
> -        "--targetname", pool->def->source.devices[0].path, "--interface",
> -        ifacename, action, NULL
> -    };
> +    nargs = 0;
> +    for (i = 0 ; baseargv[i] != NULL ; i++)
> +        cmdargv[nargs++] = baseargv[i];
> +    for (i = 0 ; extraargv[i] != NULL ; i++)
> +        cmdargv[nargs++] = extraargv[i];
>  
> -    if (virRun(cmdargv, NULL) < 0) {
> -        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
> -                              _("Failed to run command '%s' with action '%s'"),
> -                              cmdargv[0], action);
> -        goto out;
> +    if (initiatoriqn) {
> +        switch (virStorageBackendIQNFound(initiatoriqn, &ifacename)) {
> +        case IQN_FOUND:
> +            VIR_DEBUG("ifacename: '%s'", ifacename);
> +            break;
> +        case IQN_MISSING:
> +            if (virStorageBackendCreateIfaceIQN(initiatoriqn, &ifacename) != 0) {
> +                goto cleanup;
> +            }
> +            break;
> +        case IQN_ERROR:
> +        default:
> +            goto cleanup;
> +        }
> +
> +        cmdargv[nargs++] = "--interface";
> +        cmdargv[nargs++] = ifacename;
>      }
> +    cmdargv[nargs++] = NULL;
> +
> +    if (virRun(cmdargv, NULL) < 0)
> +        goto cleanup;
>  
>      ret = 0;
>  
> -out:
> +cleanup:
> +    VIR_FREE(cmdargv);
>      VIR_FREE(ifacename);
> -    return ret;
> -}
> -
> -
> -static int
> -virStorageBackendISCSIConnection(virStoragePoolObjPtr pool,
> -                                 const char *portal,
> -                                 const char *action)
> -{
> -    int ret = 0;
> -
> -    if (pool->def->source.initiator.iqn != NULL) {
> -
> -        ret = virStorageBackendISCSIConnectionIQN(pool, portal, action);
> -
> -    } else {
> -
> -        const char *const cmdargv[] = {
> -            ISCSIADM, "--mode", "node", "--portal", portal,
> -            "--targetname", pool->def->source.devices[0].path, action, NULL
> -        };
> -
> -        if (virRun(cmdargv, NULL) < 0) {
> -            ret = -1;
> -        }
> -
> -    }
>  
>      return ret;
>  }
> @@ -441,46 +452,18 @@ virStorageBackendISCSIRescanLUNs(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
>  
>  
>  static int
> -virStorageBackendISCSILogin(virStoragePoolObjPtr pool,
> -                            const char *portal)
> +virStorageBackendISCSIScanTargets(const char *portal)
>  {
> -    const char *const cmdsendtarget[] = {
> -        ISCSIADM, "--mode", "discovery", "--type", "sendtargets",
> -        "--portal", portal, NULL
> +    const char *const sendtargets[] = {
> +        ISCSIADM, "--mode", "discovery", "--type", "sendtargets", "--portal", portal, NULL
>      };
> -
> -    if (virRun(cmdsendtarget, NULL) < 0)
> +    if (virRun(sendtargets, NULL) < 0) {
> +        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
> +                              _("Failed to run %s to get target list"),
> +                              sendtargets[0]);
>          return -1;
> -
> -    return virStorageBackendISCSIConnection(pool, portal, "--login");
> -}
> -
> -static int
> -virStorageBackendISCSILogout(virStoragePoolObjPtr pool,
> -                             const char *portal)
> -{
> -    return virStorageBackendISCSIConnection(pool, portal, "--logout");
> -}
> -
> -static char *
> -virStorageBackendISCSIPortal(virStoragePoolObjPtr pool)
> -{
> -    char ipaddr[NI_MAXHOST];
> -    char *portal;
> -
> -    if (virStorageBackendISCSITargetIP(pool->def->source.host.name,
> -                                       ipaddr, sizeof(ipaddr)) < 0)
> -        return NULL;
> -
> -    if (VIR_ALLOC_N(portal, strlen(ipaddr) + 1 + 4 + 2 + 1) < 0) {
> -        virReportOOMError();
> -        return NULL;
>      }
> -
> -    strcpy(portal, ipaddr);
> -    strcat(portal, ":3260,1");
> -
> -    return portal;
> +    return 0;
>  }
>  
>  
> @@ -489,7 +472,9 @@ virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
>                                  virStoragePoolObjPtr pool)
>  {
>      char *portal = NULL;
> -    char *session;
> +    char *session = NULL;
> +    int ret = -1;
> +    const char *loginargv[] = { "--login", NULL };
>  
>      if (pool->def->source.host.name == NULL) {
>          virStorageReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -505,17 +490,26 @@ virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
>      }
>  
>      if ((session = virStorageBackendISCSISession(pool, 1)) == NULL) {
> -        if ((portal = virStorageBackendISCSIPortal(pool)) == NULL)
> -            return -1;
> -        if (virStorageBackendISCSILogin(pool, portal) < 0) {
> -            VIR_FREE(portal);
> -            return -1;
> -        }
> -        VIR_FREE(portal);
> -    } else {
> -        VIR_FREE(session);
> +        if ((portal = virStorageBackendISCSIPortal(&pool->def->source)) == NULL)
> +            goto cleanup;
> +        /*
> +         * iscsiadm doesn't let you login to a target, unless you've
> +         * first issued a 'sendtargets' command to the portal :-(
> +         */
> +        if (virStorageBackendISCSIScanTargets(portal) < 0)
> +            goto cleanup;
> +
> +        if (virStorageBackendISCSIConnection(portal,
> +                                             pool->def->source.initiator.iqn,
> +                                             pool->def->source.devices[0].path,
> +                                             loginargv) < 0)
> +            goto cleanup;
>      }
> -    return 0;
> +    ret = 0;
> +
> +cleanup:
> +    VIR_FREE(session);
> +    return ret;
>  }
>  
>  static int
> @@ -546,18 +540,23 @@ static int
>  virStorageBackendISCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED,
>                                 virStoragePoolObjPtr pool)
>  {
> +    const char *logoutargv[] = { "--logout", NULL };
>      char *portal;
> +    int ret = -1;
>  
> -    if ((portal = virStorageBackendISCSIPortal(pool)) == NULL)
> +    if ((portal = virStorageBackendISCSIPortal(&pool->def->source)) == NULL)
>          return -1;
>  
> -    if (virStorageBackendISCSILogout(pool, portal) < 0) {
> -        VIR_FREE(portal);
> -        return -1;
> -    }
> -    VIR_FREE(portal);
> +    if (virStorageBackendISCSIConnection(portal,
> +                                         pool->def->source.initiator.iqn,
> +                                         pool->def->source.devices[0].path,
> +                                         logoutargv) < 0)
> +        goto cleanup;
> +    ret = 0;
>  
> -    return 0;
> +cleanup:
> +    VIR_FREE(portal);
> +    return ret;
>  }
>  
>  virStorageBackend virStorageBackendISCSI = {
> -- 
> 1.7.2.3
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list




More information about the libvir-list mailing list