From: Alexander Burluka <aburluka@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list