virDomainStorageSourceTranslateSourcePool(virStorageSourcePtr src,
                                          virConnectPtr conn)
{
    virStorageVolInfo info;
    g_autoptr(virStoragePoolDef) pooldef = NULL;
    g_autofree char *poolxml = NULL;
    g_autoptr(virStoragePool) pool = NULL;
    g_autoptr(virStorageVol) vol = NULL;

    if (!(pool = virStoragePoolLookupByName(conn, src->srcpool->pool)))
        return -1;

    if (virStoragePoolIsActive(pool) != 1) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("storage pool '%s' containing volume '%s' "
                         "is not active"),
                       src->srcpool->pool, src->srcpool->volume);
        return -1;
    }

    if (!(vol = virStorageVolLookupByName(pool, src->srcpool->volume)))
        return -1;

    if (virStorageVolGetInfo(vol, &info) < 0)
        return -1;

    if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
        return -1;

    if (!(pooldef = virStoragePoolDefParseString(poolxml)))
        return -1;

    src->srcpool->pooltype = pooldef->type;
    src->srcpool->voltype = info.type;

    if (src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("disk source mode is only valid when "
                         "storage pool is of iscsi type"));
        return -1;
    }

    VIR_FREE(src->path);
    virStorageNetHostDefFree(src->nhosts, src->hosts);
    src->nhosts = 0;
    src->hosts = NULL;
    virStorageAuthDefFree(src->auth);
    src->auth = NULL;

    switch ((virStoragePoolType) pooldef->type) {
    case VIR_STORAGE_POOL_DIR:
    case VIR_STORAGE_POOL_FS:
    case VIR_STORAGE_POOL_NETFS:
    case VIR_STORAGE_POOL_LOGICAL:
    case VIR_STORAGE_POOL_DISK:
    case VIR_STORAGE_POOL_SCSI:
    case VIR_STORAGE_POOL_ZFS:
    case VIR_STORAGE_POOL_VSTORAGE:
        if (!(src->path = virStorageVolGetPath(vol)))
            return -1;

        switch (info.type) {
        case VIR_STORAGE_VOL_FILE:
            src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
            break;

        case VIR_STORAGE_VOL_DIR:
            src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
            break;

        case VIR_STORAGE_VOL_BLOCK:
            src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
            break;

        case VIR_STORAGE_VOL_PLOOP:
            src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
            break;

        case VIR_STORAGE_VOL_NETWORK:
        case VIR_STORAGE_VOL_NETDIR:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected storage volume type '%s' "
                             "for storage pool type '%s'"),
                           virStorageVolTypeToString(info.type),
                           virStoragePoolTypeToString(pooldef->type));
            return -1;
        }

        break;

    case VIR_STORAGE_POOL_ISCSI_DIRECT:
        if (virDomainDiskTranslateISCSIDirect(src, pooldef) < 0)
            return -1;

        break;

    case VIR_STORAGE_POOL_ISCSI:
       switch (src->srcpool->mode) {
       case VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT:
       case VIR_STORAGE_SOURCE_POOL_MODE_LAST:
           src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
           G_GNUC_FALLTHROUGH;
       case VIR_STORAGE_SOURCE_POOL_MODE_HOST:
           src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
           if (!(src->path = virStorageVolGetPath(vol)))
               return -1;
           break;

       case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
           if (virDomainDiskTranslateISCSIDirect(src, pooldef) < 0)
               return -1;
           break;
       }
       break;

    case VIR_STORAGE_POOL_MPATH:
    case VIR_STORAGE_POOL_RBD:
    case VIR_STORAGE_POOL_SHEEPDOG:
    case VIR_STORAGE_POOL_GLUSTER:
    case VIR_STORAGE_POOL_LAST:
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("using '%s' pools for backing 'volume' disks "
                         "isn't yet supported"),
                       virStoragePoolTypeToString(pooldef->type));
        return -1;
    }

    return 0;
}