Ejemplo n.º 1
0
void
virStoragePoolObjDispose(void *opaque)
{
    virStoragePoolObjPtr obj = opaque;

    if (!obj)
        return;

    virStoragePoolObjClearVols(obj);

    virStoragePoolDefFree(obj->def);
    virStoragePoolDefFree(obj->newDef);

    VIR_FREE(obj->configFile);
    VIR_FREE(obj->autostartLink);
}
Ejemplo n.º 2
0
static int virStorageBackendRBDRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
        virStoragePoolObjPtr pool)
{
    size_t max_size = 1024;
    int ret = -1;
    int len = -1;
    int i;
    char *name, *names = NULL;
    virStorageBackendRBDStatePtr ptr;
    ptr.cluster = NULL;
    ptr.ioctx = NULL;

    if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) {
        goto cleanup;
    }

    if (rados_ioctx_create(ptr.cluster,
                           pool->def->source.name, &ptr.ioctx) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to create the RBD IoCTX. Does the pool '%s' exist?"),
                       pool->def->source.name);
        goto cleanup;
    }

    struct rados_cluster_stat_t stat;
    if (rados_cluster_stat(ptr.cluster, &stat) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to stat the RADOS cluster"));
        goto cleanup;
    }

    struct rados_pool_stat_t poolstat;
    if (rados_ioctx_pool_stat(ptr.ioctx, &poolstat) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to stat the RADOS pool '%s'"),
                       pool->def->source.name);
        goto cleanup;
    }

    pool->def->capacity = stat.kb * 1024;
    pool->def->available = stat.kb_avail * 1024;
    pool->def->allocation = poolstat.num_bytes;

    VIR_DEBUG("Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu)",
              pool->def->source.name, (unsigned long long)stat.kb,
              (unsigned long long)stat.kb_avail,
              (unsigned long long)poolstat.num_bytes);

    while (true) {
        if (VIR_ALLOC_N(names, max_size) < 0)
            goto out_of_memory;

        len = rbd_list(ptr.ioctx, names, &max_size);
        if (len >= 0)
            break;
        if (len != -ERANGE) {
            VIR_WARN("%s", _("A problem occurred while listing RBD images"));
            goto cleanup;
        }
        VIR_FREE(names);
    }

    for (i = 0, name = names; name < names + max_size; i++) {
        virStorageVolDefPtr vol;

        if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count + 1) < 0) {
            virStoragePoolObjClearVols(pool);
            goto out_of_memory;
        }

        if (STREQ(name, ""))
            break;

        if (VIR_ALLOC(vol) < 0)
            goto out_of_memory;

        vol->name = strdup(name);
        if (vol->name == NULL) {
            VIR_FREE(vol);
            goto out_of_memory;
        }

        name += strlen(name) + 1;

        if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) {
            virStorageVolDefFree(vol);
            goto cleanup;
        }

        pool->volumes.objs[pool->volumes.count++] = vol;
    }

    VIR_DEBUG("Found %d images in RBD pool %s",
              pool->volumes.count, pool->def->source.name);

    ret = 0;

cleanup:
    VIR_FREE(names);
    virStorageBackendRBDCloseRADOSConn(ptr);
    return ret;

out_of_memory:
    virReportOOMError();
    goto cleanup;
}
Ejemplo n.º 3
0
/**
 * Iterate over the pool's directory and enumerate all disk images
 * within it. This is non-recursive.
 */
