Result StorageVolControlThread::resizeStorageVol()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString name = task.object;
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());

    unsigned long long capacity = task.args.size;
    bool resized = false;
    virStorageVol *storageVol = virStorageVolLookupByName(
                currStoragePool, name.toUtf8().data());
    if ( storageVol!=NULL ) {
        int ret = virStorageVolResize(
                    storageVol, capacity,
                    VIR_STORAGE_VOL_RESIZE_ALLOCATE |
                    VIR_STORAGE_VOL_RESIZE_SHRINK);
        if ( ret<0 ) {
            result.err = sendConnErrors();
        } else
            resized = true;
        virStorageVolFree(storageVol);
    } else
        result.err = sendConnErrors();
    result.msg.append(
                QString("'<b>%1</b>' StorageVol %2 Resized to %3 (bytes).")
                .arg(name).arg((resized)?"":"don't").arg(capacity));
    result.result = resized;
    return result;
}
Result StorageVolControlThread::deleteStorageVol()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString name = task.object;
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());

    // flags: extra flags; not used yet, so callers should always pass 0
    unsigned int flags = 0;
    bool deleted = false;
    virStorageVol *storageVol = virStorageVolLookupByName(
                currStoragePool, name.toUtf8().data());
    if ( storageVol!=NULL ) {
        deleted = (virStorageVolDelete(storageVol, flags)+1) ? true : false;
        if (!deleted)
            result.err = sendConnErrors();
        virStorageVolFree(storageVol);
    } else
        result.err = sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StorageVol %2 Deleted.")
                      .arg(name).arg((deleted)?"":"don't"));
    result.result = deleted;
    return result;
}
Exemple #3
0
static virStorageVolPtr
vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
                   const char *optname,
                   const char *pooloptname,
                   const char **name, int flag)
{
    virStorageVolPtr vol = NULL;
    virStoragePoolPtr pool = NULL;
    const char *n = NULL, *p = NULL;

    if (vshCommandOptString(cmd, optname, &n) <= 0)
        return NULL;

    if (pooloptname != NULL && vshCommandOptString(cmd, pooloptname, &p) < 0) {
        vshError(ctl, "%s", _("missing option"));
        return NULL;
    }

    if (p)
        pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flag);

    vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
             cmd->def->name, optname, n);

    if (name)
        *name = n;

    /* try it by name */
    if (pool && (flag & VSH_BYNAME)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByName(pool, n);
    }
    /* try it by key */
    if (vol == NULL && (flag & VSH_BYUUID)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByKey(ctl->conn, n);
    }
    /* try it by path */
    if (vol == NULL && (flag & VSH_BYUUID)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByPath(ctl->conn, n);
    }

    if (!vol) {
        if (pool)
            vshError(ctl, _("failed to get vol '%s'"), n);
        else
            vshError(ctl, _("failed to get vol '%s', specifying --%s "
                            "might help"), n, pooloptname);
    }

    if (pool)
        virStoragePoolFree(pool);

    return vol;
}
Result StorageVolControlThread::getStorageVolXMLDesc()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString name = task.object;
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());

    bool read = false;
    char *Returns = NULL;
    // flags: extra flags; not used yet, so callers should always pass 0
    unsigned int flags = 0;
    virStorageVol *storageVol = virStorageVolLookupByName(
                currStoragePool, name.toUtf8().data());
    if ( storageVol!=NULL ) {
        Returns = virStorageVolGetXMLDesc(storageVol, flags);
        if ( Returns==NULL )
            result.err = sendConnErrors();
        else read = true;
        virStorageVolFree(storageVol);
    } else
        result.err = sendConnErrors();
    QTemporaryFile f;
    f.setAutoRemove(false);
    f.setFileTemplate(QString("%1%2XML_Desc-XXXXXX.xml")
                      .arg(QDir::tempPath()).arg(QDir::separator()));
    read = f.open();
    if (read) f.write(Returns);
    result.fileName.append(f.fileName());
    f.close();
    if ( Returns!=NULL ) free(Returns);
    result.msg.append(QString("'<b>%1</b>' StorageVol %2 XML'ed")
                  .arg(name).arg((read)?"":"don't"));
    result.result = read;
    return result;
}
/**
 * gvir_storage_pool_refresh:
 * @pool: the storage pool
 * @cancellable: (allow-none)(transfer none): cancellation object
 */
