示例#1
0
/*
 * 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;
}
示例#2
0
文件: stream.c 项目: miurahr/libvirt
/*
 * 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);	
}
示例#4
0
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);
}
示例#5
0
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;
}