From: Alexander Burluka <aburluka(a)parallels.com>
Add code, which can fill virDomainDef structure
by parallels sdk handle. prlsdkCreateDomainObj function
is an analogue of parallelsLoadDomain from parallels_driver.c.
Also use this new code in parallelsDomainGetXMLDesc to check
it and remove build error about unused function.
Signed-off-by: Dmitry Guryanov <dguryanov(a)parallels.com>
---
src/parallels/parallels_driver.c | 5 +-
src/parallels/parallels_sdk.c | 779 ++++++++++++++++++++++++++++++++++++++-
src/parallels/parallels_sdk.h | 2 +
src/parallels/parallels_utils.h | 1 +
4 files changed, 781 insertions(+), 6 deletions(-)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index fac1f8e..ac192a0 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -1284,16 +1284,13 @@ parallelsDomainGetState(virDomainPtr domain,
static char *
parallelsDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
{
- parallelsConnPtr privconn = domain->conn->privateData;
virDomainDefPtr def;
virDomainObjPtr privdom;
char *ret = NULL;
/* Flags checked by virDomainDefFormat */
- parallelsDriverLock(privconn);
- privdom = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
- parallelsDriverUnlock(privconn);
+ privdom = prlsdkDomainObjLookupByUUID(domain->conn, domain->uuid);
if (privdom == NULL) {
parallelsDomNotFoundError(domain);
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index 111c52a..ba9d226 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -25,12 +25,17 @@
#include "virerror.h"
#include "viralloc.h"
#include "datatypes.h"
+#include "virstring.h"
+#include "nodeinfo.h"
+#include "virlog.h"
#include "parallels_sdk.h"
#define VIR_FROM_THIS VIR_FROM_PARALLELS
#define JOB_INFINIT_WAIT_TIMEOUT UINT_MAX
+VIR_LOG_INIT("parallels.sdk");
+
PRL_UINT32 defaultJobTimeout = JOB_INFINIT_WAIT_TIMEOUT;
/*
@@ -475,8 +480,8 @@ prlsdkListAllDomains(virConnectPtr conn,
return j;
error:
- for (j = i - 1; j <= 0; j--)
- virDomainFree(domPtrArray[j]);
+ for (i = j - 1; i <= 0; i--)
+ virDomainFree(domPtrArray[i]);
VIR_FREE(domPtrArray);
PrlHandle_Free(result);
PrlHandle_Free(job);
@@ -565,3 +570,773 @@ prlsdkDomainLookupByName(virConnectPtr conn, const char *name)
PrlHandle_Free(sdkdom);
return dom;
}
+
+static void
+prlsdkDomObjFreePrivate(void *p)
+{
+ parallelsDomObjPtr pdom = p;
+
+ if (!pdom)
+ return;
+
+ PrlHandle_Free(pdom->sdkdom);
+ virBitmapFree(pdom->cpumask);
+ VIR_FREE(pdom->uuid);
+ VIR_FREE(pdom->home);
+ VIR_FREE(p);
+};
+
+
+static int
+prlsdkAddDomainVideoInfo(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ virDomainVideoDefPtr video = NULL;
+ virDomainVideoAccelDefPtr accel = NULL;
+ PRL_RESULT ret;
+ PRL_UINT32 videoRam;
+
+ /* video info */
+ ret = PrlVmCfg_GetVideoRamSize(sdkdom, &videoRam);
+ prlsdkCheckRetGoto(ret, error);
+
+ if (VIR_ALLOC(video) < 0)
+ goto error;
+
+ if (VIR_ALLOC(accel) < 0)
+ goto error;
+
+ if (VIR_APPEND_ELEMENT_COPY(def->videos, def->nvideos, video) < 0)
+ goto error;
+
+ video->type = VIR_DOMAIN_VIDEO_TYPE_VGA;
+ video->vram = videoRam << 10; /* from mbibytes to kbibytes */
+ video->heads = 1;
+ video->accel = accel;
+
+ return 0;
+
+ error:
+ VIR_FREE(accel);
+ virDomainVideoDefFree(video);
+ return -1;
+}
+
+static int
+prlsdkGetHddInfo(PRL_HANDLE hdd,
+ virDomainDiskDefPtr disk)
+{
+ char *buf = NULL;
+ PRL_UINT32 buflen = 0;
+ PRL_RESULT pret;
+ PRL_UINT32 emulatedType;
+ PRL_UINT32 ifType;
+ PRL_UINT32 pos;
+ PRL_UINT32 hddIndex;
+ int ret = -1;
+
+ pret = PrlVmDev_GetEmulatedType(hdd, &emulatedType);
+ prlsdkCheckRetGoto(pret, cleanup);
+ if (emulatedType == PDT_USE_IMAGE_FILE) {
+ virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
+ virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_PLOOP);
+ } else {
+ virDomainDiskSetType(disk, VIR_STORAGE_TYPE_BLOCK);
+ }
+
+ pret = PrlVmDev_GetFriendlyName(hdd, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (VIR_ALLOC_N(buf, buflen) < 0)
+ goto cleanup;
+
+ pret = PrlVmDev_GetFriendlyName(hdd, buf, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (virDomainDiskSetSource(disk, buf) < 0)
+ goto cleanup;
+
+ pret = PrlVmDev_GetIfaceType(hdd, &ifType);
+ prlsdkCheckRetGoto(pret, cleanup);
+ switch (ifType) {
+ case PMS_IDE_DEVICE:
+ disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
+ break;
+ case PMS_SCSI_DEVICE:
+ disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
+ break;
+ case PMS_SATA_DEVICE:
+ disk->bus = VIR_DOMAIN_DISK_BUS_SATA;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown disk bus: %X"), ifType);
+ goto cleanup;
+ break;
+ }
+
+ pret = PrlVmDev_GetStackIndex(hdd, &pos);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
+ disk->info.addr.drive.target = pos;
+
+ pret = PrlVmDev_GetIndex(hdd, &hddIndex);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (!(disk->dst = virIndexToDiskName(hddIndex, "sd")))
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(buf);
+ return ret;
+}
+
+static int
+prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ PRL_RESULT pret;
+ PRL_UINT32 hddCount;
+ PRL_UINT32 i;
+ PRL_HANDLE hdd = PRL_INVALID_HANDLE;
+ virDomainDiskDefPtr disk = NULL;
+
+ pret = PrlVmCfg_GetHardDisksCount(sdkdom, &hddCount);
+ prlsdkCheckRetGoto(pret, error);
+
+ for (i = 0; i < hddCount; ++i) {
+ pret = PrlVmCfg_GetHardDisk(sdkdom, i, &hdd);
+ prlsdkCheckRetGoto(pret, error);
+
+ if (IS_CT(def)) {
+ /* TODO: convert info about disks in container
+ * to virDomainFSDef structs */
+ VIR_WARN("Skipping disk information for container");
+
+ PrlHandle_Free(hdd);
+ hdd = PRL_INVALID_HANDLE;
+ } else {
+ if (!(disk = virDomainDiskDefNew()))
+ goto error;
+
+ if (prlsdkGetHddInfo(hdd, disk) < 0)
+ goto error;
+
+ PrlHandle_Free(hdd);
+ hdd = PRL_INVALID_HANDLE;
+
+ if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
+ goto error;
+ }
+ }
+
+ return 0;
+
+ error:
+ PrlHandle_Free(hdd);
+ virDomainDiskDefFree(disk);
+ return -1;
+}
+
+static int
+prlsdkGetNetInfo(PRL_HANDLE netAdapter, virDomainNetDefPtr net, bool isCt)
+{
+ char macstr[VIR_MAC_STRING_BUFLEN];
+ PRL_UINT32 buflen;
+ PRL_UINT32 netAdapterIndex;
+ PRL_UINT32 emulatedType;
+ PRL_RESULT pret;
+ PRL_BOOL isConnected;
+ int ret = -1;
+
+ net->type = VIR_DOMAIN_NET_TYPE_NETWORK;
+
+
+ /* use device name, shown by prlctl as target device
+ * for identifying network adapter in virDomainDefineXML */
+ pret = PrlVmDev_GetIndex(netAdapter, &netAdapterIndex);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ pret = PrlVmDevNet_GetHostInterfaceName(netAdapter, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (VIR_ALLOC_N(net->ifname, buflen) < 0)
+ goto cleanup;
+
+ pret = PrlVmDevNet_GetHostInterfaceName(netAdapter, net->ifname, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (isCt && netAdapterIndex == (PRL_UINT32) -1) {
+ /* venet devices don't have mac address and
+ * always up */
+ net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP;
+ if (VIR_STRDUP(net->data.network.name,
+ PARALLELS_ROUTED_NETWORK_NAME) < 0)
+ goto cleanup;
+ return 0;
+ }
+
+ buflen = ARRAY_CARDINALITY(macstr);
+ if (VIR_ALLOC_N(macstr, buflen))
+ goto cleanup;
+ pret = PrlVmDevNet_GetMacAddressCanonical(netAdapter, macstr, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (virMacAddrParse(macstr, &net->mac) < 0)
+ goto cleanup;
+
+ pret = PrlVmDev_GetEmulatedType(netAdapter, &emulatedType);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (emulatedType == PNA_ROUTED) {
+ if (VIR_STRDUP(net->data.network.name,
+ PARALLELS_ROUTED_NETWORK_NAME) < 0)
+ goto cleanup;
+ } else {
+ pret = PrlVmDevNet_GetVirtualNetworkId(netAdapter, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (VIR_ALLOC_N(net->data.network.name, buflen) < 0)
+ goto cleanup;
+
+ pret = PrlVmDevNet_GetVirtualNetworkId(netAdapter,
+ net->data.network.name,
+ &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+ }
+
+ pret = PrlVmDev_IsConnected(netAdapter, &isConnected);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (isConnected)
+ net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP;
+ else
+ net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN;
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+static int
+prlsdkAddDomainNetInfo(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ virDomainNetDefPtr net = NULL;
+ PRL_RESULT ret;
+ PRL_HANDLE netAdapter;
+ PRL_UINT32 netAdaptersCount;
+ PRL_UINT32 i;
+
+ ret = PrlVmCfg_GetNetAdaptersCount(sdkdom, &netAdaptersCount);
+ prlsdkCheckRetGoto(ret, error);
+ for (i = 0; i < netAdaptersCount; ++i) {
+ ret = PrlVmCfg_GetNetAdapter(sdkdom, i, &netAdapter);
+ prlsdkCheckRetGoto(ret, error);
+
+ if (VIR_ALLOC(net) < 0)
+ goto error;
+
+ if (prlsdkGetNetInfo(netAdapter, net, IS_CT(def)) < 0)
+ goto error;
+
+ PrlHandle_Free(netAdapter);
+ netAdapter = PRL_INVALID_HANDLE;
+
+ if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0)
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ PrlHandle_Free(netAdapter);
+ virDomainNetDefFree(net);
+ return -1;
+}
+
+static int
+prlsdkGetSerialInfo(PRL_HANDLE serialPort, virDomainChrDefPtr chr)
+{
+ PRL_RESULT pret;
+ PRL_UINT32 serialPortIndex;
+ PRL_UINT32 emulatedType;
+ char *friendlyName = NULL;
+ PRL_UINT32 buflen;
+
+ chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+ chr->targetTypeAttr = false;
+ pret = PrlVmDev_GetIndex(serialPort, &serialPortIndex);
+ prlsdkCheckRetGoto(pret, error);
+ chr->target.port = serialPortIndex;
+
+ pret = PrlVmDev_GetEmulatedType(serialPort, &emulatedType);
+ prlsdkCheckRetGoto(pret, error);
+
+ pret = PrlVmDev_GetFriendlyName(serialPort, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, error);
+
+ if (VIR_ALLOC_N(friendlyName, buflen) < 0)
+ goto error;
+
+ pret = PrlVmDev_GetFriendlyName(serialPort, friendlyName, &buflen);
+ prlsdkCheckRetGoto(pret, error);
+
+ switch (emulatedType) {
+ case PDT_USE_OUTPUT_FILE:
+ chr->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
+ chr->source.data.file.path = friendlyName;
+ break;
+ case PDT_USE_SERIAL_PORT_SOCKET_MODE:
+ chr->source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+ chr->source.data.nix.path = friendlyName;
+ break;
+ case PDT_USE_REAL_DEVICE:
+ chr->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
+ chr->source.data.file.path = friendlyName;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown serial type: %X"), emulatedType);
+ goto error;
+ break;
+ }
+
+ return 0;
+ error:
+ VIR_FREE(friendlyName);
+ return -1;
+}
+
+
+static int
+prlsdkAddSerialInfo(PRL_HANDLE sdkdom,
+ virDomainChrDefPtr **serials,
+ size_t *nserials)
+{
+ PRL_RESULT ret;
+ PRL_HANDLE serialPort;
+ PRL_UINT32 serialPortsCount;
+ PRL_UINT32 i;
+ virDomainChrDefPtr chr = NULL;
+
+ ret = PrlVmCfg_GetSerialPortsCount(sdkdom, &serialPortsCount);
+ prlsdkCheckRetGoto(ret, cleanup);
+ for (i = 0; i < serialPortsCount; ++i) {
+ ret = PrlVmCfg_GetSerialPort(sdkdom, i, &serialPort);
+ prlsdkCheckRetGoto(ret, cleanup);
+
+ if (!(chr = virDomainChrDefNew()))
+ goto cleanup;
+
+ if (prlsdkGetSerialInfo(serialPort, chr))
+ goto cleanup;
+
+ PrlHandle_Free(serialPort);
+ serialPort = PRL_INVALID_HANDLE;
+
+ if (VIR_APPEND_ELEMENT(*serials, *nserials, chr) < 0)
+ goto cleanup;
+ }
+
+ return 0;
+
+ cleanup:
+ PrlHandle_Free(serialPort);
+ virDomainChrDefFree(chr);
+ return -1;
+}
+
+
+static int
+prlsdkAddDomainHardware(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ if (!IS_CT(def))
+ if (prlsdkAddDomainVideoInfo(sdkdom, def) < 0)
+ goto error;
+
+ if (prlsdkAddDomainHardDisksInfo(sdkdom, def) < 0)
+ goto error;
+
+ if (prlsdkAddDomainNetInfo(sdkdom, def) < 0)
+ goto error;
+
+ if (prlsdkAddSerialInfo(sdkdom,
+ &def->serials,
+ &def->nserials) < 0)
+ goto error;
+
+ return 0;
+ error:
+ return -1;
+}
+
+
+static int
+prlsdkAddVNCInfo(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ virDomainGraphicsDefPtr gr = NULL;
+ PRL_VM_REMOTE_DISPLAY_MODE vncMode;
+ PRL_UINT32 port;
+ PRL_UINT32 buflen = 0;
+ PRL_RESULT pret;
+
+ pret = PrlVmCfg_GetVNCMode(sdkdom, &vncMode);
+ prlsdkCheckRetGoto(pret, error);
+
+ if (vncMode == PRD_DISABLED)
+ return 0;
+
+ if (VIR_ALLOC(gr) < 0)
+ goto error;
+
+ pret = PrlVmCfg_GetVNCPort(sdkdom, &port);
+ prlsdkCheckRetGoto(pret, error);
+
+ gr->data.vnc.autoport = (vncMode == PRD_AUTO);
+ gr->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
+ gr->data.vnc.port = port;
+ gr->data.vnc.keymap = NULL;
+ gr->data.vnc.socket = NULL;
+ gr->data.vnc.auth.passwd = NULL;
+ gr->data.vnc.auth.expires = false;
+ gr->data.vnc.auth.connected = 0;
+
+ if (VIR_ALLOC(gr->listens) < 0)
+ goto error;
+
+ gr->nListens = 1;
+
+ pret = PrlVmCfg_GetVNCHostName(sdkdom, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, error);
+
+ if (VIR_ALLOC_N(gr->listens[0].address, buflen) < 0)
+ goto error;
+
+ pret = PrlVmCfg_GetVNCHostName(sdkdom, gr->listens[0].address, &buflen);
+ prlsdkCheckRetGoto(pret, error);
+
+ gr->listens[0].type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
+
+ if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, gr) < 0)
+ goto error;
+
+ return 0;
+
+ error:
+ virDomainGraphicsDefFree(gr);
+ return -1;
+}
+
+static int
+prlsdkConvertDomainState(parallelsConnPtr privconn,
+ PRL_HANDLE sdkdom,
+ PRL_UINT32 envId,
+ virDomainObjPtr dom)
+{
+ VIRTUAL_MACHINE_STATE domainState;
+
+ if (prlsdkGetDomainState(privconn, sdkdom, &domainState) < 0)
+ return -1;
+
+ switch (domainState) {
+ case VMS_STOPPED:
+ case VMS_MOUNTED:
+ virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF,
+ VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+ dom->def->id = -1;
+ break;
+ case VMS_STARTING:
+ case VMS_COMPACTING:
+ case VMS_RESETTING:
+ case VMS_PAUSING:
+ case VMS_RECONNECTING:
+ case VMS_RUNNING:
+ virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
+ VIR_DOMAIN_RUNNING_BOOTED);
+ dom->def->id = envId;
+ break;
+ case VMS_PAUSED:
+ virDomainObjSetState(dom, VIR_DOMAIN_PAUSED,
+ VIR_DOMAIN_PAUSED_USER);
+ dom->def->id = envId;
+ break;
+ case VMS_SUSPENDED:
+ case VMS_DELETING_STATE:
+ case VMS_SUSPENDING_SYNC:
+ virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF,
+ VIR_DOMAIN_SHUTOFF_SAVED);
+ dom->def->id = -1;
+ break;
+ case VMS_STOPPING:
+ virDomainObjSetState(dom, VIR_DOMAIN_SHUTDOWN,
+ VIR_DOMAIN_SHUTDOWN_USER);
+ dom->def->id = envId;
+ break;
+ case VMS_SNAPSHOTING:
+ virDomainObjSetState(dom, VIR_DOMAIN_PAUSED,
+ VIR_DOMAIN_PAUSED_SNAPSHOT);
+ dom->def->id = envId;
+ break;
+ case VMS_MIGRATING:
+ virDomainObjSetState(dom, VIR_DOMAIN_PAUSED,
+ VIR_DOMAIN_PAUSED_MIGRATION);
+ dom->def->id = envId;
+ break;
+ case VMS_SUSPENDING:
+ virDomainObjSetState(dom, VIR_DOMAIN_PAUSED,
+ VIR_DOMAIN_PAUSED_SAVE);
+ dom->def->id = envId;
+ break;
+ case VMS_RESTORING:
+ virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
+ VIR_DOMAIN_RUNNING_RESTORED);
+ dom->def->id = envId;
+ break;
+ case VMS_CONTINUING:
+ virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
+ VIR_DOMAIN_RUNNING_UNPAUSED);
+ dom->def->id = envId;
+ break;
+ case VMS_RESUMING:
+ virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
+ VIR_DOMAIN_RUNNING_RESTORED);
+ dom->def->id = envId;
+ break;
+ case VMS_UNKNOWN:
+ virDomainObjSetState(dom, VIR_DOMAIN_NOSTATE,
+ VIR_DOMAIN_NOSTATE_UNKNOWN);
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown domain state: %X"), domainState);
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+prlsdkConvertCpuMask(PRL_HANDLE sdkdom, parallelsDomObjPtr pdom)
+{
+ char *buf;
+ PRL_UINT32 buflen = 0;
+ int hostcpus;
+ PRL_RESULT pret;
+ int ret = -1;
+
+ pret = PrlVmCfg_GetCpuMask(sdkdom, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (VIR_ALLOC_N(buf, buflen) < 0)
+ goto cleanup;
+
+ pret = PrlVmCfg_GetCpuMask(sdkdom, buf, &buflen);
+
+ if ((hostcpus = nodeGetCPUCount()) < 0)
+ goto cleanup;
+
+ if (strlen(buf) == 0) {
+ if (!(pdom->cpumask = virBitmapNew(hostcpus)))
+ goto cleanup;
+ virBitmapSetAll(pdom->cpumask);
+ } else {
+ if (virBitmapParse(buf, 0, &pdom->cpumask, hostcpus) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(buf);
+ return ret;
+}
+
+static int
+prlsdkConvertDomainType(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ PRL_VM_TYPE domainType;
+ PRL_RESULT pret;
+
+ pret = PrlVmCfg_GetVmType(sdkdom, &domainType);
+ prlsdkCheckRetGoto(pret, error);
+
+ switch (domainType) {
+ case PVT_VM:
+ if (VIR_STRDUP(def->os.type, "hvm") < 0)
+ return -1;
+ break;
+ case PVT_CT:
+ if (VIR_STRDUP(def->os.type, "exe") < 0)
+ return -1;
+ if (VIR_STRDUP(def->os.init, "/sbin/init") < 0)
+ return -1;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown domain type: %X"), domainType);
+ return -1;
+ }
+
+ return 0;
+
+ error:
+ return -1;
+}
+
+static int
+prlsdkConvertCpuMode(PRL_HANDLE sdkdom, virDomainDefPtr def)
+{
+ PRL_RESULT pret;
+ PRL_CPU_MODE cpuMode;
+
+ pret = PrlVmCfg_GetCpuMode(sdkdom, &cpuMode);
+ prlsdkCheckRetGoto(pret, error);
+
+ switch (cpuMode) {
+ case PCM_CPU_MODE_32:
+ def->os.arch = VIR_ARCH_I686;
+ break;
+ case VIR_ARCH_X86_64:
+ def->os.arch = VIR_ARCH_X86_64;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown CPU mode: %X"), cpuMode);
+ return -1;
+ }
+
+ return 0;
+ error:
+ return -1;
+}
+
+static virDomainObjPtr
+prlsdkCreateDomainObj(parallelsConnPtr privconn, PRL_HANDLE sdkdom)
+{
+ virDomainObjPtr dom = NULL;
+ virDomainDefPtr def = NULL;
+ parallelsDomObjPtr pdom = NULL;
+
+ PRL_UINT32 buflen = 0;
+ PRL_RESULT pret;
+ PRL_UINT32 cpuCount;
+ PRL_UINT32 ram;
+ PRL_UINT32 envId;
+ PRL_VM_AUTOSTART_OPTION autostart;
+
+ virCheckNonNullArgGoto(privconn, cleanup);
+ virCheckNonNullArgGoto(sdkdom, cleanup);
+
+ if (VIR_ALLOC(def) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC(pdom) < 0)
+ goto cleanup;
+
+ def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
+ def->id = -1;
+
+ /* we will remove this field in the near future, so let's set it
+ * to NULL temporarily */
+ pdom->uuid = NULL;
+
+ if (prlsdkGetDomainIds(sdkdom, &def->name, def->uuid) < 0)
+ goto cleanup;
+
+ /* get number of CPUs */
+ pret = PrlVmCfg_GetCpuCount(sdkdom, &cpuCount);
+ prlsdkCheckRetGoto(pret, cleanup);
+ def->vcpus = cpuCount;
+ def->maxvcpus = cpuCount;
+
+ /* get RAM parameters */
+ pret = PrlVmCfg_GetRamSize(sdkdom, &ram);
+ prlsdkCheckRetGoto(pret, cleanup);
+ def->mem.max_balloon = ram << 10; /* RAM size obtained in Mbytes,
+ convert to Kbytes */
+ def->mem.cur_balloon = def->mem.max_balloon;
+
+ if (prlsdkConvertCpuMask(sdkdom, pdom) < 0)
+ goto cleanup;
+
+ if (prlsdkConvertCpuMode(sdkdom, def) < 0)
+ goto cleanup;
+
+ if (prlsdkConvertDomainType(sdkdom, def) < 0)
+ goto cleanup;
+
+ if (prlsdkAddDomainHardware(sdkdom, def) < 0)
+ goto cleanup;
+
+ if (prlsdkAddVNCInfo(sdkdom, def) < 0)
+ goto cleanup;
+
+ pret = PrlVmCfg_GetEnvId(sdkdom, &envId);
+ prlsdkCheckRetGoto(pret, cleanup);
+ pdom->id = envId;
+
+ buflen = 0;
+ pret = PrlVmCfg_GetHomePath(sdkdom, NULL, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (VIR_ALLOC_N(pdom->home, buflen) < 0)
+ goto cleanup;
+
+ pret = PrlVmCfg_GetHomePath(sdkdom, pdom->home, &buflen);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ if (!(dom = virDomainObjNew(privconn->xmlopt)))
+ goto cleanup;
+
+ dom->def = def;
+ dom->privateData = pdom;
+ dom->privateDataFreeFunc = prlsdkDomObjFreePrivate;
+ dom->persistent = 1;
+
+ if (prlsdkConvertDomainState(privconn, sdkdom, envId, dom) < 0)
+ goto cleanup;
+
+ pret = PrlVmCfg_GetAutoStart(sdkdom, &autostart);
+ prlsdkCheckRetGoto(pret, cleanup);
+
+ switch (autostart) {
+ case PAO_VM_START_ON_LOAD:
+ dom->autostart = 1;
+ break;
+ case PAO_VM_START_MANUAL:
+ dom->autostart = 0;
+ break;
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown autostart mode: %X"), autostart);
+ goto cleanup;
+ }
+
+ pret = PrlHandle_AddRef(sdkdom);
+ prlsdkCheckRetGoto(pret, cleanup);
+ pdom->sdkdom = sdkdom;
+ /* dom is locked here */
+
+ return dom;
+ cleanup:
+ virDomainDefFree(def);
+ prlsdkDomObjFreePrivate(pdom);
+ return NULL;
+}
+
+virDomainObjPtr
+prlsdkDomainObjLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
+{
+ PRL_HANDLE sdkdom;
+ virDomainObjPtr dom = NULL;
+
+ sdkdom = prlsdkSdkDomainLookupByUUID(conn, uuid);
+ if (sdkdom == PRL_INVALID_HANDLE)
+ return NULL;
+
+ dom = prlsdkCreateDomainObj(conn->privateData, sdkdom);
+ PrlHandle_Free(sdkdom);
+
+ return dom;
+}
diff --git a/src/parallels/parallels_sdk.h b/src/parallels/parallels_sdk.h
index 16df5f2..30c6c21 100644
--- a/src/parallels/parallels_sdk.h
+++ b/src/parallels/parallels_sdk.h
@@ -35,3 +35,5 @@ virDomainPtr
prlsdkDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
virDomainPtr
prlsdkDomainLookupByName(virConnectPtr conn, const char *name);
+virDomainObjPtr
+prlsdkDomainObjLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
diff --git a/src/parallels/parallels_utils.h b/src/parallels/parallels_utils.h
index 269020a..95206d6 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -61,6 +61,7 @@ struct parallelsDomObj {
char *uuid;
char *home;
virBitmapPtr cpumask;
+ PRL_HANDLE sdkdom;
};
typedef struct parallelsDomObj *parallelsDomObjPtr;
--
1.9.3