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; }
static virStorageVolPtr vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char *pooloptname, const char **name, int flag) { virStorageVolPtr vol = NULL; virStoragePoolPtr pool = NULL; const char *n = NULL, *p = NULL; if (vshCommandOptString(cmd, optname, &n) <= 0) return NULL; if (pooloptname != NULL && vshCommandOptString(cmd, pooloptname, &p) < 0) { vshError(ctl, "%s", _("missing option")); return NULL; } if (p) pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flag); vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n", cmd->def->name, optname, n); if (name) *name = n; /* try it by name */ if (pool && (flag & VSH_BYNAME)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n", cmd->def->name, optname); vol = virStorageVolLookupByName(pool, n); } /* try it by key */ if (vol == NULL && (flag & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n", cmd->def->name, optname); vol = virStorageVolLookupByKey(ctl->conn, n); } /* try it by path */ if (vol == NULL && (flag & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n", cmd->def->name, optname); vol = virStorageVolLookupByPath(ctl->conn, n); } if (!vol) { if (pool) vshError(ctl, _("failed to get vol '%s'"), n); else vshError(ctl, _("failed to get vol '%s', specifying --%s " "might help"), n, pooloptname); } if (pool) virStoragePoolFree(pool); return vol; }
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; }
/** * gvir_storage_pool_refresh: * @pool: the storage pool * @cancellable: (allow-none)(transfer none): cancellation object */ gboolean gvir_storage_pool_refresh(GVirStoragePool *pool, GCancellable *cancellable, GError **err) { GVirStoragePoolPrivate *priv; GHashTable *vol_hash; gchar **volumes = NULL; gint nvolumes = 0; gboolean ret = FALSE; gint i; virStoragePoolPtr vpool = NULL; GError *lerr = NULL; g_return_val_if_fail(GVIR_IS_STORAGE_POOL(pool), FALSE); g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable), FALSE); g_return_val_if_fail(err == NULL || *err == NULL, FALSE); priv = pool->priv; vpool = priv->handle; if (virStoragePoolRefresh(vpool, 0) < 0) { gvir_set_error_literal(err, GVIR_STORAGE_POOL_ERROR, 0, "Unable to refresh storage pool"); goto cleanup; } volumes = fetch_list(vpool, "Storage Volumes", virStoragePoolNumOfVolumes, virStoragePoolListVolumes, cancellable, &nvolumes, &lerr); if (lerr) { g_propagate_error(err, lerr); lerr = NULL; goto cleanup; } if (g_cancellable_set_error_if_cancelled(cancellable, err)) goto cleanup; vol_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); for (i = 0 ; i < nvolumes ; i++) { if (g_cancellable_set_error_if_cancelled(cancellable, err)) goto cleanup; virStorageVolPtr vvolume; GVirStorageVol *volume; vvolume = virStorageVolLookupByName(vpool, volumes[i]); if (!vvolume) continue; volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL, "handle", vvolume, "pool", pool, NULL)); virStorageVolFree(vvolume); g_hash_table_insert(vol_hash, g_strdup(volumes[i]), volume); } g_mutex_lock(priv->lock); if (priv->volumes) g_hash_table_unref(priv->volumes); priv->volumes = vol_hash; g_mutex_unlock(priv->lock); ret = TRUE; cleanup: for (i = 0 ; i < nvolumes ; i++) g_free(volumes[i]); g_free(volumes); return ret; }
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; }
static bool cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) { virStoragePoolPtr pool; virStorageVolPtr vol; char *xml; const char *name, *capacityStr = NULL, *allocationStr = NULL, *format = NULL; const char *snapshotStrVol = NULL, *snapshotStrFormat = NULL; unsigned long long capacity, allocation = 0; virBuffer buf = VIR_BUFFER_INITIALIZER; if (!vshConnectionUsability(ctl, ctl->conn)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, VSH_BYNAME))) return false; if (vshCommandOptString(cmd, "name", &name) <= 0) goto cleanup; if (vshCommandOptString(cmd, "capacity", &capacityStr) <= 0) goto cleanup; if (vshVolSize(capacityStr, &capacity) < 0) { vshError(ctl, _("Malformed size %s"), capacityStr); goto cleanup; } if (vshCommandOptString(cmd, "allocation", &allocationStr) > 0 && vshVolSize(allocationStr, &allocation) < 0) { vshError(ctl, _("Malformed size %s"), allocationStr); goto cleanup; } if (vshCommandOptString(cmd, "format", &format) < 0 || vshCommandOptString(cmd, "backing-vol", &snapshotStrVol) < 0 || vshCommandOptString(cmd, "backing-vol-format", &snapshotStrFormat) < 0) { vshError(ctl, "%s", _("missing argument")); goto cleanup; } virBufferAddLit(&buf, "<volume>\n"); virBufferAsprintf(&buf, " <name>%s</name>\n", name); virBufferAsprintf(&buf, " <capacity>%llu</capacity>\n", capacity); if (allocationStr) virBufferAsprintf(&buf, " <allocation>%llu</allocation>\n", allocation); if (format) { virBufferAddLit(&buf, " <target>\n"); virBufferAsprintf(&buf, " <format type='%s'/>\n",format); virBufferAddLit(&buf, " </target>\n"); } /* Convert the snapshot parameters into backingStore XML */ if (snapshotStrVol) { /* Lookup snapshot backing volume. Try the backing-vol * parameter as a name */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as name\n", cmd->def->name, snapshotStrVol); virStorageVolPtr snapVol = virStorageVolLookupByName(pool, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as name\n", cmd->def->name, snapshotStrVol); if (snapVol == NULL) { /* Snapshot backing volume not found by name. Try the * backing-vol parameter as a key */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as key\n", cmd->def->name, snapshotStrVol); snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as key\n", cmd->def->name, snapshotStrVol); } if (snapVol == NULL) { /* Snapshot backing volume not found by key. Try the * backing-vol parameter as a path */ vshDebug(ctl, VSH_ERR_DEBUG, "%s: Look up backing store volume '%s' as path\n", cmd->def->name, snapshotStrVol); snapVol = virStorageVolLookupByPath(ctl->conn, snapshotStrVol); if (snapVol) vshDebug(ctl, VSH_ERR_DEBUG, "%s: Backing store volume found using '%s' as path\n", cmd->def->name, snapshotStrVol); } if (snapVol == NULL) { vshError(ctl, _("failed to get vol '%s'"), snapshotStrVol); goto cleanup; } char *snapshotStrVolPath; if ((snapshotStrVolPath = virStorageVolGetPath(snapVol)) == NULL) { virStorageVolFree(snapVol); goto cleanup; } /* Create XML for the backing store */ virBufferAddLit(&buf, " <backingStore>\n"); virBufferAsprintf(&buf, " <path>%s</path>\n",snapshotStrVolPath); if (snapshotStrFormat) virBufferAsprintf(&buf, " <format type='%s'/>\n",snapshotStrFormat); virBufferAddLit(&buf, " </backingStore>\n"); /* Cleanup snapshot allocations */ VIR_FREE(snapshotStrVolPath); virStorageVolFree(snapVol); } virBufferAddLit(&buf, "</volume>\n"); if (virBufferError(&buf)) { vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); goto cleanup; } xml = virBufferContentAndReset(&buf); vol = virStorageVolCreateXML(pool, xml, 0); VIR_FREE(xml); virStoragePoolFree(pool); if (vol != NULL) { vshPrint(ctl, _("Vol %s created\n"), name); virStorageVolFree(vol); return true; } else { vshError(ctl, _("Failed to create vol %s"), name); return false; } cleanup: virBufferFreeAndReset(&buf); virStoragePoolFree(pool); return false; }
virStorageVolPtr vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char *pooloptname, const char **name, unsigned int flags) { virStorageVolPtr vol = NULL; virStoragePoolPtr pool = NULL; const char *n = NULL, *p = NULL; virCheckFlags(VSH_BYUUID | VSH_BYNAME, NULL); if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0) return NULL; if (pooloptname != NULL && vshCommandOptStringReq(ctl, cmd, pooloptname, &p) < 0) return NULL; if (p) { if (!(pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flags))) return NULL; if (virStoragePoolIsActive(pool) != 1) { vshError(ctl, _("pool '%s' is not active"), p); virStoragePoolFree(pool); return NULL; } } vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n", cmd->def->name, optname, n); if (name) *name = n; /* try it by name */ if (pool && (flags & VSH_BYNAME)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n", cmd->def->name, optname); vol = virStorageVolLookupByName(pool, n); } /* try it by key */ if (!vol && (flags & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n", cmd->def->name, optname); vol = virStorageVolLookupByKey(ctl->conn, n); } /* try it by path */ if (!vol && (flags & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n", cmd->def->name, optname); vol = virStorageVolLookupByPath(ctl->conn, n); } if (!vol) { if (pool || !pooloptname) vshError(ctl, _("failed to get vol '%s'"), n); else vshError(ctl, _("failed to get vol '%s', specifying --%s " "might help"), n, pooloptname); } /* If the pool was specified, then make sure that the returned * volume is from the given pool */ if (pool && vol) { virStoragePoolPtr volpool = NULL; if ((volpool = virStoragePoolLookupByVolume(vol))) { if (STRNEQ(virStoragePoolGetName(volpool), virStoragePoolGetName(pool))) { vshResetLibvirtError(); vshError(ctl, _("Requested volume '%s' is not in pool '%s'"), n, virStoragePoolGetName(pool)); virStorageVolFree(vol); vol = NULL; } virStoragePoolFree(volpool); } } if (pool) virStoragePoolFree(pool); return vol; }
static vshStorageVolListPtr vshStorageVolListCollect(vshControl *ctl, virStoragePoolPtr pool, unsigned int flags) { vshStorageVolListPtr list = vshMalloc(ctl, sizeof(*list)); size_t i; char **names = NULL; virStorageVolPtr vol = NULL; bool success = false; size_t deleted = 0; int nvols = 0; int ret = -1; /* try the list with flags support (0.10.2 and later) */ if ((ret = virStoragePoolListAllVolumes(pool, &list->vols, flags)) >= 0) { list->nvols = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; /* there was an error during the call */ vshError(ctl, "%s", _("Failed to list volumes")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); /* Determine the number of volumes in the pool */ if ((nvols = virStoragePoolNumOfVolumes(pool)) < 0) { vshError(ctl, "%s", _("Failed to list storage volumes")); goto cleanup; } if (nvols == 0) { success = true; return list; } /* Retrieve the list of volume names in the pool */ names = vshCalloc(ctl, nvols, sizeof(*names)); if ((nvols = virStoragePoolListVolumes(pool, names, nvols)) < 0) { vshError(ctl, "%s", _("Failed to list storage volumes")); goto cleanup; } list->vols = vshMalloc(ctl, sizeof(virStorageVolPtr) * (nvols)); list->nvols = 0; /* get the vols */ for (i = 0; i < nvols; i++) { if (!(vol = virStorageVolLookupByName(pool, names[i]))) continue; list->vols[list->nvols++] = vol; } /* truncate the list for not found vols */ deleted = nvols - list->nvols; finished: /* sort the list */ if (list->vols && list->nvols) qsort(list->vols, list->nvols, sizeof(*list->vols), vshStorageVolSorter); if (deleted) VIR_SHRINK_N(list->vols, list->nvols, deleted); success = true; cleanup: if (nvols > 0) for (i = 0; i < nvols; i++) VIR_FREE(names[i]); VIR_FREE(names); if (!success) { vshStorageVolListFree(list); list = NULL; } return list; }