On Tue, Dec 04, 2012 at 05:43:11PM +0400, Dmitry Guryanov wrote: > 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 967f545..fe034f6 100644 > --- a/src/parallels/parallels_driver.c > +++ b/src/parallels/parallels_driver.c > @@ -1499,18 +1499,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; again need to be moved to block start > + 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++) { more here > virDomainDiskDefPtr newdisk = NULL; > virDomainDiskDefPtr olddisk = olddisks[i]; > @@ -1544,7 +1614,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); interesting bug, I'm surprized this wasn't caught at compile time > return -1; > } > > @@ -1557,11 +1627,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++) same for variable declarations > + 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]; > > @@ -1794,7 +1877,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; > > @@ -1928,7 +2011,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; > } squashing the following in: diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index 60bf8b5..118dc13 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1505,12 +1505,12 @@ static int parallelsAddHddByVolume(parallelsDomObjPtr pdom, virStorageVolDefPtr voldef) { int ret = -1; + const char *strbus; + 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); @@ -1597,10 +1597,12 @@ parallelsApplyDisksParams(virConnectPtr conn, parallelsDomObjPtr pdom, virDomainDiskDefPtr *olddisks, int nold, virDomainDiskDefPtr *newdisks, int nnew) { - for (int i = 0; i < nold; i++) { + int i, j; + + for (i = 0; i < nold; i++) { virDomainDiskDefPtr newdisk = NULL; virDomainDiskDefPtr olddisk = olddisks[i]; - for (int j = 0; j < nnew; j++) { + for (j = 0; j < nnew; j++) { if (STREQ_NULLABLE(newdisks[j]->dst, olddisk->dst)) { newdisk = newdisks[j]; break; @@ -1647,10 +1649,10 @@ parallelsApplyDisksParams(virConnectPtr conn, parallelsDomObjPtr pdom, } } - for (int i = 0; i < nnew; i++) { + for (i = 0; i < nnew; i++) { virDomainDiskDefPtr newdisk = newdisks[i]; bool found = false; - for (int j = 0; j < nold; j++) + for (j = 0; j < nold; j++) if (STREQ_NULLABLE(olddisks[j]->dst, newdisk->dst)) found = true; if (found) Daniel -- Daniel Veillard | Open Source and Standards, Red Hat veillard@xxxxxxxxxx | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list