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;
}
Exemplo n.º 3
0
void NodeWrap::checkPool(char *pool_name)
{
    virStoragePoolPtr pool_ptr;

    bool found = false;
    for (std::vector<PoolWrap*>::iterator iter = pools.begin();
            iter != pools.end(); iter++) {
        if ((*iter)->pool_name == pool_name) {
            found = true;
            break;
        }
    }

    if (found) {
        return;
    }

    pool_ptr = virStoragePoolLookupByName(conn, pool_name);
    if (!pool_ptr) {
        REPORT_ERR(conn, "virStoragePoolLookupByName");
    } else {
        printf("Creating new pool: %s, ptr is %p\n", pool_name, pool_ptr);
        PoolWrap *pool;
        try {
            pool = new PoolWrap(agent, this, pool_ptr, conn);
            printf("Created new pool: %s, ptr is %p\n", pool_name, pool_ptr);
            pools.push_back(pool);
        } catch (int i) {
            printf ("Error constructing pool\n");
            REPORT_ERR(conn, "constructing pool.");
            delete pool;
        }
    }
}
Result StoragePoolControlThread::getStoragePoolXMLDesc()
{
    Result result;
    QString name = task.object;
    bool read = false;
    char *Returns = NULL;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                *task.srcConnPtr, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        Returns = (virStoragePoolGetXMLDesc(storagePool, VIR_STORAGE_XML_INACTIVE));
        if ( Returns==NULL )
            result.err = sendConnErrors();
        else read = true;
        virStoragePoolFree(storagePool);
    } 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>' StoragePool %2 XML'ed")
                  .arg(name).arg((read)?"":"don't"));
    result.name = name;
    result.result = read;
    return result;
}
QStringList StoragePoolControlThread::changeAutoStartStoragePool()
{
    QStringList result;
    QString name = args.first();
    int autostart;
    if ( args.count()<2 || args.at(1).isEmpty() ) {
        result.append("Incorrect parameters.");
        return result;
    } else {
        bool converted;
        int res = args.at(1).toInt(&converted);
        if (converted) autostart = (res) ? 1 : 0;
        else {
            result.append("Incorrect parameters.");
            return result;
        };
    };
    /*
    virStoragePoolPtr *storagePool;
    unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE |
                         VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
    int ret = virConnectListAllStoragePools( currWorkConnect, &storagePool, flags);
    if ( ret<0 ) {
        sendConnErrors();
        free(storagePool);
        return result;
    };
    //qDebug()<<QString(virConnectGetURI(currWorkConnect));

    int i = 0;
    */
    bool set = false;
    /*
    while ( storagePool[i] != NULL ) {
        QString currNetName = QString( virStoragePoolGetName(storagePool[i]) );
        if ( !set && currNetName==name ) {
            set = (virStoragePoolSetAutostart(storagePool[i], autostart)+1) ? true : false;
            if (!set) sendGlobalErrors();
        };
        virStoragePoolFree(storagePool[i]);
        i++;
    };
    free(storagePool);
    */
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(currWorkConnect, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        set = (virStoragePoolSetAutostart(storagePool, autostart)+1) ? true : false;
        if (!set) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.append(QString("'<b>%1</b>' StoragePool autostart %2 Set.").arg(name).arg((set)?"":"don't"));
    return result;
}
QStringList StoragePoolControlThread::getStoragePoolXMLDesc()
{
    QStringList result;
    QString name = args.first();
    /*
    virStoragePoolPtr *storagePool;
    unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE |
                         VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
    int ret = virConnectListAllStoragePools( currWorkConnect, &storagePool, flags);
    if ( ret<0 ) {
        sendConnErrors();
        free(storagePool);
        return result;
    };
    //qDebug()<<QString(virConnectGetURI(currWorkConnect));

    int i = 0;
    */
    bool read = false;
    char *Returns = NULL;
    /*
    while ( storagePool[i] != NULL ) {
        QString currNetName = QString( virStoragePoolGetName(storagePool[i]) );
        if ( !read && currNetName==name ) {
            Returns = (virStoragePoolGetXMLDesc(storagePool[i], VIR_STORAGE_XML_INACTIVE));
            if ( Returns==NULL ) sendGlobalErrors();
            else read = true;
        };
        virStoragePoolFree(storagePool[i]);
        i++;
    };
    free(storagePool);
    */
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(currWorkConnect, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        Returns = (virStoragePoolGetXMLDesc(storagePool, VIR_STORAGE_XML_INACTIVE));
        if ( Returns==NULL ) sendConnErrors();
        else read = true;
        virStoragePoolFree(storagePool);
    } else 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.append(f.fileName());
    f.close();
    free(Returns);
    result.append(QString("'<b>%1</b>' StoragePool %2 XML'ed").arg(name).arg((read)?"":"don't"));
    return result;
}
Result StoragePoolControlThread::undefineStoragePool()
{
    Result result;
    QString name = task.object;
    bool deleted = false;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                task.sourceConn, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        deleted = (virStoragePoolUndefine(storagePool)+1) ? true : false;
        if (!deleted) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StoragePool %2 Undefined.")
                  .arg(name).arg((deleted)?"":"don't"));
    result.name = name;
    result.result = deleted;
    return result;
}
Result StoragePoolControlThread::changeAutoStartStoragePool()
{
    Result result;
    QString name = task.object;
    int autostart = task.args.sign;
    bool set = false;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                task.sourceConn, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        set = (virStoragePoolSetAutostart(storagePool, autostart)+1) ? true : false;
        if (!set) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StoragePool autostart %2 Set.")
                  .arg(name).arg((set)?"":"don't"));
    result.name = name;
    result.result = set;
    return result;
}
QStringList StoragePoolControlThread::startStoragePool()
{
    QStringList result;
    QString name = args.first();
    unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE |
                         VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
    /*
    virStoragePoolPtr *storagePool;
    int ret = virConnectListAllStoragePools( currWorkConnect, &storagePool, flags);
    if ( ret<0 ) {
        sendConnErrors();
        free(storagePool);
        return result;
    };
    //qDebug()<<QString(virConnectGetURI(currWorkConnect));

    int i = 0;
    */
    bool started = false;
    // flags: extra flags; not used yet, so callers should always pass 0
    flags = 0;
    /*
    while ( storagePool[i] != NULL ) {
        QString currPoolName = QString( virStoragePoolGetName(storagePool[i]) );
        if ( !started && currPoolName==name ) {
            started = (virStoragePoolCreate(storagePool[i], flags)+1) ? true : false;
            if (!started) sendGlobalErrors();
        };
        virStoragePoolFree(storagePool[i]);
        i++;
    };
    free(storagePool);
    */
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(currWorkConnect, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        started = (virStoragePoolCreate(storagePool, flags)+1) ? true : false;
        if (!started) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.append(QString("'<b>%1</b>' StoragePool %2 Started.").arg(name).arg((started)?"":"don't"));
    return result;
}
Result StoragePoolControlThread::destroyStoragePool()
{
    Result result;
    QString name = task.object;
    bool deleted = false;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                *task.srcConnPtr, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        deleted = (virStoragePoolDestroy(storagePool)+1) ? true : false;
        if (!deleted)
            result.err = sendConnErrors();
        virStoragePoolFree(storagePool);
    } else
        result.err = sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StoragePool %2 Destroyed.")
                  .arg(name).arg((deleted)?"":"don't"));
    result.name = name;
    result.result = deleted;
    return result;
}
Result StoragePoolControlThread::deleteStoragePool()
{
    Result result;
    QString name = task.object;
    uint flags = (task.args.sign)? VIR_STORAGE_POOL_DELETE_ZEROED
                                 : VIR_STORAGE_POOL_DELETE_NORMAL;
    bool deleted = false;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                task.sourceConn, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        deleted = (virStoragePoolDelete(storagePool, flags)+1) ? true : false;
        if (!deleted) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StoragePool %2 Deleted.")
                  .arg(name).arg((deleted)?"":"don't"));
    result.name = name;
    result.result = deleted;
    return result;
}
QStringList StoragePoolControlThread::undefineStoragePool()
{
    QStringList result;
    QString name = args.first();
    /*
    virStoragePoolPtr *storagePool;
    unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE |
                         VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
    int ret = virConnectListAllStoragePools( currWorkConnect, &storagePool, flags);
    if ( ret<0 ) {
        sendConnErrors();
        free(storagePool);
        return result;
    };
    //qDebug()<<QString(virConnectGetURI(currWorkConnect));

    int i = 0;
    */
    bool deleted = false;
    /*
    while ( storagePool[i] != NULL ) {
        QString currPoolName = QString( virStoragePoolGetName(storagePool[i]) );
        if ( !deleted && currPoolName==name ) {
            deleted = (virStoragePoolUndefine(storagePool[i])+1) ? true : false;
            if (!deleted) sendGlobalErrors();
        };
        qDebug()<<QVariant(deleted).toString()<<currPoolName<<name;
        virStoragePoolFree(storagePool[i]);
        i++;
    };
    free(storagePool);
    */
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(currWorkConnect, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        deleted = (virStoragePoolDestroy(storagePool)+1) ? true : false;
        if (!deleted) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.append(QString("'<b>%1</b>' StoragePool %2 Undefined.").arg(name).arg((deleted)?"":"don't"));
    return result;
}
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;
}
Result StoragePoolControlThread::startStoragePool()
{
    Result result;
    QString name = task.object;
    unsigned int flags = VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE |
                         VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE;
    bool started = false;
    // flags: extra flags; not used yet, so callers should always pass 0
    flags = 0;
    virStoragePoolPtr storagePool = virStoragePoolLookupByName(
                task.sourceConn, name.toUtf8().data());
    if ( storagePool!=NULL ) {
        started = (virStoragePoolCreate(storagePool, flags)+1) ? true : false;
        if (!started) sendConnErrors();
        virStoragePoolFree(storagePool);
    } else sendConnErrors();
    result.msg.append(QString("'<b>%1</b>' StoragePool %2 Started.")
                  .arg(name).arg((started)?"":"don't"));
    result.name = name;
    result.result = started;
    return result;
}
Result StorageVolControlThread::createStorageVol()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QString path = task.args.path;
    QByteArray xmlData;
    QFile f;
    f.setFileName(path);
    if ( !f.open(QIODevice::ReadOnly) ) {
        QString msg = QString("File \"%1\"\nnot opened.").arg(path);
        emit errorMsg( msg, number );
        result.result = false;
        result.err = msg;
        return result;
    };
    xmlData = f.readAll();
    f.close();
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());
    virStorageVolPtr storageVol = virStorageVolCreateXML(
                currStoragePool, xmlData.data(), VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA);
    if ( storageVol==NULL ) {
        result.err = sendConnErrors();
        result.result = false;
        return result;
    };
    QString name = QString().fromUtf8( virStorageVolGetName(storageVol) );
    result.msg.append(
                QString("'<b>%1</b>' StorageVol from\n\"%2\"\nis created.")
                .arg(name).arg(path));
    virStorageVolFree(storageVol);
    result.result = true;
    return result;
}
Result StorageVolControlThread::getAllStorageVolList()
{
    Result result;
    result.name = QString("%1_%2").arg(task.srcConName).arg(currPoolName);
    QStringList storageVolList;
    if (currStoragePool!=NULL) {
        virStoragePoolFree(currStoragePool);
        currStoragePool = NULL;
    };
    currStoragePool = virStoragePoolLookupByName(
                *task.srcConnPtr, currPoolName.toUtf8().data());
    if ( currStoragePool!=NULL && keep_alive ) {
        virStorageVolPtr *storageVol = NULL;
        // flags: extra flags; not used yet, so callers should always pass 0
        unsigned int flags = 0;
        int ret = virStoragePoolListAllVolumes(
                    currStoragePool, &storageVol, flags);
        if ( ret<0 ) {
            result.err = sendConnErrors();
            result.result = false;
            result.msg = storageVolList;
            return result;
        };

        // therefore correctly to use for() command, because storageVol[0] can not exist.
        for (int i = 0; i < ret; i++) {
            QString type, capacity, allocation;
            virStorageVolInfo info;
            if ( virStorageVolGetInfo(storageVol[i], &info)+1 ) {
                switch (info.type) {
                case VIR_STORAGE_VOL_FILE:
                    type.append("file");
                    break;
                case VIR_STORAGE_VOL_BLOCK:
                    type.append("block");
                    break;
                case VIR_STORAGE_VOL_DIR:
                    type.append("dir");
                    break;
                case VIR_STORAGE_VOL_NETWORK:
                    type.append("net");
                    break;
                default:
                    type.append("-");
                    break;
                };
                allocation.append(QString("%1").arg(info.allocation));
                capacity.append(QString("%1").arg(info.capacity));
            } else {
                sendConnErrors();
                type.append("-");
                allocation.append("-");
                capacity.append("-");
            };
            QStringList currentAttr;
            currentAttr<< QString::fromUtf8( virStorageVolGetName(storageVol[i]) )
                       << QString::fromUtf8( virStorageVolGetPath(storageVol[i]) )
                       << QString( type )
                       << QString( allocation )
                       << QString( capacity );;
            storageVolList.append(currentAttr);
            //qDebug()<<currentAttr<<"Volume";
            virStorageVolFree(storageVol[i]);
        };
        free(storageVol);
    } else
        result.err = sendConnErrors();
    result.result = true;
    result.msg = storageVolList;
    return result;
}
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;
}