/**
 * gvir_storage_vol_upload:
 * @vol: the storage volume to upload
 * @stream: stream to use as input
 * @offset: position in @vol to start to write to
 * @length: limit on amount of data to upload, or 0 for uploading all data
 * @flags: the flags, not set yet, pass 0
 *
 * Returns: #TRUE of success, #FALSE otherwise
 */
gboolean gvir_storage_vol_upload(GVirStorageVol *vol,
                                 GVirStream *stream,
                                 guint64 offset,
                                 guint64 length,
                                 guint flags G_GNUC_UNUSED,
                                 GError **err)
{
    virStreamPtr stream_handle = NULL;
    gboolean ret = FALSE;

    g_object_get(stream, "handle", &stream_handle, NULL);

    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), FALSE);
    g_return_val_if_fail(GVIR_IS_STREAM(stream), FALSE);
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

    if (virStorageVolUpload(vol->priv->handle,
                            stream_handle,
                            offset,
                            length,
                            0) < 0) {
        gvir_set_error_literal(err,
                               GVIR_STORAGE_VOL_ERROR,
                               0,
                               "Unable to upload to stream");

        goto cleanup;
    }

    ret = TRUE;
cleanup:
    if (stream_handle != NULL)
        virStreamFree(stream_handle);
    return ret;
}
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;
}
Exemplo n.º 3
0
static bool
cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
{
    const char *file = NULL;
    virStorageVolPtr vol = NULL;
    bool ret = false;
    int fd = -1;
    virStreamPtr st = NULL;
    const char *name = NULL;
    unsigned long long offset = 0, length = 0;

    if (!vshConnectionUsability(ctl, ctl->conn))
        goto cleanup;

    if (vshCommandOptULongLong(cmd, "offset", &offset) < 0) {
        vshError(ctl, _("Unable to parse integer"));
        return false;
    }

    if (vshCommandOptULongLong(cmd, "length", &length) < 0) {
        vshError(ctl, _("Unable to parse integer"));
        return false;
    }

    if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) {
        return false;
    }

    if (vshCommandOptString(cmd, "file", &file) < 0) {
        vshError(ctl, _("file must not be empty"));
        goto cleanup;
    }

    if ((fd = open(file, O_RDONLY)) < 0) {
        vshError(ctl, _("cannot read %s"), file);
        goto cleanup;
    }

    st = virStreamNew(ctl->conn, 0);
    if (virStorageVolUpload(vol, st, offset, length, 0) < 0) {
        vshError(ctl, _("cannot upload to volume %s"), name);
        goto cleanup;
    }

    if (virStreamSendAll(st, cmdVolUploadSource, &fd) < 0) {
        vshError(ctl, _("cannot send data to volume %s"), name);
        goto cleanup;
    }

    if (VIR_CLOSE(fd) < 0) {
        vshError(ctl, _("cannot close file %s"), file);
        virStreamAbort(st);
        goto cleanup;
    }

    if (virStreamFinish(st) < 0) {
        vshError(ctl, _("cannot close volume %s"), name);
        goto cleanup;
    }

    ret = true;

cleanup:
    if (vol)
        virStorageVolFree(vol);
    if (st)
        virStreamFree(st);
    VIR_FORCE_CLOSE(fd);
    return ret;
}