gboolean gvir_storage_pool_refresh(GVirStoragePool *pool,
                                   GCancellable *cancellable,
                                   GError **err)
{
    GVirStoragePoolPrivate *priv;
    GHashTable *vol_hash;
    gchar **volumes = NULL;
    gint nvolumes = 0;
    gboolean ret = FALSE;
    gint i;
    virStoragePoolPtr vpool = NULL;
    GError *lerr = NULL;

    g_return_val_if_fail(GVIR_IS_STORAGE_POOL(pool), FALSE);
    g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
                         FALSE);
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

    priv = pool->priv;
    vpool = priv->handle;

    if (virStoragePoolRefresh(vpool, 0) < 0) {
        gvir_set_error_literal(err, GVIR_STORAGE_POOL_ERROR,
                               0,
                               "Unable to refresh storage pool");
        goto cleanup;
    }

    volumes = fetch_list(vpool,
                         "Storage Volumes",
                         virStoragePoolNumOfVolumes,
                         virStoragePoolListVolumes,
                         cancellable,
                         &nvolumes,
                         &lerr);
    if (lerr) {
        g_propagate_error(err, lerr);
        lerr = NULL;
        goto cleanup;
    }

    if (g_cancellable_set_error_if_cancelled(cancellable, err))
        goto cleanup;

    vol_hash = g_hash_table_new_full(g_str_hash,
                                     g_str_equal,
                                     g_free,
                                     g_object_unref);

    for (i = 0 ; i < nvolumes ; i++) {
        if (g_cancellable_set_error_if_cancelled(cancellable, err))
            goto cleanup;

        virStorageVolPtr vvolume;
        GVirStorageVol *volume;

        vvolume = virStorageVolLookupByName(vpool, volumes[i]);
        if (!vvolume)
            continue;

        volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL,
                                               "handle", vvolume,
                                               "pool", pool,
                                               NULL));
        virStorageVolFree(vvolume);
        g_hash_table_insert(vol_hash, g_strdup(volumes[i]), volume);
    }

    g_mutex_lock(priv->lock);
    if (priv->volumes)
        g_hash_table_unref(priv->volumes);
    priv->volumes = vol_hash;
    g_mutex_unlock(priv->lock);

    ret = TRUE;

