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(a)parallels.com>
---
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