/* * Returns: * -1 if fatal error occurred * 0 if message was fully processed * 1 if message is still being processed */ static int remoteStreamHandleWriteData(struct qemud_client *client, struct qemud_client_stream *stream, struct qemud_client_message *msg) { remote_error rerr; int ret; VIR_DEBUG("stream=%p proc=%d serial=%d len=%d offset=%d", stream, msg->hdr.proc, msg->hdr.serial, msg->bufferLength, msg->bufferOffset); memset(&rerr, 0, sizeof rerr); ret = virStreamSend(stream->st, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset); if (ret > 0) { msg->bufferOffset += ret; /* Partial write, so indicate we have more todo later */ if (msg->bufferOffset < msg->bufferLength) return 1; } else if (ret == -2) { /* Blocking, so indicate we have more todo later */ return 1; } else { VIR_INFO("Stream send failed"); stream->closed = 1; remoteDispatchError(&rerr); return remoteSerializeReplyError(client, &rerr, &msg->hdr); } return 0; }
/* * Returns: * -1 if fatal error occurred * 0 if message was fully processed * 1 if message is still being processed */ static int daemonStreamHandleWriteData(virNetServerClientPtr client, daemonClientStream *stream, virNetMessagePtr msg) { int ret; VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d, len=%zu, offset=%zu", client, stream, msg->header.proc, msg->header.serial, msg->bufferLength, msg->bufferOffset); ret = virStreamSend(stream->st, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset); if (ret > 0) { msg->bufferOffset += ret; /* Partial write, so indicate we have more todo later */ if (msg->bufferOffset < msg->bufferLength) return 1; } else if (ret == -2) { /* Blocking, so indicate we have more todo later */ return 1; } else { virNetMessageError rerr; memset(&rerr, 0, sizeof(rerr)); VIR_INFO("Stream send failed"); stream->closed = 1; return virNetServerProgramSendReplyError(stream->prog, client, msg, &rerr, &msg->header); } return 0; }
// here be a compress func void compressFunc(virConnectPtr conn) { int fd; // открываем некомпрессированный файл // компрессуем virStreamPtr st = virStreamNew(conn, 0); fd = open("compressed_file", O_RDONLY); // открываем компрессированный, считываем, передаём стрим - сенд по указателю на поток СТ, буф+смещение, до гот-смещение while (1) { char buf[1024]; int got; got = read(fd, buf, 1024); if (got < 0) { virStreamAbort(st); break; } if (got == 0) { virStreamFinish(st); break; } int offset = 0; while (offset < got) { int sent; sent = virStreamSend(st, buf+offset, got-offset); if (sent < 0) { virStreamAbort(st); goto done; } offset += sent; } } if (virStreamFinish(st) < 0) // обработчик ошибки done: virStreamFree(st); close(fd); }
static void virConsoleEventOnStream(virStreamPtr st, int events, void *opaque) { virConsolePtr con = opaque; virObjectLock(con); /* we got late event after console was shutdown */ if (!con->st) goto cleanup; if (events & VIR_STREAM_EVENT_READABLE) { size_t avail = con->streamToTerminal.length - con->streamToTerminal.offset; int got; if (avail < 1024) { if (VIR_REALLOC_N(con->streamToTerminal.data, con->streamToTerminal.length + 1024) < 0) { virConsoleShutdown(con); goto cleanup; } con->streamToTerminal.length += 1024; avail += 1024; } got = virStreamRecv(st, con->streamToTerminal.data + con->streamToTerminal.offset, avail); if (got == -2) goto cleanup; /* blocking */ if (got <= 0) { if (got == 0) virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("console stream EOF")); virConsoleShutdown(con); goto cleanup; } con->streamToTerminal.offset += got; if (con->streamToTerminal.offset) virEventUpdateHandle(con->stdoutWatch, VIR_EVENT_HANDLE_WRITABLE); } if (events & VIR_STREAM_EVENT_WRITABLE && con->terminalToStream.offset) { ssize_t done; size_t avail; done = virStreamSend(con->st, con->terminalToStream.data, con->terminalToStream.offset); if (done == -2) goto cleanup; /* blocking */ if (done < 0) { virConsoleShutdown(con); goto cleanup; } memmove(con->terminalToStream.data, con->terminalToStream.data + done, con->terminalToStream.offset - done); con->terminalToStream.offset -= done; avail = con->terminalToStream.length - con->terminalToStream.offset; if (avail > 1024) { ignore_value(VIR_REALLOC_N(con->terminalToStream.data, con->terminalToStream.offset + 1024)); con->terminalToStream.length = con->terminalToStream.offset + 1024; } } if (!con->terminalToStream.offset) virStreamEventUpdateCallback(con->st, VIR_STREAM_EVENT_READABLE); if (events & VIR_STREAM_EVENT_ERROR || events & VIR_STREAM_EVENT_HANGUP) { virConsoleShutdown(con); } cleanup: virObjectUnlock(con); }
static void virConsoleEventOnStream(virStreamPtr st, int events, void *opaque) { virConsolePtr con = opaque; if (events & VIR_STREAM_EVENT_READABLE) { size_t avail = con->streamToTerminal.length - con->streamToTerminal.offset; int got; if (avail < 1024) { if (VIR_REALLOC_N(con->streamToTerminal.data, con->streamToTerminal.length + 1024) < 0) { virReportOOMError(); virConsoleShutdown(con); return; } con->streamToTerminal.length += 1024; avail += 1024; } got = virStreamRecv(st, con->streamToTerminal.data + con->streamToTerminal.offset, avail); if (got == -2) return; /* blocking */ if (got <= 0) { virConsoleShutdown(con); return; } con->streamToTerminal.offset += got; if (con->streamToTerminal.offset) virEventUpdateHandle(con->stdoutWatch, VIR_EVENT_HANDLE_WRITABLE); } if (events & VIR_STREAM_EVENT_WRITABLE && con->terminalToStream.offset) { ssize_t done; size_t avail; done = virStreamSend(con->st, con->terminalToStream.data, con->terminalToStream.offset); if (done == -2) return; /* blocking */ if (done < 0) { virConsoleShutdown(con); return; } memmove(con->terminalToStream.data, con->terminalToStream.data + done, con->terminalToStream.offset - done); con->terminalToStream.offset -= done; avail = con->terminalToStream.length - con->terminalToStream.offset; if (avail > 1024) { if (VIR_REALLOC_N(con->terminalToStream.data, con->terminalToStream.offset + 1024) < 0) {} con->terminalToStream.length = con->terminalToStream.offset + 1024; } } if (!con->terminalToStream.offset) virStreamEventUpdateCallback(con->st, VIR_STREAM_EVENT_READABLE); if (events & VIR_STREAM_EVENT_ERROR || events & VIR_STREAM_EVENT_HANGUP) { virConsoleShutdown(con); } }
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; }