cleanup:
    for (i = 0 ; i < nvolumes ; i++)
        g_free(volumes[i]);
    g_free(volumes);
    return ret;
}
Result StorageVolControlThread::wipeStorageVol()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString name, algorithm;
    name = task.object;
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());

    //flags: extra flags; not used yet, so callers should always pass 0
    unsigned int flags = 0;
    unsigned int alg = task.args.sign;
    bool wiped = false;
    virStorageVol *storageVol = virStorageVolLookupByName(
                currStoragePool, name.toUtf8().data());
    if ( storageVol!=NULL ) {
        int ret = virStorageVolWipePattern(storageVol, alg, flags);
        if ( ret<0 ) {
            result.err = sendConnErrors();
        } else wiped = true;
        virStorageVolFree(storageVol);
    } else
        result.err = sendConnErrors();
    switch (alg) {
    case VIR_STORAGE_VOL_WIPE_ALG_ZERO:
        algorithm.append("ZERO");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_NNSA:
        algorithm.append("NNSA");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_DOD:
        algorithm.append("DOD");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_BSI:
        algorithm.append("BSI");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_GUTMANN:
        algorithm.append("GUTMANN");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7:
        algorithm.append("PFITZNER7");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33:
        algorithm.append("PFITZNER33");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_RANDOM:
        algorithm.append("RANDOM");
        break;
    case VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER:
        algorithm.append("SCHNEIER");
        break;
    default:
        algorithm.append("NONE");
        break;
    };
    result.msg.append(
                QString("'<b>%1</b>' StorageVol %2 Wiped with %3 algorithm.")
                .arg(name).arg((wiped)?"":"don't").arg(algorithm));
    result.result = wiped;
    return result;
}
Result StorageVolControlThread::uploadStorageVol()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString name, path;
    name = task.object;
    path = task.args.path;
    //qDebug()<<path<<"upload";
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());
    QFile *f = new QFile(path);
    f->open(QIODevice::ReadOnly);

    bool uploaded = false;
    virStreamPtr stream = virStreamNew(*task.srcConnPtr, 0);
    unsigned long long offset = 0;
    unsigned long long length = f->size();
    // flags: extra flags; not used yet, so callers should always pass 0
    unsigned int flags = 0;
    virStorageVol *storageVol = virStorageVolLookupByName(
                currStoragePool, name.toUtf8().data());
    if ( storageVol!=NULL ) {
        int ret = virStorageVolUpload(
                    storageVol, stream, offset, length, flags);
        if ( ret<0 ) {
            result.err = sendConnErrors();
        } else {
            uploaded = true;
            length = 0;
            int got, saved, step;
            step = 0;
            char buf[BLOCK_SIZE];
            while ( 1 && keep_alive ) {
                got = f->read(buf, BLOCK_SIZE);
                if (got == 0) break;
                if ( got<0 ) {
                    QString msg = QString("ReadError after (%2): %1 bytes")
                            .arg(length).arg(step);
                    emit errorMsg( msg, number );
                    result.err = msg;
                } else {
                    saved = virStreamSend(stream, buf, got);
                    if (saved < 0) {
                        result.err = sendConnErrors();
                        uploaded = false;
                        break;
                    };
                    step++;
                    length += saved;
                    //qDebug()<<"got<>saved:length"<<got<<saved<<step<<length;
                };
            };
            virStreamFinish(stream);
        };
        virStorageVolFree(storageVol);
    } else
        result.err = sendConnErrors();
    if ( stream!=NULL ) virStreamFree(stream);
    f->close();
    delete f; f = 0;
    result.msg.append(
                QString("'<b>%1</b>' StorageVol %2 Uploaded from %3 (%4).")
                .arg(name).arg((uploaded)?"":"don't")
                .arg(path).arg(length));
    result.result = uploaded;
    return result;
}
Exemple #8
0
static bool
cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd)
{
    virStoragePoolPtr pool;
    virStorageVolPtr vol;
    char *xml;
    const char *name, *capacityStr = NULL, *allocationStr = NULL, *format = NULL;
    const char *snapshotStrVol = NULL, *snapshotStrFormat = NULL;
    unsigned long long capacity, allocation = 0;
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (!vshConnectionUsability(ctl, ctl->conn))
        return false;

    if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL,
                                     VSH_BYNAME)))
        return false;

    if (vshCommandOptString(cmd, "name", &name) <= 0)
        goto cleanup;

    if (vshCommandOptString(cmd, "capacity", &capacityStr) <= 0)
        goto cleanup;

    if (vshVolSize(capacityStr, &capacity) < 0) {
        vshError(ctl, _("Malformed size %s"), capacityStr);
        goto cleanup;
    }

    if (vshCommandOptString(cmd, "allocation", &allocationStr) > 0 &&
        vshVolSize(allocationStr, &allocation) < 0) {
        vshError(ctl, _("Malformed size %s"), allocationStr);
        goto cleanup;
    }

    if (vshCommandOptString(cmd, "format", &format) < 0 ||
        vshCommandOptString(cmd, "backing-vol", &snapshotStrVol) < 0 ||
        vshCommandOptString(cmd, "backing-vol-format",
                            &snapshotStrFormat) < 0) {
        vshError(ctl, "%s", _("missing argument"));
        goto cleanup;
    }


    virBufferAddLit(&buf, "<volume>\n");
    virBufferAsprintf(&buf, "  <name>%s</name>\n", name);
    virBufferAsprintf(&buf, "  <capacity>%llu</capacity>\n", capacity);
    if (allocationStr)
        virBufferAsprintf(&buf, "  <allocation>%llu</allocation>\n", allocation);

    if (format) {
        virBufferAddLit(&buf, "  <target>\n");
        virBufferAsprintf(&buf, "    <format type='%s'/>\n",format);
        virBufferAddLit(&buf, "  </target>\n");
    }

    /* Convert the snapshot parameters into backingStore XML */
    if (snapshotStrVol) {
        /* Lookup snapshot backing volume.  Try the backing-vol
         *  parameter as a name */
        vshDebug(ctl, VSH_ERR_DEBUG,
                 "%s: Look up backing store volume '%s' as name\n",
                 cmd->def->name, snapshotStrVol);
        virStorageVolPtr snapVol = virStorageVolLookupByName(pool, snapshotStrVol);
        if (snapVol)
                vshDebug(ctl, VSH_ERR_DEBUG,
                         "%s: Backing store volume found using '%s' as name\n",
                         cmd->def->name, snapshotStrVol);

        if (snapVol == NULL) {
            /* Snapshot backing volume not found by name.  Try the
             *  backing-vol parameter as a key */
            vshDebug(ctl, VSH_ERR_DEBUG,
                     "%s: Look up backing store volume '%s' as key\n",
                     cmd->def->name, snapshotStrVol);
            snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol);
            if (snapVol)
                vshDebug(ctl, VSH_ERR_DEBUG,
                         "%s: Backing store volume found using '%s' as key\n",
                         cmd->def->name, snapshotStrVol);
        }
        if (snapVol == NULL) {
            /* Snapshot backing volume not found by key.  Try the
             *  backing-vol parameter as a path */
            vshDebug(ctl, VSH_ERR_DEBUG,
                     "%s: Look up backing store volume '%s' as path\n",
                     cmd->def->name, snapshotStrVol);
            snapVol = virStorageVolLookupByPath(ctl->conn, snapshotStrVol);
            if (snapVol)
                vshDebug(ctl, VSH_ERR_DEBUG,
                         "%s: Backing store volume found using '%s' as path\n",
                         cmd->def->name, snapshotStrVol);
        }
        if (snapVol == NULL) {
            vshError(ctl, _("failed to get vol '%s'"), snapshotStrVol);
            goto cleanup;
        }

        char *snapshotStrVolPath;
        if ((snapshotStrVolPath = virStorageVolGetPath(snapVol)) == NULL) {
            virStorageVolFree(snapVol);
            goto cleanup;
        }

        /* Create XML for the backing store */
        virBufferAddLit(&buf, "  <backingStore>\n");
        virBufferAsprintf(&buf, "    <path>%s</path>\n",snapshotStrVolPath);
        if (snapshotStrFormat)
            virBufferAsprintf(&buf, "    <format type='%s'/>\n",snapshotStrFormat);
        virBufferAddLit(&buf, "  </backingStore>\n");

        /* Cleanup snapshot allocations */
        VIR_FREE(snapshotStrVolPath);
        virStorageVolFree(snapVol);
    }

    virBufferAddLit(&buf, "</volume>\n");

    if (virBufferError(&buf)) {
        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
        goto cleanup;
    }
    xml = virBufferContentAndReset(&buf);
    vol = virStorageVolCreateXML(pool, xml, 0);
    VIR_FREE(xml);
    virStoragePoolFree(pool);

    if (vol != NULL) {
        vshPrint(ctl, _("Vol %s created\n"), name);
        virStorageVolFree(vol);
        return true;
    } else {
        vshError(ctl, _("Failed to create vol %s"), name);
        return false;
    }

 cleanup:
    virBufferFreeAndReset(&buf);
    virStoragePoolFree(pool);
    return false;
}
Exemple #9
0
virStorageVolPtr
vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
                   const char *optname,
                   const char *pooloptname,
                   const char **name, unsigned int flags)
{
    virStorageVolPtr vol = NULL;
    virStoragePoolPtr pool = NULL;
    const char *n = NULL, *p = NULL;
    virCheckFlags(VSH_BYUUID | VSH_BYNAME, NULL);

    if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0)
        return NULL;

    if (pooloptname != NULL &&
        vshCommandOptStringReq(ctl, cmd, pooloptname, &p) < 0)
        return NULL;

    if (p) {
        if (!(pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flags)))
            return NULL;

        if (virStoragePoolIsActive(pool) != 1) {
            vshError(ctl, _("pool '%s' is not active"), p);
            virStoragePoolFree(pool);
            return NULL;
        }
    }

    vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
             cmd->def->name, optname, n);

    if (name)
        *name = n;

    /* try it by name */
    if (pool && (flags & VSH_BYNAME)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByName(pool, n);
    }
    /* try it by key */
    if (!vol && (flags & VSH_BYUUID)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByKey(ctl->conn, n);
    }
    /* try it by path */
    if (!vol && (flags & VSH_BYUUID)) {
        vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n",
                 cmd->def->name, optname);
        vol = virStorageVolLookupByPath(ctl->conn, n);
    }

    if (!vol) {
        if (pool || !pooloptname)
            vshError(ctl, _("failed to get vol '%s'"), n);
        else
            vshError(ctl, _("failed to get vol '%s', specifying --%s "
                            "might help"), n, pooloptname);
    }

    /* If the pool was specified, then make sure that the returned
     * volume is from the given pool */
    if (pool && vol) {
        virStoragePoolPtr volpool = NULL;

        if ((volpool = virStoragePoolLookupByVolume(vol))) {
            if (STRNEQ(virStoragePoolGetName(volpool),
                       virStoragePoolGetName(pool))) {
                vshResetLibvirtError();
                vshError(ctl,
                         _("Requested volume '%s' is not in pool '%s'"),
                         n, virStoragePoolGetName(pool));
                virStorageVolFree(vol);
                vol = NULL;
            }
            virStoragePoolFree(volpool);
        }
    }

    if (pool)
        virStoragePoolFree(pool);

    return vol;
}
Exemple #10
0
static vshStorageVolListPtr
vshStorageVolListCollect(vshControl *ctl,
                         virStoragePoolPtr pool,
                         unsigned int flags)
{
    vshStorageVolListPtr list = vshMalloc(ctl, sizeof(*list));
    size_t i;
    char **names = NULL;
    virStorageVolPtr vol = NULL;
    bool success = false;
    size_t deleted = 0;
    int nvols = 0;
    int ret = -1;

    /* try the list with flags support (0.10.2 and later) */
    if ((ret = virStoragePoolListAllVolumes(pool,
                                            &list->vols,
                                            flags)) >= 0) {
        list->nvols = ret;
        goto finished;
    }

    /* check if the command is actually supported */
    if (last_error && last_error->code == VIR_ERR_NO_SUPPORT)
        goto fallback;

    /* there was an error during the call */
    vshError(ctl, "%s", _("Failed to list volumes"));
    goto cleanup;

 fallback:
    /* fall back to old method (0.10.1 and older) */
    vshResetLibvirtError();

    /* Determine the number of volumes in the pool */
    if ((nvols = virStoragePoolNumOfVolumes(pool)) < 0) {
        vshError(ctl, "%s", _("Failed to list storage volumes"));
        goto cleanup;
    }

    if (nvols == 0) {
        success = true;
        return list;
    }

    /* Retrieve the list of volume names in the pool */
    names = vshCalloc(ctl, nvols, sizeof(*names));
    if ((nvols = virStoragePoolListVolumes(pool, names, nvols)) < 0) {
        vshError(ctl, "%s", _("Failed to list storage volumes"));
        goto cleanup;
    }

    list->vols = vshMalloc(ctl, sizeof(virStorageVolPtr) * (nvols));
    list->nvols = 0;

    /* get the vols */
    for (i = 0; i < nvols; i++) {
        if (!(vol = virStorageVolLookupByName(pool, names[i])))
            continue;
        list->vols[list->nvols++] = vol;
    }

    /* truncate the list for not found vols */
    deleted = nvols - list->nvols;

 finished:
    /* sort the list */
    if (list->vols && list->nvols)
        qsort(list->vols, list->nvols, sizeof(*list->vols), vshStorageVolSorter);

    if (deleted)
        VIR_SHRINK_N(list->vols, list->nvols, deleted);

    success = true;

 cleanup:
    if (nvols > 0)
        for (i = 0; i < nvols; i++)
            VIR_FREE(names[i]);
    VIR_FREE(names);

    if (!success) {
        vshStorageVolListFree(list);
        list = NULL;
    }

    return list;
}