---
src/vbox/vbox_common.c | 1169 +++++++++++
src/vbox/vbox_common.h | 90 +
src/vbox/vbox_tmpl.c | 4535 ++++++++++++++++++++---------------------
src/vbox/vbox_uniformed_api.h | 128 ++
4 files changed, 3557 insertions(+), 2365 deletions(-)
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index efcda7a..f4e992d 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -81,6 +81,14 @@ VIR_LOG_INIT("vbox.vbox_common");
} \
} while (0)
+#define VBOX_MEDIUM_RELEASE(arg) \
+ do { \
+ if (arg) { \
+ gVBoxAPI.UIMedium.Release(arg); \
+ (arg) = NULL; \
+ } \
+ } while (0)
+
#define VBOX_OBJECT_CHECK(conn, type, value) \
vboxGlobalData *data = conn->privateData;\
type ret = value;\
@@ -152,6 +160,123 @@ static int openSessionForMachine(vboxGlobalData *data, const
unsigned char *dom_
return 0;
}
+/**
+ * function to get the values for max port per
+ * instance and max slots per port for the devices
+ *
+ * @returns true on Success, false on failure.
+ * @param vbox Input IVirtualBox pointer
+ * @param maxPortPerInst Output array of max port per instance
+ * @param maxSlotPerPort Output array of max slot per port
+ *
+ */
+
+static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox,
+ PRUint32 *maxPortPerInst,
+ PRUint32 *maxSlotPerPort)
+{
+ ISystemProperties *sysProps = NULL;
+
+ if (!vbox)
+ return false;
+
+ gVBoxAPI.UIVirtualBox.GetSystemProperties(vbox, &sysProps);
+
+ if (!sysProps)
+ return false;
+
+ gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps,
+ StorageBus_IDE,
+
&maxPortPerInst[StorageBus_IDE]);
+ gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps,
+ StorageBus_SATA,
+
&maxPortPerInst[StorageBus_SATA]);
+ gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps,
+ StorageBus_SCSI,
+
&maxPortPerInst[StorageBus_SCSI]);
+ gVBoxAPI.UISystemProperties.GetMaxPortCountForStorageBus(sysProps,
+ StorageBus_Floppy,
+
&maxPortPerInst[StorageBus_Floppy]);
+
+ gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps,
+ StorageBus_IDE,
+
&maxSlotPerPort[StorageBus_IDE]);
+ gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps,
+ StorageBus_SATA,
+
&maxSlotPerPort[StorageBus_SATA]);
+ gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps,
+ StorageBus_SCSI,
+
&maxSlotPerPort[StorageBus_SCSI]);
+ gVBoxAPI.UISystemProperties.GetMaxDevicesPerPortForStorageBus(sysProps,
+ StorageBus_Floppy,
+
&maxSlotPerPort[StorageBus_Floppy]);
+
+ VBOX_RELEASE(sysProps);
+
+ return true;
+}
+
+/**
+ * function to get the StorageBus, Port number
+ * and Device number for the given devicename
+ * e.g: hda has StorageBus = IDE, port = 0,
+ * device = 0
+ *
+ * @returns true on Success, false on failure.
+ * @param deviceName Input device name
+ * @param aMaxPortPerInst Input array of max port per device instance
+ * @param aMaxSlotPerPort Input array of max slot per device port
+ * @param storageBus Input storage bus type
+ * @param deviceInst Output device instance number
+ * @param devicePort Output port number
+ * @param deviceSlot Output slot number
+ *
+ */
+static bool vboxGetDeviceDetails(const char *deviceName,
+ PRUint32 *aMaxPortPerInst,
+ PRUint32 *aMaxSlotPerPort,
+ PRUint32 storageBus,
+ PRInt32 *deviceInst,
+ PRInt32 *devicePort,
+ PRInt32 *deviceSlot) {
+ int total = 0;
+ PRUint32 maxPortPerInst = 0;
+ PRUint32 maxSlotPerPort = 0;
+
+ if (!deviceName ||
+ !deviceInst ||
+ !devicePort ||
+ !deviceSlot ||
+ !aMaxPortPerInst ||
+ !aMaxSlotPerPort)
+ return false;
+
+ if ((storageBus < StorageBus_IDE) ||
+ (storageBus > StorageBus_Floppy))
+ return false;
+
+ total = virDiskNameToIndex(deviceName);
+
+ maxPortPerInst = aMaxPortPerInst[storageBus];
+ maxSlotPerPort = aMaxSlotPerPort[storageBus];
+
+ if (!maxPortPerInst ||
+ !maxSlotPerPort ||
+ (total < 0))
+ return false;
+
+ *deviceInst = total / (maxPortPerInst * maxSlotPerPort);
+ *devicePort = (total % (maxPortPerInst * maxSlotPerPort)) / maxSlotPerPort;
+ *deviceSlot = (total % (maxPortPerInst * maxSlotPerPort)) % maxSlotPerPort;
+
+ VIR_DEBUG("name=%s, total=%d, storageBus=%u, deviceInst=%d, "
+ "devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u",
+ deviceName, total, storageBus, *deviceInst, *devicePort,
+ *deviceSlot, maxPortPerInst, maxSlotPerPort);
+
+ return true;
+}
+
static virDomainDefParserConfig vboxDomainDefParserConfig = {
.macPrefix = { 0x08, 0x00, 0x27 },
};
@@ -700,6 +825,1050 @@ virDomainPtr vboxDomainLookupByUUID(virConnectPtr conn,
}
static void
+vboxSetBootDeviceOrder(virDomainDefPtr def, vboxGlobalData *data,
+ IMachine *machine)
+{
+ ISystemProperties *systemProperties = NULL;
+ PRUint32 maxBootPosition = 0;
+ size_t i = 0;
+
+ VIR_DEBUG("def->os.type %s", def->os.type);
+ VIR_DEBUG("def->os.arch %s",
virArchToString(def->os.arch));
+ VIR_DEBUG("def->os.machine %s", def->os.machine);
+ VIR_DEBUG("def->os.nBootDevs %zu", def->os.nBootDevs);
+ VIR_DEBUG("def->os.bootDevs[0] %d", def->os.bootDevs[0]);
+ VIR_DEBUG("def->os.bootDevs[1] %d", def->os.bootDevs[1]);
+ VIR_DEBUG("def->os.bootDevs[2] %d", def->os.bootDevs[2]);
+ VIR_DEBUG("def->os.bootDevs[3] %d", def->os.bootDevs[3]);
+ VIR_DEBUG("def->os.init %s", def->os.init);
+ VIR_DEBUG("def->os.kernel %s", def->os.kernel);
+ VIR_DEBUG("def->os.initrd %s", def->os.initrd);
+ VIR_DEBUG("def->os.cmdline %s", def->os.cmdline);
+ VIR_DEBUG("def->os.root %s", def->os.root);
+ VIR_DEBUG("def->os.loader %s", def->os.loader);
+ VIR_DEBUG("def->os.bootloader %s", def->os.bootloader);
+ VIR_DEBUG("def->os.bootloaderArgs %s", def->os.bootloaderArgs);
+
+ gVBoxAPI.UIVirtualBox.GetSystemProperties(data->vboxObj, &systemProperties);
+ if (systemProperties) {
+ gVBoxAPI.UISystemProperties.GetMaxBootPosition(systemProperties,
+ &maxBootPosition);
+ VBOX_RELEASE(systemProperties);
+ }
+
+ /* Clear the defaults first */
+ for (i = 0; i < maxBootPosition; i++) {
+ gVBoxAPI.UIMachine.SetBootOrder(machine, i+1, DeviceType_Null);
+ }
+
+ for (i = 0; (i < def->os.nBootDevs) && (i < maxBootPosition); i++)
{
+ PRUint32 device = DeviceType_Null;
+
+ if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_FLOPPY) {
+ device = DeviceType_Floppy;
+ } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_CDROM) {
+ device = DeviceType_DVD;
+ } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_DISK) {
+ device = DeviceType_HardDisk;
+ } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
+ device = DeviceType_Network;
+ }
+ gVBoxAPI.UIMachine.SetBootOrder(machine, i+1, device);
+ }
+}
+
+static void
+vboxAttachDrivesNew(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ /* AttachDrives for 3.0 and later */
+ size_t i;
+ nsresult rc;
+ PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {};
+ PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {};
+ PRUnichar *storageCtlName = NULL;
+ bool error = false;
+
+ if (gVBoxAPI.vboxAttachDrivesUseOld)
+ VIR_WARN("This function may not work in current vbox version");
+
+ /* get the max port/slots/etc for the given storage bus */
+ error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst,
+ maxSlotPerPort);
+
+ /* add a storage controller for the mediums to be attached */
+ /* this needs to change when multiple controller are supported for
+ * ver > 3.1 */
+ {
+ IStorageController *storageCtl = NULL;
+ PRUnichar *sName = NULL;
+
+ VBOX_UTF8_TO_UTF16("IDE Controller", &sName);
+ gVBoxAPI.UIMachine.AddStorageController(machine,
+ sName,
+ StorageBus_IDE,
+ &storageCtl);
+ VBOX_UTF16_FREE(sName);
+ VBOX_RELEASE(storageCtl);
+
+ VBOX_UTF8_TO_UTF16("SATA Controller", &sName);
+ gVBoxAPI.UIMachine.AddStorageController(machine,
+ sName,
+ StorageBus_SATA,
+ &storageCtl);
+ VBOX_UTF16_FREE(sName);
+ VBOX_RELEASE(storageCtl);
+
+ VBOX_UTF8_TO_UTF16("SCSI Controller", &sName);
+ gVBoxAPI.UIMachine.AddStorageController(machine,
+ sName,
+ StorageBus_SCSI,
+ &storageCtl);
+ VBOX_UTF16_FREE(sName);
+ VBOX_RELEASE(storageCtl);
+
+ VBOX_UTF8_TO_UTF16("Floppy Controller", &sName);
+ gVBoxAPI.UIMachine.AddStorageController(machine,
+ sName,
+ StorageBus_Floppy,
+ &storageCtl);
+ VBOX_UTF16_FREE(sName);
+ VBOX_RELEASE(storageCtl);
+ }
+
+ for (i = 0; i < def->ndisks && !error; i++) {
+ const char *src = virDomainDiskGetSource(def->disks[i]);
+ int type = virDomainDiskGetType(def->disks[i]);
+ int format = virDomainDiskGetFormat(def->disks[i]);
+
+ VIR_DEBUG("disk(%zu) type: %d", i, type);
+ VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]->device);
+ VIR_DEBUG("disk(%zu) bus: %d", i, def->disks[i]->bus);
+ VIR_DEBUG("disk(%zu) src: %s", i, src);
+ VIR_DEBUG("disk(%zu) dst: %s", i, def->disks[i]->dst);
+ VIR_DEBUG("disk(%zu) driverName: %s", i,
+ virDomainDiskGetDriver(def->disks[i]));
+ VIR_DEBUG("disk(%zu) driverType: %s", i,
+ virStorageFileFormatTypeToString(format));
+ VIR_DEBUG("disk(%zu) cachemode: %d", i,
def->disks[i]->cachemode);
+ VIR_DEBUG("disk(%zu) readonly: %s", i,
(def->disks[i]->src->readonly
+ ? "True" : "False"));
+ VIR_DEBUG("disk(%zu) shared: %s", i,
(def->disks[i]->src->shared
+ ? "True" : "False"));
+
+ if (type == VIR_STORAGE_TYPE_FILE && src) {
+ IMedium *medium = NULL;
+ vboxIIDUnion mediumUUID;
+ PRUnichar *mediumFileUtf16 = NULL;
+ PRUint32 storageBus = StorageBus_Null;
+ PRUint32 deviceType = DeviceType_Null;
+ PRUint32 accessMode = AccessMode_ReadOnly;
+ PRInt32 deviceInst = 0;
+ PRInt32 devicePort = 0;
+ PRInt32 deviceSlot = 0;
+
+ VBOX_IID_INITIALIZE(&mediumUUID);
+ VBOX_UTF8_TO_UTF16(src, &mediumFileUtf16);
+
+ if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+ deviceType = DeviceType_HardDisk;
+ accessMode = AccessMode_ReadWrite;
+ } else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+ deviceType = DeviceType_DVD;
+ accessMode = AccessMode_ReadOnly;
+ } else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+ deviceType = DeviceType_Floppy;
+ accessMode = AccessMode_ReadWrite;
+ } else {
+ VBOX_UTF16_FREE(mediumFileUtf16);
+ continue;
+ }
+
+ gVBoxAPI.UIVirtualBox.FindMedium(data->vboxObj, mediumFileUtf16,
+ deviceType, accessMode, &medium);
+
+ if (!medium) {
+ PRUnichar *mediumEmpty = NULL;
+
+ VBOX_UTF8_TO_UTF16("", &mediumEmpty);
+
+ rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
+ mediumFileUtf16,
+ deviceType, accessMode,
+ &medium);
+ VBOX_UTF16_FREE(mediumEmpty);
+ }
+
+ if (!medium) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to attach the following disk/dvd/floppy
"
+ "to the machine: %s, rc=%08x"),
+ src, (unsigned)rc);
+ VBOX_UTF16_FREE(mediumFileUtf16);
+ continue;
+ }
+
+ rc = gVBoxAPI.UIMedium.GetId(medium, &mediumUUID);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("can't get the uuid of the file to be attached
"
+ "as harddisk/dvd/floppy: %s, rc=%08x"),
+ src, (unsigned)rc);
+ VBOX_MEDIUM_RELEASE(medium);
+ VBOX_UTF16_FREE(mediumFileUtf16);
+ continue;
+ }
+
+ if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+ if (def->disks[i]->src->readonly) {
+ gVBoxAPI.UIMedium.SetType(medium, MediumType_Immutable);
+ VIR_DEBUG("setting harddisk to immutable");
+ } else if (!def->disks[i]->src->readonly) {
+ gVBoxAPI.UIMedium.SetType(medium, MediumType_Normal);
+ VIR_DEBUG("setting harddisk type to normal");
+ }
+ }
+
+ if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_IDE) {
+ VBOX_UTF8_TO_UTF16("IDE Controller", &storageCtlName);
+ storageBus = StorageBus_IDE;
+ } else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_SATA) {
+ VBOX_UTF8_TO_UTF16("SATA Controller", &storageCtlName);
+ storageBus = StorageBus_SATA;
+ } else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ VBOX_UTF8_TO_UTF16("SCSI Controller", &storageCtlName);
+ storageBus = StorageBus_SCSI;
+ } else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_FDC) {
+ VBOX_UTF8_TO_UTF16("Floppy Controller", &storageCtlName);
+ storageBus = StorageBus_Floppy;
+ }
+
+ /* get the device details i.e instance, port and slot */
+ if (!vboxGetDeviceDetails(def->disks[i]->dst,
+ maxPortPerInst,
+ maxSlotPerPort,
+ storageBus,
+ &deviceInst,
+ &devicePort,
+ &deviceSlot)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("can't get the port/slot number of "
+ "harddisk/dvd/floppy to be attached: "
+ "%s, rc=%08x"),
+ src, (unsigned)rc);
+ VBOX_MEDIUM_RELEASE(medium);
+ vboxIIDUnalloc(&mediumUUID);
+ VBOX_UTF16_FREE(mediumFileUtf16);
+ continue;
+ }
+
+ /* attach the harddisk/dvd/Floppy to the storage controller */
+ rc = gVBoxAPI.UIMachine.AttachDevice(machine,
+ storageCtlName,
+ devicePort,
+ deviceSlot,
+ deviceType,
+ medium);
+
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not attach the file as "
+ "harddisk/dvd/floppy: %s, rc=%08x"),
+ src, (unsigned)rc);
+ } else {
+ DEBUGIID("Attached HDD/DVD/Floppy with UUID",
&mediumUUID);
+ }
+
+ VBOX_MEDIUM_RELEASE(medium);
+ vboxIIDUnalloc(&mediumUUID);
+ VBOX_UTF16_FREE(mediumFileUtf16);
+ VBOX_UTF16_FREE(storageCtlName);
+ }
+ }
+}
+
+static void
+vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ /* Here, About the vboxAttachDrives. In fact,there is
+ * three different implementations. We name it as
+ * v1, v2 and v3.
+ *
+ * The first version(v1) is only used in vbox 2.2 and 3.0,
+ * v2 is used by 3.1 and 3.2, and v3 is used for later
+ * vbox versions. In sight of implementation, the v1 is
+ * totally different with v2 and v3. The v2 shares the same
+ * outline with v3, meanwhile the API they used has much
+ * difference.
+ *
+ * It seems we have no thing to do with old versions such as
+ * v1 and v2 when developing new vbox drivers. What's more,
+ * most of the vbox APIs used in v1 and v2 is incompatible with
+ * new vbox versions. It is a burden to put these APIs into
+ * vboxUniformedAPI, I prefer not to do that.
+ *
+ * After balancing the code size and the complied code size,
+ * I put my solution here. The v1 and v2 is a version specified
+ * code, which only be generated for first four version. The v3
+ * will be put in vbox_common.c, it be complied only once, then
+ * be used by all next vbox drivers.
+ *
+ * Check the flag vboxAttachDrivesUseOld can tell you which
+ * implementation to use. When the flag is set, we need use
+ * the old version though gVBoxAPI.vboxAttachDrivesOld. It
+ * will automatically point to v1 or v2 deponds on you version.
+ * If the flag is clear, just call vboxAttachDrivesNew, which
+ * is the v3 implementation.
+ */
+ if (gVBoxAPI.vboxAttachDrivesUseOld)
+ gVBoxAPI.vboxAttachDrivesOld(def, data, machine);
+ else
+ vboxAttachDrivesNew(def, data, machine);
+}
+
+static void
+vboxAttachSound(virDomainDefPtr def, IMachine *machine)
+{
+ nsresult rc;
+ IAudioAdapter *audioAdapter = NULL;
+
+ /* Check if def->nsounds is one as VirtualBox currently supports
+ * only one sound card
+ */
+ if (def->nsounds != 1)
+ return;
+
+ gVBoxAPI.UIMachine.GetAudioAdapter(machine, &audioAdapter);
+ if (!audioAdapter)
+ return;
+
+ rc = gVBoxAPI.UIAudioAdapter.SetEnabled(audioAdapter, 1);
+ if (NS_FAILED(rc))
+ goto cleanup;
+
+ if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_SB16) {
+ gVBoxAPI.UIAudioAdapter.SetAudioController(audioAdapter,
+ AudioControllerType_SB16);
+ } else
+ if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_AC97) {
+ gVBoxAPI.UIAudioAdapter.SetAudioController(audioAdapter,
+ AudioControllerType_AC97);
+ }
+
+ cleanup:
+ VBOX_RELEASE(audioAdapter);
+}
+
+static void
+vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ ISystemProperties *systemProperties = NULL;
+ PRUint32 chipsetType = ChipsetType_Null;
+ PRUint32 networkAdapterCount = 0;
+ size_t i = 0;
+
+ if (gVBoxAPI.chipsetType)
+ gVBoxAPI.UIMachine.GetChipsetType(machine, &chipsetType);
+
+ gVBoxAPI.UIVirtualBox.GetSystemProperties(data->vboxObj, &systemProperties);
+ if (systemProperties) {
+ gVBoxAPI.UISystemProperties.GetMaxNetworkAdapters(systemProperties, chipsetType,
+ &networkAdapterCount);
+ VBOX_RELEASE(systemProperties);
+ }
+
+ VIR_DEBUG("Number of Network Cards to be connected: %zu", def->nnets);
+ VIR_DEBUG("Number of Network Cards available: %d", networkAdapterCount);
+
+ for (i = 0; (i < def->nnets) && (i < networkAdapterCount); i++) {
+ INetworkAdapter *adapter = NULL;
+ PRUint32 adapterType = NetworkAdapterType_Null;
+ char macaddr[VIR_MAC_STRING_BUFLEN] = {0};
+ char macaddrvbox[VIR_MAC_STRING_BUFLEN - 5] = {0};
+ PRUnichar *MACAddress = NULL;
+
+ virMacAddrFormat(&def->nets[i]->mac, macaddr);
+ snprintf(macaddrvbox, VIR_MAC_STRING_BUFLEN - 5,
+ "%02X%02X%02X%02X%02X%02X",
+ def->nets[i]->mac.addr[0],
+ def->nets[i]->mac.addr[1],
+ def->nets[i]->mac.addr[2],
+ def->nets[i]->mac.addr[3],
+ def->nets[i]->mac.addr[4],
+ def->nets[i]->mac.addr[5]);
+ macaddrvbox[VIR_MAC_STRING_BUFLEN - 6] = '\0';
+
+ VIR_DEBUG("NIC(%zu): Type: %d", i, def->nets[i]->type);
+ VIR_DEBUG("NIC(%zu): Model: %s", i, def->nets[i]->model);
+ VIR_DEBUG("NIC(%zu): Mac: %s", i, macaddr);
+ VIR_DEBUG("NIC(%zu): ifname: %s", i, def->nets[i]->ifname);
+ if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ VIR_DEBUG("NIC(%zu): name: %s", i,
def->nets[i]->data.network.name);
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
+ VIR_DEBUG("NIC(%zu): name: %s", i,
def->nets[i]->data.internal.name);
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
+ VIR_DEBUG("NIC(%zu): NAT.", i);
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+ VIR_DEBUG("NIC(%zu): brname: %s", i,
def->nets[i]->data.bridge.brname);
+ VIR_DEBUG("NIC(%zu): script: %s", i, def->nets[i]->script);
+ VIR_DEBUG("NIC(%zu): ipaddr: %s", i,
def->nets[i]->data.bridge.ipaddr);
+ }
+
+ gVBoxAPI.UIMachine.GetNetworkAdapter(machine, i, &adapter);
+ if (!adapter)
+ continue;
+
+ gVBoxAPI.UINetworkAdapter.SetEnabled(adapter, 1);
+
+ if (def->nets[i]->model) {
+ if (STRCASEEQ(def->nets[i]->model, "Am79C970A")) {
+ adapterType = NetworkAdapterType_Am79C970A;
+ } else if (STRCASEEQ(def->nets[i]->model, "Am79C973")) {
+ adapterType = NetworkAdapterType_Am79C973;
+ } else if (STRCASEEQ(def->nets[i]->model, "82540EM")) {
+ adapterType = NetworkAdapterType_I82540EM;
+ } else if (STRCASEEQ(def->nets[i]->model, "82545EM")) {
+ adapterType = NetworkAdapterType_I82545EM;
+ } else if (STRCASEEQ(def->nets[i]->model, "82543GC")) {
+ adapterType = NetworkAdapterType_I82543GC;
+ } else if (gVBoxAPI.APIVersion >= 3000051 &&
+ STRCASEEQ(def->nets[i]->model, "virtio")) {
+ /* Only vbox 3.1 and later support NetworkAdapterType_Virto */
+ adapterType = NetworkAdapterType_Virtio;
+ }
+ } else {
+ adapterType = NetworkAdapterType_Am79C973;
+ }
+
+ gVBoxAPI.UINetworkAdapter.SetAdapterType(adapter, adapterType);
+
+ if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+ PRUnichar *hostInterface = NULL;
+ /* Bridged Network */
+
+ gVBoxAPI.UINetworkAdapter.AttachToBridgedInterface(adapter);
+
+ if (def->nets[i]->data.bridge.brname) {
+ VBOX_UTF8_TO_UTF16(def->nets[i]->data.bridge.brname,
+ &hostInterface);
+ gVBoxAPI.UINetworkAdapter.SetBridgedInterface(adapter, hostInterface);
+ VBOX_UTF16_FREE(hostInterface);
+ }
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
+ PRUnichar *internalNetwork = NULL;
+ /* Internal Network */
+
+ gVBoxAPI.UINetworkAdapter.AttachToInternalNetwork(adapter);
+
+ if (def->nets[i]->data.internal.name) {
+ VBOX_UTF8_TO_UTF16(def->nets[i]->data.internal.name,
+ &internalNetwork);
+ gVBoxAPI.UINetworkAdapter.SetInternalNetwork(adapter, internalNetwork);
+ VBOX_UTF16_FREE(internalNetwork);
+ }
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ PRUnichar *hostInterface = NULL;
+ /* Host Only Networking (currently only vboxnet0 available
+ * on *nix and mac, on windows you can create and configure
+ * as many as you want)
+ */
+ gVBoxAPI.UINetworkAdapter.AttachToHostOnlyInterface(adapter);
+
+ if (def->nets[i]->data.network.name) {
+ VBOX_UTF8_TO_UTF16(def->nets[i]->data.network.name,
+ &hostInterface);
+ gVBoxAPI.UINetworkAdapter.SetHostOnlyInterface(adapter, hostInterface);
+ VBOX_UTF16_FREE(hostInterface);
+ }
+ } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
+ /* NAT */
+ gVBoxAPI.UINetworkAdapter.AttachToNAT(adapter);
+ } else {
+ /* else always default to NAT if we don't understand
+ * what option is been passed to us
+ */
+ gVBoxAPI.UINetworkAdapter.AttachToNAT(adapter);
+ }
+
+ VBOX_UTF8_TO_UTF16(macaddrvbox, &MACAddress);
+ gVBoxAPI.UINetworkAdapter.SetMACAddress(adapter, MACAddress);
+ VBOX_UTF16_FREE(MACAddress);
+ }
+}
+
+static void
+vboxAttachSerial(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ ISystemProperties *systemProperties = NULL;
+ PRUint32 serialPortCount = 0;
+ size_t i = 0;
+
+ gVBoxAPI.UIVirtualBox.GetSystemProperties(data->vboxObj, &systemProperties);
+ if (systemProperties) {
+ gVBoxAPI.UISystemProperties.GetSerialPortCount(systemProperties,
+ &serialPortCount);
+ VBOX_RELEASE(systemProperties);
+ }
+
+ VIR_DEBUG("Number of Serial Ports to be connected: %zu",
def->nserials);
+ VIR_DEBUG("Number of Serial Ports available: %d", serialPortCount);
+
+ for (i = 0; (i < def->nserials) && (i < serialPortCount); i++) {
+ ISerialPort *serialPort = NULL;
+ PRUnichar *pathUtf16 = NULL;
+
+ VIR_DEBUG("SerialPort(%zu): Type: %d", i,
def->serials[i]->source.type);
+ VIR_DEBUG("SerialPort(%zu): target.port: %d", i,
+ def->serials[i]->target.port);
+
+ gVBoxAPI.UIMachine.GetSerialPort(machine, i, &serialPort);
+ if (!serialPort)
+ continue;
+
+ gVBoxAPI.UISerialPort.SetEnabled(serialPort, 1);
+
+ if (def->serials[i]->source.data.file.path) {
+ VBOX_UTF8_TO_UTF16(def->serials[i]->source.data.file.path,
+ &pathUtf16);
+ gVBoxAPI.UISerialPort.SetPath(serialPort, pathUtf16);
+ }
+
+ /* For now hard code the serial ports to COM1 and COM2,
+ * COM1 (Base Addr: 0x3F8 (decimal: 1016), IRQ: 4)
+ * COM2 (Base Addr: 0x2F8 (decimal: 760), IRQ: 3)
+ * TODO: make this more flexible
+ */
+ /* TODO: to improve the libvirt XMl handling so
+ * that def->serials[i]->target.port shows real port
+ * and not always start at 0
+ */
+ if (def->serials[i]->target.port == 0) {
+ gVBoxAPI.UISerialPort.SetIRQ(serialPort, 4);
+ gVBoxAPI.UISerialPort.SetIOBase(serialPort, 1016);
+ VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
+ i, 4, 1016, def->serials[i]->source.data.file.path);
+ } else if (def->serials[i]->target.port == 1) {
+ gVBoxAPI.UISerialPort.SetIRQ(serialPort, 3);
+ gVBoxAPI.UISerialPort.SetIOBase(serialPort, 760);
+ VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
+ i, 3, 760, def->serials[i]->source.data.file.path);
+ }
+
+ if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) {
+ gVBoxAPI.UISerialPort.SetHostMode(serialPort, PortMode_HostDevice);
+ } else if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE) {
+ gVBoxAPI.UISerialPort.SetHostMode(serialPort, PortMode_HostPipe);
+ } else if (gVBoxAPI.APIVersion >= 2002051 &&
+ def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) {
+ /* PortMode RawFile is used for vbox 3.0 or later */
+ gVBoxAPI.UISerialPort.SetHostMode(serialPort, PortMode_RawFile);
+ } else {
+ gVBoxAPI.UISerialPort.SetHostMode(serialPort,
+ PortMode_Disconnected);
+ }
+
+ VBOX_RELEASE(serialPort);
+ VBOX_UTF16_FREE(pathUtf16);
+ }
+}
+
+static void
+vboxAttachParallel(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ ISystemProperties *systemProperties = NULL;
+ PRUint32 parallelPortCount = 0;
+ size_t i = 0;
+
+ gVBoxAPI.UIVirtualBox.GetSystemProperties(data->vboxObj, &systemProperties);
+ if (systemProperties) {
+ gVBoxAPI.UISystemProperties.GetParallelPortCount(systemProperties,
+ ¶llelPortCount);
+ VBOX_RELEASE(systemProperties);
+ }
+
+ VIR_DEBUG("Number of Parallel Ports to be connected: %zu",
def->nparallels);
+ VIR_DEBUG("Number of Parallel Ports available: %d", parallelPortCount);
+ for (i = 0; (i < def->nparallels) && (i < parallelPortCount); i++)
{
+ IParallelPort *parallelPort = NULL;
+ PRUnichar *pathUtf16 = NULL;
+
+ VIR_DEBUG("ParallelPort(%zu): Type: %d", i,
def->parallels[i]->source.type);
+ VIR_DEBUG("ParallelPort(%zu): target.port: %d", i,
+ def->parallels[i]->target.port);
+
+ gVBoxAPI.UIMachine.GetParallelPort(machine, i, ¶llelPort);
+ if (!parallelPort)
+ continue;
+
+ VBOX_UTF8_TO_UTF16(def->parallels[i]->source.data.file.path,
&pathUtf16);
+
+ /* For now hard code the parallel ports to
+ * LPT1 (Base Addr: 0x378 (decimal: 888), IRQ: 7)
+ * LPT2 (Base Addr: 0x278 (decimal: 632), IRQ: 5)
+ * TODO: make this more flexible
+ */
+ if ((def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) ||
+ (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PTY) ||
+ (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) ||
+ (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE)) {
+ gVBoxAPI.UIParallelPort.SetPath(parallelPort, pathUtf16);
+ if (i == 0) {
+ gVBoxAPI.UIParallelPort.SetIRQ(parallelPort, 7);
+ gVBoxAPI.UIParallelPort.SetIOBase(parallelPort, 888);
+ VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path: %s",
+ i, 7, 888, def->parallels[i]->source.data.file.path);
+ } else if (i == 1) {
+ gVBoxAPI.UIParallelPort.SetIRQ(parallelPort, 5);
+ gVBoxAPI.UIParallelPort.SetIOBase(parallelPort, 632);
+ VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path: %s",
+ i, 5, 632, def->parallels[i]->source.data.file.path);
+ }
+ }
+
+ /* like serial port, parallel port can't be enabled unless
+ * correct IRQ and IOBase values are specified.
+ */
+ gVBoxAPI.UIParallelPort.SetEnabled(parallelPort, 1);
+
+ VBOX_RELEASE(parallelPort);
+ VBOX_UTF16_FREE(pathUtf16);
+ }
+}
+
+static void
+vboxAttachVideo(virDomainDefPtr def, IMachine *machine)
+{
+ if ((def->nvideos == 1) &&
+ (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_VBOX)) {
+ gVBoxAPI.UIMachine.SetVRAMSize(machine,
+ VIR_DIV_UP(def->videos[0]->vram, 1024));
+ gVBoxAPI.UIMachine.SetMonitorCount(machine, def->videos[0]->heads);
+ if (def->videos[0]->accel) {
+ gVBoxAPI.UIMachine.SetAccelerate3DEnabled(machine,
+
def->videos[0]->accel->support3d);
+ if (gVBoxAPI.accelerate2DVideo)
+ gVBoxAPI.UIMachine.SetAccelerate2DVideoEnabled(machine,
+
def->videos[0]->accel->support2d);
+ } else {
+ gVBoxAPI.UIMachine.SetAccelerate3DEnabled(machine, 0);
+ if (gVBoxAPI.accelerate2DVideo)
+ gVBoxAPI.UIMachine.SetAccelerate2DVideoEnabled(machine, 0);
+ }
+ }
+}
+
+static void
+vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ int vrdpPresent = 0;
+ int sdlPresent = 0;
+ int guiPresent = 0;
+ char *guiDisplay = NULL;
+ char *sdlDisplay = NULL;
+ size_t i = 0;
+
+ for (i = 0; i < def->ngraphics; i++) {
+ IVRDxServer *VRDxServer = NULL;
+
+ if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) &&
+ (vrdpPresent == 0)) {
+
+ vrdpPresent = 1;
+ gVBoxAPI.UIMachine.GetVRDxServer(machine, &VRDxServer);
+ if (VRDxServer) {
+ const char *listenAddr
+ = virDomainGraphicsListenGetAddress(def->graphics[i], 0);
+
+ gVBoxAPI.UIVRDxServer.SetEnabled(VRDxServer, PR_TRUE);
+ VIR_DEBUG("VRDP Support turned ON.");
+
+ gVBoxAPI.UIVRDxServer.SetPorts(data, VRDxServer, def->graphics[i]);
+
+ if (def->graphics[i]->data.rdp.replaceUser) {
+ gVBoxAPI.UIVRDxServer.SetReuseSingleConnection(VRDxServer,
+ PR_TRUE);
+ VIR_DEBUG("VRDP set to reuse single connection");
+ }
+
+ if (def->graphics[i]->data.rdp.multiUser) {
+ gVBoxAPI.UIVRDxServer.SetAllowMultiConnection(VRDxServer,
+ PR_TRUE);
+ VIR_DEBUG("VRDP set to allow multiple connection");
+ }
+
+ if (listenAddr) {
+ PRUnichar *netAddressUtf16 = NULL;
+
+ VBOX_UTF8_TO_UTF16(listenAddr, &netAddressUtf16);
+ gVBoxAPI.UIVRDxServer.SetNetAddress(data, VRDxServer,
+ netAddressUtf16);
+ VIR_DEBUG("VRDP listen address is set to: %s",
+ listenAddr);
+
+ VBOX_UTF16_FREE(netAddressUtf16);
+ }
+
+ VBOX_RELEASE(VRDxServer);
+ }
+ }
+
+ if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP)
&&
+ (guiPresent == 0)) {
+ guiPresent = 1;
+ if (VIR_STRDUP(guiDisplay, def->graphics[i]->data.desktop.display) <
0) {
+ /* just don't go to cleanup yet as it is ok to have
+ * guiDisplay as NULL and we check it below if it
+ * exist and then only use it there
+ */
+ }
+ }
+
+ if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) &&
+ (sdlPresent == 0)) {
+ sdlPresent = 1;
+ if (VIR_STRDUP(sdlDisplay, def->graphics[i]->data.sdl.display) < 0)
{
+ /* just don't go to cleanup yet as it is ok to have
+ * sdlDisplay as NULL and we check it below if it
+ * exist and then only use it there
+ */
+ }
+ }
+ }
+
+ if ((vrdpPresent == 1) && (guiPresent == 0) && (sdlPresent == 0)) {
+ /* store extradata key that frontend is set to vrdp */
+ PRUnichar *keyTypeUtf16 = NULL;
+ PRUnichar *valueTypeUtf16 = NULL;
+
+ VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
+ VBOX_UTF8_TO_UTF16("vrdp", &valueTypeUtf16);
+
+ gVBoxAPI.UIMachine.SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
+
+ VBOX_UTF16_FREE(keyTypeUtf16);
+ VBOX_UTF16_FREE(valueTypeUtf16);
+
+ } else if ((guiPresent == 0) && (sdlPresent == 1)) {
+ /* store extradata key that frontend is set to sdl */
+ PRUnichar *keyTypeUtf16 = NULL;
+ PRUnichar *valueTypeUtf16 = NULL;
+ PRUnichar *keyDislpayUtf16 = NULL;
+ PRUnichar *valueDisplayUtf16 = NULL;
+
+ VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
+ VBOX_UTF8_TO_UTF16("sdl", &valueTypeUtf16);
+
+ gVBoxAPI.UIMachine.SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
+
+ VBOX_UTF16_FREE(keyTypeUtf16);
+ VBOX_UTF16_FREE(valueTypeUtf16);
+
+ if (sdlDisplay) {
+ VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
+ VBOX_UTF8_TO_UTF16(sdlDisplay, &valueDisplayUtf16);
+
+ gVBoxAPI.UIMachine.SetExtraData(machine, keyDislpayUtf16,
+ valueDisplayUtf16);
+
+ VBOX_UTF16_FREE(keyDislpayUtf16);
+ VBOX_UTF16_FREE(valueDisplayUtf16);
+ }
+
+ } else {
+ /* if all are set then default is gui, with vrdp turned on */
+ PRUnichar *keyTypeUtf16 = NULL;
+ PRUnichar *valueTypeUtf16 = NULL;
+ PRUnichar *keyDislpayUtf16 = NULL;
+ PRUnichar *valueDisplayUtf16 = NULL;
+
+ VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
+ VBOX_UTF8_TO_UTF16("gui", &valueTypeUtf16);
+
+ gVBoxAPI.UIMachine.SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
+
+ VBOX_UTF16_FREE(keyTypeUtf16);
+ VBOX_UTF16_FREE(valueTypeUtf16);
+
+ if (guiDisplay) {
+ VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
+ VBOX_UTF8_TO_UTF16(guiDisplay, &valueDisplayUtf16);
+
+ gVBoxAPI.UIMachine.SetExtraData(machine, keyDislpayUtf16,
+ valueDisplayUtf16);
+
+ VBOX_UTF16_FREE(keyDislpayUtf16);
+ VBOX_UTF16_FREE(valueDisplayUtf16);
+ }
+ }
+
+ VIR_FREE(guiDisplay);
+ VIR_FREE(sdlDisplay);
+}
+
+static void
+vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ IUSBCommon *USBCommon = NULL;
+ size_t i = 0;
+ bool isUSB = false;
+ nsresult rc;
+
+ if (def->nhostdevs == 0)
+ return;
+
+ /* Loop through the devices first and see if you
+ * have a USB Device, only if you have one then
+ * start the USB controller else just proceed as
+ * usual
+ */
+ for (i = 0; i < def->nhostdevs; i++) {
+ if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+
+ if (def->hostdevs[i]->source.subsys.type !=
+ VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+ continue;
+
+ if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
+ !def->hostdevs[i]->source.subsys.u.usb.product)
+ continue;
+
+ VIR_DEBUG("USB Device detected, VendorId:0x%x, ProductId:0x%x",
+ def->hostdevs[i]->source.subsys.u.usb.vendor,
+ def->hostdevs[i]->source.subsys.u.usb.product);
+ isUSB = true;
+ break;
+ }
+
+ if (!isUSB)
+ return;
+
+ /* First Start the USB Controller and then loop
+ * to attach USB Devices to it
+ */
+ rc = gVBoxAPI.UIMachine.GetUSBCommon(machine, &USBCommon);
+ if (NS_FAILED(rc) || !USBCommon)
+ return;
+ gVBoxAPI.UIUSBCommon.Enable(USBCommon);
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ char *filtername = NULL;
+ PRUnichar *filternameUtf16 = NULL;
+ IUSBDeviceFilter *filter = NULL;
+ PRUnichar *vendorIdUtf16 = NULL;
+ char vendorId[40] = {0};
+ PRUnichar *productIdUtf16 = NULL;
+ char productId[40] = {0};
+
+ if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+
+ if (def->hostdevs[i]->source.subsys.type !=
+ VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+ continue;
+
+ /* Zero pad for nice alignment when fewer than 9999
+ * devices.
+ */
+ if (virAsprintf(&filtername, "filter%04zu", i) >= 0) {
+ VBOX_UTF8_TO_UTF16(filtername, &filternameUtf16);
+ VIR_FREE(filtername);
+ gVBoxAPI.UIUSBCommon.CreateDeviceFilter(USBCommon,
+ filternameUtf16,
+ &filter);
+ }
+ VBOX_UTF16_FREE(filternameUtf16);
+
+ if (!filter)
+ continue;
+
+ if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
+ !def->hostdevs[i]->source.subsys.u.usb.product)
+ continue;
+
+ if (def->hostdevs[i]->source.subsys.u.usb.vendor) {
+ snprintf(vendorId, sizeof(vendorId), "%x",
+ def->hostdevs[i]->source.subsys.u.usb.vendor);
+ VBOX_UTF8_TO_UTF16(vendorId, &vendorIdUtf16);
+ gVBoxAPI.UIUSBDeviceFilter.SetVendorId(filter, vendorIdUtf16);
+ VBOX_UTF16_FREE(vendorIdUtf16);
+ }
+ if (def->hostdevs[i]->source.subsys.u.usb.product) {
+ snprintf(productId, sizeof(productId), "%x",
+ def->hostdevs[i]->source.subsys.u.usb.product);
+ VBOX_UTF8_TO_UTF16(productId, &productIdUtf16);
+ gVBoxAPI.UIUSBDeviceFilter.SetProductId(filter,
+ productIdUtf16);
+ VBOX_UTF16_FREE(productIdUtf16);
+ }
+ gVBoxAPI.UIUSBDeviceFilter.SetActive(filter, 1);
+ gVBoxAPI.UIUSBCommon.InsertDeviceFilter(USBCommon, i, filter);
+ VBOX_RELEASE(filter);
+ }
+
+ VBOX_RELEASE(USBCommon);
+}
+
+static void
+vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ size_t i;
+ PRUnichar *nameUtf16;
+ PRUnichar *hostPathUtf16;
+ PRBool writable;
+
+ if (def->nfss == 0)
+ return;
+
+ for (i = 0; i < def->nfss; i++) {
+ if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+ continue;
+
+ VBOX_UTF8_TO_UTF16(def->fss[i]->dst, &nameUtf16);
+ VBOX_UTF8_TO_UTF16(def->fss[i]->src, &hostPathUtf16);
+ writable = !def->fss[i]->readonly;
+
+ gVBoxAPI.UIMachine.CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+ writable, PR_FALSE);
+
+ VBOX_UTF16_FREE(nameUtf16);
+ VBOX_UTF16_FREE(hostPathUtf16);
+ }
+}
+
+virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+ VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
+ IMachine *machine = NULL;
+ IBIOSSettings *bios = NULL;
+ vboxIIDUnion mchiid;
+ virDomainDefPtr def = NULL;
+ nsresult rc;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ VBOX_IID_INITIALIZE(&mchiid);
+ if (!(def = virDomainDefParseString(xml, data->caps, data->xmlopt,
+ 1 << VIR_DOMAIN_VIRT_VBOX,
+ VIR_DOMAIN_XML_INACTIVE))) {
+ goto cleanup;
+ }
+
+ virUUIDFormat(def->uuid, uuidstr);
+
+ rc = gVBoxAPI.UIVirtualBox.CreateMachine(data, def, &machine, uuidstr);
+
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not define a domain, rc=%08x"), (unsigned)rc);
+ goto cleanup;
+ }
+
+ rc = gVBoxAPI.UIMachine.SetMemorySize(machine,
+ VIR_DIV_UP(def->mem.cur_balloon, 1024));
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not set the memory size of the domain to: %llu Kb,
"
+ "rc=%08x"),
+ def->mem.cur_balloon, (unsigned)rc);
+ }
+
+ if (def->vcpus != def->maxvcpus) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("current vcpu count must equal maximum"));
+ }
+ rc = gVBoxAPI.UIMachine.SetCPUCount(machine, def->maxvcpus);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not set the number of virtual CPUs to: %u,
rc=%08x"),
+ def->maxvcpus, (unsigned)rc);
+ }
+
+ rc = gVBoxAPI.UIMachine.SetCPUProperty(machine, CPUPropertyType_PAE,
+ def->features[VIR_DOMAIN_FEATURE_PAE] ==
+ VIR_TRISTATE_SWITCH_ON);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not change PAE status to: %s, rc=%08x"),
+ (def->features[VIR_DOMAIN_FEATURE_PAE] ==
VIR_TRISTATE_SWITCH_ON)
+ ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ }
+
+ gVBoxAPI.UIMachine.GetBIOSSettings(machine, &bios);
+ if (bios) {
+ rc = gVBoxAPI.UIBIOSSettings.SetACPIEnabled(bios,
+
def->features[VIR_DOMAIN_FEATURE_ACPI] ==
+ VIR_TRISTATE_SWITCH_ON);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not change ACPI status to: %s, rc=%08x"),
+ (def->features[VIR_DOMAIN_FEATURE_ACPI] ==
VIR_TRISTATE_SWITCH_ON)
+ ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ }
+ rc = gVBoxAPI.UIBIOSSettings.SetIOAPICEnabled(bios,
+
def->features[VIR_DOMAIN_FEATURE_APIC] ==
+ VIR_TRISTATE_SWITCH_ON);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not change APIC status to: %s, rc=%08x"),
+ (def->features[VIR_DOMAIN_FEATURE_APIC] ==
VIR_TRISTATE_SWITCH_ON)
+ ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ }
+ VBOX_RELEASE(bios);
+ }
+
+ /* Register the machine before attaching other devices to it */
+ rc = gVBoxAPI.UIVirtualBox.RegisterMachine(data->vboxObj, machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not define a domain, rc=%08x"), (unsigned)rc);
+ goto cleanup;
+ }
+
+ /* Get the uuid of the machine, currently it is immutable
+ * object so open a session to it and get it back, so that
+ * you can make changes to the machine setting
+ */
+ gVBoxAPI.UIMachine.GetId(machine, &mchiid);
+ gVBoxAPI.UISession.Open(data, &mchiid, machine);
+ gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine);
+
+ vboxSetBootDeviceOrder(def, data, machine);
+ vboxAttachDrives(def, data, machine);
+ vboxAttachSound(def, machine);
+ vboxAttachNetwork(def, data, machine);
+ vboxAttachSerial(def, data, machine);
+ vboxAttachParallel(def, data, machine);
+ vboxAttachVideo(def, machine);
+ vboxAttachDisplay(def, data, machine);
+ vboxAttachUSB(def, data, machine);
+ vboxAttachSharedFolder(def, data, machine);
+
+ /* Save the machine settings made till now and close the
+ * session. also free up the mchiid variable used.
+ */
+ rc = gVBoxAPI.UIMachine.SaveSettings(machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed no saving settings, rc=%08x"), (unsigned)rc);
+ goto cleanup;
+ }
+
+ gVBoxAPI.UISession.Close(data->vboxSession);
+ vboxIIDUnalloc(&mchiid);
+
+ ret = virGetDomain(conn, def->name, def->uuid);
+ VBOX_RELEASE(machine);
+
+ virDomainDefFree(def);
+
+ return ret;
+
+ cleanup:
+ VBOX_RELEASE(machine);
+ virDomainDefFree(def);
+ return NULL;
+}
+
+static void
detachDevices_common(vboxGlobalData *data, vboxIIDUnion *iidu)
{
/* Block for checking if HDD's are attched to VM.
diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h
index c4147a1..eedd755 100644
--- a/src/vbox/vbox_common.h
+++ b/src/vbox/vbox_common.h
@@ -158,6 +158,86 @@ struct _vboxArray {
# endif /* !WIN32 */
+/* We make the assumption that these enum flags
+ * are compatible in all vbox API version.
+ *
+ * Yes it is, as it has been checked from vbox 2.2 to
+ * vbox 4.3.3. And this rule MAY NOT stands for new
+ * vbox versions.
+ * */
+enum CPUPropertyType
+{
+ CPUPropertyType_Null = 0,
+ CPUPropertyType_PAE = 1,
+ CPUPropertyType_Synthetic = 2,
+};
+
+enum AudioControllerType
+{
+ AudioControllerType_AC97 = 0,
+ AudioControllerType_SB16 = 1
+};
+
+enum ChipsetType
+{
+ ChipsetType_Null = 0,
+ ChipsetType_PIIX3 = 1,
+ ChipsetType_ICH9 = 2
+};
+
+enum NetworkAdapterType
+{
+ NetworkAdapterType_Null = 0,
+ NetworkAdapterType_Am79C970A = 1,
+ NetworkAdapterType_Am79C973 = 2,
+ NetworkAdapterType_I82540EM = 3,
+ NetworkAdapterType_I82543GC = 4,
+ NetworkAdapterType_I82545EM = 5,
+ NetworkAdapterType_Virtio = 6
+};
+
+enum PortMode
+{
+ PortMode_Disconnected = 0,
+ PortMode_HostPipe = 1,
+ PortMode_HostDevice = 2,
+ PortMode_RawFile = 3
+};
+
+enum DeviceType
+{
+ DeviceType_Null = 0,
+ DeviceType_Floppy = 1,
+ DeviceType_DVD = 2,
+ DeviceType_HardDisk = 3,
+ DeviceType_Network = 4,
+ DeviceType_USB = 5,
+ DeviceType_SharedFolder = 6
+};
+
+enum StorageBus
+{
+ StorageBus_Null = 0,
+ StorageBus_IDE = 1,
+ StorageBus_SATA = 2,
+ StorageBus_SCSI = 3,
+ StorageBus_Floppy = 4,
+ StorageBus_SAS = 5
+};
+
+enum AccessMode
+{
+ AccessMode_ReadOnly = 1,
+ AccessMode_ReadWrite = 2
+};
+
+enum MediumType
+{
+ MediumType_Normal = 0,
+ MediumType_Immutable = 1,
+ MediumType_Writethrough = 2,
+};
+
/* Simplied definitions in vbox_CAPI_*.h */
typedef void const *PCVBOXXPCOM;
@@ -168,5 +248,15 @@ typedef nsISupports IConsole;
typedef nsISupports IProgress;
typedef nsISupports IMachine;
typedef nsISupports ISystemProperties;
+typedef nsISupports IBIOSSettings;
+typedef nsISupports IAudioAdapter;
+typedef nsISupports INetworkAdapter;
+typedef nsISupports ISerialPort;
+typedef nsISupports IParallelPort;
+typedef nsISupports IVRDxServer;
+typedef nsISupports IUSBCommon;
+typedef nsISupports IUSBDeviceFilter;
+typedef nsISupports IMedium;
+typedef nsISupports IStorageController;
#endif /* VBOX_COMMON_H */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 86c02f1..537616d 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -89,6 +89,19 @@
/* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */
#include "vbox_glue.h"
+
+#if VBOX_API_VERSION < 4000000
+typedef IVRDPServer IVRDxServer;
+#else /* VBOX_API_VERSION >= 4000000 */
+typedef IVRDEServer IVRDxServer;
+#endif /* VBOX_API_VERSION >= 4000000 */
+
+#if VBOX_API_VERSION < 4003000
+typedef IUSBController IUSBCommon;
+#else /* VBOX_API_VERSION >= 4003000 */
+typedef IUSBDeviceFilters IUSBCommon;
+#endif /* VBOX_API_VERSION >= 4003000 */
+
#include "vbox_uniformed_api.h"
#define VIR_FROM_THIS VIR_FROM_VBOX
@@ -252,7 +265,6 @@ static vboxGlobalData *g_pVBoxGlobalData = NULL;
#endif /* VBOX_API_VERSION >= 4000000 */
-static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml);
static int vboxDomainCreate(virDomainPtr dom);
#if VBOX_API_VERSION > 2002000 && VBOX_API_VERSION < 4000000
@@ -660,7 +672,9 @@ _vboxIIDFromArrayItem(vboxGlobalData *data, vboxIIDUnion *iidu,
vboxIIDFromArrayItem_v3_x(data, iid, array, idx)
# define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
-# if VBOX_API_VERSION >= 3001000
+#endif /* !(VBOX_API_VERSION == 2002000) */
+
+#if VBOX_API_VERSION >= 3001000
/**
* function to generate the name for medium,
@@ -738,6 +752,8 @@ static char *vboxGenerateMediumName(PRUint32 storageBus,
* @param deviceSlot Output slot number
*
*/
+# if VBOX_API_VERSION < 4000000
+/* Only 3.x will use this function. */
static bool vboxGetDeviceDetails(const char *deviceName,
PRUint32 *aMaxPortPerInst,
PRUint32 *aMaxSlotPerPort,
@@ -782,6 +798,7 @@ static bool vboxGetDeviceDetails(const char *deviceName,
return true;
}
+# endif /* VBOX_API_VERSION < 4000000 */
/**
* function to get the values for max port per
@@ -876,9 +893,7 @@ static PRUnichar *PRUnicharFromInt(int n) {
return strUtf16;
}
-# endif /* VBOX_API_VERSION >= 3001000 */
-
-#endif /* !(VBOX_API_VERSION == 2002000) */
+#endif /* VBOX_API_VERSION >= 3001000 */
static PRUnichar *
vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr)
@@ -3302,67 +3317,14 @@ static int vboxDomainCreate(virDomainPtr dom)
return vboxDomainCreateWithFlags(dom, 0);
}
-static void
-vboxSetBootDeviceOrder(virDomainDefPtr def, vboxGlobalData *data,
- IMachine *machine)
-{
- ISystemProperties *systemProperties = NULL;
- PRUint32 maxBootPosition = 0;
- size_t i = 0;
-
- VIR_DEBUG("def->os.type %s", def->os.type);
- VIR_DEBUG("def->os.arch %s",
virArchToString(def->os.arch));
- VIR_DEBUG("def->os.machine %s", def->os.machine);
- VIR_DEBUG("def->os.nBootDevs %zu", def->os.nBootDevs);
- VIR_DEBUG("def->os.bootDevs[0] %d", def->os.bootDevs[0]);
- VIR_DEBUG("def->os.bootDevs[1] %d", def->os.bootDevs[1]);
- VIR_DEBUG("def->os.bootDevs[2] %d", def->os.bootDevs[2]);
- VIR_DEBUG("def->os.bootDevs[3] %d", def->os.bootDevs[3]);
- VIR_DEBUG("def->os.init %s", def->os.init);
- VIR_DEBUG("def->os.kernel %s", def->os.kernel);
- VIR_DEBUG("def->os.initrd %s", def->os.initrd);
- VIR_DEBUG("def->os.cmdline %s", def->os.cmdline);
- VIR_DEBUG("def->os.root %s", def->os.root);
- VIR_DEBUG("def->os.loader %s", def->os.loader);
- VIR_DEBUG("def->os.bootloader %s", def->os.bootloader);
- VIR_DEBUG("def->os.bootloaderArgs %s", def->os.bootloaderArgs);
-
- data->vboxObj->vtbl->GetSystemProperties(data->vboxObj,
&systemProperties);
- if (systemProperties) {
- systemProperties->vtbl->GetMaxBootPosition(systemProperties,
- &maxBootPosition);
- VBOX_RELEASE(systemProperties);
- systemProperties = NULL;
- }
-
- /* Clear the defaults first */
- for (i = 0; i < maxBootPosition; i++) {
- machine->vtbl->SetBootOrder(machine, i+1, DeviceType_Null);
- }
-
- for (i = 0; (i < def->os.nBootDevs) && (i < maxBootPosition); i++)
{
- PRUint32 device = DeviceType_Null;
-
- if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_FLOPPY) {
- device = DeviceType_Floppy;
- } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_CDROM) {
- device = DeviceType_DVD;
- } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_DISK) {
- device = DeviceType_HardDisk;
- } else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
- device = DeviceType_Network;
- }
- machine->vtbl->SetBootOrder(machine, i+1, device);
- }
-}
+#if VBOX_API_VERSION < 3001000
static void
-vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+_vboxAttachDrivesOld(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
{
size_t i;
nsresult rc;
-#if VBOX_API_VERSION < 3001000
if (def->ndisks == 0)
return;
@@ -3599,7 +3561,16 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data,
IMachine *machine)
}
}
}
-#else /* VBOX_API_VERSION >= 3001000 */
+}
+
+#elif VBOX_API_VERSION < 4000000
+
+static void
+_vboxAttachDrivesOld(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ size_t i;
+ nsresult rc;
+
PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {};
PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {};
PRUnichar *storageCtlName = NULL;
@@ -3675,9 +3646,6 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine
*machine)
PRUnichar *mediumFileUtf16 = NULL;
PRUint32 storageBus = StorageBus_Null;
PRUint32 deviceType = DeviceType_Null;
-# if VBOX_API_VERSION >= 4000000
- PRUint32 accessMode = AccessMode_ReadOnly;
-# endif
PRInt32 deviceInst = 0;
PRInt32 devicePort = 0;
PRInt32 deviceSlot = 0;
@@ -3686,47 +3654,26 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data,
IMachine *machine)
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
deviceType = DeviceType_HardDisk;
-# if VBOX_API_VERSION < 4000000
data->vboxObj->vtbl->FindHardDisk(data->vboxObj,
mediumFileUtf16, &medium);
-# else
- accessMode = AccessMode_ReadWrite;
-# endif
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
deviceType = DeviceType_DVD;
-# if VBOX_API_VERSION < 4000000
data->vboxObj->vtbl->FindDVDImage(data->vboxObj,
mediumFileUtf16, &medium);
-# else
- accessMode = AccessMode_ReadOnly;
-# endif
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
deviceType = DeviceType_Floppy;
-# if VBOX_API_VERSION < 4000000
data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
mediumFileUtf16, &medium);
-# else
- accessMode = AccessMode_ReadWrite;
-# endif
} else {
VBOX_UTF16_FREE(mediumFileUtf16);
continue;
}
-# if VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- data->vboxObj->vtbl->FindMedium(data->vboxObj, mediumFileUtf16,
- deviceType, &medium);
-# elif VBOX_API_VERSION >= 4002000
- data->vboxObj->vtbl->OpenMedium(data->vboxObj, mediumFileUtf16,
- deviceType, accessMode, PR_FALSE,
&medium);
-# endif
-
if (!medium) {
PRUnichar *mediumEmpty = NULL;
VBOX_UTF8_TO_UTF16("", &mediumEmpty);
-# if VBOX_API_VERSION < 4000000
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
rc = data->vboxObj->vtbl->OpenHardDisk(data->vboxObj,
mediumFileUtf16,
@@ -3751,19 +3698,6 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data,
IMachine *machine)
} else {
rc = 0;
}
-# elif VBOX_API_VERSION == 4000000
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
- mediumFileUtf16,
- deviceType, accessMode,
- &medium);
-# elif VBOX_API_VERSION >= 4001000
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
- mediumFileUtf16,
- deviceType, accessMode,
- false,
- &medium);
-# endif /* VBOX_API_VERSION >= 4001000 */
-
VBOX_UTF16_FREE(mediumEmpty);
}
@@ -3836,11 +3770,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data,
IMachine *machine)
devicePort,
deviceSlot,
deviceType,
-# if VBOX_API_VERSION < 4000000
mediumUUID);
-# else /* VBOX_API_VERSION >= 4000000 */
- medium);
-# endif /* VBOX_API_VERSION >= 4000000 */
if (NS_FAILED(rc)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3857,1421 +3787,510 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data,
IMachine *machine)
VBOX_UTF16_FREE(storageCtlName);
}
}
-#endif /* VBOX_API_VERSION >= 3001000 */
}
-static void
-vboxAttachSound(virDomainDefPtr def, IMachine *machine)
-{
- nsresult rc;
-
- /* Check if def->nsounds is one as VirtualBox currently supports
- * only one sound card
- */
- if (def->nsounds == 1) {
- IAudioAdapter *audioAdapter = NULL;
-
- machine->vtbl->GetAudioAdapter(machine, &audioAdapter);
- if (audioAdapter) {
- rc = audioAdapter->vtbl->SetEnabled(audioAdapter, 1);
- if (NS_SUCCEEDED(rc)) {
- if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_SB16) {
- audioAdapter->vtbl->SetAudioController(audioAdapter,
- AudioControllerType_SB16);
- } else if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_AC97) {
- audioAdapter->vtbl->SetAudioController(audioAdapter,
- AudioControllerType_AC97);
- }
- }
- VBOX_RELEASE(audioAdapter);
- }
- }
-}
+#else /* VBOX_API_VERSION >= 4000000 */
static void
-vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+_vboxAttachDrivesOld(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ vboxGlobalData *data ATTRIBUTE_UNUSED,
+ IMachine *machine ATTRIBUTE_UNUSED)
{
- ISystemProperties *systemProperties = NULL;
-#if VBOX_API_VERSION >= 4001000
- PRUint32 chipsetType = ChipsetType_Null;
-#endif /* VBOX_API_VERSION >= 4001000 */
- PRUint32 networkAdapterCount = 0;
- size_t i = 0;
-
-#if VBOX_API_VERSION >= 4001000
- machine->vtbl->GetChipsetType(machine, &chipsetType);
-#endif /* VBOX_API_VERSION >= 4001000 */
+ vboxUnsupported();
+}
- data->vboxObj->vtbl->GetSystemProperties(data->vboxObj,
&systemProperties);
- if (systemProperties) {
-#if VBOX_API_VERSION < 4001000
- systemProperties->vtbl->GetNetworkAdapterCount(systemProperties,
- &networkAdapterCount);
-#else /* VBOX_API_VERSION >= 4000000 */
- systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties,
chipsetType,
- &networkAdapterCount);
#endif /* VBOX_API_VERSION >= 4000000 */
- VBOX_RELEASE(systemProperties);
- systemProperties = NULL;
- }
-
- VIR_DEBUG("Number of Network Cards to be connected: %zu", def->nnets);
- VIR_DEBUG("Number of Network Cards available: %d", networkAdapterCount);
-
- for (i = 0; (i < def->nnets) && (i < networkAdapterCount); i++) {
- INetworkAdapter *adapter = NULL;
- PRUint32 adapterType = NetworkAdapterType_Null;
- char macaddr[VIR_MAC_STRING_BUFLEN] = {0};
- char macaddrvbox[VIR_MAC_STRING_BUFLEN - 5] = {0};
-
- virMacAddrFormat(&def->nets[i]->mac, macaddr);
- snprintf(macaddrvbox, VIR_MAC_STRING_BUFLEN - 5,
- "%02X%02X%02X%02X%02X%02X",
- def->nets[i]->mac.addr[0],
- def->nets[i]->mac.addr[1],
- def->nets[i]->mac.addr[2],
- def->nets[i]->mac.addr[3],
- def->nets[i]->mac.addr[4],
- def->nets[i]->mac.addr[5]);
- macaddrvbox[VIR_MAC_STRING_BUFLEN - 6] = '\0';
-
- VIR_DEBUG("NIC(%zu): Type: %d", i, def->nets[i]->type);
- VIR_DEBUG("NIC(%zu): Model: %s", i, def->nets[i]->model);
- VIR_DEBUG("NIC(%zu): Mac: %s", i, macaddr);
- VIR_DEBUG("NIC(%zu): ifname: %s", i, def->nets[i]->ifname);
- if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
- VIR_DEBUG("NIC(%zu): name: %s", i,
def->nets[i]->data.network.name);
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
- VIR_DEBUG("NIC(%zu): name: %s", i,
def->nets[i]->data.internal.name);
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
- VIR_DEBUG("NIC(%zu): NAT.", i);
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
- VIR_DEBUG("NIC(%zu): brname: %s", i,
def->nets[i]->data.bridge.brname);
- VIR_DEBUG("NIC(%zu): script: %s", i, def->nets[i]->script);
- VIR_DEBUG("NIC(%zu): ipaddr: %s", i,
def->nets[i]->data.bridge.ipaddr);
- }
-
- machine->vtbl->GetNetworkAdapter(machine, i, &adapter);
- if (adapter) {
- PRUnichar *MACAddress = NULL;
-
- adapter->vtbl->SetEnabled(adapter, 1);
-
- if (def->nets[i]->model) {
- if (STRCASEEQ(def->nets[i]->model, "Am79C970A")) {
- adapterType = NetworkAdapterType_Am79C970A;
- } else if (STRCASEEQ(def->nets[i]->model, "Am79C973")) {
- adapterType = NetworkAdapterType_Am79C973;
- } else if (STRCASEEQ(def->nets[i]->model, "82540EM")) {
- adapterType = NetworkAdapterType_I82540EM;
- } else if (STRCASEEQ(def->nets[i]->model, "82545EM")) {
- adapterType = NetworkAdapterType_I82545EM;
- } else if (STRCASEEQ(def->nets[i]->model, "82543GC")) {
- adapterType = NetworkAdapterType_I82543GC;
-#if VBOX_API_VERSION >= 3001000
- } else if (STRCASEEQ(def->nets[i]->model, "virtio")) {
- adapterType = NetworkAdapterType_Virtio;
-#endif /* VBOX_API_VERSION >= 3001000 */
- }
- } else {
- adapterType = NetworkAdapterType_Am79C973;
- }
-
- adapter->vtbl->SetAdapterType(adapter, adapterType);
-
- if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
- PRUnichar *hostInterface = NULL;
- /* Bridged Network */
-
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->AttachToBridgedInterface(adapter);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_Bridged);
-#endif /* VBOX_API_VERSION >= 4001000 */
-
- if (def->nets[i]->data.bridge.brname) {
- VBOX_UTF8_TO_UTF16(def->nets[i]->data.bridge.brname,
- &hostInterface);
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->SetHostInterface(adapter, hostInterface);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetBridgedInterface(adapter, hostInterface);
-#endif /* VBOX_API_VERSION >= 4001000 */
- VBOX_UTF16_FREE(hostInterface);
- }
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
- PRUnichar *internalNetwork = NULL;
- /* Internal Network */
-
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->AttachToInternalNetwork(adapter);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_Internal);
-#endif /* VBOX_API_VERSION >= 4001000 */
-
- if (def->nets[i]->data.internal.name) {
- VBOX_UTF8_TO_UTF16(def->nets[i]->data.internal.name,
- &internalNetwork);
- adapter->vtbl->SetInternalNetwork(adapter, internalNetwork);
- VBOX_UTF16_FREE(internalNetwork);
- }
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
- PRUnichar *hostInterface = NULL;
- /* Host Only Networking (currently only vboxnet0 available
- * on *nix and mac, on windows you can create and configure
- * as many as you want)
- */
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->AttachToHostOnlyInterface(adapter);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_HostOnly);
-#endif /* VBOX_API_VERSION >= 4001000 */
-
- if (def->nets[i]->data.network.name) {
- VBOX_UTF8_TO_UTF16(def->nets[i]->data.network.name,
- &hostInterface);
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->SetHostInterface(adapter, hostInterface);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetHostOnlyInterface(adapter, hostInterface);
-#endif /* VBOX_API_VERSION >= 4001000 */
- VBOX_UTF16_FREE(hostInterface);
- }
- } else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
- /* NAT */
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->AttachToNAT(adapter);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_NAT);
-#endif /* VBOX_API_VERSION >= 4001000 */
- } else {
- /* else always default to NAT if we don't understand
- * what option is been passed to us
- */
-#if VBOX_API_VERSION < 4001000
- adapter->vtbl->AttachToNAT(adapter);
-#else /* VBOX_API_VERSION >= 4001000 */
- adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_NAT);
-#endif /* VBOX_API_VERSION >= 4001000 */
- }
-
- VBOX_UTF8_TO_UTF16(macaddrvbox, &MACAddress);
- adapter->vtbl->SetMACAddress(adapter, MACAddress);
- VBOX_UTF16_FREE(MACAddress);
- }
- }
-}
-static void
-vboxAttachSerial(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+static int
+vboxDomainUndefine(virDomainPtr dom)
{
- ISystemProperties *systemProperties = NULL;
- PRUint32 serialPortCount = 0;
- size_t i = 0;
-
- data->vboxObj->vtbl->GetSystemProperties(data->vboxObj,
&systemProperties);
- if (systemProperties) {
- systemProperties->vtbl->GetSerialPortCount(systemProperties,
- &serialPortCount);
- VBOX_RELEASE(systemProperties);
- systemProperties = NULL;
- }
-
- VIR_DEBUG("Number of Serial Ports to be connected: %zu",
def->nserials);
- VIR_DEBUG("Number of Serial Ports available: %d", serialPortCount);
- for (i = 0; (i < def->nserials) && (i < serialPortCount); i++) {
- ISerialPort *serialPort = NULL;
-
- VIR_DEBUG("SerialPort(%zu): Type: %d", i,
def->serials[i]->source.type);
- VIR_DEBUG("SerialPort(%zu): target.port: %d", i,
- def->serials[i]->target.port);
-
- machine->vtbl->GetSerialPort(machine, i, &serialPort);
- if (serialPort) {
- PRUnichar *pathUtf16 = NULL;
-
- serialPort->vtbl->SetEnabled(serialPort, 1);
-
- if (def->serials[i]->source.data.file.path) {
- VBOX_UTF8_TO_UTF16(def->serials[i]->source.data.file.path,
- &pathUtf16);
- serialPort->vtbl->SetPath(serialPort, pathUtf16);
- }
-
- /* For now hard code the serial ports to COM1 and COM2,
- * COM1 (Base Addr: 0x3F8 (decimal: 1016), IRQ: 4)
- * COM2 (Base Addr: 0x2F8 (decimal: 760), IRQ: 3)
- * TODO: make this more flexible
- */
- /* TODO: to improve the libvirt XMl handling so
- * that def->serials[i]->target.port shows real port
- * and not always start at 0
- */
- if (def->serials[i]->target.port == 0) {
- serialPort->vtbl->SetIRQ(serialPort, 4);
- serialPort->vtbl->SetIOBase(serialPort, 1016);
- VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
- i, 4, 1016, def->serials[i]->source.data.file.path);
- } else if (def->serials[i]->target.port == 1) {
- serialPort->vtbl->SetIRQ(serialPort, 3);
- serialPort->vtbl->SetIOBase(serialPort, 760);
- VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
- i, 3, 760, def->serials[i]->source.data.file.path);
- }
-
- if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) {
- serialPort->vtbl->SetHostMode(serialPort, PortMode_HostDevice);
- } else if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE) {
- serialPort->vtbl->SetHostMode(serialPort, PortMode_HostPipe);
-#if VBOX_API_VERSION >= 3000000
- } else if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) {
- serialPort->vtbl->SetHostMode(serialPort, PortMode_RawFile);
-#endif /* VBOX_API_VERSION >= 3000000 */
- } else {
- serialPort->vtbl->SetHostMode(serialPort,
- PortMode_Disconnected);
- }
-
- VBOX_RELEASE(serialPort);
- VBOX_UTF16_FREE(pathUtf16);
- }
- }
+ return vboxDomainUndefineFlags(dom, 0);
}
-static void
-vboxAttachParallel(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
+ const char *xml,
+ int mediaChangeOnly ATTRIBUTE_UNUSED)
{
- ISystemProperties *systemProperties = NULL;
- PRUint32 parallelPortCount = 0;
- size_t i = 0;
-
- data->vboxObj->vtbl->GetSystemProperties(data->vboxObj,
&systemProperties);
- if (systemProperties) {
- systemProperties->vtbl->GetParallelPortCount(systemProperties,
- ¶llelPortCount);
- VBOX_RELEASE(systemProperties);
- systemProperties = NULL;
- }
-
- VIR_DEBUG("Number of Parallel Ports to be connected: %zu",
def->nparallels);
- VIR_DEBUG("Number of Parallel Ports available: %d", parallelPortCount);
- for (i = 0; (i < def->nparallels) && (i < parallelPortCount); i++)
{
- IParallelPort *parallelPort = NULL;
-
- VIR_DEBUG("ParallelPort(%zu): Type: %d", i,
def->parallels[i]->source.type);
- VIR_DEBUG("ParallelPort(%zu): target.port: %d", i,
- def->parallels[i]->target.port);
-
- machine->vtbl->GetParallelPort(machine, i, ¶llelPort);
- if (parallelPort) {
- PRUnichar *pathUtf16 = NULL;
+ VBOX_OBJECT_CHECK(dom->conn, int, -1);
+ IMachine *machine = NULL;
+ vboxIID iid = VBOX_IID_INITIALIZER;
+ PRUint32 state = MachineState_Null;
+ virDomainDefPtr def = NULL;
+ virDomainDeviceDefPtr dev = NULL;
+ nsresult rc;
- VBOX_UTF8_TO_UTF16(def->parallels[i]->source.data.file.path,
&pathUtf16);
+ if (VIR_ALLOC(def) < 0)
+ return ret;
- /* For now hard code the parallel ports to
- * LPT1 (Base Addr: 0x378 (decimal: 888), IRQ: 7)
- * LPT2 (Base Addr: 0x278 (decimal: 632), IRQ: 5)
- * TODO: make this more flexible
- */
- if ((def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) ||
- (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PTY) ||
- (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) ||
- (def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE)) {
- parallelPort->vtbl->SetPath(parallelPort, pathUtf16);
- if (i == 0) {
- parallelPort->vtbl->SetIRQ(parallelPort, 7);
- parallelPort->vtbl->SetIOBase(parallelPort, 888);
- VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path:
%s",
- i, 7, 888, def->parallels[i]->source.data.file.path);
- } else if (i == 1) {
- parallelPort->vtbl->SetIRQ(parallelPort, 5);
- parallelPort->vtbl->SetIOBase(parallelPort, 632);
- VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path:
%s",
- i, 5, 632, def->parallels[i]->source.data.file.path);
- }
- }
+ if (VIR_STRDUP(def->os.type, "hvm") < 0)
+ goto cleanup;
- /* like serial port, parallel port can't be enabled unless
- * correct IRQ and IOBase values are specified.
- */
- parallelPort->vtbl->SetEnabled(parallelPort, 1);
+ dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
+ VIR_DOMAIN_XML_INACTIVE);
+ if (dev == NULL)
+ goto cleanup;
- VBOX_RELEASE(parallelPort);
- VBOX_UTF16_FREE(pathUtf16);
- }
+ vboxIIDFromUUID(&iid, dom->uuid);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ goto cleanup;
}
-}
-static void
-vboxAttachVideo(virDomainDefPtr def, IMachine *machine)
-{
- if ((def->nvideos == 1) &&
- (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_VBOX)) {
- machine->vtbl->SetVRAMSize(machine,
- VIR_DIV_UP(def->videos[0]->vram, 1024));
- machine->vtbl->SetMonitorCount(machine, def->videos[0]->heads);
- if (def->videos[0]->accel) {
- machine->vtbl->SetAccelerate3DEnabled(machine,
-
def->videos[0]->accel->support3d);
-#if VBOX_API_VERSION >= 3001000
- machine->vtbl->SetAccelerate2DVideoEnabled(machine,
-
def->videos[0]->accel->support2d);
-#endif /* VBOX_API_VERSION >= 3001000 */
+ if (machine) {
+ machine->vtbl->GetState(machine, &state);
+
+ if ((state == MachineState_Running) ||
+ (state == MachineState_Paused)) {
+ rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
} else {
- machine->vtbl->SetAccelerate3DEnabled(machine, 0);
-#if VBOX_API_VERSION >= 3001000
- machine->vtbl->SetAccelerate2DVideoEnabled(machine, 0);
-#endif /* VBOX_API_VERSION >= 3001000 */
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
}
- }
-}
-
-static void
-vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
-{
- int vrdpPresent = 0;
- int sdlPresent = 0;
- int guiPresent = 0;
- char *guiDisplay = NULL;
- char *sdlDisplay = NULL;
- size_t i = 0;
-
- for (i = 0; i < def->ngraphics; i++) {
-#if VBOX_API_VERSION < 4000000
- IVRDPServer *VRDxServer = NULL;
-#else /* VBOX_API_VERSION >= 4000000 */
- IVRDEServer *VRDxServer = NULL;
-#endif /* VBOX_API_VERSION >= 4000000 */
-
- if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) &&
- (vrdpPresent == 0)) {
+ if (NS_SUCCEEDED(rc)) {
+ rc = data->vboxSession->vtbl->GetMachine(data->vboxSession,
&machine);
+ if (NS_SUCCEEDED(rc) && machine) {
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+#if VBOX_API_VERSION < 3001000
+ const char *src = virDomainDiskGetSource(dev->data.disk);
+ int type = virDomainDiskGetType(dev->data.disk);
- vrdpPresent = 1;
-#if VBOX_API_VERSION < 4000000
- machine->vtbl->GetVRDPServer(machine, &VRDxServer);
-#else /* VBOX_API_VERSION >= 4000000 */
- machine->vtbl->GetVRDEServer(machine, &VRDxServer);
-#endif /* VBOX_API_VERSION >= 4000000 */
- if (VRDxServer) {
- const char *listenAddr
- = virDomainGraphicsListenGetAddress(def->graphics[i], 0);
+ if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+ if (type == VIR_STORAGE_TYPE_FILE && src) {
+ IDVDDrive *dvdDrive = NULL;
+ /* Currently CDROM/DVD Drive is always IDE
+ * Secondary Master so neglecting the following
+ * parameter dev->data.disk->bus
+ */
+ machine->vtbl->GetDVDDrive(machine, &dvdDrive);
+ if (dvdDrive) {
+ IDVDImage *dvdImage = NULL;
+ PRUnichar *dvdfileUtf16 = NULL;
+ vboxIID dvduuid = VBOX_IID_INITIALIZER;
+ vboxIID dvdemptyuuid = VBOX_IID_INITIALIZER;
- VRDxServer->vtbl->SetEnabled(VRDxServer, PR_TRUE);
- VIR_DEBUG("VRDP Support turned ON.");
+ VBOX_UTF8_TO_UTF16(src, &dvdfileUtf16);
-#if VBOX_API_VERSION < 3001000
- if (def->graphics[i]->data.rdp.port) {
- VRDxServer->vtbl->SetPort(VRDxServer,
- def->graphics[i]->data.rdp.port);
- VIR_DEBUG("VRDP Port changed to: %d",
- def->graphics[i]->data.rdp.port);
- } else if (def->graphics[i]->data.rdp.autoport) {
- /* Setting the port to 0 will reset its value to
- * the default one which is 3389 currently
- */
- VRDxServer->vtbl->SetPort(VRDxServer, 0);
- VIR_DEBUG("VRDP Port changed to default, which is 3389
currently");
- }
-#elif VBOX_API_VERSION < 4000000 /* 3001000 <= VBOX_API_VERSION < 4000000 */
- PRUnichar *portUtf16 = NULL;
- portUtf16 = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
- VRDxServer->vtbl->SetPorts(VRDxServer, portUtf16);
- VBOX_UTF16_FREE(portUtf16);
-#else /* VBOX_API_VERSION >= 4000000 */
- PRUnichar *VRDEPortsKey = NULL;
- PRUnichar *VRDEPortsValue = NULL;
- VBOX_UTF8_TO_UTF16("TCP/Ports", &VRDEPortsKey);
- VRDEPortsValue =
PRUnicharFromInt(def->graphics[i]->data.rdp.port);
- VRDxServer->vtbl->SetVRDEProperty(VRDxServer, VRDEPortsKey,
- VRDEPortsValue);
- VBOX_UTF16_FREE(VRDEPortsKey);
- VBOX_UTF16_FREE(VRDEPortsValue);
-#endif /* VBOX_API_VERSION >= 4000000 */
+
data->vboxObj->vtbl->FindDVDImage(data->vboxObj, dvdfileUtf16,
&dvdImage);
+ if (!dvdImage) {
+
data->vboxObj->vtbl->OpenDVDImage(data->vboxObj, dvdfileUtf16,
dvdemptyuuid.value, &dvdImage);
+ }
+ if (dvdImage) {
+ rc = dvdImage->vtbl->imedium.GetId((IMedium
*)dvdImage, &dvduuid.value);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("can't get the uuid of
the file to "
+ "be attached to cdrom: %s,
rc=%08x"),
+ src, (unsigned)rc);
+ } else {
+ /* unmount the previous mounted image */
+ dvdDrive->vtbl->Unmount(dvdDrive);
+ rc = dvdDrive->vtbl->MountImage(dvdDrive,
dvduuid.value);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not attach the
file to cdrom: %s, rc=%08x"),
+ src, (unsigned)rc);
+ } else {
+ ret = 0;
+ DEBUGIID("CD/DVD Image UUID:",
dvduuid.value);
+ }
+ }
- if (def->graphics[i]->data.rdp.replaceUser) {
- VRDxServer->vtbl->SetReuseSingleConnection(VRDxServer,
- PR_TRUE);
- VIR_DEBUG("VRDP set to reuse single connection");
- }
+ VBOX_MEDIUM_RELEASE(dvdImage);
+ }
+ vboxIIDUnalloc(&dvduuid);
+ VBOX_UTF16_FREE(dvdfileUtf16);
+ VBOX_RELEASE(dvdDrive);
+ }
+ } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+ }
+ } else if (dev->data.disk->device ==
VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+ if (type == VIR_STORAGE_TYPE_FILE && src) {
+ IFloppyDrive *floppyDrive;
+ machine->vtbl->GetFloppyDrive(machine,
&floppyDrive);
+ if (floppyDrive) {
+ rc = floppyDrive->vtbl->SetEnabled(floppyDrive,
1);
+ if (NS_SUCCEEDED(rc)) {
+ IFloppyImage *floppyImage = NULL;
+ PRUnichar *fdfileUtf16 = NULL;
+ vboxIID fduuid = VBOX_IID_INITIALIZER;
+ vboxIID fdemptyuuid = VBOX_IID_INITIALIZER;
+ VBOX_UTF8_TO_UTF16(src, &fdfileUtf16);
+ rc =
data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
+
fdfileUtf16,
+
&floppyImage);
- if (def->graphics[i]->data.rdp.multiUser) {
- VRDxServer->vtbl->SetAllowMultiConnection(VRDxServer,
- PR_TRUE);
- VIR_DEBUG("VRDP set to allow multiple connection");
- }
+ if (!floppyImage) {
+
data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
+
fdfileUtf16,
+
fdemptyuuid.value,
+
&floppyImage);
+ }
- if (listenAddr) {
-#if VBOX_API_VERSION >= 4000000
- PRUnichar *netAddressKey = NULL;
-#endif
- PRUnichar *netAddressUtf16 = NULL;
+ if (floppyImage) {
+ rc =
floppyImage->vtbl->imedium.GetId((IMedium *)floppyImage, &fduuid.value);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("can't get the uuid
of the file to be "
+ "attached to floppy
drive: %s, rc=%08x"),
+ src, (unsigned)rc);
+ } else {
+ rc =
floppyDrive->vtbl->MountImage(floppyDrive, fduuid.value);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not attach
the file to floppy drive: %s, rc=%08x"),
+ src, (unsigned)rc);
+ } else {
+ ret = 0;
+ DEBUGIID("attached floppy,
UUID:", fduuid.value);
+ }
+ }
+ VBOX_MEDIUM_RELEASE(floppyImage);
+ }
+ vboxIIDUnalloc(&fduuid);
+ VBOX_UTF16_FREE(fdfileUtf16);
+ }
+ VBOX_RELEASE(floppyDrive);
+ }
+ } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+ }
+ }
+#else /* VBOX_API_VERSION >= 3001000 */
+#endif /* VBOX_API_VERSION >= 3001000 */
+ } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+ if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
{
+ if (dev->data.hostdev->source.subsys.type ==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+ }
+ }
+ } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
+ dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
+ PRUnichar *nameUtf16;
+ PRUnichar *hostPathUtf16;
+ PRBool writable;
+
+ VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
+ VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16);
+ writable = !dev->data.fs->readonly;
- VBOX_UTF8_TO_UTF16(listenAddr, &netAddressUtf16);
#if VBOX_API_VERSION < 4000000
- VRDxServer->vtbl->SetNetAddress(VRDxServer,
- netAddressUtf16);
+ rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16,
hostPathUtf16,
+ writable);
#else /* VBOX_API_VERSION >= 4000000 */
- VBOX_UTF8_TO_UTF16("TCP/Address", &netAddressKey);
- VRDxServer->vtbl->SetVRDEProperty(VRDxServer, netAddressKey,
- netAddressUtf16);
- VBOX_UTF16_FREE(netAddressKey);
+ rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16,
hostPathUtf16,
+ writable, PR_FALSE);
#endif /* VBOX_API_VERSION >= 4000000 */
- VIR_DEBUG("VRDP listen address is set to: %s",
- listenAddr);
-
- VBOX_UTF16_FREE(netAddressUtf16);
- }
-
- VBOX_RELEASE(VRDxServer);
- }
- }
- if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP)
&&
- (guiPresent == 0)) {
- guiPresent = 1;
- if (VIR_STRDUP(guiDisplay, def->graphics[i]->data.desktop.display) <
0) {
- /* just don't go to cleanup yet as it is ok to have
- * guiDisplay as NULL and we check it below if it
- * exist and then only use it there
- */
- }
- }
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not attach shared folder
'%s', rc=%08x"),
+ dev->data.fs->dst, (unsigned)rc);
+ } else {
+ ret = 0;
+ }
- if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) &&
- (sdlPresent == 0)) {
- sdlPresent = 1;
- if (VIR_STRDUP(sdlDisplay, def->graphics[i]->data.sdl.display) < 0)
{
- /* just don't go to cleanup yet as it is ok to have
- * sdlDisplay as NULL and we check it below if it
- * exist and then only use it there
- */
+ VBOX_UTF16_FREE(nameUtf16);
+ VBOX_UTF16_FREE(hostPathUtf16);
+ }
+ machine->vtbl->SaveSettings(machine);
+ VBOX_RELEASE(machine);
}
+ VBOX_SESSION_CLOSE();
}
}
- if ((vrdpPresent == 1) && (guiPresent == 0) && (sdlPresent == 0)) {
- /* store extradata key that frontend is set to vrdp */
- PRUnichar *keyTypeUtf16 = NULL;
- PRUnichar *valueTypeUtf16 = NULL;
-
- VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
- VBOX_UTF8_TO_UTF16("vrdp", &valueTypeUtf16);
-
- machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
-
- VBOX_UTF16_FREE(keyTypeUtf16);
- VBOX_UTF16_FREE(valueTypeUtf16);
-
- } else if ((guiPresent == 0) && (sdlPresent == 1)) {
- /* store extradata key that frontend is set to sdl */
- PRUnichar *keyTypeUtf16 = NULL;
- PRUnichar *valueTypeUtf16 = NULL;
- PRUnichar *keyDislpayUtf16 = NULL;
- PRUnichar *valueDisplayUtf16 = NULL;
-
- VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
- VBOX_UTF8_TO_UTF16("sdl", &valueTypeUtf16);
-
- machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
-
- VBOX_UTF16_FREE(keyTypeUtf16);
- VBOX_UTF16_FREE(valueTypeUtf16);
-
- if (sdlDisplay) {
- VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
- VBOX_UTF8_TO_UTF16(sdlDisplay, &valueDisplayUtf16);
-
- machine->vtbl->SetExtraData(machine, keyDislpayUtf16,
- valueDisplayUtf16);
-
- VBOX_UTF16_FREE(keyDislpayUtf16);
- VBOX_UTF16_FREE(valueDisplayUtf16);
- }
-
- } else {
- /* if all are set then default is gui, with vrdp turned on */
- PRUnichar *keyTypeUtf16 = NULL;
- PRUnichar *valueTypeUtf16 = NULL;
- PRUnichar *keyDislpayUtf16 = NULL;
- PRUnichar *valueDisplayUtf16 = NULL;
+ cleanup:
+ vboxIIDUnalloc(&iid);
+ virDomainDefFree(def);
+ virDomainDeviceDefFree(dev);
+ return ret;
+}
- VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
- VBOX_UTF8_TO_UTF16("gui", &valueTypeUtf16);
+static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml)
+{
+ return vboxDomainAttachDeviceImpl(dom, xml, 0);
+}
- machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
+static int
+vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
+ unsigned int flags)
+{
+ virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
- VBOX_UTF16_FREE(keyTypeUtf16);
- VBOX_UTF16_FREE(valueTypeUtf16);
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot modify the persistent configuration of a
domain"));
+ return -1;
+ }
- if (guiDisplay) {
- VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
- VBOX_UTF8_TO_UTF16(guiDisplay, &valueDisplayUtf16);
+ return vboxDomainAttachDeviceImpl(dom, xml, 0);
+}
- machine->vtbl->SetExtraData(machine, keyDislpayUtf16,
- valueDisplayUtf16);
+static int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
+ unsigned int flags)
+{
+ virCheckFlags(VIR_DOMAIN_AFFECT_CURRENT |
+ VIR_DOMAIN_AFFECT_LIVE |
+ VIR_DOMAIN_AFFECT_CONFIG, -1);
- VBOX_UTF16_FREE(keyDislpayUtf16);
- VBOX_UTF16_FREE(valueDisplayUtf16);
- }
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot modify the persistent configuration of a
domain"));
+ return -1;
}
- VIR_FREE(guiDisplay);
- VIR_FREE(sdlDisplay);
+ return vboxDomainAttachDeviceImpl(dom, xml, 1);
}
-static void
-vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml)
{
-#if VBOX_API_VERSION < 4003000
- IUSBController *USBController = NULL;
-#else
- IUSBDeviceFilters *USBDeviceFilters = NULL;
-#endif
- size_t i = 0;
- bool isUSB = false;
-
- if (def->nhostdevs == 0)
- return;
+ VBOX_OBJECT_CHECK(dom->conn, int, -1);
+ IMachine *machine = NULL;
+ vboxIID iid = VBOX_IID_INITIALIZER;
+ PRUint32 state = MachineState_Null;
+ virDomainDefPtr def = NULL;
+ virDomainDeviceDefPtr dev = NULL;
+ nsresult rc;
- /* Loop through the devices first and see if you
- * have a USB Device, only if you have one then
- * start the USB controller else just proceed as
- * usual
- */
- for (i = 0; i < def->nhostdevs; i++) {
- if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
+ if (VIR_ALLOC(def) < 0)
+ return ret;
- if (def->hostdevs[i]->source.subsys.type !=
- VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
- continue;
+ if (VIR_STRDUP(def->os.type, "hvm") < 0)
+ goto cleanup;
- if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
- !def->hostdevs[i]->source.subsys.u.usb.product)
- continue;
+ dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
+ VIR_DOMAIN_XML_INACTIVE);
+ if (dev == NULL)
+ goto cleanup;
- VIR_DEBUG("USB Device detected, VendorId:0x%x, ProductId:0x%x",
- def->hostdevs[i]->source.subsys.u.usb.vendor,
- def->hostdevs[i]->source.subsys.u.usb.product);
- isUSB = true;
- break;
+ vboxIIDFromUUID(&iid, dom->uuid);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ goto cleanup;
}
- if (!isUSB)
- return;
-
-#if VBOX_API_VERSION < 4003000
- /* First Start the USB Controller and then loop
- * to attach USB Devices to it
- */
- machine->vtbl->GetUSBController(machine, &USBController);
-
- if (!USBController)
- return;
+ if (machine) {
+ machine->vtbl->GetState(machine, &state);
- USBController->vtbl->SetEnabled(USBController, 1);
-# if VBOX_API_VERSION < 4002000
- USBController->vtbl->SetEnabledEhci(USBController, 1);
-# else
- USBController->vtbl->SetEnabledEHCI(USBController, 1);
-# endif
-#else
- machine->vtbl->GetUSBDeviceFilters(machine, &USBDeviceFilters);
+ if ((state == MachineState_Running) ||
+ (state == MachineState_Paused)) {
+ rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
+ } else {
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
+ }
- if (!USBDeviceFilters)
- return;
-#endif
+ if (NS_SUCCEEDED(rc)) {
+ rc = data->vboxSession->vtbl->GetMachine(data->vboxSession,
&machine);
+ if (NS_SUCCEEDED(rc) && machine) {
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+#if VBOX_API_VERSION < 3001000
+ int type = virDomainDiskGetType(dev->data.disk);
- for (i = 0; i < def->nhostdevs; i++) {
- char *filtername = NULL;
- PRUnichar *filternameUtf16 = NULL;
- IUSBDeviceFilter *filter = NULL;
- PRUnichar *vendorIdUtf16 = NULL;
- char vendorId[40] = {0};
- PRUnichar *productIdUtf16 = NULL;
- char productId[40] = {0};
-
- if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- continue;
+ if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+ if (type == VIR_STORAGE_TYPE_FILE) {
+ IDVDDrive *dvdDrive = NULL;
+ /* Currently CDROM/DVD Drive is always IDE
+ * Secondary Master so neglecting the following
+ * parameter dev->data.disk->bus
+ */
+ machine->vtbl->GetDVDDrive(machine, &dvdDrive);
+ if (dvdDrive) {
+ rc = dvdDrive->vtbl->Unmount(dvdDrive);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not de-attach the
mounted ISO, rc=%08x"),
+ (unsigned)rc);
+ } else {
+ ret = 0;
+ }
+ VBOX_RELEASE(dvdDrive);
+ }
+ } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+ }
+ } else if (dev->data.disk->device ==
VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+ if (type == VIR_STORAGE_TYPE_FILE) {
+ IFloppyDrive *floppyDrive;
+ machine->vtbl->GetFloppyDrive(machine,
&floppyDrive);
+ if (floppyDrive) {
+ PRBool enabled = PR_FALSE;
- if (def->hostdevs[i]->source.subsys.type !=
- VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
- continue;
+ floppyDrive->vtbl->GetEnabled(floppyDrive,
&enabled);
+ if (enabled) {
+ rc = floppyDrive->vtbl->Unmount(floppyDrive);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not attach the file
"
+ "to floppy drive,
rc=%08x"),
+ (unsigned)rc);
+ } else {
+ ret = 0;
+ }
+ } else {
+ /* If you are here means floppy drive is already
unmounted
+ * so don't flag error, just say everything is
fine and quit
+ */
+ ret = 0;
+ }
+ VBOX_RELEASE(floppyDrive);
+ }
+ } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+ }
+ }
+#else /* VBOX_API_VERSION >= 3001000 */
+#endif /* VBOX_API_VERSION >= 3001000 */
+ } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+ if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
{
+ if (dev->data.hostdev->source.subsys.type ==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+ }
+ }
+ } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
+ dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
+ PRUnichar *nameUtf16;
- /* Zero pad for nice alignment when fewer than 9999
- * devices.
- */
- if (virAsprintf(&filtername, "filter%04zu", i) >= 0) {
- VBOX_UTF8_TO_UTF16(filtername, &filternameUtf16);
- VIR_FREE(filtername);
-#if VBOX_API_VERSION < 4003000
- USBController->vtbl->CreateDeviceFilter(USBController,
- filternameUtf16,
- &filter);
-#else
- USBDeviceFilters->vtbl->CreateDeviceFilter(USBDeviceFilters,
- filternameUtf16,
- &filter);
-#endif
- }
- VBOX_UTF16_FREE(filternameUtf16);
+ VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
- if (!filter)
- continue;
+ rc = machine->vtbl->RemoveSharedFolder(machine, nameUtf16);
- if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
- !def->hostdevs[i]->source.subsys.u.usb.product)
- continue;
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not detach shared folder
'%s', rc=%08x"),
+ dev->data.fs->dst, (unsigned)rc);
+ } else {
+ ret = 0;
+ }
- if (def->hostdevs[i]->source.subsys.u.usb.vendor) {
- snprintf(vendorId, sizeof(vendorId), "%x",
- def->hostdevs[i]->source.subsys.u.usb.vendor);
- VBOX_UTF8_TO_UTF16(vendorId, &vendorIdUtf16);
- filter->vtbl->SetVendorId(filter, vendorIdUtf16);
- VBOX_UTF16_FREE(vendorIdUtf16);
- }
- if (def->hostdevs[i]->source.subsys.u.usb.product) {
- snprintf(productId, sizeof(productId), "%x",
- def->hostdevs[i]->source.subsys.u.usb.product);
- VBOX_UTF8_TO_UTF16(productId, &productIdUtf16);
- filter->vtbl->SetProductId(filter,
- productIdUtf16);
- VBOX_UTF16_FREE(productIdUtf16);
- }
- filter->vtbl->SetActive(filter, 1);
-#if VBOX_API_VERSION < 4003000
- USBController->vtbl->InsertDeviceFilter(USBController,
- i,
- filter);
-#else
- USBDeviceFilters->vtbl->InsertDeviceFilter(USBDeviceFilters,
- i,
- filter);
-#endif
- VBOX_RELEASE(filter);
+ VBOX_UTF16_FREE(nameUtf16);
+ }
+ machine->vtbl->SaveSettings(machine);
+ VBOX_RELEASE(machine);
+ }
+ VBOX_SESSION_CLOSE();
+ }
}
-#if VBOX_API_VERSION < 4003000
- VBOX_RELEASE(USBController);
-#else
- VBOX_RELEASE(USBDeviceFilters);
-#endif
+ cleanup:
+ vboxIIDUnalloc(&iid);
+ virDomainDefFree(def);
+ virDomainDeviceDefFree(dev);
+ return ret;
}
-static void
-vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+static int
+vboxDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
+ unsigned int flags)
{
- size_t i;
- PRUnichar *nameUtf16;
- PRUnichar *hostPathUtf16;
- PRBool writable;
-
- if (def->nfss == 0)
- return;
-
- for (i = 0; i < def->nfss; i++) {
- if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
- continue;
-
- VBOX_UTF8_TO_UTF16(def->fss[i]->dst, &nameUtf16);
- VBOX_UTF8_TO_UTF16(def->fss[i]->src, &hostPathUtf16);
- writable = !def->fss[i]->readonly;
-
-#if VBOX_API_VERSION < 4000000
- machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
- writable);
-#else /* VBOX_API_VERSION >= 4000000 */
- machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
- writable, PR_FALSE);
-#endif /* VBOX_API_VERSION >= 4000000 */
+ virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
- VBOX_UTF16_FREE(nameUtf16);
- VBOX_UTF16_FREE(hostPathUtf16);
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot modify the persistent configuration of a
domain"));
+ return -1;
}
+
+ return vboxDomainDetachDevice(dom, xml);
}
-static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml)
+static int
+vboxDomainSnapshotGetAll(virDomainPtr dom,
+ IMachine *machine,
+ ISnapshot ***snapshots)
{
- VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
- IMachine *machine = NULL;
- IBIOSSettings *bios = NULL;
- vboxIID iid = VBOX_IID_INITIALIZER;
- vboxIID mchiid = VBOX_IID_INITIALIZER;
- virDomainDefPtr def = NULL;
- PRUnichar *machineNameUtf16 = NULL;
-#if VBOX_API_VERSION >= 3002000 && VBOX_API_VERSION < 4002000
- PRBool override = PR_FALSE;
-#endif
+ vboxIID empty = VBOX_IID_INITIALIZER;
+ ISnapshot **list = NULL;
+ PRUint32 count;
nsresult rc;
- char uuidstr[VIR_UUID_STRING_BUFLEN];
-#if VBOX_API_VERSION >= 4002000
- const char *flagsUUIDPrefix = "UUID=";
- const char *flagsForceOverwrite = "forceOverwrite=0";
- const char *flagsSeparator = ",";
- char createFlags[strlen(flagsUUIDPrefix) + VIR_UUID_STRING_BUFLEN +
strlen(flagsSeparator) + strlen(flagsForceOverwrite) + 1];
- PRUnichar *createFlagsUtf16 = NULL;
-#endif
-
- if (!(def = virDomainDefParseString(xml, data->caps, data->xmlopt,
- 1 << VIR_DOMAIN_VIRT_VBOX,
- VIR_DOMAIN_XML_INACTIVE))) {
- goto cleanup;
- }
-
- VBOX_UTF8_TO_UTF16(def->name, &machineNameUtf16);
- vboxIIDFromUUID(&iid, def->uuid);
- virUUIDFormat(def->uuid, uuidstr);
-
-#if VBOX_API_VERSION < 3002000
- rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
- machineNameUtf16,
- NULL,
- NULL,
- iid.value,
- &machine);
-#elif VBOX_API_VERSION < 4000000 /* 3002000 <= VBOX_API_VERSION < 4000000 */
- rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
- machineNameUtf16,
- NULL,
- NULL,
- iid.value,
- override,
- &machine);
-#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
- NULL,
- machineNameUtf16,
- NULL,
- iid.value,
- override,
- &machine);
-#else /* VBOX_API_VERSION >= 4002000 */
- snprintf(createFlags, sizeof(createFlags), "%s%s%s%s",
- flagsUUIDPrefix,
- uuidstr,
- flagsSeparator,
- flagsForceOverwrite
- );
- VBOX_UTF8_TO_UTF16(createFlags, &createFlagsUtf16);
- rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
- NULL,
- machineNameUtf16,
- 0,
- nsnull,
- nsnull,
- createFlagsUtf16,
- &machine);
-#endif /* VBOX_API_VERSION >= 4002000 */
- VBOX_UTF16_FREE(machineNameUtf16);
+ unsigned int next;
+ unsigned int top;
+ rc = machine->vtbl->GetSnapshotCount(machine, &count);
if (NS_FAILED(rc)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not define a domain, rc=%08x"), (unsigned)rc);
- goto cleanup;
+ _("could not get snapshot count for domain %s"),
+ dom->name);
+ goto error;
}
- rc = machine->vtbl->SetMemorySize(machine,
- VIR_DIV_UP(def->mem.cur_balloon, 1024));
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not set the memory size of the domain to: %llu Kb,
"
- "rc=%08x"),
- def->mem.cur_balloon, (unsigned)rc);
- }
+ if (count == 0)
+ goto out;
- if (def->vcpus != def->maxvcpus) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("current vcpu count must equal maximum"));
- }
- rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not set the number of virtual CPUs to: %u,
rc=%08x"),
- def->maxvcpus, (unsigned)rc);
- }
+ if (VIR_ALLOC_N(list, count) < 0)
+ goto error;
-#if VBOX_API_VERSION < 3001000
- rc = machine->vtbl->SetPAEEnabled(machine,
- def->features[VIR_DOMAIN_FEATURE_PAE] ==
- VIR_TRISTATE_SWITCH_ON);
-#elif VBOX_API_VERSION == 3001000
- rc = machine->vtbl->SetCpuProperty(machine, CpuPropertyType_PAE,
- def->features[VIR_DOMAIN_FEATURE_PAE] ==
- VIR_TRISTATE_SWITCH_ON);
-#elif VBOX_API_VERSION >= 3002000
- rc = machine->vtbl->SetCPUProperty(machine, CPUPropertyType_PAE,
- def->features[VIR_DOMAIN_FEATURE_PAE] ==
- VIR_TRISTATE_SWITCH_ON);
-#endif
- if (NS_FAILED(rc)) {
+#if VBOX_API_VERSION < 4000000
+ rc = machine->vtbl->GetSnapshot(machine, empty.value, list);
+#else /* VBOX_API_VERSION >= 4000000 */
+ rc = machine->vtbl->FindSnapshot(machine, empty.value, list);
+#endif /* VBOX_API_VERSION >= 4000000 */
+ if (NS_FAILED(rc) || !list[0]) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not change PAE status to: %s, rc=%08x"),
- (def->features[VIR_DOMAIN_FEATURE_PAE] ==
VIR_TRISTATE_SWITCH_ON)
- ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ _("could not get root snapshot for domain %s"),
+ dom->name);
+ goto error;
}
- machine->vtbl->GetBIOSSettings(machine, &bios);
- if (bios) {
- rc = bios->vtbl->SetACPIEnabled(bios,
- def->features[VIR_DOMAIN_FEATURE_ACPI] ==
- VIR_TRISTATE_SWITCH_ON);
- if (NS_FAILED(rc)) {
+ /* BFS walk through snapshot tree */
+ top = 1;
+ for (next = 0; next < count; next++) {
+ vboxArray children = VBOX_ARRAY_INITIALIZER;
+ size_t i;
+
+ if (!list[next]) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not change ACPI status to: %s, rc=%08x"),
- (def->features[VIR_DOMAIN_FEATURE_ACPI] ==
VIR_TRISTATE_SWITCH_ON)
- ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ _("unexpected number of snapshots < %u"),
count);
+ goto error;
}
- rc = bios->vtbl->SetIOAPICEnabled(bios,
- def->features[VIR_DOMAIN_FEATURE_APIC] ==
- VIR_TRISTATE_SWITCH_ON);
+
+ rc = vboxArrayGet(&children, list[next],
+ list[next]->vtbl->GetChildren);
if (NS_FAILED(rc)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not change APIC status to: %s, rc=%08x"),
- (def->features[VIR_DOMAIN_FEATURE_APIC] ==
VIR_TRISTATE_SWITCH_ON)
- ? _("Enabled") : _("Disabled"),
(unsigned)rc);
+ "%s", _("could not get children
snapshots"));
+ goto error;
}
- VBOX_RELEASE(bios);
- }
-
- /* Register the machine before attaching other devices to it */
- rc = data->vboxObj->vtbl->RegisterMachine(data->vboxObj, machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not define a domain, rc=%08x"), (unsigned)rc);
- goto cleanup;
+ for (i = 0; i < children.count; i++) {
+ ISnapshot *child = children.items[i];
+ if (!child)
+ continue;
+ if (top == count) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected number of snapshots > %u"),
count);
+ vboxArrayRelease(&children);
+ goto error;
+ }
+ VBOX_ADDREF(child);
+ list[top++] = child;
+ }
+ vboxArrayRelease(&children);
}
- /* Get the uuid of the machine, currently it is immutable
- * object so open a session to it and get it back, so that
- * you can make changes to the machine setting
- */
- machine->vtbl->GetId(machine, &mchiid.value);
- VBOX_SESSION_OPEN(mchiid.value, machine);
- data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
-
- vboxSetBootDeviceOrder(def, data, machine);
- vboxAttachDrives(def, data, machine);
- vboxAttachSound(def, machine);
- vboxAttachNetwork(def, data, machine);
- vboxAttachSerial(def, data, machine);
- vboxAttachParallel(def, data, machine);
- vboxAttachVideo(def, machine);
- vboxAttachDisplay(def, data, machine);
- vboxAttachUSB(def, data, machine);
- vboxAttachSharedFolder(def, data, machine);
-
- /* Save the machine settings made till now and close the
- * session. also free up the mchiid variable used.
- */
- rc = machine->vtbl->SaveSettings(machine);
- VBOX_SESSION_CLOSE();
- vboxIIDUnalloc(&mchiid);
-
- ret = virGetDomain(conn, def->name, def->uuid);
- VBOX_RELEASE(machine);
-
- vboxIIDUnalloc(&iid);
- virDomainDefFree(def);
+ out:
+ *snapshots = list;
+ return count;
- return ret;
+ error:
+ if (list) {
+ for (next = 0; next < count; next++)
+ VBOX_RELEASE(list[next]);
+ }
+ VIR_FREE(list);
- cleanup:
- VBOX_RELEASE(machine);
- vboxIIDUnalloc(&iid);
- virDomainDefFree(def);
- return NULL;
+ return -1;
}
-static int
-vboxDomainUndefine(virDomainPtr dom)
+static ISnapshot *
+vboxDomainSnapshotGet(vboxGlobalData *data,
+ virDomainPtr dom,
+ IMachine *machine,
+ const char *name)
{
- return vboxDomainUndefineFlags(dom, 0);
-}
-
-static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
- const char *xml,
- int mediaChangeOnly ATTRIBUTE_UNUSED)
-{
- VBOX_OBJECT_CHECK(dom->conn, int, -1);
- IMachine *machine = NULL;
- vboxIID iid = VBOX_IID_INITIALIZER;
- PRUint32 state = MachineState_Null;
- virDomainDefPtr def = NULL;
- virDomainDeviceDefPtr dev = NULL;
- nsresult rc;
-
- if (VIR_ALLOC(def) < 0)
- return ret;
-
- if (VIR_STRDUP(def->os.type, "hvm") < 0)
- goto cleanup;
-
- dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
- VIR_DOMAIN_XML_INACTIVE);
- if (dev == NULL)
- goto cleanup;
-
- vboxIIDFromUUID(&iid, dom->uuid);
- rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- goto cleanup;
- }
-
- if (machine) {
- machine->vtbl->GetState(machine, &state);
-
- if ((state == MachineState_Running) ||
- (state == MachineState_Paused)) {
- rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
- } else {
- rc = VBOX_SESSION_OPEN(iid.value, machine);
- }
- if (NS_SUCCEEDED(rc)) {
- rc = data->vboxSession->vtbl->GetMachine(data->vboxSession,
&machine);
- if (NS_SUCCEEDED(rc) && machine) {
- if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
-#if VBOX_API_VERSION < 3001000
- const char *src = virDomainDiskGetSource(dev->data.disk);
- int type = virDomainDiskGetType(dev->data.disk);
-
- if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
- if (type == VIR_STORAGE_TYPE_FILE && src) {
- IDVDDrive *dvdDrive = NULL;
- /* Currently CDROM/DVD Drive is always IDE
- * Secondary Master so neglecting the following
- * parameter dev->data.disk->bus
- */
- machine->vtbl->GetDVDDrive(machine, &dvdDrive);
- if (dvdDrive) {
- IDVDImage *dvdImage = NULL;
- PRUnichar *dvdfileUtf16 = NULL;
- vboxIID dvduuid = VBOX_IID_INITIALIZER;
- vboxIID dvdemptyuuid = VBOX_IID_INITIALIZER;
-
- VBOX_UTF8_TO_UTF16(src, &dvdfileUtf16);
-
-
data->vboxObj->vtbl->FindDVDImage(data->vboxObj, dvdfileUtf16,
&dvdImage);
- if (!dvdImage) {
-
data->vboxObj->vtbl->OpenDVDImage(data->vboxObj, dvdfileUtf16,
dvdemptyuuid.value, &dvdImage);
- }
- if (dvdImage) {
- rc = dvdImage->vtbl->imedium.GetId((IMedium
*)dvdImage, &dvduuid.value);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("can't get the uuid of
the file to "
- "be attached to cdrom: %s,
rc=%08x"),
- src, (unsigned)rc);
- } else {
- /* unmount the previous mounted image */
- dvdDrive->vtbl->Unmount(dvdDrive);
- rc = dvdDrive->vtbl->MountImage(dvdDrive,
dvduuid.value);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not attach the
file to cdrom: %s, rc=%08x"),
- src, (unsigned)rc);
- } else {
- ret = 0;
- DEBUGIID("CD/DVD Image UUID:",
dvduuid.value);
- }
- }
-
- VBOX_MEDIUM_RELEASE(dvdImage);
- }
- vboxIIDUnalloc(&dvduuid);
- VBOX_UTF16_FREE(dvdfileUtf16);
- VBOX_RELEASE(dvdDrive);
- }
- } else if (type == VIR_STORAGE_TYPE_BLOCK) {
- }
- } else if (dev->data.disk->device ==
VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
- if (type == VIR_STORAGE_TYPE_FILE && src) {
- IFloppyDrive *floppyDrive;
- machine->vtbl->GetFloppyDrive(machine,
&floppyDrive);
- if (floppyDrive) {
- rc = floppyDrive->vtbl->SetEnabled(floppyDrive,
1);
- if (NS_SUCCEEDED(rc)) {
- IFloppyImage *floppyImage = NULL;
- PRUnichar *fdfileUtf16 = NULL;
- vboxIID fduuid = VBOX_IID_INITIALIZER;
- vboxIID fdemptyuuid = VBOX_IID_INITIALIZER;
- VBOX_UTF8_TO_UTF16(src, &fdfileUtf16);
- rc =
data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
-
fdfileUtf16,
-
&floppyImage);
-
- if (!floppyImage) {
-
data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
-
fdfileUtf16,
-
fdemptyuuid.value,
-
&floppyImage);
- }
-
- if (floppyImage) {
- rc =
floppyImage->vtbl->imedium.GetId((IMedium *)floppyImage, &fduuid.value);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("can't get the uuid
of the file to be "
- "attached to floppy
drive: %s, rc=%08x"),
- src, (unsigned)rc);
- } else {
- rc =
floppyDrive->vtbl->MountImage(floppyDrive, fduuid.value);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not attach
the file to floppy drive: %s, rc=%08x"),
- src, (unsigned)rc);
- } else {
- ret = 0;
- DEBUGIID("attached floppy,
UUID:", fduuid.value);
- }
- }
- VBOX_MEDIUM_RELEASE(floppyImage);
- }
- vboxIIDUnalloc(&fduuid);
- VBOX_UTF16_FREE(fdfileUtf16);
- }
- VBOX_RELEASE(floppyDrive);
- }
- } else if (type == VIR_STORAGE_TYPE_BLOCK) {
- }
- }
-#else /* VBOX_API_VERSION >= 3001000 */
-#endif /* VBOX_API_VERSION >= 3001000 */
- } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
- } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
- if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
{
- if (dev->data.hostdev->source.subsys.type ==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
- }
- }
- } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
- dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
- PRUnichar *nameUtf16;
- PRUnichar *hostPathUtf16;
- PRBool writable;
-
- VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
- VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16);
- writable = !dev->data.fs->readonly;
-
-#if VBOX_API_VERSION < 4000000
- rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16,
hostPathUtf16,
- writable);
-#else /* VBOX_API_VERSION >= 4000000 */
- rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16,
hostPathUtf16,
- writable, PR_FALSE);
-#endif /* VBOX_API_VERSION >= 4000000 */
-
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not attach shared folder
'%s', rc=%08x"),
- dev->data.fs->dst, (unsigned)rc);
- } else {
- ret = 0;
- }
-
- VBOX_UTF16_FREE(nameUtf16);
- VBOX_UTF16_FREE(hostPathUtf16);
- }
- machine->vtbl->SaveSettings(machine);
- VBOX_RELEASE(machine);
- }
- VBOX_SESSION_CLOSE();
- }
- }
-
- cleanup:
- vboxIIDUnalloc(&iid);
- virDomainDefFree(def);
- virDomainDeviceDefFree(dev);
- return ret;
-}
-
-static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml)
-{
- return vboxDomainAttachDeviceImpl(dom, xml, 0);
-}
-
-static int
-vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
- unsigned int flags)
-{
- virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
-
- if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot modify the persistent configuration of a
domain"));
- return -1;
- }
-
- return vboxDomainAttachDeviceImpl(dom, xml, 0);
-}
-
-static int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
- unsigned int flags)
-{
- virCheckFlags(VIR_DOMAIN_AFFECT_CURRENT |
- VIR_DOMAIN_AFFECT_LIVE |
- VIR_DOMAIN_AFFECT_CONFIG, -1);
-
- if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot modify the persistent configuration of a
domain"));
- return -1;
- }
-
- return vboxDomainAttachDeviceImpl(dom, xml, 1);
-}
-
-static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml)
-{
- VBOX_OBJECT_CHECK(dom->conn, int, -1);
- IMachine *machine = NULL;
- vboxIID iid = VBOX_IID_INITIALIZER;
- PRUint32 state = MachineState_Null;
- virDomainDefPtr def = NULL;
- virDomainDeviceDefPtr dev = NULL;
- nsresult rc;
-
- if (VIR_ALLOC(def) < 0)
- return ret;
-
- if (VIR_STRDUP(def->os.type, "hvm") < 0)
- goto cleanup;
-
- dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
- VIR_DOMAIN_XML_INACTIVE);
- if (dev == NULL)
- goto cleanup;
-
- vboxIIDFromUUID(&iid, dom->uuid);
- rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- goto cleanup;
- }
-
- if (machine) {
- machine->vtbl->GetState(machine, &state);
-
- if ((state == MachineState_Running) ||
- (state == MachineState_Paused)) {
- rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
- } else {
- rc = VBOX_SESSION_OPEN(iid.value, machine);
- }
-
- if (NS_SUCCEEDED(rc)) {
- rc = data->vboxSession->vtbl->GetMachine(data->vboxSession,
&machine);
- if (NS_SUCCEEDED(rc) && machine) {
- if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
-#if VBOX_API_VERSION < 3001000
- int type = virDomainDiskGetType(dev->data.disk);
-
- if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
- if (type == VIR_STORAGE_TYPE_FILE) {
- IDVDDrive *dvdDrive = NULL;
- /* Currently CDROM/DVD Drive is always IDE
- * Secondary Master so neglecting the following
- * parameter dev->data.disk->bus
- */
- machine->vtbl->GetDVDDrive(machine, &dvdDrive);
- if (dvdDrive) {
- rc = dvdDrive->vtbl->Unmount(dvdDrive);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not de-attach the
mounted ISO, rc=%08x"),
- (unsigned)rc);
- } else {
- ret = 0;
- }
- VBOX_RELEASE(dvdDrive);
- }
- } else if (type == VIR_STORAGE_TYPE_BLOCK) {
- }
- } else if (dev->data.disk->device ==
VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
- if (type == VIR_STORAGE_TYPE_FILE) {
- IFloppyDrive *floppyDrive;
- machine->vtbl->GetFloppyDrive(machine,
&floppyDrive);
- if (floppyDrive) {
- PRBool enabled = PR_FALSE;
-
- floppyDrive->vtbl->GetEnabled(floppyDrive,
&enabled);
- if (enabled) {
- rc = floppyDrive->vtbl->Unmount(floppyDrive);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not attach the file
"
- "to floppy drive,
rc=%08x"),
- (unsigned)rc);
- } else {
- ret = 0;
- }
- } else {
- /* If you are here means floppy drive is already
unmounted
- * so don't flag error, just say everything is
fine and quit
- */
- ret = 0;
- }
- VBOX_RELEASE(floppyDrive);
- }
- } else if (type == VIR_STORAGE_TYPE_BLOCK) {
- }
- }
-#else /* VBOX_API_VERSION >= 3001000 */
-#endif /* VBOX_API_VERSION >= 3001000 */
- } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
- } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
- if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
{
- if (dev->data.hostdev->source.subsys.type ==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
- }
- }
- } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
- dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
- PRUnichar *nameUtf16;
-
- VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
-
- rc = machine->vtbl->RemoveSharedFolder(machine, nameUtf16);
-
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not detach shared folder
'%s', rc=%08x"),
- dev->data.fs->dst, (unsigned)rc);
- } else {
- ret = 0;
- }
-
- VBOX_UTF16_FREE(nameUtf16);
- }
- machine->vtbl->SaveSettings(machine);
- VBOX_RELEASE(machine);
- }
- VBOX_SESSION_CLOSE();
- }
- }
-
- cleanup:
- vboxIIDUnalloc(&iid);
- virDomainDefFree(def);
- virDomainDeviceDefFree(dev);
- return ret;
-}
-
-static int
-vboxDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
- unsigned int flags)
-{
- virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
-
- if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot modify the persistent configuration of a
domain"));
- return -1;
- }
-
- return vboxDomainDetachDevice(dom, xml);
-}
-
-static int
-vboxDomainSnapshotGetAll(virDomainPtr dom,
- IMachine *machine,
- ISnapshot ***snapshots)
-{
- vboxIID empty = VBOX_IID_INITIALIZER;
- ISnapshot **list = NULL;
- PRUint32 count;
- nsresult rc;
- unsigned int next;
- unsigned int top;
-
- rc = machine->vtbl->GetSnapshotCount(machine, &count);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not get snapshot count for domain %s"),
- dom->name);
- goto error;
- }
-
- if (count == 0)
- goto out;
-
- if (VIR_ALLOC_N(list, count) < 0)
- goto error;
-
-#if VBOX_API_VERSION < 4000000
- rc = machine->vtbl->GetSnapshot(machine, empty.value, list);
-#else /* VBOX_API_VERSION >= 4000000 */
- rc = machine->vtbl->FindSnapshot(machine, empty.value, list);
-#endif /* VBOX_API_VERSION >= 4000000 */
- if (NS_FAILED(rc) || !list[0]) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not get root snapshot for domain %s"),
- dom->name);
- goto error;
- }
-
- /* BFS walk through snapshot tree */
- top = 1;
- for (next = 0; next < count; next++) {
- vboxArray children = VBOX_ARRAY_INITIALIZER;
- size_t i;
-
- if (!list[next]) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected number of snapshots < %u"),
count);
- goto error;
- }
-
- rc = vboxArrayGet(&children, list[next],
- list[next]->vtbl->GetChildren);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("could not get children
snapshots"));
- goto error;
- }
- for (i = 0; i < children.count; i++) {
- ISnapshot *child = children.items[i];
- if (!child)
- continue;
- if (top == count) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected number of snapshots > %u"),
count);
- vboxArrayRelease(&children);
- goto error;
- }
- VBOX_ADDREF(child);
- list[top++] = child;
- }
- vboxArrayRelease(&children);
- }
-
- out:
- *snapshots = list;
- return count;
-
- error:
- if (list) {
- for (next = 0; next < count; next++)
- VBOX_RELEASE(list[next]);
- }
- VIR_FREE(list);
-
- return -1;
-}
-
-static ISnapshot *
-vboxDomainSnapshotGet(vboxGlobalData *data,
- virDomainPtr dom,
- IMachine *machine,
- const char *name)
-{
- ISnapshot **snapshots = NULL;
- ISnapshot *snapshot = NULL;
- nsresult rc;
- int count = 0;
- size_t i;
+ ISnapshot **snapshots = NULL;
+ ISnapshot *snapshot = NULL;
+ nsresult rc;
+ int count = 0;
+ size_t i;
if ((count = vboxDomainSnapshotGetAll(dom, machine, &snapshots)) < 0)
goto cleanup;
@@ -9801,22 +8820,265 @@ vboxStorageVolLookupByName(virStoragePoolPtr pool, const char
*name)
return ret;
}
-static virStorageVolPtr
-vboxStorageVolLookupByKey(virConnectPtr conn, const char *key)
+static virStorageVolPtr
+vboxStorageVolLookupByKey(virConnectPtr conn, const char *key)
+{
+ VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ IHardDisk *hardDisk = NULL;
+ nsresult rc;
+
+ if (!key)
+ return ret;
+
+ if (virUUIDParse(key, uuid) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("Could not parse UUID from '%s'"), key);
+ return NULL;
+ }
+
+ vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000000
+ rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
+#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#else
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, AccessMode_ReadWrite,
+ PR_FALSE, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000000 */
+ if (NS_SUCCEEDED(rc)) {
+ PRUint32 hddstate;
+
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
+ if (hddstate != MediaState_Inaccessible) {
+ PRUnichar *hddNameUtf16 = NULL;
+ char *hddNameUtf8 = NULL;
+
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
+ VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
+
+ if (hddNameUtf8) {
+ if (vboxConnectNumOfStoragePools(conn) == 1) {
+ ret = virGetStorageVol(conn, "default-pool", hddNameUtf8,
key,
+ NULL, NULL);
+ VIR_DEBUG("Storage Volume Pool: %s",
"default-pool");
+ } else {
+ /* TODO: currently only one default pool and thus
+ * nothing here, change it when pools are supported
+ */
+ }
+
+ VIR_DEBUG("Storage Volume Name: %s", key);
+ VIR_DEBUG("Storage Volume key : %s", hddNameUtf8);
+
+ VBOX_UTF8_FREE(hddNameUtf8);
+ VBOX_UTF16_FREE(hddNameUtf16);
+ }
+ }
+
+ VBOX_MEDIUM_RELEASE(hardDisk);
+ }
+
+ vboxIIDUnalloc(&hddIID);
+ return ret;
+}
+
+static virStorageVolPtr
+vboxStorageVolLookupByPath(virConnectPtr conn, const char *path)
+{
+ VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
+ PRUnichar *hddPathUtf16 = NULL;
+ IHardDisk *hardDisk = NULL;
+ nsresult rc;
+
+ if (!path)
+ return ret;
+
+ VBOX_UTF8_TO_UTF16(path, &hddPathUtf16);
+
+ if (!hddPathUtf16)
+ return ret;
+
+#if VBOX_API_VERSION < 4000000
+ rc = data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddPathUtf16,
&hardDisk);
+#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddPathUtf16,
+ DeviceType_HardDisk, &hardDisk);
+#else
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddPathUtf16,
+ DeviceType_HardDisk, AccessMode_ReadWrite,
+ PR_FALSE, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000000 */
+ if (NS_SUCCEEDED(rc)) {
+ PRUint32 hddstate;
+
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
+ if (hddstate != MediaState_Inaccessible) {
+ PRUnichar *hddNameUtf16 = NULL;
+ char *hddNameUtf8 = NULL;
+
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
+
+ if (hddNameUtf16) {
+ VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
+ VBOX_UTF16_FREE(hddNameUtf16);
+ }
+
+ if (hddNameUtf8) {
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ char key[VIR_UUID_STRING_BUFLEN] = "";
+
+ rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
+ if (NS_SUCCEEDED(rc)) {
+ vboxIIDToUUID(&hddIID, uuid);
+ virUUIDFormat(uuid, key);
+
+ /* TODO: currently only one default pool and thus
+ * the check below, change it when pools are supported
+ */
+ if (vboxConnectNumOfStoragePools(conn) == 1)
+ ret = virGetStorageVol(conn, "default-pool",
hddNameUtf8, key,
+ NULL, NULL);
+
+ VIR_DEBUG("Storage Volume Pool: %s",
"default-pool");
+ VIR_DEBUG("Storage Volume Name: %s", hddNameUtf8);
+ VIR_DEBUG("Storage Volume key : %s", key);
+ }
+
+ vboxIIDUnalloc(&hddIID);
+ }
+
+ VBOX_UTF8_FREE(hddNameUtf8);
+ }
+
+ VBOX_MEDIUM_RELEASE(hardDisk);
+ }
+
+ VBOX_UTF16_FREE(hddPathUtf16);
+
+ return ret;
+}
+
+static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool,
+ const char *xml,
+ unsigned int flags)
+{
+ VBOX_OBJECT_CHECK(pool->conn, virStorageVolPtr, NULL);
+ virStorageVolDefPtr def = NULL;
+ PRUnichar *hddFormatUtf16 = NULL;
+ PRUnichar *hddNameUtf16 = NULL;
+ virStoragePoolDef poolDef;
+ nsresult rc;
+
+ virCheckFlags(0, NULL);
+
+ /* since there is currently one default pool now
+ * and virStorageVolDefFormat() just checks it type
+ * so just assign it for now, change the behaviour
+ * when vbox supports pools.
+ */
+ memset(&poolDef, 0, sizeof(poolDef));
+ poolDef.type = VIR_STORAGE_POOL_DIR;
+
+ if ((def = virStorageVolDefParseString(&poolDef, xml)) == NULL)
+ goto cleanup;
+
+ if (!def->name ||
+ (def->type != VIR_STORAGE_VOL_FILE))
+ goto cleanup;
+
+ /* For now only the vmdk, vpc and vdi type harddisk
+ * variants can be created. For historical reason, we default to vdi */
+ if (def->target.format == VIR_STORAGE_FILE_VMDK) {
+ VBOX_UTF8_TO_UTF16("VMDK", &hddFormatUtf16);
+ } else if (def->target.format == VIR_STORAGE_FILE_VPC) {
+ VBOX_UTF8_TO_UTF16("VHD", &hddFormatUtf16);
+ } else {
+ VBOX_UTF8_TO_UTF16("VDI", &hddFormatUtf16);
+ }
+
+ VBOX_UTF8_TO_UTF16(def->name, &hddNameUtf16);
+
+ if (hddFormatUtf16 && hddNameUtf16) {
+ IHardDisk *hardDisk = NULL;
+
+ rc = data->vboxObj->vtbl->CreateHardDisk(data->vboxObj,
hddFormatUtf16, hddNameUtf16, &hardDisk);
+ if (NS_SUCCEEDED(rc)) {
+ IProgress *progress = NULL;
+ PRUint64 logicalSize = VIR_DIV_UP(def->target.capacity,
+ 1024 * 1024);
+ PRUint32 variant = HardDiskVariant_Standard;
+
+ if (def->target.capacity == def->target.allocation)
+ variant = HardDiskVariant_Fixed;
+
+#if VBOX_API_VERSION < 4003000
+ rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, variant,
&progress);
+#else
+ rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, 1,
&variant, &progress);
+#endif
+ if (NS_SUCCEEDED(rc) && progress) {
+#if VBOX_API_VERSION == 2002000
+ nsresult resultCode;
+#else
+ PRInt32 resultCode;
+#endif
+
+ progress->vtbl->WaitForCompletion(progress, -1);
+ progress->vtbl->GetResultCode(progress, &resultCode);
+
+ if (NS_SUCCEEDED(resultCode)) {
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ char key[VIR_UUID_STRING_BUFLEN] = "";
+
+ rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
+ if (NS_SUCCEEDED(rc)) {
+ vboxIIDToUUID(&hddIID, uuid);
+ virUUIDFormat(uuid, key);
+
+ ret = virGetStorageVol(pool->conn, pool->name,
def->name, key,
+ NULL, NULL);
+ }
+
+ vboxIIDUnalloc(&hddIID);
+ }
+
+ VBOX_RELEASE(progress);
+ }
+ }
+ }
+
+ VBOX_UTF16_FREE(hddFormatUtf16);
+ VBOX_UTF16_FREE(hddNameUtf16);
+
+ cleanup:
+ virStorageVolDefFree(def);
+ return ret;
+}
+
+static int vboxStorageVolDelete(virStorageVolPtr vol,
+ unsigned int flags)
{
- VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
+ VBOX_OBJECT_CHECK(vol->conn, int, -1);
vboxIID hddIID = VBOX_IID_INITIALIZER;
unsigned char uuid[VIR_UUID_BUFLEN];
IHardDisk *hardDisk = NULL;
+ int deregister = 0;
nsresult rc;
+ size_t i = 0;
+ size_t j = 0;
- if (!key)
- return ret;
+ virCheckFlags(0, -1);
- if (virUUIDParse(key, uuid) < 0) {
+ if (virUUIDParse(vol->key, uuid) < 0) {
virReportError(VIR_ERR_INVALID_ARG,
- _("Could not parse UUID from '%s'"), key);
- return NULL;
+ _("Could not parse UUID from '%s'"),
vol->key);
+ return -1;
}
vboxIIDFromUUID(&hddIID, uuid);
@@ -9835,28 +9097,134 @@ vboxStorageVolLookupByKey(virConnectPtr conn, const char *key)
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
if (hddstate != MediaState_Inaccessible) {
- PRUnichar *hddNameUtf16 = NULL;
- char *hddNameUtf8 = NULL;
+ PRUint32 machineIdsSize = 0;
+ vboxArray machineIds = VBOX_ARRAY_INITIALIZER;
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
- VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
+#if VBOX_API_VERSION < 3001000
+ vboxArrayGet(&machineIds, hardDisk,
hardDisk->vtbl->imedium.GetMachineIds);
+#else /* VBOX_API_VERSION >= 3001000 */
+ vboxArrayGet(&machineIds, hardDisk,
hardDisk->vtbl->GetMachineIds);
+#endif /* VBOX_API_VERSION >= 3001000 */
- if (hddNameUtf8) {
- if (vboxConnectNumOfStoragePools(conn) == 1) {
- ret = virGetStorageVol(conn, "default-pool", hddNameUtf8,
key,
- NULL, NULL);
- VIR_DEBUG("Storage Volume Pool: %s",
"default-pool");
- } else {
- /* TODO: currently only one default pool and thus
- * nothing here, change it when pools are supported
- */
+#if VBOX_API_VERSION == 2002000 && defined WIN32
+ /* VirtualBox 2.2 on Windows represents IIDs as GUIDs and the
+ * machineIds array contains direct instances of the GUID struct
+ * instead of pointers to the actual struct instances. But there
+ * is no 128bit width simple item type for a SafeArray to fit a
+ * GUID in. The largest simple type it 64bit width and VirtualBox
+ * uses two of this 64bit items to represents one GUID. Therefore,
+ * we divide the size of the SafeArray by two, to compensate for
+ * this workaround in VirtualBox */
+ machineIds.count /= 2;
+#endif /* VBOX_API_VERSION >= 2002000 */
+
+ machineIdsSize = machineIds.count;
+
+ for (i = 0; i < machineIds.count; i++) {
+ IMachine *machine = NULL;
+ vboxIID machineId = VBOX_IID_INITIALIZER;
+
+ vboxIIDFromArrayItem(&machineId, &machineIds, i);
+
+#if VBOX_API_VERSION >= 4000000
+ rc = VBOX_OBJECT_GET_MACHINE(machineId.value, &machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ break;
}
+#endif
- VIR_DEBUG("Storage Volume Name: %s", key);
- VIR_DEBUG("Storage Volume key : %s", hddNameUtf8);
+ rc = VBOX_SESSION_OPEN(machineId.value, machine);
- VBOX_UTF8_FREE(hddNameUtf8);
- VBOX_UTF16_FREE(hddNameUtf16);
+ if (NS_SUCCEEDED(rc)) {
+
+ rc =
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
+ if (NS_SUCCEEDED(rc)) {
+ vboxArray hddAttachments = VBOX_ARRAY_INITIALIZER;
+
+#if VBOX_API_VERSION < 3001000
+ vboxArrayGet(&hddAttachments, machine,
+ machine->vtbl->GetHardDiskAttachments);
+#else /* VBOX_API_VERSION >= 3001000 */
+ vboxArrayGet(&hddAttachments, machine,
+ machine->vtbl->GetMediumAttachments);
+#endif /* VBOX_API_VERSION >= 3001000 */
+ for (j = 0; j < hddAttachments.count; j++) {
+ IHardDiskAttachment *hddAttachment =
hddAttachments.items[j];
+
+ if (hddAttachment) {
+ IHardDisk *hdd = NULL;
+
+#if VBOX_API_VERSION < 3001000
+ rc =
hddAttachment->vtbl->GetHardDisk(hddAttachment, &hdd);
+#else /* VBOX_API_VERSION >= 3001000 */
+ rc = hddAttachment->vtbl->GetMedium(hddAttachment,
&hdd);
+#endif /* VBOX_API_VERSION >= 3001000 */
+ if (NS_SUCCEEDED(rc) && hdd) {
+ vboxIID iid = VBOX_IID_INITIALIZER;
+
+ rc = VBOX_MEDIUM_FUNC_ARG1(hdd, GetId,
&iid.value);
+ if (NS_SUCCEEDED(rc)) {
+
+ DEBUGIID("HardDisk (to delete)
UUID", hddIID.value);
+ DEBUGIID("HardDisk (currently
processing) UUID", iid.value);
+
+ if (vboxIIDIsEqual(&hddIID, &iid)) {
+ PRUnichar *controller = NULL;
+ PRInt32 port = 0;
+ PRInt32 device = 0;
+
+ DEBUGIID("Found HardDisk to delete,
UUID", hddIID.value);
+
+
hddAttachment->vtbl->GetController(hddAttachment, &controller);
+
hddAttachment->vtbl->GetPort(hddAttachment, &port);
+
hddAttachment->vtbl->GetDevice(hddAttachment, &device);
+
+#if VBOX_API_VERSION < 3001000
+ rc =
machine->vtbl->DetachHardDisk(machine, controller, port, device);
+#else /* VBOX_API_VERSION >= 3001000 */
+ rc =
machine->vtbl->DetachDevice(machine, controller, port, device);
+#endif /* VBOX_API_VERSION >= 3001000 */
+ if (NS_SUCCEEDED(rc)) {
+ rc =
machine->vtbl->SaveSettings(machine);
+ VIR_DEBUG("saving machine
settings");
+ }
+
+ if (NS_SUCCEEDED(rc)) {
+ deregister++;
+ VIR_DEBUG("deregistering
hdd:%d", deregister);
+ }
+
+ VBOX_UTF16_FREE(controller);
+ }
+ vboxIIDUnalloc(&iid);
+ }
+ VBOX_MEDIUM_RELEASE(hdd);
+ }
+ }
+ }
+ vboxArrayRelease(&hddAttachments);
+ VBOX_RELEASE(machine);
+ }
+ VBOX_SESSION_CLOSE();
+ }
+
+ vboxIIDUnalloc(&machineId);
+ }
+
+ vboxArrayUnalloc(&machineIds);
+
+ if (machineIdsSize == 0 || machineIdsSize == deregister) {
+ IProgress *progress = NULL;
+ rc = hardDisk->vtbl->DeleteStorage(hardDisk, &progress);
+
+ if (NS_SUCCEEDED(rc) && progress) {
+ progress->vtbl->WaitForCompletion(progress, -1);
+ VBOX_RELEASE(progress);
+ DEBUGIID("HardDisk deleted, UUID", hddIID.value);
+ ret = 0;
+ }
}
}
@@ -9864,32 +9232,36 @@ vboxStorageVolLookupByKey(virConnectPtr conn, const char *key)
}
vboxIIDUnalloc(&hddIID);
+
return ret;
}
-static virStorageVolPtr
-vboxStorageVolLookupByPath(virConnectPtr conn, const char *path)
+static int
+vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info)
{
- VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
- PRUnichar *hddPathUtf16 = NULL;
- IHardDisk *hardDisk = NULL;
+ VBOX_OBJECT_CHECK(vol->conn, int, -1);
+ IHardDisk *hardDisk = NULL;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
nsresult rc;
- if (!path)
+ if (!info)
return ret;
- VBOX_UTF8_TO_UTF16(path, &hddPathUtf16);
-
- if (!hddPathUtf16)
+ if (virUUIDParse(vol->key, uuid) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("Could not parse UUID from '%s'"),
vol->key);
return ret;
+ }
+ vboxIIDFromUUID(&hddIID, uuid);
#if VBOX_API_VERSION < 4000000
- rc = data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddPathUtf16,
&hardDisk);
+ rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddPathUtf16,
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
DeviceType_HardDisk, &hardDisk);
#else
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddPathUtf16,
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
DeviceType_HardDisk, AccessMode_ReadWrite,
PR_FALSE, &hardDisk);
#endif /* VBOX_API_VERSION >= 4000000 */
@@ -9898,168 +9270,169 @@ vboxStorageVolLookupByPath(virConnectPtr conn, const char
*path)
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
if (hddstate != MediaState_Inaccessible) {
- PRUnichar *hddNameUtf16 = NULL;
- char *hddNameUtf8 = NULL;
-
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
-
- if (hddNameUtf16) {
- VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
- VBOX_UTF16_FREE(hddNameUtf16);
- }
-
- if (hddNameUtf8) {
- vboxIID hddIID = VBOX_IID_INITIALIZER;
- unsigned char uuid[VIR_UUID_BUFLEN];
- char key[VIR_UUID_STRING_BUFLEN] = "";
+#if VBOX_API_VERSION < 4000000
+ PRUint64 hddLogicalSize;
+ PRUint64 hddActualSize;
+#else /* VBOX_API_VERSION >= 4000000 */
+ PRInt64 hddLogicalSize;
+ PRInt64 hddActualSize;
+#endif /* VBOX_API_VERSION >= 4000000 */
- rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
- if (NS_SUCCEEDED(rc)) {
- vboxIIDToUUID(&hddIID, uuid);
- virUUIDFormat(uuid, key);
+ info->type = VIR_STORAGE_VOL_FILE;
- /* TODO: currently only one default pool and thus
- * the check below, change it when pools are supported
- */
- if (vboxConnectNumOfStoragePools(conn) == 1)
- ret = virGetStorageVol(conn, "default-pool",
hddNameUtf8, key,
- NULL, NULL);
+ hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
+#if VBOX_API_VERSION < 4000000
+ info->capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
+#else /* VBOX_API_VERSION >= 4000000 */
+ info->capacity = hddLogicalSize;
+#endif /* VBOX_API_VERSION >= 4000000 */
- VIR_DEBUG("Storage Volume Pool: %s",
"default-pool");
- VIR_DEBUG("Storage Volume Name: %s", hddNameUtf8);
- VIR_DEBUG("Storage Volume key : %s", key);
- }
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
+ info->allocation = hddActualSize;
- vboxIIDUnalloc(&hddIID);
- }
+ ret = 0;
- VBOX_UTF8_FREE(hddNameUtf8);
+ VIR_DEBUG("Storage Volume Name: %s", vol->name);
+ VIR_DEBUG("Storage Volume Type: %s", info->type ==
VIR_STORAGE_VOL_BLOCK ? "Block" : "File");
+ VIR_DEBUG("Storage Volume Capacity: %llu", info->capacity);
+ VIR_DEBUG("Storage Volume Allocation: %llu", info->allocation);
}
VBOX_MEDIUM_RELEASE(hardDisk);
}
- VBOX_UTF16_FREE(hddPathUtf16);
+ vboxIIDUnalloc(&hddIID);
return ret;
}
-static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool,
- const char *xml,
- unsigned int flags)
+static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
{
- VBOX_OBJECT_CHECK(pool->conn, virStorageVolPtr, NULL);
- virStorageVolDefPtr def = NULL;
- PRUnichar *hddFormatUtf16 = NULL;
- PRUnichar *hddNameUtf16 = NULL;
- virStoragePoolDef poolDef;
+ VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
+ IHardDisk *hardDisk = NULL;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
+ virStoragePoolDef pool;
+ virStorageVolDef def;
+ int defOk = 0;
nsresult rc;
virCheckFlags(0, NULL);
- /* since there is currently one default pool now
- * and virStorageVolDefFormat() just checks it type
- * so just assign it for now, change the behaviour
- * when vbox supports pools.
- */
- memset(&poolDef, 0, sizeof(poolDef));
- poolDef.type = VIR_STORAGE_POOL_DIR;
+ memset(&pool, 0, sizeof(pool));
+ memset(&def, 0, sizeof(def));
- if ((def = virStorageVolDefParseString(&poolDef, xml)) == NULL)
- goto cleanup;
+ if (virUUIDParse(vol->key, uuid) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("Could not parse UUID from '%s'"),
vol->key);
+ return ret;
+ }
- if (!def->name ||
- (def->type != VIR_STORAGE_VOL_FILE))
- goto cleanup;
+ vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000000
+ rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
+#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#else
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, AccessMode_ReadWrite,
+ PR_FALSE, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000000 */
+ if (NS_SUCCEEDED(rc)) {
+ PRUint32 hddstate;
- /* For now only the vmdk, vpc and vdi type harddisk
- * variants can be created. For historical reason, we default to vdi */
- if (def->target.format == VIR_STORAGE_FILE_VMDK) {
- VBOX_UTF8_TO_UTF16("VMDK", &hddFormatUtf16);
- } else if (def->target.format == VIR_STORAGE_FILE_VPC) {
- VBOX_UTF8_TO_UTF16("VHD", &hddFormatUtf16);
- } else {
- VBOX_UTF8_TO_UTF16("VDI", &hddFormatUtf16);
- }
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
+ if (NS_SUCCEEDED(rc) && hddstate != MediaState_Inaccessible) {
+ PRUnichar *hddFormatUtf16 = NULL;
+#if VBOX_API_VERSION < 4000000
+ PRUint64 hddLogicalSize;
+ PRUint64 hddActualSize;
+#else /* VBOX_API_VERSION >= 4000000 */
+ PRInt64 hddLogicalSize;
+ PRInt64 hddActualSize;
+#endif /* VBOX_API_VERSION >= 4000000 */
- VBOX_UTF8_TO_UTF16(def->name, &hddNameUtf16);
+ /* since there is currently one default pool now
+ * and virStorageVolDefFormat() just checks it type
+ * so just assign it for now, change the behaviour
+ * when vbox supports pools.
+ */
+ pool.type = VIR_STORAGE_POOL_DIR;
+ def.type = VIR_STORAGE_VOL_FILE;
+ defOk = 1;
- if (hddFormatUtf16 && hddNameUtf16) {
- IHardDisk *hardDisk = NULL;
+ rc = hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
+ if (NS_SUCCEEDED(rc) && defOk) {
+#if VBOX_API_VERSION < 4000000
+ def.target.capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
+#else /* VBOX_API_VERSION >= 4000000 */
+ def.target.capacity = hddLogicalSize;
+#endif /* VBOX_API_VERSION >= 4000000 */
+ } else
+ defOk = 0;
- rc = data->vboxObj->vtbl->CreateHardDisk(data->vboxObj,
hddFormatUtf16, hddNameUtf16, &hardDisk);
- if (NS_SUCCEEDED(rc)) {
- IProgress *progress = NULL;
- PRUint64 logicalSize = VIR_DIV_UP(def->target.capacity,
- 1024 * 1024);
- PRUint32 variant = HardDiskVariant_Standard;
+ rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
+ if (NS_SUCCEEDED(rc) && defOk)
+ def.target.allocation = hddActualSize;
+ else
+ defOk = 0;
- if (def->target.capacity == def->target.allocation)
- variant = HardDiskVariant_Fixed;
+ if (VIR_STRDUP(def.name, vol->name) < 0)
+ defOk = 0;
-#if VBOX_API_VERSION < 4003000
- rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, variant,
&progress);
-#else
- rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, 1,
&variant, &progress);
-#endif
- if (NS_SUCCEEDED(rc) && progress) {
-#if VBOX_API_VERSION == 2002000
- nsresult resultCode;
-#else
- PRInt32 resultCode;
-#endif
+ if (VIR_STRDUP(def.key, vol->key) < 0)
+ defOk = 0;
- progress->vtbl->WaitForCompletion(progress, -1);
- progress->vtbl->GetResultCode(progress, &resultCode);
+ rc = hardDisk->vtbl->GetFormat(hardDisk, &hddFormatUtf16);
+ if (NS_SUCCEEDED(rc) && defOk) {
+ char *hddFormatUtf8 = NULL;
- if (NS_SUCCEEDED(resultCode)) {
- vboxIID hddIID = VBOX_IID_INITIALIZER;
- unsigned char uuid[VIR_UUID_BUFLEN];
- char key[VIR_UUID_STRING_BUFLEN] = "";
+ VBOX_UTF16_TO_UTF8(hddFormatUtf16, &hddFormatUtf8);
+ if (hddFormatUtf8) {
- rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
- if (NS_SUCCEEDED(rc)) {
- vboxIIDToUUID(&hddIID, uuid);
- virUUIDFormat(uuid, key);
+ VIR_DEBUG("Storage Volume Format: %s", hddFormatUtf8);
- ret = virGetStorageVol(pool->conn, pool->name,
def->name, key,
- NULL, NULL);
- }
+ if (STRCASEEQ("vmdk", hddFormatUtf8))
+ def.target.format = VIR_STORAGE_FILE_VMDK;
+ else if (STRCASEEQ("vhd", hddFormatUtf8))
+ def.target.format = VIR_STORAGE_FILE_VPC;
+ else if (STRCASEEQ("vdi", hddFormatUtf8))
+ def.target.format = VIR_STORAGE_FILE_VDI;
+ else
+ def.target.format = VIR_STORAGE_FILE_RAW;
- vboxIIDUnalloc(&hddIID);
+ VBOX_UTF8_FREE(hddFormatUtf8);
}
- VBOX_RELEASE(progress);
+ VBOX_UTF16_FREE(hddFormatUtf16);
+ } else {
+ defOk = 0;
}
}
+
+ VBOX_MEDIUM_RELEASE(hardDisk);
}
- VBOX_UTF16_FREE(hddFormatUtf16);
- VBOX_UTF16_FREE(hddNameUtf16);
+ vboxIIDUnalloc(&hddIID);
+
+ if (defOk)
+ ret = virStorageVolDefFormat(&pool, &def);
- cleanup:
- virStorageVolDefFree(def);
return ret;
}
-static int vboxStorageVolDelete(virStorageVolPtr vol,
- unsigned int flags)
-{
- VBOX_OBJECT_CHECK(vol->conn, int, -1);
- vboxIID hddIID = VBOX_IID_INITIALIZER;
- unsigned char uuid[VIR_UUID_BUFLEN];
+static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
+ VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
IHardDisk *hardDisk = NULL;
- int deregister = 0;
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ vboxIID hddIID = VBOX_IID_INITIALIZER;
nsresult rc;
- size_t i = 0;
- size_t j = 0;
-
- virCheckFlags(0, -1);
if (virUUIDParse(vol->key, uuid) < 0) {
virReportError(VIR_ERR_INVALID_ARG,
_("Could not parse UUID from '%s'"),
vol->key);
- return -1;
+ return ret;
}
vboxIIDFromUUID(&hddIID, uuid);
@@ -10078,1123 +9451,1437 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
if (hddstate != MediaState_Inaccessible) {
- PRUint32 machineIdsSize = 0;
- vboxArray machineIds = VBOX_ARRAY_INITIALIZER;
+ PRUnichar *hddLocationUtf16 = NULL;
+ char *hddLocationUtf8 = NULL;
-#if VBOX_API_VERSION < 3001000
- vboxArrayGet(&machineIds, hardDisk,
hardDisk->vtbl->imedium.GetMachineIds);
-#else /* VBOX_API_VERSION >= 3001000 */
- vboxArrayGet(&machineIds, hardDisk,
hardDisk->vtbl->GetMachineIds);
-#endif /* VBOX_API_VERSION >= 3001000 */
+ VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetLocation, &hddLocationUtf16);
-#if VBOX_API_VERSION == 2002000 && defined WIN32
- /* VirtualBox 2.2 on Windows represents IIDs as GUIDs and the
- * machineIds array contains direct instances of the GUID struct
- * instead of pointers to the actual struct instances. But there
- * is no 128bit width simple item type for a SafeArray to fit a
- * GUID in. The largest simple type it 64bit width and VirtualBox
- * uses two of this 64bit items to represents one GUID. Therefore,
- * we divide the size of the SafeArray by two, to compensate for
- * this workaround in VirtualBox */
- machineIds.count /= 2;
-#endif /* VBOX_API_VERSION >= 2002000 */
+ VBOX_UTF16_TO_UTF8(hddLocationUtf16, &hddLocationUtf8);
+ if (hddLocationUtf8) {
- machineIdsSize = machineIds.count;
+ ignore_value(VIR_STRDUP(ret, hddLocationUtf8));
- for (i = 0; i < machineIds.count; i++) {
- IMachine *machine = NULL;
- vboxIID machineId = VBOX_IID_INITIALIZER;
+ VIR_DEBUG("Storage Volume Name: %s", vol->name);
+ VIR_DEBUG("Storage Volume Path: %s", hddLocationUtf8);
+ VIR_DEBUG("Storage Volume Pool: %s", vol->pool);
- vboxIIDFromArrayItem(&machineId, &machineIds, i);
+ VBOX_UTF8_FREE(hddLocationUtf8);
+ }
-#if VBOX_API_VERSION >= 4000000
- rc = VBOX_OBJECT_GET_MACHINE(machineId.value, &machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- break;
- }
-#endif
+ VBOX_UTF16_FREE(hddLocationUtf16);
+ }
- rc = VBOX_SESSION_OPEN(machineId.value, machine);
+ VBOX_MEDIUM_RELEASE(hardDisk);
+ }
- if (NS_SUCCEEDED(rc)) {
+ vboxIIDUnalloc(&hddIID);
- rc =
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
- if (NS_SUCCEEDED(rc)) {
- vboxArray hddAttachments = VBOX_ARRAY_INITIALIZER;
+ return ret;
+}
-#if VBOX_API_VERSION < 3001000
- vboxArrayGet(&hddAttachments, machine,
- machine->vtbl->GetHardDiskAttachments);
-#else /* VBOX_API_VERSION >= 3001000 */
- vboxArrayGet(&hddAttachments, machine,
- machine->vtbl->GetMediumAttachments);
-#endif /* VBOX_API_VERSION >= 3001000 */
- for (j = 0; j < hddAttachments.count; j++) {
- IHardDiskAttachment *hddAttachment =
hddAttachments.items[j];
+#if VBOX_API_VERSION >= 4000000
+static char *
+vboxDomainScreenshot(virDomainPtr dom,
+ virStreamPtr st,
+ unsigned int screen,
+ unsigned int flags)
+{
+ VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
+ IConsole *console = NULL;
+ vboxIID iid = VBOX_IID_INITIALIZER;
+ IMachine *machine = NULL;
+ nsresult rc;
+ char *tmp;
+ int tmp_fd = -1;
+ unsigned int max_screen;
+
+ virCheckFlags(0, NULL);
+
+ vboxIIDFromUUID(&iid, dom->uuid);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return NULL;
+ }
+
+ rc = machine->vtbl->GetMonitorCount(machine, &max_screen);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("unable to get monitor count"));
+ VBOX_RELEASE(machine);
+ return NULL;
+ }
- if (hddAttachment) {
- IHardDisk *hdd = NULL;
+ if (screen >= max_screen) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("screen ID higher than monitor "
+ "count (%d)"), max_screen);
+ VBOX_RELEASE(machine);
+ return NULL;
+ }
-#if VBOX_API_VERSION < 3001000
- rc =
hddAttachment->vtbl->GetHardDisk(hddAttachment, &hdd);
-#else /* VBOX_API_VERSION >= 3001000 */
- rc = hddAttachment->vtbl->GetMedium(hddAttachment,
&hdd);
-#endif /* VBOX_API_VERSION >= 3001000 */
- if (NS_SUCCEEDED(rc) && hdd) {
- vboxIID iid = VBOX_IID_INITIALIZER;
+ if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX",
LOCALSTATEDIR) < 0) {
+ VBOX_RELEASE(machine);
+ return NULL;
+ }
- rc = VBOX_MEDIUM_FUNC_ARG1(hdd, GetId,
&iid.value);
- if (NS_SUCCEEDED(rc)) {
+ if ((tmp_fd = mkostemp(tmp, O_CLOEXEC)) == -1) {
+ virReportSystemError(errno, _("mkostemp(\"%s\") failed"),
tmp);
+ VIR_FREE(tmp);
+ VBOX_RELEASE(machine);
+ return NULL;
+ }
- DEBUGIID("HardDisk (to delete)
UUID", hddIID.value);
- DEBUGIID("HardDisk (currently
processing) UUID", iid.value);
- if (vboxIIDIsEqual(&hddIID, &iid)) {
- PRUnichar *controller = NULL;
- PRInt32 port = 0;
- PRInt32 device = 0;
+ rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
+ if (NS_SUCCEEDED(rc)) {
+ rc = data->vboxSession->vtbl->GetConsole(data->vboxSession,
&console);
+ if (NS_SUCCEEDED(rc) && console) {
+ IDisplay *display = NULL;
- DEBUGIID("Found HardDisk to delete,
UUID", hddIID.value);
+ console->vtbl->GetDisplay(console, &display);
-
hddAttachment->vtbl->GetController(hddAttachment, &controller);
-
hddAttachment->vtbl->GetPort(hddAttachment, &port);
-
hddAttachment->vtbl->GetDevice(hddAttachment, &device);
+ if (display) {
+ PRUint32 width, height, bitsPerPixel;
+ PRUint32 screenDataSize;
+ PRUint8 *screenData;
+# if VBOX_API_VERSION >= 4003000
+ PRInt32 xOrigin, yOrigin;
+# endif
-#if VBOX_API_VERSION < 3001000
- rc =
machine->vtbl->DetachHardDisk(machine, controller, port, device);
-#else /* VBOX_API_VERSION >= 3001000 */
- rc =
machine->vtbl->DetachDevice(machine, controller, port, device);
-#endif /* VBOX_API_VERSION >= 3001000 */
- if (NS_SUCCEEDED(rc)) {
- rc =
machine->vtbl->SaveSettings(machine);
- VIR_DEBUG("saving machine
settings");
- }
+ rc = display->vtbl->GetScreenResolution(display, screen,
+ &width, &height,
+# if VBOX_API_VERSION < 4003000
+ &bitsPerPixel);
+# else
+ &bitsPerPixel,
+ &xOrigin, &yOrigin);
+# endif
- if (NS_SUCCEEDED(rc)) {
- deregister++;
- VIR_DEBUG("deregistering
hdd:%d", deregister);
- }
+ if (NS_FAILED(rc) || !width || !height) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("unable to get screen resolution"));
+ goto endjob;
+ }
- VBOX_UTF16_FREE(controller);
- }
- vboxIIDUnalloc(&iid);
- }
- VBOX_MEDIUM_RELEASE(hdd);
- }
- }
- }
- vboxArrayRelease(&hddAttachments);
- VBOX_RELEASE(machine);
- }
- VBOX_SESSION_CLOSE();
+ rc = display->vtbl->TakeScreenShotPNGToArray(display, screen,
+ width, height,
+ &screenDataSize,
+ &screenData);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("failed to take screenshot"));
+ goto endjob;
}
- vboxIIDUnalloc(&machineId);
- }
+ if (safewrite(tmp_fd, (char *) screenData,
+ screenDataSize) < 0) {
+ virReportSystemError(errno, _("unable to write data "
+ "to '%s'"), tmp);
+ goto endjob;
+ }
- vboxArrayUnalloc(&machineIds);
+ if (VIR_CLOSE(tmp_fd) < 0) {
+ virReportSystemError(errno, _("unable to close %s"), tmp);
+ goto endjob;
+ }
- if (machineIdsSize == 0 || machineIdsSize == deregister) {
- IProgress *progress = NULL;
- rc = hardDisk->vtbl->DeleteStorage(hardDisk, &progress);
+ if (VIR_STRDUP(ret, "image/png") < 0)
+ goto endjob;
- if (NS_SUCCEEDED(rc) && progress) {
- progress->vtbl->WaitForCompletion(progress, -1);
- VBOX_RELEASE(progress);
- DEBUGIID("HardDisk deleted, UUID", hddIID.value);
- ret = 0;
+ if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY) < 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("unable to open stream"));
+ VIR_FREE(ret);
}
+ endjob:
+ VIR_FREE(screenData);
+ VBOX_RELEASE(display);
}
+ VBOX_RELEASE(console);
}
-
- VBOX_MEDIUM_RELEASE(hardDisk);
+ VBOX_SESSION_CLOSE();
}
- vboxIIDUnalloc(&hddIID);
-
+ VIR_FORCE_CLOSE(tmp_fd);
+ unlink(tmp);
+ VIR_FREE(tmp);
+ VBOX_RELEASE(machine);
+ vboxIIDUnalloc(&iid);
return ret;
}
+#endif /* VBOX_API_VERSION >= 4000000 */
+
+#define MATCH(FLAG) (flags & (FLAG))
static int
-vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info)
+vboxConnectListAllDomains(virConnectPtr conn,
+ virDomainPtr **domains,
+ unsigned int flags)
{
- VBOX_OBJECT_CHECK(vol->conn, int, -1);
- IHardDisk *hardDisk = NULL;
+ VBOX_OBJECT_CHECK(conn, int, -1);
+ vboxArray machines = VBOX_ARRAY_INITIALIZER;
+ char *machineNameUtf8 = NULL;
+ PRUnichar *machineNameUtf16 = NULL;
unsigned char uuid[VIR_UUID_BUFLEN];
- vboxIID hddIID = VBOX_IID_INITIALIZER;
+ vboxIID iid = VBOX_IID_INITIALIZER;
+ PRUint32 state;
nsresult rc;
+ size_t i;
+ virDomainPtr dom;
+ virDomainPtr *doms = NULL;
+ int count = 0;
+ bool active;
+ PRUint32 snapshotCount;
- if (!info)
- return ret;
+ virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
- if (virUUIDParse(vol->key, uuid) < 0) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("Could not parse UUID from '%s'"),
vol->key);
- return ret;
+ /* filter out flag options that will produce 0 results in vbox driver:
+ * - managed save: vbox guests don't have managed save images
+ * - autostart: vbox doesn't support autostarting guests
+ * - persistance: vbox doesn't support transient guests
+ */
+ if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
+ !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) {
+ if (domains &&
+ VIR_ALLOC_N(*domains, 1) < 0)
+ goto cleanup;
+
+ ret = 0;
+ goto cleanup;
}
- vboxIIDFromUUID(&hddIID, uuid);
-#if VBOX_API_VERSION < 4000000
- rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
-#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, &hardDisk);
-#else
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, AccessMode_ReadWrite,
- PR_FALSE, &hardDisk);
-#endif /* VBOX_API_VERSION >= 4000000 */
- if (NS_SUCCEEDED(rc)) {
- PRUint32 hddstate;
+ rc = vboxArrayGet(&machines, data->vboxObj,
data->vboxObj->vtbl->GetMachines);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not get list of domains, rc=%08x"),
(unsigned)rc);
+ goto cleanup;
+ }
+
+ if (domains &&
+ VIR_ALLOC_N(doms, machines.count + 1) < 0)
+ goto cleanup;
+
+ for (i = 0; i < machines.count; i++) {
+ IMachine *machine = machines.items[i];
+
+ if (machine) {
+ PRBool isAccessible = PR_FALSE;
+ machine->vtbl->GetAccessible(machine, &isAccessible);
+ if (isAccessible) {
+ machine->vtbl->GetState(machine, &state);
+
+ if (state >= MachineState_FirstOnline &&
+ state <= MachineState_LastOnline)
+ active = true;
+ else
+ active = false;
+
+ /* filter by active state */
+ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && active) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && !active)))
+ continue;
+
+ /* filter by snapshot existence */
+ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
+ rc = machine->vtbl->GetSnapshotCount(machine,
&snapshotCount);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not get snapshot count for listed
domains"));
+ goto cleanup;
+ }
+ if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
+ snapshotCount > 0) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) &&
+ snapshotCount == 0)))
+ continue;
+ }
+
+ /* filter by machine state */
+ if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE) &&
+ !((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
+ state == MachineState_Running) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
+ state == MachineState_Paused) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
+ state == MachineState_PoweredOff) ||
+ (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
+ (state != MachineState_Running &&
+ state != MachineState_Paused &&
+ state != MachineState_PoweredOff))))
+ continue;
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
- if (hddstate != MediaState_Inaccessible) {
-#if VBOX_API_VERSION < 4000000
- PRUint64 hddLogicalSize;
- PRUint64 hddActualSize;
-#else /* VBOX_API_VERSION >= 4000000 */
- PRInt64 hddLogicalSize;
- PRInt64 hddActualSize;
-#endif /* VBOX_API_VERSION >= 4000000 */
+ /* just count the machines */
+ if (!doms) {
+ count++;
+ continue;
+ }
- info->type = VIR_STORAGE_VOL_FILE;
+ machine->vtbl->GetName(machine, &machineNameUtf16);
+ VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
+ machine->vtbl->GetId(machine, &iid.value);
+ vboxIIDToUUID(&iid, uuid);
+ vboxIIDUnalloc(&iid);
- hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
-#if VBOX_API_VERSION < 4000000
- info->capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
-#else /* VBOX_API_VERSION >= 4000000 */
- info->capacity = hddLogicalSize;
-#endif /* VBOX_API_VERSION >= 4000000 */
+ dom = virGetDomain(conn, machineNameUtf8, uuid);
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
- info->allocation = hddActualSize;
+ VBOX_UTF8_FREE(machineNameUtf8);
+ VBOX_UTF16_FREE(machineNameUtf16);
- ret = 0;
+ if (!dom)
+ goto cleanup;
- VIR_DEBUG("Storage Volume Name: %s", vol->name);
- VIR_DEBUG("Storage Volume Type: %s", info->type ==
VIR_STORAGE_VOL_BLOCK ? "Block" : "File");
- VIR_DEBUG("Storage Volume Capacity: %llu", info->capacity);
- VIR_DEBUG("Storage Volume Allocation: %llu", info->allocation);
+ if (active)
+ dom->id = i + 1;
+
+ doms[count++] = dom;
+ }
}
+ }
- VBOX_MEDIUM_RELEASE(hardDisk);
+ if (doms) {
+ /* safe to ignore, new size will be equal or less than
+ * previous allocation*/
+ ignore_value(VIR_REALLOC_N(doms, count + 1));
+ *domains = doms;
+ doms = NULL;
}
- vboxIIDUnalloc(&hddIID);
+ ret = count;
+
+ cleanup:
+ if (doms) {
+ for (i = 0; i < count; i++) {
+ if (doms[i])
+ virDomainFree(doms[i]);
+ }
+ }
+ VIR_FREE(doms);
+ vboxArrayRelease(&machines);
return ret;
}
+#undef MATCH
-static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
-{
- VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
- IHardDisk *hardDisk = NULL;
- unsigned char uuid[VIR_UUID_BUFLEN];
- vboxIID hddIID = VBOX_IID_INITIALIZER;
- virStoragePoolDef pool;
- virStorageVolDef def;
- int defOk = 0;
- nsresult rc;
-
- virCheckFlags(0, NULL);
- memset(&pool, 0, sizeof(pool));
- memset(&def, 0, sizeof(def));
+static int
+vboxNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virNodeInfoPtr nodeinfo)
+{
+ return nodeGetInfo(nodeinfo);
+}
- if (virUUIDParse(vol->key, uuid) < 0) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("Could not parse UUID from '%s'"),
vol->key);
- return ret;
- }
- vboxIIDFromUUID(&hddIID, uuid);
-#if VBOX_API_VERSION < 4000000
- rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
-#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, &hardDisk);
-#else
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, AccessMode_ReadWrite,
- PR_FALSE, &hardDisk);
-#endif /* VBOX_API_VERSION >= 4000000 */
- if (NS_SUCCEEDED(rc)) {
- PRUint32 hddstate;
+static int
+vboxNodeGetCellsFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED,
+ unsigned long long *freeMems,
+ int startCell,
+ int maxCells)
+{
+ return nodeGetCellsFreeMemory(freeMems, startCell, maxCells);
+}
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
- if (NS_SUCCEEDED(rc) && hddstate != MediaState_Inaccessible) {
- PRUnichar *hddFormatUtf16 = NULL;
-#if VBOX_API_VERSION < 4000000
- PRUint64 hddLogicalSize;
- PRUint64 hddActualSize;
-#else /* VBOX_API_VERSION >= 4000000 */
- PRInt64 hddLogicalSize;
- PRInt64 hddActualSize;
-#endif /* VBOX_API_VERSION >= 4000000 */
- /* since there is currently one default pool now
- * and virStorageVolDefFormat() just checks it type
- * so just assign it for now, change the behaviour
- * when vbox supports pools.
- */
- pool.type = VIR_STORAGE_POOL_DIR;
- def.type = VIR_STORAGE_VOL_FILE;
- defOk = 1;
+static unsigned long long
+vboxNodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ unsigned long long freeMem;
+ if (nodeGetMemory(NULL, &freeMem) < 0)
+ return 0;
+ return freeMem;
+}
- rc = hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
- if (NS_SUCCEEDED(rc) && defOk) {
-#if VBOX_API_VERSION < 4000000
- def.target.capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
-#else /* VBOX_API_VERSION >= 4000000 */
- def.target.capacity = hddLogicalSize;
-#endif /* VBOX_API_VERSION >= 4000000 */
- } else
- defOk = 0;
- rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
- if (NS_SUCCEEDED(rc) && defOk)
- def.target.allocation = hddActualSize;
- else
- defOk = 0;
+static int
+vboxNodeGetFreePages(virConnectPtr conn ATTRIBUTE_UNUSED,
+ unsigned int npages,
+ unsigned int *pages,
+ int startCell,
+ unsigned int cellCount,
+ unsigned long long *counts,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
- if (VIR_STRDUP(def.name, vol->name) < 0)
- defOk = 0;
+ return nodeGetFreePages(npages, pages, startCell, cellCount, counts);
+}
- if (VIR_STRDUP(def.key, vol->key) < 0)
- defOk = 0;
+static int _pfnInitialize(vboxGlobalData *data)
+{
+ data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
+ if (data->pFuncs == NULL)
+ return -1;
+#if VBOX_XPCOMC_VERSION == 0x00010000U
+ data->pFuncs->pfnComInitialize(&data->vboxObj,
&data->vboxSession);
+#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
+ data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
ISESSION_IID_STR, &data->vboxSession);
+#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
+ return 0;
+}
- rc = hardDisk->vtbl->GetFormat(hardDisk, &hddFormatUtf16);
- if (NS_SUCCEEDED(rc) && defOk) {
- char *hddFormatUtf8 = NULL;
+static int
+_initializeDomainEvent(vboxGlobalData *data ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
+ /* No event queue functionality in 2.2.* and 4.* as of now */
+ vboxUnsupported();
+#else /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
+ /* Initialize the fWatch needed for Event Callbacks */
+ data->fdWatch = -1;
+ data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
+ if (data->vboxQueue == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("nsIEventQueue object is null"));
+ return -1;
+ }
+#endif /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
+ return 0;
+}
- VBOX_UTF16_TO_UTF8(hddFormatUtf16, &hddFormatUtf8);
- if (hddFormatUtf8) {
+static
+void _registerGlobalData(vboxGlobalData *data ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION == 2002000
+ vboxUnsupported();
+#else /* VBOX_API_VERSION != 2002000 */
+ g_pVBoxGlobalData = data;
+#endif /* VBOX_API_VERSION != 2002000 */
+}
- VIR_DEBUG("Storage Volume Format: %s", hddFormatUtf8);
+#if VBOX_API_VERSION < 4000000
- if (STRCASEEQ("vmdk", hddFormatUtf8))
- def.target.format = VIR_STORAGE_FILE_VMDK;
- else if (STRCASEEQ("vhd", hddFormatUtf8))
- def.target.format = VIR_STORAGE_FILE_VPC;
- else if (STRCASEEQ("vdi", hddFormatUtf8))
- def.target.format = VIR_STORAGE_FILE_VDI;
- else
- def.target.format = VIR_STORAGE_FILE_RAW;
+# if VBOX_API_VERSION < 3001000
+static void
+_detachDevices(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ IMachine *machine, PRUnichar *hddcnameUtf16)
+{
+ /* Disconnect all the drives if present */
+ machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 0);
+ machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 1);
+ machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 1, 1);
+}
+# else /* VBOX_API_VERSION >= 3001000 */
+static void
+_detachDevices(vboxGlobalData *data, IMachine *machine,
+ PRUnichar *hddcnameUtf16 ATTRIBUTE_UNUSED)
+{
+ /* get all the controller first, then the attachments and
+ * remove them all so that the machine can be undefined
+ */
+ vboxArray storageControllers = VBOX_ARRAY_INITIALIZER;
+ size_t i = 0, j = 0;
- VBOX_UTF8_FREE(hddFormatUtf8);
- }
+ vboxArrayGet(&storageControllers, machine,
+ machine->vtbl->GetStorageControllers);
- VBOX_UTF16_FREE(hddFormatUtf16);
- } else {
- defOk = 0;
- }
- }
+ for (i = 0; i < storageControllers.count; i++) {
+ IStorageController *strCtl = storageControllers.items[i];
+ PRUnichar *strCtlName = NULL;
+ vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
- VBOX_MEDIUM_RELEASE(hardDisk);
- }
+ if (!strCtl)
+ continue;
- vboxIIDUnalloc(&hddIID);
+ strCtl->vtbl->GetName(strCtl, &strCtlName);
+ vboxArrayGetWithPtrArg(&mediumAttachments, machine,
+ machine->vtbl->GetMediumAttachmentsOfController,
+ strCtlName);
- if (defOk)
- ret = virStorageVolDefFormat(&pool, &def);
+ for (j = 0; j < mediumAttachments.count; j++) {
+ IMediumAttachment *medAtt = mediumAttachments.items[j];
+ PRInt32 port = ~0U;
+ PRInt32 device = ~0U;
- return ret;
-}
+ if (!medAtt)
+ continue;
-static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
- VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
- IHardDisk *hardDisk = NULL;
- unsigned char uuid[VIR_UUID_BUFLEN];
- vboxIID hddIID = VBOX_IID_INITIALIZER;
- nsresult rc;
+ medAtt->vtbl->GetPort(medAtt, &port);
+ medAtt->vtbl->GetDevice(medAtt, &device);
- if (virUUIDParse(vol->key, uuid) < 0) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("Could not parse UUID from '%s'"),
vol->key);
- return ret;
- }
+ if ((port != ~0U) && (device != ~0U)) {
+ machine->vtbl->DetachDevice(machine,
+ strCtlName,
+ port,
+ device);
+ }
+ }
+ vboxArrayRelease(&storageControllers);
+ machine->vtbl->RemoveStorageController(machine, strCtlName);
+ VBOX_UTF16_FREE(strCtlName);
+ }
+ vboxArrayRelease(&storageControllers);
+}
+# endif /* VBOX_API_VERSION >= 3001000 */
- vboxIIDFromUUID(&hddIID, uuid);
-#if VBOX_API_VERSION < 4000000
- rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value,
&hardDisk);
-#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
- rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, &hardDisk);
-#else
- rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
- DeviceType_HardDisk, AccessMode_ReadWrite,
- PR_FALSE, &hardDisk);
-#endif /* VBOX_API_VERSION >= 4000000 */
- if (NS_SUCCEEDED(rc)) {
- PRUint32 hddstate;
+static nsresult
+_unregisterMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return data->vboxObj->vtbl->UnregisterMachine(data->vboxObj,
IID_MEMBER(value), machine);
+}
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
- if (hddstate != MediaState_Inaccessible) {
- PRUnichar *hddLocationUtf16 = NULL;
- char *hddLocationUtf8 = NULL;
+static void
+_deleteConfig(IMachine *machine)
+{
+ machine->vtbl->DeleteSettings(machine);
+}
- VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetLocation, &hddLocationUtf16);
+#else /* VBOX_API_VERSION >= 4000000 */
- VBOX_UTF16_TO_UTF8(hddLocationUtf16, &hddLocationUtf8);
- if (hddLocationUtf8) {
+static void
+_detachDevices(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ IMachine *machine ATTRIBUTE_UNUSED,
+ PRUnichar *hddcnameUtf16 ATTRIBUTE_UNUSED)
+{
+ vboxUnsupported();
+}
- ignore_value(VIR_STRDUP(ret, hddLocationUtf8));
+static nsresult
+_unregisterMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+{
+ nsresult rc;
+ vboxArray media = VBOX_ARRAY_INITIALIZER;
+ rc = VBOX_OBJECT_GET_MACHINE(IID_MEMBER(value), machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return rc;
+ }
- VIR_DEBUG("Storage Volume Name: %s", vol->name);
- VIR_DEBUG("Storage Volume Path: %s", hddLocationUtf8);
- VIR_DEBUG("Storage Volume Pool: %s", vol->pool);
+ /* We're not interested in the array returned by the Unregister method,
+ * but in the side effect of unregistering the virtual machine. In order
+ * to call the Unregister method correctly we need to use the vboxArray
+ * wrapper here. */
+ rc = vboxArrayGetWithUintArg(&media, *machine,
(*machine)->vtbl->Unregister,
+ CleanupMode_DetachAllReturnNone);
+ vboxArrayUnalloc(&media);
+ return rc;
+}
- VBOX_UTF8_FREE(hddLocationUtf8);
- }
+static void
+_deleteConfig(IMachine *machine)
+{
+ IProgress *progress = NULL;
- VBOX_UTF16_FREE(hddLocationUtf16);
- }
+ /* The IMachine Delete method takes an array of IMedium items to be
+ * deleted along with the virtual machine. We just want to pass an
+ * empty array. But instead of adding a full vboxArraySetWithReturn to
+ * the glue layer (in order to handle the required signature of the
+ * Delete method) we use a local solution here. */
+# ifdef WIN32
+ SAFEARRAY *safeArray = NULL;
+ typedef HRESULT __stdcall (*IMachine_Delete)(IMachine *self,
+ SAFEARRAY **media,
+ IProgress **progress);
- VBOX_MEDIUM_RELEASE(hardDisk);
+# if VBOX_API_VERSION < 4003000
+ ((IMachine_Delete)machine->vtbl->Delete)(machine, &safeArray,
&progress);
+# else
+ ((IMachine_Delete)machine->vtbl->DeleteConfig)(machine, &safeArray,
&progress);
+# endif
+# else
+ /* XPCOM doesn't like NULL as an array, even when the array size is 0.
+ * Instead pass it a dummy array to avoid passing NULL. */
+ IMedium *array[] = { NULL };
+# if VBOX_API_VERSION < 4003000
+ machine->vtbl->Delete(machine, 0, array, &progress);
+# else
+ machine->vtbl->DeleteConfig(machine, 0, array, &progress);
+# endif
+# endif
+ if (progress != NULL) {
+ progress->vtbl->WaitForCompletion(progress, -1);
+ VBOX_RELEASE(progress);
}
+}
- vboxIIDUnalloc(&hddIID);
+#endif /* VBOX_API_VERSION >= 4000000 */
- return ret;
+static void _pfnUninitialize(vboxGlobalData *data)
+{
+ if (data->pFuncs)
+ data->pFuncs->pfnComUninitialize();
}
-#if VBOX_API_VERSION >= 4000000
-static char *
-vboxDomainScreenshot(virDomainPtr dom,
- virStreamPtr st,
- unsigned int screen,
- unsigned int flags)
+static void _pfnComUnallocMem(PCVBOXXPCOM pFuncs, void *pv)
{
- VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
- IConsole *console = NULL;
- vboxIID iid = VBOX_IID_INITIALIZER;
- IMachine *machine = NULL;
- nsresult rc;
- char *tmp;
- int tmp_fd = -1;
- unsigned int max_screen;
+ pFuncs->pfnComUnallocMem(pv);
+}
- virCheckFlags(0, NULL);
+static void _pfnUtf16Free(PCVBOXXPCOM pFuncs, PRUnichar *pwszString)
+{
+ pFuncs->pfnUtf16Free(pwszString);
+}
- vboxIIDFromUUID(&iid, dom->uuid);
- rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- return NULL;
- }
+static void _pfnUtf8Free(PCVBOXXPCOM pFuncs, char *pszString)
+{
+ pFuncs->pfnUtf8Free(pszString);
+}
- rc = machine->vtbl->GetMonitorCount(machine, &max_screen);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("unable to get monitor count"));
- VBOX_RELEASE(machine);
- return NULL;
- }
+static int _pfnUtf16ToUtf8(PCVBOXXPCOM pFuncs, const PRUnichar *pwszString, char
**ppszString)
+{
+ return pFuncs->pfnUtf16ToUtf8(pwszString, ppszString);
+}
- if (screen >= max_screen) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("screen ID higher than monitor "
- "count (%d)"), max_screen);
- VBOX_RELEASE(machine);
- return NULL;
- }
+static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar
**ppwszString)
+{
+ return pFuncs->pfnUtf8ToUtf16(pszString, ppwszString);
+}
- if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX",
LOCALSTATEDIR) < 0) {
- VBOX_RELEASE(machine);
- return NULL;
- }
+#if VBOX_API_VERSION == 2002000
- if ((tmp_fd = mkostemp(tmp, O_CLOEXEC)) == -1) {
- virReportSystemError(errno, _("mkostemp(\"%s\") failed"),
tmp);
- VIR_FREE(tmp);
- VBOX_RELEASE(machine);
- return NULL;
- }
+static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+}
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+# ifdef WIN32
+ DEBUGUUID(msg, (nsID *)&IID_MEMBER(value));
+# else /* !WIN32 */
+ DEBUGUUID(msg, IID_MEMBER(value));
+# endif /* !WIN32 */
+}
- rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
- if (NS_SUCCEEDED(rc)) {
- rc = data->vboxSession->vtbl->GetConsole(data->vboxSession,
&console);
- if (NS_SUCCEEDED(rc) && console) {
- IDisplay *display = NULL;
+#else /* VBOX_API_VERSION != 2002000 */
- console->vtbl->GetDisplay(console, &display);
+static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+ IID_MEMBER(owner) = true;
+}
- if (display) {
- PRUint32 width, height, bitsPerPixel;
- PRUint32 screenDataSize;
- PRUint8 *screenData;
-# if VBOX_API_VERSION >= 4003000
- PRInt32 xOrigin, yOrigin;
-# endif
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+ DEBUGPRUnichar(msg, IID_MEMBER(value));
+}
- rc = display->vtbl->GetScreenResolution(display, screen,
- &width, &height,
-# if VBOX_API_VERSION < 4003000
- &bitsPerPixel);
-# else
- &bitsPerPixel,
- &xOrigin, &yOrigin);
-# endif
+#endif /* VBOX_API_VERSION != 2002000 */
- if (NS_FAILED(rc) || !width || !height) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("unable to get screen resolution"));
- goto endjob;
- }
+static void* _handleGetMachines(IVirtualBox *vboxObj)
+{
+ return vboxObj->vtbl->GetMachines;
+}
- rc = display->vtbl->TakeScreenShotPNGToArray(display, screen,
- width, height,
- &screenDataSize,
- &screenData);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("failed to take screenshot"));
- goto endjob;
- }
+static nsresult _nsisupportsRelease(nsISupports *nsi)
+{
+ return nsi->vtbl->Release(nsi);
+}
- if (safewrite(tmp_fd, (char *) screenData,
- screenDataSize) < 0) {
- virReportSystemError(errno, _("unable to write data "
- "to '%s'"), tmp);
- goto endjob;
- }
+static nsresult
+_virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16)
+{
+ return vboxObj->vtbl->GetVersion(vboxObj, versionUtf16);
+}
- if (VIR_CLOSE(tmp_fd) < 0) {
- virReportSystemError(errno, _("unable to close %s"), tmp);
- goto endjob;
- }
+#if VBOX_API_VERSION < 4000000
- if (VIR_STRDUP(ret, "image/png") < 0)
- goto endjob;
+static nsresult
+_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return vboxObj->vtbl->GetMachine(vboxObj, IID_MEMBER(value), machine);
+}
- if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY) < 0) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("unable to open stream"));
- VIR_FREE(ret);
- }
- endjob:
- VIR_FREE(screenData);
- VBOX_RELEASE(display);
- }
- VBOX_RELEASE(console);
- }
- VBOX_SESSION_CLOSE();
- }
+#else /* VBOX_API_VERSION >= 4000000 */
- VIR_FORCE_CLOSE(tmp_fd);
- unlink(tmp);
- VIR_FREE(tmp);
- VBOX_RELEASE(machine);
- vboxIIDUnalloc(&iid);
- return ret;
+static nsresult
+_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return vboxObj->vtbl->FindMachine(vboxObj, IID_MEMBER(value), machine);
}
+
#endif /* VBOX_API_VERSION >= 4000000 */
+static nsresult
+_virtualboxGetSystemProperties(IVirtualBox *vboxObj, ISystemProperties
**systemProperties)
+{
+ return vboxObj->vtbl->GetSystemProperties(vboxObj, systemProperties);
+}
-#define MATCH(FLAG) (flags & (FLAG))
-static int
-vboxConnectListAllDomains(virConnectPtr conn,
- virDomainPtr **domains,
- unsigned int flags)
+static nsresult
+_virtualboxCreateMachine(vboxGlobalData *data, virDomainDefPtr def, IMachine **machine,
char *uuidstr ATTRIBUTE_UNUSED)
{
- VBOX_OBJECT_CHECK(conn, int, -1);
- vboxArray machines = VBOX_ARRAY_INITIALIZER;
- char *machineNameUtf8 = NULL;
- PRUnichar *machineNameUtf16 = NULL;
- unsigned char uuid[VIR_UUID_BUFLEN];
vboxIID iid = VBOX_IID_INITIALIZER;
- PRUint32 state;
+ PRUnichar *machineNameUtf16 = NULL;
nsresult rc;
- size_t i;
- virDomainPtr dom;
- virDomainPtr *doms = NULL;
- int count = 0;
- bool active;
- PRUint32 snapshotCount;
-
- virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
-
- /* filter out flag options that will produce 0 results in vbox driver:
- * - managed save: vbox guests don't have managed save images
- * - autostart: vbox doesn't support autostarting guests
- * - persistance: vbox doesn't support transient guests
- */
- if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
- !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
- !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
- !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) {
- if (domains &&
- VIR_ALLOC_N(*domains, 1) < 0)
- goto cleanup;
-
- ret = 0;
- goto cleanup;
- }
- rc = vboxArrayGet(&machines, data->vboxObj,
data->vboxObj->vtbl->GetMachines);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not get list of domains, rc=%08x"),
(unsigned)rc);
- goto cleanup;
+ VBOX_UTF8_TO_UTF16(def->name, &machineNameUtf16);
+ vboxIIDFromUUID(&iid, def->uuid);
+ {
+#if VBOX_API_VERSION < 3002000
+ rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
+ machineNameUtf16,
+ NULL,
+ NULL,
+ iid.value,
+ machine);
+#elif VBOX_API_VERSION < 4000000 /* 3002000 <= VBOX_API_VERSION < 4000000 */
+ PRBool override = PR_FALSE;
+ rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
+ machineNameUtf16,
+ NULL,
+ NULL,
+ iid.value,
+ override,
+ machine);
+#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
+ PRBool override = PR_FALSE;
+ rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
+ NULL,
+ machineNameUtf16,
+ NULL,
+ iid.value,
+ override,
+ machine);
+#else /* VBOX_API_VERSION >= 4002000 */
+ const char *flagsUUIDPrefix = "UUID=";
+ const char *flagsForceOverwrite = "forceOverwrite=0";
+ const char *flagsSeparator = ",";
+ char createFlags[strlen(flagsUUIDPrefix) + VIR_UUID_STRING_BUFLEN +
strlen(flagsSeparator) + strlen(flagsForceOverwrite) + 1];
+ PRUnichar *createFlagsUtf16 = NULL;
+
+ snprintf(createFlags, sizeof(createFlags), "%s%s%s%s",
+ flagsUUIDPrefix,
+ uuidstr,
+ flagsSeparator,
+ flagsForceOverwrite
+ );
+ VBOX_UTF8_TO_UTF16(createFlags, &createFlagsUtf16);
+ rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
+ NULL,
+ machineNameUtf16,
+ 0,
+ nsnull,
+ nsnull,
+ createFlagsUtf16,
+ machine);
+#endif /* VBOX_API_VERSION >= 4002000 */
}
+ VBOX_UTF16_FREE(machineNameUtf16);
+ vboxIIDUnalloc(&iid);
+ return rc;
+}
- if (domains &&
- VIR_ALLOC_N(doms, machines.count + 1) < 0)
- goto cleanup;
-
- for (i = 0; i < machines.count; i++) {
- IMachine *machine = machines.items[i];
-
- if (machine) {
- PRBool isAccessible = PR_FALSE;
- machine->vtbl->GetAccessible(machine, &isAccessible);
- if (isAccessible) {
- machine->vtbl->GetState(machine, &state);
+static nsresult
+_virtualboxRegisterMachine(IVirtualBox *vboxObj, IMachine *machine)
+{
+ return vboxObj->vtbl->RegisterMachine(vboxObj, machine);
+}
- if (state >= MachineState_FirstOnline &&
- state <= MachineState_LastOnline)
- active = true;
- else
- active = false;
+static nsresult
+_virtualboxFindMedium(IVirtualBox *vboxObj ATTRIBUTE_UNUSED,
+ PRUnichar *location ATTRIBUTE_UNUSED,
+ PRUint32 deviceType ATTRIBUTE_UNUSED,
+ PRUint32 accessMode ATTRIBUTE_UNUSED,
+ IMedium **medium ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
+ return vboxObj->vtbl->FindMedium(vboxObj, location,
+ deviceType, medium);
+#elif VBOX_API_VERSION >= 4002000
+ return vboxObj->vtbl->OpenMedium(vboxObj, location,
+ deviceType, accessMode, PR_FALSE, medium);
+#else
+ vboxUnsupported();
+ return 0;
+#endif
+}
- /* filter by active state */
- if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
- !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && active) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && !active)))
- continue;
+static nsresult
+_virtualboxOpenMedium(IVirtualBox *vboxObj ATTRIBUTE_UNUSED,
+ PRUnichar *location ATTRIBUTE_UNUSED,
+ PRUint32 deviceType ATTRIBUTE_UNUSED,
+ PRUint32 accessMode ATTRIBUTE_UNUSED,
+ IMedium **medium ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION == 4000000
+ return vboxObj->vtbl->OpenMedium(vboxObj,
+ location,
+ deviceType, accessMode,
+ medium);
+#elif VBOX_API_VERSION >= 4001000
+ return vboxObj->vtbl->OpenMedium(vboxObj,
+ location,
+ deviceType, accessMode,
+ false,
+ medium);
+#else
+ vboxUnsupported();
+ return 0;
+#endif
+}
- /* filter by snapshot existence */
- if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
- rc = machine->vtbl->GetSnapshotCount(machine,
&snapshotCount);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not get snapshot count for listed
domains"));
- goto cleanup;
- }
- if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
- snapshotCount > 0) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) &&
- snapshotCount == 0)))
- continue;
- }
+static nsresult
+_machineAddStorageController(IMachine *machine, PRUnichar *name,
+ PRUint32 connectionType,
+ IStorageController **controller)
+{
+ return machine->vtbl->AddStorageController(machine, name, connectionType,
+ controller);
+}
- /* filter by machine state */
- if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE) &&
- !((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
- state == MachineState_Running) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
- state == MachineState_Paused) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
- state == MachineState_PoweredOff) ||
- (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
- (state != MachineState_Running &&
- state != MachineState_Paused &&
- state != MachineState_PoweredOff))))
- continue;
+static nsresult
+_machineAttachDevice(IMachine *machine ATTRIBUTE_UNUSED,
+ PRUnichar *name ATTRIBUTE_UNUSED,
+ PRInt32 controllerPort ATTRIBUTE_UNUSED,
+ PRInt32 device ATTRIBUTE_UNUSED,
+ PRUint32 type ATTRIBUTE_UNUSED,
+ IMedium * medium ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION >= 4000000
+ return machine->vtbl->AttachDevice(machine, name, controllerPort,
+ device, type, medium);
+#else /* VBOX_API_VERSION < 4000000 */
+ vboxUnsupported();
+ return 0;
+#endif /* VBOX_API_VERSION < 4000000 */
+}
- /* just count the machines */
- if (!doms) {
- count++;
- continue;
- }
+static nsresult
+_machineCreateSharedFolder(IMachine *machine, PRUnichar *name,
+ PRUnichar *hostPath, PRBool writable,
+ PRBool automount ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION < 4000000
+ return machine->vtbl->CreateSharedFolder(machine, name, hostPath,
+ writable);
+#else /* VBOX_API_VERSION >= 4000000 */
+ return machine->vtbl->CreateSharedFolder(machine, name, hostPath,
+ writable, automount);
+#endif /* VBOX_API_VERSION >= 4000000 */
+}
- machine->vtbl->GetName(machine, &machineNameUtf16);
- VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
- machine->vtbl->GetId(machine, &iid.value);
- vboxIIDToUUID(&iid, uuid);
- vboxIIDUnalloc(&iid);
- dom = virGetDomain(conn, machineNameUtf8, uuid);
+static nsresult
+_machineGetAccessible(IMachine *machine, PRBool *isAccessible)
+{
+ return machine->vtbl->GetAccessible(machine, isAccessible);
+}
- VBOX_UTF8_FREE(machineNameUtf8);
- VBOX_UTF16_FREE(machineNameUtf16);
+static nsresult
+_machineGetState(IMachine *machine, PRUint32 *state)
+{
+ return machine->vtbl->GetState(machine, state);
+}
- if (!dom)
- goto cleanup;
+static nsresult
+_machineGetName(IMachine *machine, PRUnichar **name)
+{
+ return machine->vtbl->GetName(machine, name);
+}
- if (active)
- dom->id = i + 1;
+static nsresult
+_machineGetId(IMachine *machine, vboxIIDUnion *iidu)
+{
+ return machine->vtbl->GetId(machine, &IID_MEMBER(value));
+}
- doms[count++] = dom;
- }
- }
- }
+static nsresult
+_machineGetBIOSSettings(IMachine *machine, IBIOSSettings **bios)
+{
+ return machine->vtbl->GetBIOSSettings(machine, bios);
+}
- if (doms) {
- /* safe to ignore, new size will be equal or less than
- * previous allocation*/
- ignore_value(VIR_REALLOC_N(doms, count + 1));
- *domains = doms;
- doms = NULL;
- }
+static nsresult
+_machineGetAudioAdapter(IMachine *machine, IAudioAdapter **audioadapter)
+{
+ return machine->vtbl->GetAudioAdapter(machine, audioadapter);
+}
- ret = count;
+static nsresult
+_machineGetNetworkAdapter(IMachine *machine, PRUint32 slot, INetworkAdapter **adapter)
+{
+ return machine->vtbl->GetNetworkAdapter(machine, slot, adapter);
+}
- cleanup:
- if (doms) {
- for (i = 0; i < count; i++) {
- if (doms[i])
- virDomainFree(doms[i]);
- }
- }
- VIR_FREE(doms);
+static nsresult
+_machineGetChipsetType(IMachine *machine ATTRIBUTE_UNUSED, PRUint32 *chipsetType
ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION >= 4001000
+ return machine->vtbl->GetChipsetType(machine, chipsetType);
+#else /* VBOX_API_VERSION < 4001000 */
+ vboxUnsupported();
+ return 0;
+#endif /* VBOX_API_VERSION < 4001000 */
+}
- vboxArrayRelease(&machines);
- return ret;
+static nsresult
+_machineGetSerialPort(IMachine *machine, PRUint32 slot, ISerialPort **port)
+{
+ return machine->vtbl->GetSerialPort(machine, slot, port);
}
-#undef MATCH
+static nsresult
+_machineGetParallelPort(IMachine *machine, PRUint32 slot, IParallelPort **port)
+{
+ return machine->vtbl->GetParallelPort(machine, slot, port);
+}
-static int
-vboxNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
- virNodeInfoPtr nodeinfo)
+static nsresult
+_machineGetVRDxServer(IMachine *machine, IVRDxServer **VRDxServer)
{
- return nodeGetInfo(nodeinfo);
+#if VBOX_API_VERSION < 4000000
+ return machine->vtbl->GetVRDPServer(machine, VRDxServer);
+#else /* VBOX_API_VERSION >= 4000000 */
+ return machine->vtbl->GetVRDEServer(machine, VRDxServer);
+#endif /* VBOX_API_VERSION >= 4000000 */
}
+static nsresult
+_machineGetUSBCommon(IMachine *machine, IUSBCommon **USBCommon)
+{
+#if VBOX_API_VERSION < 4003000
+ return machine->vtbl->GetUSBController(machine, USBCommon);
+#else
+ return machine->vtbl->GetUSBDeviceFilters(machine, USBCommon);
+#endif
+}
-static int
-vboxNodeGetCellsFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED,
- unsigned long long *freeMems,
- int startCell,
- int maxCells)
+static nsresult
+_machineSetCPUCount(IMachine *machine, PRUint32 CPUCount)
{
- return nodeGetCellsFreeMemory(freeMems, startCell, maxCells);
+ return machine->vtbl->SetCPUCount(machine, CPUCount);
}
+static nsresult
+_machineSetMemorySize(IMachine *machine, PRUint32 memorySize)
+{
+ return machine->vtbl->SetMemorySize(machine, memorySize);
+}
-static unsigned long long
-vboxNodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
+static nsresult
+_machineSetCPUProperty(IMachine *machine, PRUint32 property ATTRIBUTE_UNUSED, PRBool
value)
{
- unsigned long long freeMem;
- if (nodeGetMemory(NULL, &freeMem) < 0)
- return 0;
- return freeMem;
+#if VBOX_API_VERSION < 3001000
+ return machine->vtbl->SetPAEEnabled(machine, value);
+#elif VBOX_API_VERSION == 3001000
+ return machine->vtbl->SetCpuProperty(machine, property, value);
+#elif VBOX_API_VERSION >= 3002000
+ return machine->vtbl->SetCPUProperty(machine, property, value);
+#endif
}
+static nsresult
+_machineSetBootOrder(IMachine *machine, PRUint32 position, PRUint32 device)
+{
+ return machine->vtbl->SetBootOrder(machine, position, device);
+}
-static int
-vboxNodeGetFreePages(virConnectPtr conn ATTRIBUTE_UNUSED,
- unsigned int npages,
- unsigned int *pages,
- int startCell,
- unsigned int cellCount,
- unsigned long long *counts,
- unsigned int flags)
+static nsresult
+_machineSetVRAMSize(IMachine *machine, PRUint32 VRAMSize)
{
- virCheckFlags(0, -1);
+ return machine->vtbl->SetVRAMSize(machine, VRAMSize);
+}
- return nodeGetFreePages(npages, pages, startCell, cellCount, counts);
+static nsresult
+_machineSetMonitorCount(IMachine *machine, PRUint32 monitorCount)
+{
+ return machine->vtbl->SetMonitorCount(machine, monitorCount);
}
-static int _pfnInitialize(vboxGlobalData *data)
+static nsresult
+_machineSetAccelerate3DEnabled(IMachine *machine, PRBool accelerate3DEnabled)
{
- data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
- if (data->pFuncs == NULL)
- return -1;
-#if VBOX_XPCOMC_VERSION == 0x00010000U
- data->pFuncs->pfnComInitialize(&data->vboxObj,
&data->vboxSession);
-#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
- data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
ISESSION_IID_STR, &data->vboxSession);
-#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
- return 0;
+ return machine->vtbl->SetAccelerate3DEnabled(machine, accelerate3DEnabled);
}
-static int
-_initializeDomainEvent(vboxGlobalData *data ATTRIBUTE_UNUSED)
+static nsresult
+_machineSetAccelerate2DVideoEnabled(IMachine *machine ATTRIBUTE_UNUSED,
+ PRBool accelerate2DVideoEnabled ATTRIBUTE_UNUSED)
{
-#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
- /* No event queue functionality in 2.2.* and 4.* as of now */
+#if VBOX_API_VERSION >= 3001000
+ return machine->vtbl->SetAccelerate2DVideoEnabled(machine,
accelerate2DVideoEnabled);
+#else /* VBOX_API_VERSION < 3001000 */
vboxUnsupported();
-#else /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
- /* Initialize the fWatch needed for Event Callbacks */
- data->fdWatch = -1;
- data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
- if (data->vboxQueue == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("nsIEventQueue object is null"));
- return -1;
- }
-#endif /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
return 0;
+#endif /* VBOX_API_VERSION < 3001000 */
}
-static
-void _registerGlobalData(vboxGlobalData *data ATTRIBUTE_UNUSED)
+static nsresult
+_machineSetExtraData(IMachine *machine, PRUnichar *key, PRUnichar *value)
{
-#if VBOX_API_VERSION == 2002000
- vboxUnsupported();
-#else /* VBOX_API_VERSION != 2002000 */
- g_pVBoxGlobalData = data;
-#endif /* VBOX_API_VERSION != 2002000 */
+ return machine->vtbl->SetExtraData(machine, key, value);
+}
+
+static nsresult
+_machineSaveSettings(IMachine *machine)
+{
+ return machine->vtbl->SaveSettings(machine);
}
#if VBOX_API_VERSION < 4000000
-# if VBOX_API_VERSION < 3001000
-static void
-_detachDevices(vboxGlobalData *data ATTRIBUTE_UNUSED,
- IMachine *machine, PRUnichar *hddcnameUtf16)
+static nsresult
+_sessionOpen(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
{
- /* Disconnect all the drives if present */
- machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 0);
- machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 1);
- machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 1, 1);
+ return data->vboxObj->vtbl->OpenSession(data->vboxObj,
data->vboxSession, IID_MEMBER(value));
}
-# else /* VBOX_API_VERSION >= 3001000 */
-static void
-_detachDevices(vboxGlobalData *data, IMachine *machine,
- PRUnichar *hddcnameUtf16 ATTRIBUTE_UNUSED)
+
+static nsresult
+_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
{
- /* get all the controller first, then the attachments and
- * remove them all so that the machine can be undefined
- */
- vboxArray storageControllers = VBOX_ARRAY_INITIALIZER;
- size_t i = 0, j = 0;
+ return data->vboxObj->vtbl->OpenExistingSession(data->vboxObj,
data->vboxSession, IID_MEMBER(value));
+}
- vboxArrayGet(&storageControllers, machine,
- machine->vtbl->GetStorageControllers);
+static nsresult
+_sessionClose(ISession *session)
+{
+ return session->vtbl->Close(session);
+}
- for (i = 0; i < storageControllers.count; i++) {
- IStorageController *strCtl = storageControllers.items[i];
- PRUnichar *strCtlName = NULL;
- vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
+#else /* VBOX_API_VERSION >= 4000000 */
- if (!strCtl)
- continue;
+static nsresult
+_sessionOpen(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine
*machine)
+{
+ return machine->vtbl->LockMachine(machine, data->vboxSession,
LockType_Write);
+}
- strCtl->vtbl->GetName(strCtl, &strCtlName);
- vboxArrayGetWithPtrArg(&mediumAttachments, machine,
- machine->vtbl->GetMediumAttachmentsOfController,
- strCtlName);
+static nsresult
+_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine
*machine)
+{
+ return machine->vtbl->LockMachine(machine, data->vboxSession,
LockType_Shared);
+}
- for (j = 0; j < mediumAttachments.count; j++) {
- IMediumAttachment *medAtt = mediumAttachments.items[j];
- PRInt32 port = ~0U;
- PRInt32 device = ~0U;
+static nsresult
+_sessionClose(ISession *session)
+{
+ return session->vtbl->UnlockMachine(session);
+}
- if (!medAtt)
- continue;
+#endif /* VBOX_API_VERSION >= 4000000 */
- medAtt->vtbl->GetPort(medAtt, &port);
- medAtt->vtbl->GetDevice(medAtt, &device);
+static nsresult
+_sessionGetConsole(ISession *session, IConsole **console)
+{
+ return session->vtbl->GetConsole(session, console);
+}
- if ((port != ~0U) && (device != ~0U)) {
- machine->vtbl->DetachDevice(machine,
- strCtlName,
- port,
- device);
- }
- }
- vboxArrayRelease(&storageControllers);
- machine->vtbl->RemoveStorageController(machine, strCtlName);
- VBOX_UTF16_FREE(strCtlName);
- }
- vboxArrayRelease(&storageControllers);
+static nsresult
+_sessionGetMachine(ISession *session, IMachine **machine)
+{
+ return session->vtbl->GetMachine(session, machine);
+}
+
+static nsresult
+_consoleSaveState(IConsole *console, IProgress **progress)
+{
+ return console->vtbl->SaveState(console, progress);
+}
+
+static nsresult
+_progressWaitForCompletion(IProgress *progress, PRInt32 timeout)
+{
+ return progress->vtbl->WaitForCompletion(progress, timeout);
+}
+
+static nsresult
+_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode)
+{
+#if VBOX_API_VERSION == 2002000
+ return progress->vtbl->GetResultCode(progress,
&resultCode->uResultCode);
+#else /* VBOX_API_VERSION != 2002000 */
+ return progress->vtbl->GetResultCode(progress,
&resultCode->resultCode);
+#endif /* VBOX_API_VERSION != 2002000 */
+}
+
+static nsresult
+_systemPropertiesGetMaxGuestCPUCount(ISystemProperties *systemProperties, PRUint32
*maxCPUCount)
+{
+ return systemProperties->vtbl->GetMaxGuestCPUCount(systemProperties,
maxCPUCount);
}
-# endif /* VBOX_API_VERSION >= 3001000 */
static nsresult
-_unregisterMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+_systemPropertiesGetMaxBootPosition(ISystemProperties *systemProperties, PRUint32
*maxBootPosition)
{
- return data->vboxObj->vtbl->UnregisterMachine(data->vboxObj,
IID_MEMBER(value), machine);
+ return systemProperties->vtbl->GetMaxBootPosition(systemProperties,
maxBootPosition);
}
-static void
-_deleteConfig(IMachine *machine)
+static nsresult
+_systemPropertiesGetMaxNetworkAdapters(ISystemProperties *systemProperties, PRUint32
chipset ATTRIBUTE_UNUSED,
+ PRUint32 *maxNetworkAdapters)
{
- machine->vtbl->DeleteSettings(machine);
+#if VBOX_API_VERSION < 4001000
+ return systemProperties->vtbl->GetNetworkAdapterCount(systemProperties,
+ maxNetworkAdapters);
+#else /* VBOX_API_VERSION >= 4000000 */
+ return systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties,
chipset,
+ maxNetworkAdapters);
+#endif /* VBOX_API_VERSION >= 4000000 */
}
-#else /* VBOX_API_VERSION >= 4000000 */
-
-static void
-_detachDevices(vboxGlobalData *data ATTRIBUTE_UNUSED,
- IMachine *machine ATTRIBUTE_UNUSED,
- PRUnichar *hddcnameUtf16 ATTRIBUTE_UNUSED)
+static nsresult
+_systemPropertiesGetSerialPortCount(ISystemProperties *systemProperties, PRUint32
*SerialPortCount)
{
- vboxUnsupported();
+ return systemProperties->vtbl->GetSerialPortCount(systemProperties,
SerialPortCount);
}
static nsresult
-_unregisterMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+_systemPropertiesGetParallelPortCount(ISystemProperties *systemProperties, PRUint32
*ParallelPortCount)
{
- nsresult rc;
- vboxArray media = VBOX_ARRAY_INITIALIZER;
- rc = VBOX_OBJECT_GET_MACHINE(IID_MEMBER(value), machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- return rc;
- }
+ return systemProperties->vtbl->GetParallelPortCount(systemProperties,
ParallelPortCount);
+}
- /* We're not interested in the array returned by the Unregister method,
- * but in the side effect of unregistering the virtual machine. In order
- * to call the Unregister method correctly we need to use the vboxArray
- * wrapper here. */
- rc = vboxArrayGetWithUintArg(&media, *machine,
(*machine)->vtbl->Unregister,
- CleanupMode_DetachAllReturnNone);
- vboxArrayUnalloc(&media);
- return rc;
+#if VBOX_API_VERSION >= 3001000
+static nsresult
+_systemPropertiesGetMaxPortCountForStorageBus(ISystemProperties *systemProperties,
PRUint32 bus,
+ PRUint32 *maxPortCount)
+{
+ return systemProperties->vtbl->GetMaxPortCountForStorageBus(systemProperties,
bus, maxPortCount);
}
-static void
-_deleteConfig(IMachine *machine)
+static nsresult
+_systemPropertiesGetMaxDevicesPerPortForStorageBus(ISystemProperties *systemProperties,
+ PRUint32 bus, PRUint32
*maxDevicesPerPort)
{
- IProgress *progress = NULL;
+ return
systemProperties->vtbl->GetMaxDevicesPerPortForStorageBus(systemProperties,
+ bus,
maxDevicesPerPort);
+}
+#else /* VBOX_API_VERSION < 3001000 */
+static nsresult
+_systemPropertiesGetMaxPortCountForStorageBus(ISystemProperties *systemProperties
ATTRIBUTE_UNUSED,
+ PRUint32 bus ATTRIBUTE_UNUSED,
+ PRUint32 *maxPortCount ATTRIBUTE_UNUSED)
+{
+ vboxUnsupported();
+ return 0;
+}
- /* The IMachine Delete method takes an array of IMedium items to be
- * deleted along with the virtual machine. We just want to pass an
- * empty array. But instead of adding a full vboxArraySetWithReturn to
- * the glue layer (in order to handle the required signature of the
- * Delete method) we use a local solution here. */
-# ifdef WIN32
- SAFEARRAY *safeArray = NULL;
- typedef HRESULT __stdcall (*IMachine_Delete)(IMachine *self,
- SAFEARRAY **media,
- IProgress **progress);
+static nsresult
+_systemPropertiesGetMaxDevicesPerPortForStorageBus(ISystemProperties *systemProperties
ATTRIBUTE_UNUSED,
+ PRUint32 bus ATTRIBUTE_UNUSED,
+ PRUint32 *maxDevicesPerPort
ATTRIBUTE_UNUSED)
+{
+ vboxUnsupported();
+ return 0;
+}
+#endif
-# if VBOX_API_VERSION < 4003000
- ((IMachine_Delete)machine->vtbl->Delete)(machine, &safeArray,
&progress);
-# else
- ((IMachine_Delete)machine->vtbl->DeleteConfig)(machine, &safeArray,
&progress);
-# endif
-# else
- /* XPCOM doesn't like NULL as an array, even when the array size is 0.
- * Instead pass it a dummy array to avoid passing NULL. */
- IMedium *array[] = { NULL };
-# if VBOX_API_VERSION < 4003000
- machine->vtbl->Delete(machine, 0, array, &progress);
-# else
- machine->vtbl->DeleteConfig(machine, 0, array, &progress);
-# endif
-# endif
- if (progress != NULL) {
- progress->vtbl->WaitForCompletion(progress, -1);
- VBOX_RELEASE(progress);
- }
+static nsresult
+_biosSettingsSetACPIEnabled(IBIOSSettings *bios, PRBool ACPIEnabled)
+{
+ return bios->vtbl->SetACPIEnabled(bios, ACPIEnabled);
}
-#endif /* VBOX_API_VERSION >= 4000000 */
+static nsresult
+_biosSettingsSetIOAPICEnabled(IBIOSSettings *bios, PRBool IOAPICEnabled)
+{
+ return bios->vtbl->SetIOAPICEnabled(bios, IOAPICEnabled);
+}
-static void _pfnUninitialize(vboxGlobalData *data)
+static nsresult
+_audioAdapterSetEnabled(IAudioAdapter *audioAdapter, PRBool enabled)
{
- if (data->pFuncs)
- data->pFuncs->pfnComUninitialize();
+ return audioAdapter->vtbl->SetEnabled(audioAdapter, enabled);
}
-static void _pfnComUnallocMem(PCVBOXXPCOM pFuncs, void *pv)
+static nsresult
+_audioAdapterSetAudioController(IAudioAdapter *audioAdapter, PRUint32 audioController)
{
- pFuncs->pfnComUnallocMem(pv);
+ return audioAdapter->vtbl->SetAudioController(audioAdapter, audioController);
}
-static void _pfnUtf16Free(PCVBOXXPCOM pFuncs, PRUnichar *pwszString)
+static nsresult
+_networkAdapterSetEnabled(INetworkAdapter *adapter, PRBool enabled)
{
- pFuncs->pfnUtf16Free(pwszString);
+ return adapter->vtbl->SetEnabled(adapter, enabled);
}
-static void _pfnUtf8Free(PCVBOXXPCOM pFuncs, char *pszString)
+static nsresult
+_networkAdapterSetAdapterType(INetworkAdapter *adapter, PRUint32 adapterType)
{
- pFuncs->pfnUtf8Free(pszString);
+ return adapter->vtbl->SetAdapterType(adapter, adapterType);
}
-static int _pfnUtf16ToUtf8(PCVBOXXPCOM pFuncs, const PRUnichar *pwszString, char
**ppszString)
+static nsresult
+_networkAdapterSetInternalNetwork(INetworkAdapter *adapter, PRUnichar *internalNetwork)
{
- return pFuncs->pfnUtf16ToUtf8(pwszString, ppszString);
+ return adapter->vtbl->SetInternalNetwork(adapter, internalNetwork);
}
-static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar
**ppwszString)
+static nsresult
+_networkAdapterSetMACAddress(INetworkAdapter *adapter, PRUnichar *MACAddress)
{
- return pFuncs->pfnUtf8ToUtf16(pszString, ppwszString);
+ return adapter->vtbl->SetMACAddress(adapter, MACAddress);
}
-#if VBOX_API_VERSION == 2002000
+#if VBOX_API_VERSION < 4001000
-static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+static nsresult
+_networkAdapterSetBridgedInterface(INetworkAdapter *adapter, PRUnichar *hostInterface)
{
- memset(iidu, 0, sizeof(vboxIIDUnion));
+ return adapter->vtbl->SetHostInterface(adapter, hostInterface);
}
-static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+static nsresult
+_networkAdapterSetHostOnlyInterface(INetworkAdapter *adapter, PRUnichar
*hostOnlyInterface)
{
-# ifdef WIN32
- DEBUGUUID(msg, (nsID *)&IID_MEMBER(value));
-# else /* !WIN32 */
- DEBUGUUID(msg, IID_MEMBER(value));
-# endif /* !WIN32 */
+ return adapter->vtbl->SetHostInterface(adapter, hostOnlyInterface);
}
-#else /* VBOX_API_VERSION != 2002000 */
-
-static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+static nsresult
+_networkAdapterAttachToBridgedInterface(INetworkAdapter *adapter)
{
- memset(iidu, 0, sizeof(vboxIIDUnion));
- IID_MEMBER(owner) = true;
+ return adapter->vtbl->AttachToBridgedInterface(adapter);
}
-static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+static nsresult
+_networkAdapterAttachToInternalNetwork(INetworkAdapter *adapter)
{
- DEBUGPRUnichar(msg, IID_MEMBER(value));
+ return adapter->vtbl->AttachToInternalNetwork(adapter);
}
-#endif /* VBOX_API_VERSION != 2002000 */
+static nsresult
+_networkAdapterAttachToHostOnlyInterface(INetworkAdapter *adapter)
+{
+ return adapter->vtbl->AttachToHostOnlyInterface(adapter);
+}
-static void* _handleGetMachines(IVirtualBox *vboxObj)
+static nsresult
+_networkAdapterAttachToNAT(INetworkAdapter *adapter)
{
- return vboxObj->vtbl->GetMachines;
+ return adapter->vtbl->AttachToNAT(adapter);
}
-static nsresult _nsisupportsRelease(nsISupports *nsi)
+#else /* VBOX_API_VERSION >= 4001000 */
+
+static nsresult
+_networkAdapterSetBridgedInterface(INetworkAdapter *adapter, PRUnichar
*bridgedInterface)
{
- return nsi->vtbl->Release(nsi);
+ return adapter->vtbl->SetBridgedInterface(adapter, bridgedInterface);
}
static nsresult
-_virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16)
+_networkAdapterSetHostOnlyInterface(INetworkAdapter *adapter, PRUnichar
*hostOnlyInterface)
{
- return vboxObj->vtbl->GetVersion(vboxObj, versionUtf16);
+ return adapter->vtbl->SetHostOnlyInterface(adapter, hostOnlyInterface);
}
-#if VBOX_API_VERSION < 4000000
+static nsresult
+_networkAdapterAttachToBridgedInterface(INetworkAdapter *adapter)
+{
+ return adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_Bridged);
+}
static nsresult
-_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+_networkAdapterAttachToInternalNetwork(INetworkAdapter *adapter)
{
- return vboxObj->vtbl->GetMachine(vboxObj, IID_MEMBER(value), machine);
+ return adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_Internal);
}
-#else /* VBOX_API_VERSION >= 4000000 */
+static nsresult
+_networkAdapterAttachToHostOnlyInterface(INetworkAdapter *adapter)
+{
+ return adapter->vtbl->SetAttachmentType(adapter,
NetworkAttachmentType_HostOnly);
+}
static nsresult
-_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+_networkAdapterAttachToNAT(INetworkAdapter *adapter)
{
- return vboxObj->vtbl->FindMachine(vboxObj, IID_MEMBER(value), machine);
+ return adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_NAT);
}
-#endif /* VBOX_API_VERSION >= 4000000 */
+#endif /* VBOX_API_VERSION >= 4001000 */
static nsresult
-_virtualboxGetSystemProperties(IVirtualBox *vboxObj, ISystemProperties
**systemProperties)
+_serialPortSetEnabled(ISerialPort *port, PRBool enabled)
{
- return vboxObj->vtbl->GetSystemProperties(vboxObj, systemProperties);
+ return port->vtbl->SetEnabled(port, enabled);
}
static nsresult
-_machineGetAccessible(IMachine *machine, PRBool *isAccessible)
+_serialPortSetPath(ISerialPort *port, PRUnichar *path)
{
- return machine->vtbl->GetAccessible(machine, isAccessible);
+ return port->vtbl->SetPath(port, path);
}
static nsresult
-_machineGetState(IMachine *machine, PRUint32 *state)
+_serialPortSetIRQ(ISerialPort *port, PRUint32 IRQ)
{
- return machine->vtbl->GetState(machine, state);
+ return port->vtbl->SetIRQ(port, IRQ);
}
static nsresult
-_machineGetName(IMachine *machine, PRUnichar **name)
+_serialPortSetIOBase(ISerialPort *port, PRUint32 IOBase)
{
- return machine->vtbl->GetName(machine, name);
+ return port->vtbl->SetIOBase(port, IOBase);
}
static nsresult
-_machineGetId(IMachine *machine, vboxIIDUnion *iidu)
+_serialPortSetHostMode(ISerialPort *port, PRUint32 hostMode)
{
- return machine->vtbl->GetId(machine, &IID_MEMBER(value));
+ return port->vtbl->SetHostMode(port, hostMode);
}
static nsresult
-_machineSaveSettings(IMachine *machine)
+_parallelPortSetEnabled(IParallelPort *port, PRBool enabled)
{
- return machine->vtbl->SaveSettings(machine);
+ return port->vtbl->SetEnabled(port, enabled);
}
-#if VBOX_API_VERSION < 4000000
-
static nsresult
-_sessionOpen(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
+_parallelPortSetPath(IParallelPort *port, PRUnichar *path)
{
- return data->vboxObj->vtbl->OpenSession(data->vboxObj,
data->vboxSession, IID_MEMBER(value));
+ return port->vtbl->SetPath(port, path);
}
static nsresult
-_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
+_parallelPortSetIRQ(IParallelPort *port, PRUint32 IRQ)
{
- return data->vboxObj->vtbl->OpenExistingSession(data->vboxObj,
data->vboxSession, IID_MEMBER(value));
+ return port->vtbl->SetIRQ(port, IRQ);
}
static nsresult
-_sessionClose(ISession *session)
+_parallelPortSetIOBase(IParallelPort *port, PRUint32 IOBase)
{
- return session->vtbl->Close(session);
+ return port->vtbl->SetIOBase(port, IOBase);
}
-#else /* VBOX_API_VERSION >= 4000000 */
+static nsresult
+_vrdxServerSetEnabled(IVRDxServer *VRDxServer, PRBool enabled)
+{
+ return VRDxServer->vtbl->SetEnabled(VRDxServer, enabled);
+}
static nsresult
-_sessionOpen(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine
*machine)
+_vrdxServerSetPorts(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ IVRDxServer *VRDxServer, virDomainGraphicsDefPtr graphics)
{
- return machine->vtbl->LockMachine(machine, data->vboxSession,
LockType_Write);
+ nsresult rc = 0;
+#if VBOX_API_VERSION < 3001000
+ if (graphics->data.rdp.port) {
+ rc = VRDxServer->vtbl->SetPort(VRDxServer,
+ graphics->data.rdp.port);
+ VIR_DEBUG("VRDP Port changed to: %d",
+ graphics->data.rdp.port);
+ } else if (graphics->data.rdp.autoport) {
+ /* Setting the port to 0 will reset its value to
+ * the default one which is 3389 currently
+ */
+ rc = VRDxServer->vtbl->SetPort(VRDxServer, 0);
+ VIR_DEBUG("VRDP Port changed to default, which is 3389 currently");
+ }
+#elif VBOX_API_VERSION < 4000000 /* 3001000 <= VBOX_API_VERSION < 4000000 */
+ PRUnichar *portUtf16 = NULL;
+ portUtf16 = PRUnicharFromInt(graphics->data.rdp.port);
+ rc = VRDxServer->vtbl->SetPorts(VRDxServer, portUtf16);
+ VBOX_UTF16_FREE(portUtf16);
+#else /* VBOX_API_VERSION >= 4000000 */
+ PRUnichar *VRDEPortsKey = NULL;
+ PRUnichar *VRDEPortsValue = NULL;
+ VBOX_UTF8_TO_UTF16("TCP/Ports", &VRDEPortsKey);
+ VRDEPortsValue = PRUnicharFromInt(graphics->data.rdp.port);
+ rc = VRDxServer->vtbl->SetVRDEProperty(VRDxServer, VRDEPortsKey,
+ VRDEPortsValue);
+ VBOX_UTF16_FREE(VRDEPortsKey);
+ VBOX_UTF16_FREE(VRDEPortsValue);
+#endif /* VBOX_API_VERSION >= 4000000 */
+ return rc;
}
static nsresult
-_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine
*machine)
+_vrdxServerSetReuseSingleConnection(IVRDxServer *VRDxServer, PRBool enabled)
{
- return machine->vtbl->LockMachine(machine, data->vboxSession,
LockType_Shared);
+ return VRDxServer->vtbl->SetReuseSingleConnection(VRDxServer, enabled);
}
static nsresult
-_sessionClose(ISession *session)
+_vrdxServerSetAllowMultiConnection(IVRDxServer *VRDxServer, PRBool enabled)
{
- return session->vtbl->UnlockMachine(session);
+ return VRDxServer->vtbl->SetAllowMultiConnection(VRDxServer, enabled);
}
+static nsresult
+_vrdxServerSetNetAddress(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ IVRDxServer *VRDxServer, PRUnichar *netAddress)
+{
+#if VBOX_API_VERSION < 4000000
+ return VRDxServer->vtbl->SetNetAddress(VRDxServer,
+ netAddress);
+#else /* VBOX_API_VERSION >= 4000000 */
+ PRUnichar *netAddressKey = NULL;
+ nsresult rc;
+ VBOX_UTF8_TO_UTF16("TCP/Address", &netAddressKey);
+ rc = VRDxServer->vtbl->SetVRDEProperty(VRDxServer, netAddressKey,
+ netAddress);
+ VBOX_UTF16_FREE(netAddressKey);
+ return rc;
#endif /* VBOX_API_VERSION >= 4000000 */
+}
static nsresult
-_sessionGetConsole(ISession *session, IConsole **console)
+_usbCommonEnable(IUSBCommon *USBCommon ATTRIBUTE_UNUSED)
{
- return session->vtbl->GetConsole(session, console);
+ nsresult rc = 0;
+#if VBOX_API_VERSION < 4003000
+ USBCommon->vtbl->SetEnabled(USBCommon, 1);
+# if VBOX_API_VERSION < 4002000
+ rc = USBCommon->vtbl->SetEnabledEhci(USBCommon, 1);
+# else /* VBOX_API_VERSION >= 4002000 */
+ rc = USBCommon->vtbl->SetEnabledEHCI(USBCommon, 1);
+# endif /* VBOX_API_VERSION >= 4002000 */
+#endif /* VBOX_API_VERSION >= 4003000 */
+ /* We don't need to set usb enabled for vbox 4.3 and later */
+ return rc;
}
static nsresult
-_sessionGetMachine(ISession *session, IMachine **machine)
+_usbCommonCreateDeviceFilter(IUSBCommon *USBCommon, PRUnichar *name,
+ IUSBDeviceFilter **filter)
{
- return session->vtbl->GetMachine(session, machine);
+ return USBCommon->vtbl->CreateDeviceFilter(USBCommon, name, filter);
}
static nsresult
-_consoleSaveState(IConsole *console, IProgress **progress)
+_usbCommonInsertDeviceFilter(IUSBCommon *USBCommon, PRUint32 position,
+ IUSBDeviceFilter *filter)
{
- return console->vtbl->SaveState(console, progress);
+ return USBCommon->vtbl->InsertDeviceFilter(USBCommon, position, filter);
}
static nsresult
-_progressWaitForCompletion(IProgress *progress, PRInt32 timeout)
+_usbDeviceFilterSetProductId(IUSBDeviceFilter *USBDeviceFilter, PRUnichar *productId)
{
- return progress->vtbl->WaitForCompletion(progress, timeout);
+ return USBDeviceFilter->vtbl->SetProductId(USBDeviceFilter, productId);
}
static nsresult
-_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode)
+_usbDeviceFilterSetActive(IUSBDeviceFilter *USBDeviceFilter, PRBool active)
{
-#if VBOX_API_VERSION == 2002000
- return progress->vtbl->GetResultCode(progress,
&resultCode->uResultCode);
-#else /* VBOX_API_VERSION != 2002000 */
- return progress->vtbl->GetResultCode(progress,
&resultCode->resultCode);
-#endif /* VBOX_API_VERSION != 2002000 */
+ return USBDeviceFilter->vtbl->SetActive(USBDeviceFilter, active);
}
static nsresult
-_systemPropertiesGetMaxGuestCPUCount(ISystemProperties *systemProperties, PRUint32
*maxCPUCount)
+_usbDeviceFilterSetVendorId(IUSBDeviceFilter *USBDeviceFilter, PRUnichar *vendorId)
{
- return systemProperties->vtbl->GetMaxGuestCPUCount(systemProperties,
maxCPUCount);
+ return USBDeviceFilter->vtbl->SetVendorId(USBDeviceFilter, vendorId);
+}
+
+static nsresult _mediumGetId(IMedium *medium, vboxIIDUnion *iidu)
+{
+ return medium->vtbl->GetId(medium, &IID_MEMBER(value));
+}
+
+static nsresult _mediumRelease(IMedium *medium)
+{
+ return medium->vtbl->nsisupports.Release((nsISupports *)medium);
+}
+
+static nsresult _mediumSetType(IMedium *medium ATTRIBUTE_UNUSED,
+ PRUint32 type ATTRIBUTE_UNUSED)
+{
+#if VBOX_API_VERSION > 3000000
+ return medium->vtbl->SetType(medium, type);
+#else
+ vboxUnsupported();
+ return 0;
+#endif
}
static bool _machineStateOnline(PRUint32 state)
@@ -11237,13 +10924,37 @@ static vboxUniformedIVirtualBox _UIVirtualBox = {
.GetVersion = _virtualboxGetVersion,
.GetMachine = _virtualboxGetMachine,
.GetSystemProperties = _virtualboxGetSystemProperties,
+ .CreateMachine = _virtualboxCreateMachine,
+ .RegisterMachine = _virtualboxRegisterMachine,
+ .FindMedium = _virtualboxFindMedium,
+ .OpenMedium = _virtualboxOpenMedium,
};
static vboxUniformedIMachine _UIMachine = {
+ .AddStorageController = _machineAddStorageController,
+ .AttachDevice = _machineAttachDevice,
+ .CreateSharedFolder = _machineCreateSharedFolder,
.GetAccessible = _machineGetAccessible,
.GetState = _machineGetState,
.GetName = _machineGetName,
.GetId = _machineGetId,
+ .GetBIOSSettings = _machineGetBIOSSettings,
+ .GetAudioAdapter = _machineGetAudioAdapter,
+ .GetNetworkAdapter = _machineGetNetworkAdapter,
+ .GetChipsetType = _machineGetChipsetType,
+ .GetSerialPort = _machineGetSerialPort,
+ .GetParallelPort = _machineGetParallelPort,
+ .GetVRDxServer = _machineGetVRDxServer,
+ .GetUSBCommon = _machineGetUSBCommon,
+ .SetCPUCount = _machineSetCPUCount,
+ .SetMemorySize = _machineSetMemorySize,
+ .SetCPUProperty = _machineSetCPUProperty,
+ .SetBootOrder = _machineSetBootOrder,
+ .SetVRAMSize = _machineSetVRAMSize,
+ .SetMonitorCount = _machineSetMonitorCount,
+ .SetAccelerate3DEnabled = _machineSetAccelerate3DEnabled,
+ .SetAccelerate2DVideoEnabled = _machineSetAccelerate2DVideoEnabled,
+ .SetExtraData = _machineSetExtraData,
.SaveSettings = _machineSaveSettings,
};
@@ -11266,6 +10977,76 @@ static vboxUniformedIProgress _UIProgress = {
static vboxUniformedISystemProperties _UISystemProperties = {
.GetMaxGuestCPUCount = _systemPropertiesGetMaxGuestCPUCount,
+ .GetMaxBootPosition = _systemPropertiesGetMaxBootPosition,
+ .GetMaxNetworkAdapters = _systemPropertiesGetMaxNetworkAdapters,
+ .GetSerialPortCount = _systemPropertiesGetSerialPortCount,
+ .GetParallelPortCount = _systemPropertiesGetParallelPortCount,
+ .GetMaxPortCountForStorageBus = _systemPropertiesGetMaxPortCountForStorageBus,
+ .GetMaxDevicesPerPortForStorageBus =
_systemPropertiesGetMaxDevicesPerPortForStorageBus,
+};
+
+static vboxUniformedIBIOSSettings _UIBIOSSettings = {
+ .SetACPIEnabled = _biosSettingsSetACPIEnabled,
+ .SetIOAPICEnabled = _biosSettingsSetIOAPICEnabled,
+};
+
+static vboxUniformedIAudioAdapter _UIAudioAdapter = {
+ .SetEnabled = _audioAdapterSetEnabled,
+ .SetAudioController = _audioAdapterSetAudioController,
+};
+
+static vboxUniformedINetworkAdapter _UINetworkAdapter = {
+ .SetEnabled = _networkAdapterSetEnabled,
+ .SetAdapterType = _networkAdapterSetAdapterType,
+ .SetBridgedInterface = _networkAdapterSetBridgedInterface,
+ .SetInternalNetwork = _networkAdapterSetInternalNetwork,
+ .SetHostOnlyInterface = _networkAdapterSetHostOnlyInterface,
+ .SetMACAddress = _networkAdapterSetMACAddress,
+ .AttachToBridgedInterface = _networkAdapterAttachToBridgedInterface,
+ .AttachToInternalNetwork = _networkAdapterAttachToInternalNetwork,
+ .AttachToHostOnlyInterface = _networkAdapterAttachToHostOnlyInterface,
+ .AttachToNAT = _networkAdapterAttachToNAT,
+};
+
+static vboxUniformedISerialPort _UISerialPort = {
+ .SetEnabled = _serialPortSetEnabled,
+ .SetPath = _serialPortSetPath,
+ .SetIRQ = _serialPortSetIRQ,
+ .SetIOBase = _serialPortSetIOBase,
+ .SetHostMode = _serialPortSetHostMode,
+};
+
+static vboxUniformedIParallelPort _UIParallelPort = {
+ .SetEnabled = _parallelPortSetEnabled,
+ .SetPath = _parallelPortSetPath,
+ .SetIRQ = _parallelPortSetIRQ,
+ .SetIOBase = _parallelPortSetIOBase,
+};
+
+static vboxUniformedIVRDxServer _UIVRDxServer = {
+ .SetEnabled = _vrdxServerSetEnabled,
+ .SetPorts = _vrdxServerSetPorts,
+ .SetReuseSingleConnection = _vrdxServerSetReuseSingleConnection,
+ .SetAllowMultiConnection = _vrdxServerSetAllowMultiConnection,
+ .SetNetAddress = _vrdxServerSetNetAddress,
+};
+
+static vboxUniformedIUSBCommon _UIUSBCommon = {
+ .Enable = _usbCommonEnable,
+ .CreateDeviceFilter = _usbCommonCreateDeviceFilter,
+ .InsertDeviceFilter = _usbCommonInsertDeviceFilter,
+};
+
+static vboxUniformedIUSBDeviceFilter _UIUSBDeviceFilter = {
+ .SetProductId = _usbDeviceFilterSetProductId,
+ .SetActive = _usbDeviceFilterSetActive,
+ .SetVendorId = _usbDeviceFilterSetVendorId,
+};
+
+static vboxUniformedIMedium _UIMedium = {
+ .GetId = _mediumGetId,
+ .Release = _mediumRelease,
+ .SetType = _mediumSetType,
};
static uniformedMachineStateChecker _machineStateChecker = {
@@ -11281,6 +11062,7 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->detachDevices = _detachDevices;
pVBoxAPI->unregisterMachine = _unregisterMachine;
pVBoxAPI->deleteConfig = _deleteConfig;
+ pVBoxAPI->vboxAttachDrivesOld = _vboxAttachDrivesOld;
pVBoxAPI->UPFN = _UPFN;
pVBoxAPI->UIID = _UIID;
pVBoxAPI->UArray = _UArray;
@@ -11291,6 +11073,15 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->UIConsole = _UIConsole;
pVBoxAPI->UIProgress = _UIProgress;
pVBoxAPI->UISystemProperties = _UISystemProperties;
+ pVBoxAPI->UIBIOSSettings = _UIBIOSSettings;
+ pVBoxAPI->UIAudioAdapter = _UIAudioAdapter;
+ pVBoxAPI->UINetworkAdapter = _UINetworkAdapter;
+ pVBoxAPI->UISerialPort = _UISerialPort;
+ pVBoxAPI->UIParallelPort = _UIParallelPort;
+ pVBoxAPI->UIVRDxServer = _UIVRDxServer;
+ pVBoxAPI->UIUSBCommon = _UIUSBCommon;
+ pVBoxAPI->UIUSBDeviceFilter = _UIUSBDeviceFilter;
+ pVBoxAPI->UIMedium = _UIMedium;
pVBoxAPI->machineStateChecker = _machineStateChecker;
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
@@ -11309,10 +11100,24 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
/* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
pVBoxAPI->getMachineForSession = 1;
pVBoxAPI->detachDevicesExplicitly = 0;
+ pVBoxAPI->vboxAttachDrivesUseOld = 0;
#else /* VBOX_API_VERSION < 4000000 */
pVBoxAPI->getMachineForSession = 0;
pVBoxAPI->detachDevicesExplicitly = 1;
+ pVBoxAPI->vboxAttachDrivesUseOld = 1;
#endif /* VBOX_API_VERSION < 4000000 */
+
+#if VBOX_API_VERSION >= 4001000
+ pVBoxAPI->chipsetType = 1;
+#else /* VBOX_API_VERSION < 4001000 */
+ pVBoxAPI->chipsetType = 0;
+#endif /* VBOX_API_VERSION < 4001000 */
+
+#if VBOX_API_VERSION >= 3001000
+ pVBoxAPI->accelerate2DVideo = 1;
+#else /* VBOX_API_VERSION < 3001000 */
+ pVBoxAPI->accelerate2DVideo = 0;
+#endif /* VBOX_API_VERSION < 3001000 */
}
/**
diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h
index 01b91fc..439b1ed 100644
--- a/src/vbox/vbox_uniformed_api.h
+++ b/src/vbox/vbox_uniformed_api.h
@@ -180,14 +180,43 @@ typedef struct {
nsresult (*GetVersion)(IVirtualBox *vboxObj, PRUnichar **versionUtf16);
nsresult (*GetMachine)(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine
**machine);
nsresult (*GetSystemProperties)(IVirtualBox *vboxObj, ISystemProperties
**systemProperties);
+ nsresult (*CreateMachine)(vboxGlobalData *data, virDomainDefPtr def, IMachine
**machine, char *uuidstr);
+ nsresult (*RegisterMachine)(IVirtualBox *vboxObj, IMachine *machine);
+ nsresult (*FindMedium)(IVirtualBox *vboxObj, PRUnichar *location, PRUint32
deviceType, PRUint32 accessMode, IMedium **medium);
+ nsresult (*OpenMedium)(IVirtualBox *vboxObj, PRUnichar *location, PRUint32
deviceType, PRUint32 accessMode, IMedium **medium);
} vboxUniformedIVirtualBox;
/* Functions for IMachine */
typedef struct {
+ nsresult (*AddStorageController)(IMachine *machine, PRUnichar *name,
+ PRUint32 connectionType, IStorageController **controller);
+ nsresult (*AttachDevice)(IMachine *machine, PRUnichar *name,
+ PRInt32 controllerPort, PRInt32 device,
+ PRUint32 type, IMedium *medium);
+ nsresult (*CreateSharedFolder)(IMachine *machine, PRUnichar *name,
+ PRUnichar *hostPath, PRBool writable,
+ PRBool automount);
nsresult (*GetAccessible)(IMachine *machine, PRBool *isAccessible);
nsresult (*GetState)(IMachine *machine, PRUint32 *state);
nsresult (*GetName)(IMachine *machine, PRUnichar **name);
nsresult (*GetId)(IMachine *machine, vboxIIDUnion *iidu);
+ nsresult (*GetBIOSSettings)(IMachine *machine, IBIOSSettings **bios);
+ nsresult (*GetAudioAdapter)(IMachine *machine, IAudioAdapter **audioAdapter);
+ nsresult (*GetNetworkAdapter)(IMachine *machine, PRUint32 slot, INetworkAdapter
**adapter);
+ nsresult (*GetChipsetType)(IMachine *machine, PRUint32 *chipsetType);
+ nsresult (*GetSerialPort)(IMachine *machine, PRUint32 slot, ISerialPort **port);
+ nsresult (*GetParallelPort)(IMachine *machine, PRUint32 slot, IParallelPort **port);
+ nsresult (*GetVRDxServer)(IMachine *machine, IVRDxServer **VRDxServer);
+ nsresult (*GetUSBCommon)(IMachine *machine, IUSBCommon **USBCommon);
+ nsresult (*SetCPUCount)(IMachine *machine, PRUint32 CPUCount);
+ nsresult (*SetMemorySize)(IMachine *machine, PRUint32 memorySize);
+ nsresult (*SetCPUProperty)(IMachine *machine, PRUint32 property, PRBool value);
+ nsresult (*SetBootOrder)(IMachine *machine, PRUint32 position, PRUint32 device);
+ nsresult (*SetVRAMSize)(IMachine *machine, PRUint32 VRAMSize);
+ nsresult (*SetMonitorCount)(IMachine *machine, PRUint32 monitorCount);
+ nsresult (*SetAccelerate3DEnabled)(IMachine *machine, PRBool accelerate3DEnabled);
+ nsresult (*SetAccelerate2DVideoEnabled)(IMachine *machine, PRBool
accelerate2DVideoEnabled);
+ nsresult (*SetExtraData)(IMachine *machine, PRUnichar *key, PRUnichar *value);
nsresult (*SaveSettings)(IMachine *machine);
} vboxUniformedIMachine;
@@ -214,8 +243,93 @@ typedef struct {
/* Functions for ISystemProperties */
typedef struct {
nsresult (*GetMaxGuestCPUCount)(ISystemProperties *systemProperties, PRUint32
*maxCPUCount);
+ nsresult (*GetMaxBootPosition)(ISystemProperties *systemProperties, PRUint32
*maxBootPosition);
+ nsresult (*GetMaxNetworkAdapters)(ISystemProperties *systemProperties, PRUint32
chipset,
+ PRUint32 *maxNetworkAdapters);
+ nsresult (*GetSerialPortCount)(ISystemProperties *systemProperties, PRUint32
*SerialPortCount);
+ nsresult (*GetParallelPortCount)(ISystemProperties *systemProperties, PRUint32
*ParallelPortCount);
+ nsresult (*GetMaxPortCountForStorageBus)(ISystemProperties *systemProperties,
PRUint32 bus,
+ PRUint32 *maxPortCount);
+ nsresult (*GetMaxDevicesPerPortForStorageBus)(ISystemProperties *systemProperties,
+ PRUint32 bus, PRUint32
*maxDevicesPerPort);
} vboxUniformedISystemProperties;
+/* Functions for IBIOSSettings */
+typedef struct {
+ nsresult (*SetACPIEnabled)(IBIOSSettings *bios, PRBool ACPIEnabled);
+ nsresult (*SetIOAPICEnabled)(IBIOSSettings *bios, PRBool IOAPICEnabled);
+} vboxUniformedIBIOSSettings;
+
+/* Functions for IAudioAdapter */
+typedef struct {
+ nsresult (*SetEnabled)(IAudioAdapter *audioAdapter, PRBool enabled);
+ nsresult (*SetAudioController)(IAudioAdapter *audioAdapter, PRUint32
audioController);
+} vboxUniformedIAudioAdapter;
+
+/* Functions for INetworkAdapter */
+typedef struct {
+ nsresult (*SetEnabled)(INetworkAdapter *adapter, PRBool enabled);
+ nsresult (*SetAdapterType)(INetworkAdapter *adapter, PRUint32 adapterType);
+ nsresult (*SetBridgedInterface)(INetworkAdapter *adapter, PRUnichar
*bridgedInterface);
+ nsresult (*SetInternalNetwork)(INetworkAdapter *adapter, PRUnichar
*internalNetwork);
+ nsresult (*SetHostOnlyInterface)(INetworkAdapter *adapter, PRUnichar
*hostOnlyInterface);
+ nsresult (*SetMACAddress)(INetworkAdapter *adapter, PRUnichar *MACAddress);
+ nsresult (*AttachToBridgedInterface)(INetworkAdapter *adapter);
+ nsresult (*AttachToInternalNetwork)(INetworkAdapter *adapter);
+ nsresult (*AttachToHostOnlyInterface)(INetworkAdapter *adapter);
+ nsresult (*AttachToNAT)(INetworkAdapter *adapter);
+} vboxUniformedINetworkAdapter;
+
+/* Functions for ISerialPort */
+typedef struct {
+ nsresult (*SetEnabled)(ISerialPort *port, PRBool enabled);
+ nsresult (*SetPath)(ISerialPort *port, PRUnichar *path);
+ nsresult (*SetIRQ)(ISerialPort *port, PRUint32 IRQ);
+ nsresult (*SetIOBase)(ISerialPort *port, PRUint32 IOBase);
+ nsresult (*SetHostMode)(ISerialPort *port, PRUint32 hostMode);
+} vboxUniformedISerialPort;
+
+/* Functions for IParallelPort */
+typedef struct {
+ nsresult (*SetEnabled)(IParallelPort *port, PRBool enabled);
+ nsresult (*SetPath)(IParallelPort *port, PRUnichar *path);
+ nsresult (*SetIRQ)(IParallelPort *port, PRUint32 IRQ);
+ nsresult (*SetIOBase)(IParallelPort *port, PRUint32 IOBase);
+} vboxUniformedIParallelPort;
+
+/* Functions for IVRDPServer and IVRDEServer */
+typedef struct {
+ nsresult (*SetEnabled)(IVRDxServer *VRDxServer, PRBool enabled);
+ nsresult (*SetPorts)(vboxGlobalData *data, IVRDxServer *VRDxServer,
+ virDomainGraphicsDefPtr graphics);
+ nsresult (*SetReuseSingleConnection)(IVRDxServer *VRDxServer, PRBool enabled);
+ nsresult (*SetAllowMultiConnection)(IVRDxServer *VRDxServer, PRBool enabled);
+ nsresult (*SetNetAddress)(vboxGlobalData *data, IVRDxServer *VRDxServer,
+ PRUnichar *netAddress);
+} vboxUniformedIVRDxServer;
+
+/* Common Functions for IUSBController and IUSBDeviceFilters */
+typedef struct {
+ nsresult (*Enable)(IUSBCommon *USBCommon);
+ nsresult (*CreateDeviceFilter)(IUSBCommon *USBCommon, PRUnichar *name,
+ IUSBDeviceFilter **filter);
+ nsresult (*InsertDeviceFilter)(IUSBCommon *USBCommon, PRUint32 position,
+ IUSBDeviceFilter *filter);
+} vboxUniformedIUSBCommon;
+
+typedef struct {
+ nsresult (*SetProductId)(IUSBDeviceFilter *USBDeviceFilter, PRUnichar *productId);
+ nsresult (*SetActive)(IUSBDeviceFilter *USBDeviceFilter, PRBool active);
+ nsresult (*SetVendorId)(IUSBDeviceFilter *USBDeviceFilter, PRUnichar *vendorId);
+} vboxUniformedIUSBDeviceFilter;
+
+/* Functions for IMedium */
+typedef struct {
+ nsresult (*GetId)(IMedium *medium, vboxIIDUnion *iidu);
+ nsresult (*Release)(IMedium *medium);
+ nsresult (*SetType)(IMedium *medium, PRUint32 type);
+} vboxUniformedIMedium;
+
typedef struct {
bool (*Online)(PRUint32 state);
} uniformedMachineStateChecker;
@@ -230,6 +344,7 @@ typedef struct {
void (*detachDevices)(vboxGlobalData *data, IMachine *machine, PRUnichar
*hddcnameUtf16);
nsresult (*unregisterMachine)(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine
**machine);
void (*deleteConfig)(IMachine *machine);
+ void (*vboxAttachDrivesOld)(virDomainDefPtr def, vboxGlobalData *data, IMachine
*machine);
vboxUniformedPFN UPFN;
vboxUniformedIID UIID;
vboxUniformedArray UArray;
@@ -240,12 +355,24 @@ typedef struct {
vboxUniformedIConsole UIConsole;
vboxUniformedIProgress UIProgress;
vboxUniformedISystemProperties UISystemProperties;
+ vboxUniformedIBIOSSettings UIBIOSSettings;
+ vboxUniformedIAudioAdapter UIAudioAdapter;
+ vboxUniformedINetworkAdapter UINetworkAdapter;
+ vboxUniformedISerialPort UISerialPort;
+ vboxUniformedIParallelPort UIParallelPort;
+ vboxUniformedIVRDxServer UIVRDxServer;
+ vboxUniformedIUSBCommon UIUSBCommon;
+ vboxUniformedIUSBDeviceFilter UIUSBDeviceFilter;
+ vboxUniformedIMedium UIMedium;
uniformedMachineStateChecker machineStateChecker;
/* vbox API features */
bool domainEventCallbacks;
bool hasStaticGlobalData;
bool getMachineForSession;
bool detachDevicesExplicitly;
+ bool chipsetType;
+ bool accelerate2DVideo;
+ bool vboxAttachDrivesUseOld;
} vboxUniformedAPI;
/* libvirt API
@@ -269,6 +396,7 @@ int vboxConnectNumOfDomains(virConnectPtr conn);
virDomainPtr vboxDomainLookupByID(virConnectPtr conn, int id);
virDomainPtr vboxDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
+virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml);
int vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags);
/* Version specified functions for installing uniformed API */
--
1.7.9.5