static int
virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
                                   virStoragePoolObjPtr pool)
{
    DIR *dir;
    struct dirent *ent;
    struct statvfs sb;
    virStorageVolDefPtr vol = NULL;

    if (!(dir = opendir(pool->def->target.path))) {
        virReportSystemError(errno,
                             _("cannot open path '%s'"),
                             pool->def->target.path);
        goto cleanup;
    }

    while ((ent = readdir(dir)) != NULL) {
        int ret;
        char *backingStore;

        if (VIR_ALLOC(vol) < 0)
            goto no_memory;

        if ((vol->name = strdup(ent->d_name)) == NULL)
            goto no_memory;

        vol->type = VIR_STORAGE_VOL_FILE;
        vol->target.format = VIR_STORAGE_FILE_RAW; /* Real value is filled in during probe */
        if (virAsprintf(&vol->target.path, "%s/%s",
                        pool->def->target.path,
                        vol->name) == -1)
            goto no_memory;

        if ((vol->key = strdup(vol->target.path)) == NULL)
            goto no_memory;

        if ((ret = virStorageBackendProbeTarget(&vol->target,
                                                &backingStore,
                                                &vol->allocation,
                                                &vol->capacity,
                                                &vol->target.encryption)) < 0) {
            if (ret == -1)
                goto cleanup;
            else {
                /* Silently ignore non-regular files,
                 * eg '.' '..', 'lost+found' */
                virStorageVolDefFree(vol);
                vol = NULL;
                continue;
            }
        }

        if (backingStore != NULL) {
            if (vol->target.format == VIR_STORAGE_FILE_QCOW2 &&
                STRPREFIX("fmt:", backingStore)) {
                char *fmtstr = backingStore + 4;
                char *path = strchr(fmtstr, ':');
                if (!path) {
                    VIR_FREE(backingStore);
                } else {
                    *path = '\0';
                    if ((vol->backingStore.format =
                         virStorageFileFormatTypeFromString(fmtstr)) < 0) {
                        VIR_FREE(backingStore);
                    } else {
                        memmove(backingStore, path, strlen(path) + 1);
                        vol->backingStore.path = backingStore;

                        if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
                                                                 NULL,
                                                                 NULL) < 0)
                            VIR_FREE(vol->backingStore);
                    }
                }
            } else {
                vol->backingStore.path = backingStore;

                if ((ret = virStorageBackendProbeTarget(&vol->backingStore,
                                                        NULL, NULL, NULL,
                                                        NULL)) < 0) {
                    if (ret == -1)
                        goto cleanup;
                    else {
                        /* Silently ignore non-regular files,
                         * eg '.' '..', 'lost+found' */
                        VIR_FREE(vol->backingStore);
                    }
                }
            }
        }



        if (VIR_REALLOC_N(pool->volumes.objs,
                          pool->volumes.count+1) < 0)
            goto no_memory;
        pool->volumes.objs[pool->volumes.count++] = vol;
        vol = NULL;
    }
    closedir(dir);


    if (statvfs(pool->def->target.path, &sb) < 0) {
        virReportSystemError(errno,
                             _("cannot statvfs path '%s'"),
                             pool->def->target.path);
        return -1;
    }
    pool->def->capacity = ((unsigned long long)sb.f_frsize *
                           (unsigned long long)sb.f_blocks);
    pool->def->available = ((unsigned long long)sb.f_bfree *
                            (unsigned long long)sb.f_bsize);
    pool->def->allocation = pool->def->capacity - pool->def->available;

    return 0;

no_memory:
    virReportOOMError();
    /* fallthrough */

 cleanup:
    if (dir)
        closedir(dir);
    virStorageVolDefFree(vol);
    virStoragePoolObjClearVols(pool);
    return -1;
}
Ejemplo n.º 4
0
static int virStorageBackendRBDRefreshPool(virConnectPtr conn,
                                           virStoragePoolObjPtr pool)
{
    size_t max_size = 1024;
    int ret = -1;
    int len = -1;
    int r = 0;
    char *name, *names = NULL;
    virStorageBackendRBDState ptr;
    ptr.cluster = NULL;
    ptr.ioctx = NULL;

    if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, pool) < 0) {
        goto cleanup;
    }

    if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0) {
        goto cleanup;
    }

    struct rados_cluster_stat_t clusterstat;
    r = rados_cluster_stat(ptr.cluster, &clusterstat);
    if (r < 0) {
        virReportSystemError(-r, "%s", _("failed to stat the RADOS cluster"));
        goto cleanup;
    }

    struct rados_pool_stat_t poolstat;
    r = rados_ioctx_pool_stat(ptr.ioctx, &poolstat);
    if (r < 0) {
        virReportSystemError(-r, _("failed to stat the RADOS pool '%s'"),
                             pool->def->source.name);
        goto cleanup;
    }

    pool->def->capacity = clusterstat.kb * 1024;
    pool->def->available = clusterstat.kb_avail * 1024;
    pool->def->allocation = poolstat.num_bytes;

    VIR_DEBUG("Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu)",
              pool->def->source.name, (unsigned long long)clusterstat.kb,
              (unsigned long long)clusterstat.kb_avail,
              (unsigned long long)poolstat.num_bytes);

    while (true) {
        if (VIR_ALLOC_N(names, max_size) < 0)
            goto cleanup;

        len = rbd_list(ptr.ioctx, names, &max_size);
        if (len >= 0)
            break;
        if (len != -ERANGE) {
            VIR_WARN("%s", _("A problem occurred while listing RBD images"));
            goto cleanup;
        }
        VIR_FREE(names);
    }

    for (name = names; name < names + max_size;) {
        virStorageVolDefPtr vol;

        if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count + 1) < 0) {
            virStoragePoolObjClearVols(pool);
            goto cleanup;
        }

        if (STREQ(name, ""))
            break;

        if (VIR_ALLOC(vol) < 0)
            goto cleanup;

        if (VIR_STRDUP(vol->name, name) < 0) {
            VIR_FREE(vol);
            goto cleanup;
        }

        name += strlen(name) + 1;

        if (volStorageBackendRBDRefreshVolInfo(vol, pool, &ptr) < 0) {
            virStorageVolDefFree(vol);
            goto cleanup;
        }

        pool->volumes.objs[pool->volumes.count++] = vol;
    }

    VIR_DEBUG("Found %zu images in RBD pool %s",
              pool->volumes.count, pool->def->source.name);

    ret = 0;

cleanup:
    VIR_FREE(names);
    virStorageBackendRBDCloseRADOSConn(&ptr);
    return ret;
}