Implement creation of new disks - if a new disk found in configuration, find a volume by disk path and actually create a disk image by issuing prlctl command. If it's successfully finished - remove the file with volume definition. Signed-off-by: Dmitry Guryanov <dguryanov@xxxxxxxxxxxxx> --- src/parallels/parallels_driver.c | 107 +++++++++++++++++++++++++++++++++---- 1 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index e2ffb48..45c2c92 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1496,18 +1496,88 @@ parallelsApplyVideoParams(parallelsDomObjPtr pdom, return 0; } -static int -parallelsApplyDisksParams(parallelsDomObjPtr pdom, - virDomainDiskDefPtr *olddisks, int nold, - virDomainDiskDefPtr *newdisks, int nnew) +static int parallelsAddHddByVolume(parallelsDomObjPtr pdom, + virDomainDiskDefPtr disk, + virStoragePoolObjPtr pool, + virStorageVolDefPtr voldef) { - /* TODO: allow creating and removing disks */ - if (nold != nnew) { - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", - _("Adding and removing disks is not supported")); + int ret = -1; + virCommandPtr cmd = virCommandNewArgList(PRLCTL, "set", pdom->uuid, + "--device-add", "hdd", NULL); + virCommandAddArgFormat(cmd, "--size=%lluM", voldef->capacity >> 20); + + const char *strbus; + + if (!(strbus = parallelsGetDiskBusName(disk->bus))) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("Invalid disk bus: %d"), disk->bus); + goto cleanup; + } + + virCommandAddArgFormat(cmd, "--iface=%s", strbus); + + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + virCommandAddArgFormat(cmd, "--position=%d", + disk->info.addr.drive.target); + + if (virCommandRun(cmd, NULL)) + goto cleanup; + + if (parallelsStorageVolumeDefRemove(pool, voldef)) + goto cleanup; + + ret = 0; +cleanup: + virCommandFree(cmd); + return ret; +} + +static int parallelsAddHdd(virConnectPtr conn, + parallelsDomObjPtr pdom, + virDomainDiskDefPtr disk) +{ + parallelsConnPtr privconn = conn->privateData; + virStorageVolDefPtr voldef = NULL; + virStoragePoolObjPtr pool = NULL; + virStorageVolPtr vol = NULL; + int ret = -1; + + if (!(vol = parallelsStorageVolumeLookupByPathLocked(conn, disk->src))) { + virReportError(VIR_ERR_INVALID_ARG, + _("Can't find volume with path '%s'"), disk->src); return -1; } + pool = virStoragePoolObjFindByName(&privconn->pools, vol->pool); + if (!pool) { + virReportError(VIR_ERR_INVALID_ARG, + _("Can't find storage pool with name '%s'"), + vol->pool); + goto cleanup; + } + + voldef = virStorageVolDefFindByPath(pool, disk->src); + if (!voldef) { + virReportError(VIR_ERR_INVALID_ARG, + _("Can't find storage volume definition for path '%s'"), + disk->src); + goto cleanup; + } + + ret = parallelsAddHddByVolume(pdom, disk, pool, voldef); + +cleanup: + if (pool) + virStoragePoolObjUnlock(pool); + virObjectUnref(vol); + return ret; +} + +static int +parallelsApplyDisksParams(virConnectPtr conn, parallelsDomObjPtr pdom, + virDomainDiskDefPtr *olddisks, int nold, + virDomainDiskDefPtr *newdisks, int nnew) +{ for (int i = 0; i < nold; i++) { virDomainDiskDefPtr newdisk = NULL; virDomainDiskDefPtr olddisk = olddisks[i]; @@ -1541,7 +1611,7 @@ parallelsApplyDisksParams(parallelsDomObjPtr pdom, if (!(strbus = parallelsGetDiskBusName(newdisk->bus))) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, - _("Unsupported disk bus: %d", newdisk->bus)); + _("Unsupported disk bus: %d"), newdisk->bus); return -1; } @@ -1554,11 +1624,24 @@ parallelsApplyDisksParams(parallelsDomObjPtr pdom, } } + for (int i = 0; i < nnew; i++) { + virDomainDiskDefPtr newdisk = newdisks[i]; + bool found = false; + for (int j = 0; j < nold; j++) + if (STREQ_NULLABLE(olddisks[j]->dst, newdisk->dst)) + found = true; + if (found) + continue; + + if (parallelsAddHdd(conn, pdom, newdisk)) + return -1; + } + return 0; } static int -parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new) +parallelsApplyChanges(virConnectPtr conn, virDomainObjPtr dom, virDomainDefPtr new) { char buf[32]; @@ -1791,7 +1874,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new) if (parallelsApplyVideoParams(pdom, old->videos, old->nvideos, new->videos, new->nvideos) < 0) return -1; - if (parallelsApplyDisksParams(pdom, old->disks, old->ndisks, + if (parallelsApplyDisksParams(conn, pdom, old->disks, old->ndisks, new->disks, new->ndisks) < 0) return -1; @@ -1925,7 +2008,7 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml) if (dupVM == 1) { olddom = virDomainFindByUUID(&privconn->domains, def->uuid); - if (parallelsApplyChanges(olddom, def) < 0) { + if (parallelsApplyChanges(conn, olddom, def) < 0) { virDomainObjUnlock(olddom); goto cleanup; } -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list