/** * 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; }
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; }