[libvirt] [PATCH] storage: add lvchange operation while lvremove fails.
by chang liu
We found an issue that virStorageBackendLogicalDeleteVol() could not remove
the lv with notificaton "could not remove open logical volume.", in such
situation, we should disable the lv first, then delete it. this patch fix it.
*src/storage/storage_backend_logical.c
(virStorageBackendLogicalDeleteVol):lvremove fail, lvchange the volume
and then lvremove it second.
Signed-off-by: Chang Liu <lingjiao.lc(a)taobao.com>
---
configure.ac | 4 ++++
src/storage/storage_backend_logical.c | 14 ++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5753c08..6092c47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1691,6 +1691,7 @@ if test "$with_storage_lvm" = "yes" || test
"$with_storage_lvm" = "check"; then
AC_PATH_PROG([PVREMOVE], [pvremove], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([VGREMOVE], [vgremove], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([LVREMOVE], [lvremove], [], [$PATH:/sbin:/usr/sbin])
+ AC_PATH_PROG([LVCHANGE], [lvchange], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([VGCHANGE], [vgchange], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([VGSCAN], [vgscan], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([PVS], [pvs], [], [$PATH:/sbin:/usr/sbin])
@@ -1704,6 +1705,7 @@ if test "$with_storage_lvm" = "yes" || test
"$with_storage_lvm" = "check"; then
if test -z "$PVREMOVE" ; then AC_MSG_ERROR([We need pvremove for
LVM storage driver]) ; fi
if test -z "$VGREMOVE" ; then AC_MSG_ERROR([We need vgremove for
LVM storage driver]) ; fi
if test -z "$LVREMOVE" ; then AC_MSG_ERROR([We need lvremove for
LVM storage driver]) ; fi
+ if test -z "$LVCHANGE" ; then AC_MSG_ERROR([We need lvchange for
LVM storage driver]) ; fi
if test -z "$VGCHANGE" ; then AC_MSG_ERROR([We need vgchange for
LVM storage driver]) ; fi
if test -z "$VGSCAN" ; then AC_MSG_ERROR([We need vgscan for LVM
storage driver]) ; fi
if test -z "$PVS" ; then AC_MSG_ERROR([We need pvs for LVM
storage driver]) ; fi
@@ -1716,6 +1718,7 @@ if test "$with_storage_lvm" = "yes" || test
"$with_storage_lvm" = "check"; then
if test -z "$PVREMOVE" ; then with_storage_lvm=no ; fi
if test -z "$VGREMOVE" ; then with_storage_lvm=no ; fi
if test -z "$LVREMOVE" ; then with_storage_lvm=no ; fi
+ if test -z "$LVCHANGE" ; then with_storage_lvm=no ; fi
if test -z "$VGCHANGE" ; then with_storage_lvm=no ; fi
if test -z "$VGSCAN" ; then with_storage_lvm=no ; fi
if test -z "$PVS" ; then with_storage_lvm=no ; fi
@@ -1733,6 +1736,7 @@ if test "$with_storage_lvm" = "yes" || test
"$with_storage_lvm" = "check"; then
AC_DEFINE_UNQUOTED([PVREMOVE],["$PVREMOVE"],[Location of pvremove program])
AC_DEFINE_UNQUOTED([VGREMOVE],["$VGREMOVE"],[Location of vgremove program])
AC_DEFINE_UNQUOTED([LVREMOVE],["$LVREMOVE"],[Location of lvremove program])
+ AC_DEFINE_UNQUOTED([LVCHANGE],["$LVCHANGE"],[Location of lvchange program])
AC_DEFINE_UNQUOTED([VGCHANGE],["$VGCHANGE"],[Location of vgchange program])
AC_DEFINE_UNQUOTED([VGSCAN],["$VGSCAN"],[Location of vgscan program])
AC_DEFINE_UNQUOTED([PVS],["$PVS"],[Location of pvs program])
diff --git a/src/storage/storage_backend_logical.c
b/src/storage/storage_backend_logical.c
index 3c3e736..4a2acf1 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -772,13 +772,23 @@ virStorageBackendLogicalDeleteVol(virConnectPtr
conn ATTRIBUTE_UNUSED,
LVREMOVE, "-f", vol->target.path, NULL
};
+ const char *lvchange_cmd[] = {
+ LVCHANGE, "-a", "n", vol->target.path, NULL
+ };
+
virCheckFlags(0, -1);
virFileWaitForDevices();
if (virRun(cmdargv, NULL) < 0)
- return -1;
-
+ {
+ if(virRun(lvchange_cmd, NULL) < 0)
+ return -1;
+ else{
+ if(virRun(cmdargv,NULL) < 0)
+ return -1;
+ }
+ }
return 0;
}
--
1.7.6.2
13 years
[libvirt] [PATCH v4] pci address conflict when virtio disk with drive type
by Xu He Jie
When using the xml as below:
------------------------------------------------------
<devices>
<emulator>/home/soulxu/data/work-code/qemu-kvm/x86_64-softmmu/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/home/soulxu/data/VM/images/linux.img'/>
<target dev='vda' bus='virtio'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
</devices>
------------------------------------------------------
Then can't startup qemu, the error message as below:
virsh # start test-vm
error: Failed to start domain test-vm
error: internal error process exited while connecting to monitor: qemu-system-x86_64: -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3: PCI: slot 3 function 0 not available for virtio-balloon-pci, in use by virtio-blk-pci
qemu-system-x86_64: -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3: Device 'virtio-balloon-pci' could not be initialized
So adding check for bus type and address type. Only the address of pci type support by virtio bus.
Signed-off-by: Xu He Jie <xuhj(a)linux.vnet.ibm.com>
---
src/qemu/qemu_command.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0c5bfab..07eaece 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1319,15 +1319,21 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
goto error;
}
- /* Disks (VirtIO only for now */
+ /* Disks (VirtIO only for now) */
for (i = 0; i < def->ndisks ; i++) {
- if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
- continue;
-
/* Only VirtIO disks use PCI addrs */
if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
continue;
+ if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+ continue;
+
+ if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("virtio only support device address type 'PCI'"));
+ goto error;
+ }
+
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->disks[i]->info) < 0)
goto error;
}
--
1.7.5.4
13 years
[libvirt] [PATCH] qemu: Restore the original states of PCI device when restarting daemon
by Osier Yang
To support "managed" mode of host PCI device, we record the original
states (unbind_from_stub, remove_slot, and reprobe) so that could
reattach the device to host with original driver. But there is no XML
for theses attrs, and thus after daemon is restarted, we lose the
original states. It's easy to reproduce:
1) virsh start domain
2) virsh attach-device dom hostpci.xml (in 'managed' mode)
3) service libvirtd restart
4) virsh destroy domain
You will see the device won't be bound to the original driver
if there was one.
This patch is to solve the problem by introducing internal XML
(won't be dumped to user, only dumped to status XML). The XML is:
<origstates>
<unbind/>
<remove_slot/>
<reprobe/>
</origstates>
A new struct "virDomainHostdevOrigStates" is introduced for the XML,
and the according members are updated when preparing the PCI device.
And function "qemuUpdateActivePciHostdevs" is modified to honor
the original states. Use of qemuGetPciHostDeviceList is removed
in function "qemuUpdateActivePciHostdevs", and the "managed" value of
the device config is honored by the change. This fixes another problem
alongside:
qemuGetPciHostDeviceList set the device as "managed" force
regardless of whether the device is configured as "managed='yes'"
or not in XML, which is not right.
---
src/conf/domain_conf.c | 79 +++++++++++++++++++++++++++++++++++++++++-----
src/conf/domain_conf.h | 26 +++++++++++++++
src/libvirt_private.syms | 6 +++
src/qemu/qemu_hostdev.c | 79 ++++++++++++++++++++++++++++++++++++----------
src/util/pci.c | 36 +++++++++++++++++++++
src/util/pci.h | 9 +++++
6 files changed, 210 insertions(+), 25 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5959593..4ccf381 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -59,8 +59,12 @@ verify(VIR_DOMAIN_VIRT_LAST <= 32);
/* Private flags used internally by virDomainSaveStatus and
* virDomainLoadStatus. */
typedef enum {
- VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16), /* dump internal domain status information */
- VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET = (1<<17), /* dump/parse <actual> element */
+ /* dump internal domain status information */
+ VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16),
+ /* dump/parse <actual> element */
+ VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET = (1<<17),
+ /* dump/parse original states of host PCI device */
+ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES = (1<<18),
} virDomainXMLInternalFlags;
VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST,
@@ -5437,13 +5441,47 @@ out:
return ret;
}
+/* The internal XML for host PCI device's original states:
+ *
+ * <origstates>
+ * <unbind/>
+ * <removeslot/>
+ * <reprobe/>
+ * </origstates>
+ */
+static int
+virDomainHostdevSubsysPciOrigStatesDefParseXML(const xmlNodePtr node,
+ virDomainHostdevOrigStatesPtr def)
+{
+ xmlNodePtr cur;
+ cur = node->children;
+
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (xmlStrEqual(cur->name, BAD_CAST "unbind")) {
+ def->states.pci.unbind_from_stub = 1;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "removeslot")) {
+ def->states.pci.remove_slot = 1;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "reprobe")) {
+ def->states.pci.reprobe = 1;
+ } else {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unsupported element '%s' of 'origstates'"),
+ cur->name);
+ return -1;
+ }
+ }
+ cur = cur->next;
+ }
+
+ return 0;
+}
static int
virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node,
virDomainHostdevDefPtr def,
unsigned int flags)
{
-
int ret = -1;
xmlNodePtr cur;
@@ -5470,6 +5508,11 @@ virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node,
goto out;
}
def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ } else if ((flags & VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) &&
+ xmlStrEqual(cur->name, BAD_CAST "origstates")) {
+ virDomainHostdevOrigStatesPtr states = &def->origstates;
+ if (virDomainHostdevSubsysPciOrigStatesDefParseXML(cur, states) < 0)
+ goto out;
} else {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown pci source type '%s'"),
@@ -10445,7 +10488,9 @@ virDomainHostdevDefFormat(virBufferPtr buf,
}
type = virDomainHostdevSubsysTypeToString(def->source.subsys.type);
- if (!type || (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) ) {
+ if (!type ||
+ (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+ def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected hostdev type %d"),
def->source.subsys.type);
@@ -10474,6 +10519,20 @@ virDomainHostdevDefFormat(virBufferPtr buf,
def->source.subsys.u.pci.bus,
def->source.subsys.u.pci.slot,
def->source.subsys.u.pci.function);
+
+ if ((flags & VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) &&
+ (def->origstates.states.pci.unbind_from_stub ||
+ def->origstates.states.pci.remove_slot ||
+ def->origstates.states.pci.reprobe)) {
+ virBufferAddLit(buf, " <origstates>\n");
+ if (def->origstates.states.pci.unbind_from_stub)
+ virBufferAddLit(buf, " <unbind/>\n");
+ if (def->origstates.states.pci.remove_slot)
+ virBufferAddLit(buf, " <removeslot/>\n");
+ if (def->origstates.states.pci.reprobe)
+ virBufferAddLit(buf, " <reprobe/>\n");
+ virBufferAddLit(buf, " </origstates>\n");
+ }
}
virBufferAddLit(buf, " </source>\n");
@@ -10554,7 +10613,8 @@ virDomainHubDefFormat(virBufferPtr buf,
VIR_DOMAIN_XML_UPDATE_CPU)
verify(((VIR_DOMAIN_XML_INTERNAL_STATUS |
- VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET)
+ VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET |
+ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES)
& DUMPXML_FLAGS) == 0);
/* This internal version can accept VIR_DOMAIN_XML_INTERNAL_*,
@@ -10574,7 +10634,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virCheckFlags(DUMPXML_FLAGS |
VIR_DOMAIN_XML_INTERNAL_STATUS |
- VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET,
+ VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET |
+ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES,
-1);
if (!(type = virDomainVirtTypeToString(def->virtType))) {
@@ -11150,7 +11211,8 @@ int virDomainSaveStatus(virCapsPtr caps,
{
unsigned int flags = (VIR_DOMAIN_XML_SECURE |
VIR_DOMAIN_XML_INTERNAL_STATUS |
- VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET);
+ VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET |
+ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES);
int ret = -1;
char *xml;
@@ -11249,7 +11311,8 @@ static virDomainObjPtr virDomainLoadStatus(virCapsPtr caps,
if (!(obj = virDomainObjParseFile(caps, statusFile, expectedVirtTypes,
VIR_DOMAIN_XML_INTERNAL_STATUS |
- VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET)))
+ VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET |
+ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES)))
goto error;
virUUIDFormat(obj->def->uuid, uuidstr);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 2119b5a..c5eda75 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -153,6 +153,31 @@ struct _virDomainDeviceInfo {
} master;
};
+typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates;
+typedef virDomainHostdevOrigStates *virDomainHostdevOrigStatesPtr;
+struct _virDomainHostdevOrigStates {
+ union {
+ struct {
+ /* Does the device need to ubind from stub when
+ * reattaching to host?
+ */
+ unsigned int unbind_from_stub : 1;
+
+ /* Does it need to use remove_slot when reattaching
+ * the device to host?
+ */
+ unsigned int remove_slot : 1;
+
+ /* Does it need to reprobe driver for the device when
+ * reattaching to host?
+ */
+ unsigned int reprobe :1;
+ } pci;
+
+ /* Perhaps 'usb' in future */
+ } states;
+};
+
typedef struct _virDomainLeaseDef virDomainLeaseDef;
typedef virDomainLeaseDef *virDomainLeaseDefPtr;
struct _virDomainLeaseDef {
@@ -995,6 +1020,7 @@ struct _virDomainHostdevDef {
int bootIndex;
virDomainDeviceInfo info; /* Guest address */
int rombar; /* enum virDomainPciRombarMode */
+ virDomainHostdevOrigStates origstates;
};
enum virDomainRedirdevBus {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dedbd16..b85dabf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -882,6 +882,9 @@ pciDettachDevice;
pciDeviceFileIterate;
pciDeviceGetManaged;
pciDeviceGetName;
+pciDeviceGetRemoveSlot;
+pciDeviceGetReprobe;
+pciDeviceGetUnbindFromStub;
pciDeviceGetUsedBy;
pciDeviceIsAssignable;
pciDeviceIsVirtualFunction;
@@ -896,6 +899,9 @@ pciDeviceListSteal;
pciDeviceNetName;
pciDeviceReAttachInit;
pciDeviceSetManaged;
+pciDeviceSetRemoveSlot;
+pciDeviceSetReprobe;
+pciDeviceSetUnbindFromStub;
pciDeviceSetUsedBy;
pciFreeDevice;
pciGetDevice;
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 1fb373e..9137388 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -116,33 +116,46 @@ qemuGetActivePciHostDeviceList(struct qemud_driver *driver,
int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
virDomainDefPtr def)
{
- pciDeviceList *pcidevs;
- int ret = -1;
+ virDomainHostdevDefPtr hostdev = NULL;
+ int i;
if (!def->nhostdevs)
return 0;
- if (!(pcidevs = qemuGetPciHostDeviceList(def->hostdevs, def->nhostdevs)))
- return -1;
+ for (i = 0; i < def->nhostdevs; i++) {
+ pciDevice *dev = NULL;
+ hostdev = def->hostdevs[i];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ dev = pciGetDevice(hostdev->source.subsys.u.pci.domain,
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function);
+
+ if (!dev)
+ return -1;
+
+ pciDeviceSetManaged(dev, hostdev->managed);
+ pciDeviceSetUsedBy(dev, def->name);
+
+ /* Setup the original states for the PCI device */
+ pciDeviceSetUnbindFromStub(dev, hostdev->origstates.states.pci.unbind_from_stub);
+ pciDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot);
+ pciDeviceSetReprobe(dev, hostdev->origstates.states.pci.reprobe);
- while (pciDeviceListCount(pcidevs) > 0) {
- pciDevice *dev = pciDeviceListGet(pcidevs, 0);
- pciDeviceListSteal(pcidevs, dev);
if (pciDeviceListAdd(driver->activePciHostdevs, dev) < 0) {
pciFreeDevice(dev);
- goto cleanup;
+ return -1;
}
}
- ret = 0;
-
-cleanup:
- pciDeviceListFree(pcidevs);
- return ret;
+ return 0;
}
-
-
int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,
@@ -155,7 +168,7 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
if (!(pcidevs = qemuGetPciHostDeviceList(hostdevs, nhostdevs)))
return -1;
- /* We have to use 6 loops here. *All* devices must
+ /* We have to use 7 loops here. *All* devices must
* be detached before we reset any of them, because
* in some cases you have to reset the whole PCI,
* which impacts all devices on it. Also, all devices
@@ -232,7 +245,39 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
pciDeviceSetUsedBy(activeDev, name);
}
- /* Loop 6: Now steal all the devices from pcidevs */
+ /* Loop 6: Now set the original states for hostdev def */
+ for (i = 0; i < nhostdevs; i++) {
+ pciDevice *dev;
+ pciDevice *pcidev;
+ virDomainHostdevDefPtr hostdev = hostdevs[i];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ dev = pciGetDevice(hostdev->source.subsys.u.pci.domain,
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function);
+
+ /* original states "unbind_from_stub", "remove_slot",
+ * "reprobe" were already set by pciDettachDevice in
+ * loop 2.
+ */
+ if ((pcidev = pciDeviceListFind(pcidevs, dev))) {
+ hostdev->origstates.states.pci.unbind_from_stub =
+ pciDeviceGetUnbindFromStub(pcidev);
+ hostdev->origstates.states.pci.remove_slot =
+ pciDeviceGetRemoveSlot(pcidev);
+ hostdev->origstates.states.pci.reprobe =
+ pciDeviceGetReprobe(pcidev);
+ }
+
+ pciFreeDevice(dev);
+ }
+
+ /* Loop 7: Now steal all the devices from pcidevs */
while (pciDeviceListCount(pcidevs) > 0) {
pciDevice *dev = pciDeviceListGet(pcidevs, 0);
pciDeviceListSteal(pcidevs, dev);
diff --git a/src/util/pci.c b/src/util/pci.c
index 33b4b0e..b835979 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -1394,6 +1394,42 @@ unsigned pciDeviceGetManaged(pciDevice *dev)
return dev->managed;
}
+unsigned
+pciDeviceGetUnbindFromStub(pciDevice *dev)
+{
+ return dev->unbind_from_stub;
+}
+
+void
+pciDeviceSetUnbindFromStub(pciDevice *dev, unsigned unbind)
+{
+ dev->unbind_from_stub = !!unbind;
+}
+
+unsigned
+pciDeviceGetRemoveSlot(pciDevice *dev)
+{
+ return dev->remove_slot;
+}
+
+void
+pciDeviceSetRemoveSlot(pciDevice *dev, unsigned remove_slot)
+{
+ dev->remove_slot = !!remove_slot;
+}
+
+unsigned
+pciDeviceGetReprobe(pciDevice *dev)
+{
+ return dev->reprobe;
+}
+
+void
+pciDeviceSetReprobe(pciDevice *dev, unsigned reprobe)
+{
+ dev->reprobe = !!reprobe;
+}
+
void
pciDeviceSetUsedBy(pciDevice *dev, const char *name)
{
diff --git a/src/util/pci.h b/src/util/pci.h
index ab29c0b..76e37e3 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -51,6 +51,15 @@ unsigned pciDeviceGetManaged(pciDevice *dev);
void pciDeviceSetUsedBy(pciDevice *dev,
const char *used_by);
const char *pciDeviceGetUsedBy(pciDevice *dev);
+unsigned pciDeviceGetUnbindFromStub(pciDevice *dev);
+void pciDeviceSetUnbindFromStub(pciDevice *dev,
+ unsigned unbind);
+unsigned pciDeviceGetRemoveSlot(pciDevice *dev);
+void pciDeviceSetRemoveSlot(pciDevice *dev,
+ unsigned remove_slot);
+unsigned pciDeviceGetReprobe(pciDevice *dev);
+void pciDeviceSetReprobe(pciDevice *dev,
+ unsigned reprobe);
void pciDeviceReAttachInit(pciDevice *dev);
pciDeviceList *pciDeviceListNew (void);
--
1.7.6
13 years
[libvirt] [PATCH] vbox: Add support for VirtualBox 4.1
by Matthias Bolte
Deal with the incompatible changes in the VirtualBox 4.1 API.
INetworkAdapter has its different AttachTo* method replaced by
a settable attachmentType property.
The maximum number of network adapters is now requestable per
chipset type.
The OpenMedium method got a bool parameter to request opening
a medium under a new IID.
---
This patch is compile-tested only and was created by fixing compile
errors and looking at the changelog between VirtualBox 4.0 and 4.1.
As I currently don't have VirtualBox 4.1 installed and don't have
time to upgrade my system and test this, it would be nice if someone
with VirtualBox 4.1 at hand could runtime test this patch.
The new vbox_CAPI_v4_1.h header file hase been edited out of this patch.
The full patch is attached packed.
src/Makefile.am | 3 +-
src/vbox/vbox_CAPI_v4_1.h | 7882 +++++++++++++++++++++++++++++++++++++++++++++
src/vbox/vbox_V4_1.c | 13 +
src/vbox/vbox_driver.c | 8 +
src/vbox/vbox_tmpl.c | 88 +-
5 files changed, 7983 insertions(+), 11 deletions(-)
create mode 100644 src/vbox/vbox_CAPI_v4_1.h
create mode 100644 src/vbox/vbox_V4_1.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 2555f81..7f4b43c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -339,7 +339,8 @@ VBOX_DRIVER_SOURCES = \
vbox/vbox_V3_0.c vbox/vbox_CAPI_v3_0.h \
vbox/vbox_V3_1.c vbox/vbox_CAPI_v3_1.h \
vbox/vbox_V3_2.c vbox/vbox_CAPI_v3_2.h \
- vbox/vbox_V4_0.c vbox/vbox_CAPI_v4_0.h
+ vbox/vbox_V4_0.c vbox/vbox_CAPI_v4_0.h \
+ vbox/vbox_V4_1.c vbox/vbox_CAPI_v4_1.h
VBOX_DRIVER_EXTRA_DIST = \
vbox/vbox_tmpl.c vbox/README \
diff --git a/src/vbox/vbox_V4_1.c b/src/vbox/vbox_V4_1.c
new file mode 100644
index 0000000..00fab09
--- /dev/null
+++ b/src/vbox/vbox_V4_1.c
@@ -0,0 +1,13 @@
+/** @file vbox_V4_0.c
+ * C file to include support for multiple versions of VirtualBox
+ * at runtime.
+ */
+
+#include <config.h>
+
+/** The API Version */
+#define VBOX_API_VERSION 4001
+/** Version specific prefix. */
+#define NAME(name) vbox41##name
+
+#include "vbox_tmpl.c"
diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index 430ab40..3d208e8 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -60,6 +60,9 @@ extern virStorageDriver vbox32StorageDriver;
extern virDriver vbox40Driver;
extern virNetworkDriver vbox40NetworkDriver;
extern virStorageDriver vbox40StorageDriver;
+extern virDriver vbox41Driver;
+extern virNetworkDriver vbox41NetworkDriver;
+extern virStorageDriver vbox41StorageDriver;
static virDriver vboxDriverDummy;
@@ -122,6 +125,11 @@ int vboxRegister(void) {
driver = &vbox40Driver;
networkDriver = &vbox40NetworkDriver;
storageDriver = &vbox40StorageDriver;
+ } else if (uVersion >= 4000051 && uVersion < 4001051) {
+ VIR_DEBUG("VirtualBox API version: 4.1");
+ driver = &vbox41Driver;
+ networkDriver = &vbox41NetworkDriver;
+ storageDriver = &vbox41StorageDriver;
} else {
VIR_DEBUG("Unsupport VirtualBox API version");
}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index bc19b63..a956684 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -68,6 +68,8 @@
# include "vbox_CAPI_v3_2.h"
#elif VBOX_API_VERSION == 4000
# include "vbox_CAPI_v4_0.h"
+#elif VBOX_API_VERSION == 4001
+# include "vbox_CAPI_v4_1.h"
#else
# error "Unsupport VBOX_API_VERSION"
#endif
@@ -2207,6 +2209,9 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
#endif /* VBOX_API_VERSION >= 4000 */
IAudioAdapter *audioAdapter = NULL;
IUSBController *USBController = NULL;
+#if VBOX_API_VERSION >= 4001
+ PRUint32 chipsetType = ChipsetType_Null;
+#endif /* VBOX_API_VERSION >= 4001 */
ISystemProperties *systemProperties = NULL;
@@ -2218,11 +2223,19 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
machine->vtbl->GetMemorySize(machine, &memorySize);
def->mem.cur_balloon = memorySize * 1024;
+#if VBOX_API_VERSION >= 4001
+ machine->vtbl->GetChipsetType(machine, &chipsetType);
+#endif /* VBOX_API_VERSION >= 4001 */
+
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
if (systemProperties) {
systemProperties->vtbl->GetMaxGuestRAM(systemProperties, &maxMemorySize);
systemProperties->vtbl->GetMaxBootPosition(systemProperties, &maxBootPosition);
+#if VBOX_API_VERSION < 4001
systemProperties->vtbl->GetNetworkAdapterCount(systemProperties, &netAdpCnt);
+#else /* VBOX_API_VERSION >= 4000 */
+ systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties, chipsetType, &netAdpCnt);
+#endif /* VBOX_API_VERSION >= 4000 */
systemProperties->vtbl->GetSerialPortCount(systemProperties, &serialPortCount);
systemProperties->vtbl->GetParallelPortCount(systemProperties, ¶llelPortCount);
VBOX_RELEASE(systemProperties);
@@ -2826,7 +2839,11 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+#if VBOX_API_VERSION < 4001
adapter->vtbl->GetHostInterface(adapter, &hostIntUtf16);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->GetBridgedInterface(adapter, &hostIntUtf16);
+#endif /* VBOX_API_VERSION >= 4001 */
VBOX_UTF16_TO_UTF8(hostIntUtf16, &hostInt);
def->nets[netAdpIncCnt]->data.bridge.brname = strdup(hostInt);
@@ -2854,7 +2871,11 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_NETWORK;
+#if VBOX_API_VERSION < 4001
adapter->vtbl->GetHostInterface(adapter, &hostIntUtf16);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->GetHostOnlyInterface(adapter, &hostIntUtf16);
+#endif /* VBOX_API_VERSION >= 4001 */
VBOX_UTF16_TO_UTF8(hostIntUtf16, &hostInt);
def->nets[netAdpIncCnt]->data.network.name = strdup(hostInt);
@@ -4072,12 +4093,18 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
} else {
rc = 0;
}
-# else /* VBOX_API_VERSION >= 4000 */
+# elif VBOX_API_VERSION == 4000
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
mediumFileUtf16,
deviceType, accessMode,
&medium);
-# endif /* VBOX_API_VERSION >= 4000 */
+# elif VBOX_API_VERSION >= 4001
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
+ mediumFileUtf16,
+ deviceType, accessMode,
+ false,
+ &medium);
+# endif /* VBOX_API_VERSION >= 4001 */
VBOX_UTF16_FREE(mediumEmpty);
}
@@ -4206,13 +4233,25 @@ static void
vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
{
ISystemProperties *systemProperties = NULL;
+#if VBOX_API_VERSION >= 4001
+ PRUint32 chipsetType = ChipsetType_Null;
+#endif /* VBOX_API_VERSION >= 4001 */
PRUint32 networkAdapterCount = 0;
int i = 0;
+#if VBOX_API_VERSION >= 4001
+ machine->vtbl->GetChipsetType(machine, &chipsetType);
+#endif /* VBOX_API_VERSION >= 4001 */
+
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
if (systemProperties) {
+#if VBOX_API_VERSION < 4001
systemProperties->vtbl->GetNetworkAdapterCount(systemProperties,
&networkAdapterCount);
+#else /* VBOX_API_VERSION >= 4000 */
+ systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties, chipsetType,
+ &networkAdapterCount);
+#endif /* VBOX_API_VERSION >= 4000 */
VBOX_RELEASE(systemProperties);
systemProperties = NULL;
}
@@ -4285,19 +4324,31 @@ vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
PRUnichar *hostInterface = NULL;
/* Bridged Network */
+#if VBOX_API_VERSION < 4001
adapter->vtbl->AttachToBridgedInterface(adapter);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_Bridged);
+#endif /* VBOX_API_VERSION >= 4001 */
if (def->nets[i]->data.bridge.brname) {
VBOX_UTF8_TO_UTF16(def->nets[i]->data.bridge.brname,
&hostInterface);
+#if VBOX_API_VERSION < 4001
adapter->vtbl->SetHostInterface(adapter, hostInterface);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetBridgedInterface(adapter, hostInterface);
+#endif /* VBOX_API_VERSION >= 4001 */
VBOX_UTF16_FREE(hostInterface);
}
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
PRUnichar *internalNetwork = NULL;
/* Internal Network */
+#if VBOX_API_VERSION < 4001
adapter->vtbl->AttachToInternalNetwork(adapter);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_Internal);
+#endif /* VBOX_API_VERSION >= 4001 */
if (def->nets[i]->data.internal.name) {
VBOX_UTF8_TO_UTF16(def->nets[i]->data.internal.name,
@@ -4311,22 +4362,38 @@ vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
* on *nix and mac, on windows you can create and configure
* as many as you want)
*/
+#if VBOX_API_VERSION < 4001
adapter->vtbl->AttachToHostOnlyInterface(adapter);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_HostOnly);
+#endif /* VBOX_API_VERSION >= 4001 */
if (def->nets[i]->data.network.name) {
VBOX_UTF8_TO_UTF16(def->nets[i]->data.network.name,
&hostInterface);
+#if VBOX_API_VERSION < 4001
adapter->vtbl->SetHostInterface(adapter, hostInterface);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetHostOnlyInterface(adapter, hostInterface);
+#endif /* VBOX_API_VERSION >= 4001 */
VBOX_UTF16_FREE(hostInterface);
}
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
/* NAT */
+#if VBOX_API_VERSION < 4001
adapter->vtbl->AttachToNAT(adapter);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_NAT);
+#endif /* VBOX_API_VERSION >= 4001 */
} else {
/* else always default to NAT if we don't understand
* what option is been passed to us
*/
+#if VBOX_API_VERSION < 4001
adapter->vtbl->AttachToNAT(adapter);
+#else /* VBOX_API_VERSION >= 4001 */
+ adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_NAT);
+#endif /* VBOX_API_VERSION >= 4001 */
}
VBOX_UTF8_TO_UTF16(macaddrvbox, &MACAddress);
@@ -6534,9 +6601,10 @@ cleanup:
return ret;
}
-#if VBOX_API_VERSION == 2002 || VBOX_API_VERSION == 4000
+#if VBOX_API_VERSION <= 2002 || VBOX_API_VERSION >= 4000
/* No Callback support for VirtualBox 2.2.* series */
-#else /* !(VBOX_API_VERSION == 2002) && !(VBOX_API_VERSION == 4000) */
+ /* No Callback support for VirtualBox 4.* series */
+#else /* !(VBOX_API_VERSION == 2002 || VBOX_API_VERSION >= 4000) */
/* Functions needed for Callbacks */
static nsresult PR_COM_METHOD
@@ -7098,7 +7166,7 @@ static int vboxDomainEventDeregisterAny(virConnectPtr conn,
return ret;
}
-#endif /* !(VBOX_API_VERSION == 2002) && !(VBOX_API_VERSION == 4000) */
+#endif /* !(VBOX_API_VERSION == 2002 || VBOX_API_VERSION >= 4000) */
/**
* The Network Functions here on
@@ -8774,7 +8842,7 @@ static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
return ret;
}
-#if VBOX_API_VERSION == 4000
+#if VBOX_API_VERSION >= 4000
static char *
vboxDomainScreenshot(virDomainPtr dom,
virStreamPtr st,
@@ -8898,7 +8966,7 @@ endjob:
vboxIIDUnalloc(&iid);
return ret;
}
-#endif /* VBOX_API_VERSION == 4000 */
+#endif /* VBOX_API_VERSION >= 4000 */
/**
* Function Tables
@@ -8950,10 +9018,10 @@ virDriver NAME(Driver) = {
.domainUpdateDeviceFlags = vboxDomainUpdateDeviceFlags, /* 0.8.0 */
.nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.6.5 */
.nodeGetFreeMemory = nodeGetFreeMemory, /* 0.6.5 */
-#if VBOX_API_VERSION == 4000
+#if VBOX_API_VERSION >= 4000
.domainScreenshot = vboxDomainScreenshot, /* 0.9.2 */
#endif
-#if VBOX_API_VERSION != 2002 && VBOX_API_VERSION != 4000
+#if VBOX_API_VERSION > 2002 && VBOX_API_VERSION < 4000
.domainEventRegister = vboxDomainEventRegister, /* 0.7.0 */
.domainEventDeregister = vboxDomainEventDeregister, /* 0.7.0 */
#endif
@@ -8962,7 +9030,7 @@ virDriver NAME(Driver) = {
.domainIsActive = vboxDomainIsActive, /* 0.7.3 */
.domainIsPersistent = vboxDomainIsPersistent, /* 0.7.3 */
.domainIsUpdated = vboxDomainIsUpdated, /* 0.8.6 */
-#if VBOX_API_VERSION != 2002 && VBOX_API_VERSION != 4000
+#if VBOX_API_VERSION > 2002 && VBOX_API_VERSION < 4000
.domainEventRegisterAny = vboxDomainEventRegisterAny, /* 0.8.0 */
.domainEventDeregisterAny = vboxDomainEventDeregisterAny, /* 0.8.0 */
#endif
--
1.7.4.1
13 years
[libvirt] [PATCH] vbox: Support shared folders
by Matthias Bolte
Shared folders are handled as filesystems and can also be hotplugged.
---
Currently this just maps shared folder to a filesystem element with type
mount. The filesystem element has an accessmode attribute that is not
useful for VirtualBox. Als the target element only has a dir attribute,
but VirtualBox shares doen't support that, you can only give them a name.
<filesystem type='mount' accessmode='passthrough'>
<source dir='/tmp'/>
<target dir='foobar'/>
<readonly/>
</filesystem>
I wonder if we should add a shared folder type like this:
<filesystem type='sharedfolder'>
<source dir='/tmp'/>
<target name='foobar'/>
<readonly/>
</filesystem>
Or is this to specific to VirtualBox?
VirtualBox 4.0 added the automount option that automatically mounts a
shared folder in the guest. On Windows it is mounted to a free drive
letter on Linux it's mounted to /media/<prefix>_<shared-folder-name>.
The <prefix> is a global configuration option in VirtualBox. I wonder
if and how to expose that in libvirt.
Matthias
docs/drvvbox.html.in | 5 ++
src/vbox/vbox_tmpl.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/docs/drvvbox.html.in b/docs/drvvbox.html.in
index ef55757..1fcafde 100644
--- a/docs/drvvbox.html.in
+++ b/docs/drvvbox.html.in
@@ -61,6 +61,11 @@ vbox+ssh://user@example.com/session (remote access, SSH tunnelled)
<target dev='fda'/>
</disk>
+ <filesystem type='mount'>
+ <source dir='/home/user/stuff'/>
+ <target dir='my-shared-folder'/>
+ </filesystem>
+
<!--BRIDGE-->
<interface type='bridge'>
<source bridge='eth0'/>
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 2986f5a..13c324f 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2249,6 +2249,7 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, int flags) {
/* Not supported by libvirt yet */
} else if (device == DeviceType_SharedFolder) {
/* Not supported by libvirt yet */
+ /* Can VirtualBox really boot from a shared folder? */
}
}
@@ -2752,6 +2753,67 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, int flags) {
#endif /* VBOX_API_VERSION >= 3001 */
+ /* shared folders */
+ vboxArray sharedFolders = VBOX_ARRAY_INITIALIZER;
+
+ def->nfss = 0;
+
+ vboxArrayGet(&sharedFolders, machine,
+ machine->vtbl->GetSharedFolders);
+
+ if (sharedFolders.count > 0) {
+ if (VIR_ALLOC_N(def->fss, sharedFolders.count) < 0) {
+ virReportOOMError();
+ goto sharedFoldersCleanup;
+ }
+
+ for (i = 0; i < sharedFolders.count; i++) {
+ ISharedFolder *sharedFolder = sharedFolders.items[i];
+ PRUnichar *nameUtf16 = NULL;
+ char *name = NULL;
+ PRUnichar *hostPathUtf16 = NULL;
+ char *hostPath = NULL;
+ PRBool writable = PR_FALSE;
+
+ if (VIR_ALLOC(def->fss[i]) < 0) {
+ virReportOOMError();
+ goto sharedFoldersCleanup;
+ }
+
+ def->fss[i]->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+
+ sharedFolder->vtbl->GetHostPath(sharedFolder, &hostPathUtf16);
+ VBOX_UTF16_TO_UTF8(hostPathUtf16, &hostPath);
+ def->fss[i]->src = strdup(hostPath);
+ VBOX_UTF8_FREE(hostPath);
+ VBOX_UTF16_FREE(hostPathUtf16);
+
+ if (def->fss[i]->src == NULL) {
+ virReportOOMError();
+ goto sharedFoldersCleanup;
+ }
+
+ sharedFolder->vtbl->GetName(sharedFolder, &nameUtf16);
+ VBOX_UTF16_TO_UTF8(nameUtf16, &name);
+ def->fss[i]->dst = strdup(name);
+ VBOX_UTF8_FREE(name);
+ VBOX_UTF16_FREE(nameUtf16);
+
+ if (def->fss[i]->dst == NULL) {
+ virReportOOMError();
+ goto sharedFoldersCleanup;
+ }
+
+ sharedFolder->vtbl->GetWritable(sharedFolder, &writable);
+ def->fss[i]->readonly = !writable;
+
+ ++def->nfss;
+ }
+ }
+
+sharedFoldersCleanup:
+ vboxArrayRelease(&sharedFolders);
+
/* dump network cards if present */
def->nnets = 0;
/* Get which network cards are enabled */
@@ -4790,6 +4852,38 @@ vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
}
}
+static void
+vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+ int 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 < 4000
+ machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+ writable);
+#else /* VBOX_API_VERSION >= 4000 */
+ machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+ writable, PR_FALSE);
+#endif /* VBOX_API_VERSION >= 4000 */
+
+ VBOX_UTF16_FREE(nameUtf16);
+ VBOX_UTF16_FREE(hostPathUtf16);
+ }
+}
+
static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
IMachine *machine = NULL;
@@ -4927,6 +5021,7 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
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.
@@ -5271,6 +5366,34 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
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 < 4000
+ rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+ writable);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+ writable, PR_FALSE);
+#endif /* VBOX_API_VERSION >= 4000 */
+
+ if (NS_FAILED(rc)) {
+ vboxError(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);
@@ -5425,6 +5548,23 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
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)) {
+ vboxError(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);
--
1.7.0.4
13 years
[libvirt] [PATCH] xenapi: Improve error reporting in xenapiOpen once again
by Matthias Bolte
privP->session->error_description is a list and in order to get the
complete error message all parts of the list should be concatenated.
xenapiSessionErrorHandler does this when its third parameter is NULL.
The current code discards all but the first part of the error message
resulting in a potentially incomplete error message.
This partly reverts 006be75ee214f9b4, that tried to avoid reporting
a (null) in the error message. The actual problem is more general in
returnErrorFromSession that might return NULL if there is no error.
Make sure that returnErrorFromSession return non-NULL always. Also
don't skip the last error message part.
---
src/xenapi/xenapi_driver.c | 5 +----
src/xenapi/xenapi_utils.c | 4 +++-
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 97da1d1..77bf82d 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -193,10 +193,7 @@ xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth,
return VIR_DRV_OPEN_SUCCESS;
}
- xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED,
- *privP->session->error_description != NULL ?
- *privP->session->error_description :
- _("unknown error"));
+ xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED, NULL);
error:
VIR_FREE(username);
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
index 342ae5b..79fd946 100644
--- a/src/xenapi/xenapi_utils.c
+++ b/src/xenapi/xenapi_utils.c
@@ -272,12 +272,14 @@ returnErrorFromSession(xen_session *session)
{
int i;
virBuffer buf = VIR_BUFFER_INITIALIZER;
- for (i = 0; i < session->error_description_count - 1; i++) {
+ for (i = 0; i < session->error_description_count; i++) {
if (!i)
virBufferEscapeString(&buf, "%s", session->error_description[i]);
else
virBufferEscapeString(&buf, " : %s", session->error_description[i]);
}
+ if (virBufferUse(&buf) < 1)
+ virBufferAdd(&buf, _("unknown error"), -1);
return virBufferContentAndReset(&buf);
}
--
1.7.4.1
13 years
[libvirt] [PATCH] util: Fix virUUIDGeneratePseudoRandomBytes
by Ryota Ozaki
It forgets to move a pointer to a buffer for UUID and as a result
fills only the first byte of the buffer.
---
src/util/uuid.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/uuid.c b/src/util/uuid.c
index 0df3ebc..823a2b9 100644
--- a/src/util/uuid.c
+++ b/src/util/uuid.c
@@ -80,7 +80,7 @@ virUUIDGeneratePseudoRandomBytes(unsigned char *buf,
int buflen)
{
while (buflen > 0) {
- *buf = virRandom(256);
+ *buf++ = virRandom(256);
buflen--;
}
--
1.7.4.1
13 years
[libvirt] [PATCH] macvtap: Fix error return value convention/inconsistencies
by Roopa Prabhu
From: Roopa Prabhu <roprabhu(a)cisco.com>
- changed some return 1's to return -1
- changed if (rc) error checks to if (rc < 0)
- fixed some other minor convention violations
I might have missed some. Can fix in another patch or can respin
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
Reported-by: Eric Blake <eblake(a)redhat.com>
Reported-by: Laine Stump <laine(a)laine.org>
---
src/util/interface.c | 8 +++---
src/util/macvtap.c | 64 +++++++++++++++++++++++++++-----------------------
src/util/pci.c | 6 ++---
3 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/src/util/interface.c b/src/util/interface.c
index 5d473b7..4ab74b5 100644
--- a/src/util/interface.c
+++ b/src/util/interface.c
@@ -1244,7 +1244,7 @@ ifaceIsVirtualFunction(const char *ifname)
char *if_sysfs_device_link = NULL;
int ret = -1;
- if (ifaceSysfsFile(&if_sysfs_device_link, ifname, "device"))
+ if (ifaceSysfsFile(&if_sysfs_device_link, ifname, "device") < 0)
return ret;
ret = pciDeviceIsVirtualFunction(if_sysfs_device_link);
@@ -1272,10 +1272,10 @@ ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname,
char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL;
int ret = -1;
- if (ifaceSysfsFile(&pf_sysfs_device_link, pfname, "device"))
+ if (ifaceSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
return ret;
- if (ifaceSysfsFile(&vf_sysfs_device_link, vfname, "device")) {
+ if (ifaceSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) {
VIR_FREE(pf_sysfs_device_link);
return ret;
}
@@ -1306,7 +1306,7 @@ ifaceGetPhysicalFunction(const char *ifname, char **pfname)
char *physfn_sysfs_path = NULL;
int ret = -1;
- if (ifaceSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn"))
+ if (ifaceSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
return ret;
ret = pciDeviceNetName(physfn_sysfs_path, pfname);
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index f8b9d55..78e30f8 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -210,8 +210,11 @@ configMacvtapTap(int tapfd, int vnet_hdr)
rc_on_fail = -1;
errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap");
} else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) {
- if (ioctl(tapfd, TUNGETFEATURES, &features) != 0)
- return errno;
+ if (ioctl(tapfd, TUNGETFEATURES, &features) < 0) {
+ virReportSystemError(errno, "%s",
+ _("cannot get feature flags on macvtap tap"));
+ return -1;
+ }
if ((features & IFF_VNET_HDR)) {
new_flags = ifreq.ifr_flags | IFF_VNET_HDR;
errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap");
@@ -335,7 +338,7 @@ create_name:
macaddress,
linkdev,
virtPortProfile,
- vmuuid, vmOp) != 0) {
+ vmuuid, vmOp) < 0) {
rc = -1;
goto link_del_exit;
}
@@ -352,7 +355,6 @@ create_name:
}
rc = openTap(cr_ifname, 10);
-
if (rc >= 0) {
if (configMacvtapTap(rc, vnet_hdr) < 0) {
VIR_FORCE_CLOSE(rc); /* sets rc to -1 */
@@ -552,6 +554,8 @@ getPortProfileStatus(struct nlattr **tb, int32_t vf,
}
}
+ return rc;
+
err_exit:
if (msg)
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", msg);
@@ -572,7 +576,7 @@ doPortProfileOpSetLink(bool nltarget_kernel,
int32_t vf,
uint8_t op)
{
- int rc = 0;
+ int rc = -1;
struct nlmsghdr *resp;
struct nlmsgerr *err;
struct ifinfomsg ifinfo = {
@@ -588,7 +592,7 @@ doPortProfileOpSetLink(bool nltarget_kernel,
nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST);
if (!nl_msg) {
virReportOOMError();
- return -1;
+ return rc;
}
if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
@@ -690,16 +694,12 @@ doPortProfileOpSetLink(bool nltarget_kernel,
if (!nltarget_kernel) {
pid = getLldpadPid();
- if (pid == 0) {
- rc = -1;
+ if (pid == 0)
goto err_exit;
- }
}
- if (nlComm(nl_msg, &recvbuf, &recvbuflen, pid) < 0) {
- rc = -1;
+ if (nlComm(nl_msg, &recvbuf, &recvbuflen, pid) < 0)
goto err_exit;
- }
if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
goto malformed_resp;
@@ -716,7 +716,7 @@ doPortProfileOpSetLink(bool nltarget_kernel,
virReportSystemError(-err->error,
_("error during virtual port configuration of ifindex %d"),
ifindex);
- rc = -1;
+ goto err_exit;
}
break;
@@ -727,6 +727,8 @@ doPortProfileOpSetLink(bool nltarget_kernel,
goto malformed_resp;
}
+ rc = 0;
+
err_exit:
nlmsg_free(nl_msg);
@@ -740,14 +742,14 @@ malformed_resp:
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("malformed netlink response message"));
VIR_FREE(recvbuf);
- return -1;
+ return rc;
buffer_too_small:
nlmsg_free(nl_msg);
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("allocated netlink buffer is too small"));
- return -1;
+ return rc;
}
@@ -780,8 +782,7 @@ doPortProfileOpCommon(bool nltarget_kernel,
hostUUID,
vf,
op);
-
- if (rc) {
+ if (rc < 0) {
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("sending of PortProfileRequest failed."));
return rc;
@@ -790,11 +791,12 @@ doPortProfileOpCommon(bool nltarget_kernel,
while (--repeats >= 0) {
rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb,
&recvbuf, getLldpadPid);
- if (rc)
+ if (rc < 0)
goto err_exit;
+
rc = getPortProfileStatus(tb, vf, instanceId, nltarget_kernel,
is8021Qbg, &status);
- if (rc)
+ if (rc < 0)
goto err_exit;
if (status == PORT_PROFILE_RESPONSE_SUCCESS ||
status == PORT_VDP_RESPONSE_SUCCESS) {
@@ -818,7 +820,7 @@ doPortProfileOpCommon(bool nltarget_kernel,
if (status == PORT_PROFILE_RESPONSE_INPROGRESS) {
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("port-profile setlink timed out"));
- rc = -ETIMEDOUT;
+ rc = -2;
}
err_exit:
@@ -843,7 +845,7 @@ getPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname,
*vlanid = -1;
while (1) {
if ((ret = ifaceGetNthParent(ifindex, ifname, 1,
- root_ifindex, root_ifname, &nth)))
+ root_ifindex, root_ifname, &nth)) < 0)
return ret;
if (nth == 0)
break;
@@ -892,7 +894,7 @@ doPortProfileOp8021Qbg(const char *ifname,
int vf = PORT_SELF_VF;
if (getPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname,
- &vlanid) != 0)
+ &vlanid) < 0)
goto err_exit;
if (vlanid < 0)
@@ -943,10 +945,9 @@ getPhysfnDev(const char *linkdev,
int32_t *vf,
char **physfndev)
{
- int rc = 0;
-
- if (ifaceIsVirtualFunction(linkdev)) {
+ int rc = -1;
+ if (ifaceIsVirtualFunction(linkdev) == 1) {
/* if linkdev is SR-IOV VF, then set vf = VF index */
/* and set linkdev = PF device */
@@ -963,10 +964,13 @@ getPhysfnDev(const char *linkdev,
*physfndev = strdup(linkdev);
if (!*physfndev) {
virReportOOMError();
- rc = -1;
- }
+ goto err_exit;
+ }
+ rc = 0;
}
+err_exit:
+
return rc;
}
# endif /* IFLA_VF_PORT_MAX */
@@ -1000,7 +1004,7 @@ doPortProfileOp8021Qbh(const char *ifname,
int vlanid = -1;
rc = getPhysfnDev(ifname, &vf, &physfndev);
- if (rc)
+ if (rc < 0)
goto err_exit;
rc = ifaceGetIndex(true, physfndev, &ifindex);
@@ -1011,7 +1015,7 @@ doPortProfileOp8021Qbh(const char *ifname,
case PREASSOCIATE_RR:
case ASSOCIATE:
rc = virGetHostUUID(hostuuid);
- if (rc)
+ if (rc < 0)
goto err_exit;
rc = doPortProfileOpCommon(nltarget_kernel, NULL, ifindex,
@@ -1025,7 +1029,7 @@ doPortProfileOp8021Qbh(const char *ifname,
(virtPortOp == PREASSOCIATE_RR) ?
PORT_REQUEST_PREASSOCIATE_RR
: PORT_REQUEST_ASSOCIATE);
- if (rc == -ETIMEDOUT)
+ if (rc == -2)
/* Association timed out, disassociate */
doPortProfileOpCommon(nltarget_kernel, NULL, ifindex,
NULL,
diff --git a/src/util/pci.c b/src/util/pci.c
index 33b4b0e..077f3a2 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -1959,11 +1959,11 @@ pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
struct pci_config_address **virt_fns = NULL;
if (pciGetPciConfigAddressFromSysfsDeviceLink(vf_sysfs_device_link,
- &vf_bdf))
+ &vf_bdf) < 0)
return ret;
if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
- &num_virt_fns)) {
+ &num_virt_fns) < 0) {
pciReportError(VIR_ERR_INTERNAL_ERROR,
_("Error getting physical function's '%s' "
"virtual_functions"), pf_sysfs_device_link);
@@ -1971,7 +1971,7 @@ pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
}
for (i = 0; i < num_virt_fns; i++) {
- if (pciConfigAddressEqual(vf_bdf, virt_fns[i])) {
+ if (pciConfigAddressEqual(vf_bdf, virt_fns[i]) == 1) {
*vf_index = i;
ret = 0;
break;
13 years, 1 month
Re: [libvirt] [RFC PATCH v3 2/4] storage: add auth to virDomainDiskDef
by Daniel P. Berrange
On Thu, Oct 20, 2011 at 11:01:25AM -0700, Josh Durgin wrote:
> Add additional fields to let you specify the how to authenticate with a disk.
> The secret to use may be referenced by a usage string or a UUID, i.e.:
>
> <auth username='myuser'>
> <secret type='ceph' usage='secretname'/>
> </auth>
>
> or
>
> <auth username='myuser'>
> <secret type='ceph' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
> </auth>
>
> Signed-off-by: Josh Durgin <josh.durgin(a)dreamhost.com>
> ---
> docs/schemas/domaincommon.rng | 29 +++++++++++
> src/Makefile.am | 3 +-
> src/conf/domain_conf.c | 105 +++++++++++++++++++++++++++++++++++++---
> src/conf/domain_conf.h | 17 +++++++
> 4 files changed, 145 insertions(+), 9 deletions(-)
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 2555f81..7f48981 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -128,7 +128,8 @@ DOMAIN_CONF_SOURCES = \
> conf/capabilities.c conf/capabilities.h \
> conf/domain_conf.c conf/domain_conf.h \
> conf/domain_audit.c conf/domain_audit.h \
> - conf/domain_nwfilter.c conf/domain_nwfilter.h
> + conf/domain_nwfilter.c conf/domain_nwfilter.h \
> + conf/secret_conf.c
Unless I'm missing something, I don't think your code changes to
domain_conf.c actually introduce any dependancy on secret_conf.c
You include secret_conf.h, but that is only to get access to one
of the enum values. So there's no dep on the secret_conf.c code
and you can just drop this hunk
>
> DOMAIN_EVENT_SOURCES = \
> conf/domain_event.c conf/domain_event.h
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 5959593..1de3742 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -49,6 +49,7 @@
> #include "virfile.h"
> #include "bitmap.h"
> #include "count-one-bits.h"
> +#include "secret_conf.h"
>
> #define VIR_FROM_THIS VIR_FROM_DOMAIN
>
> @@ -185,6 +186,11 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
> "rbd",
> "sheepdog")
>
> +VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST,
> + "none",
> + "uuid",
> + "usage")
> +
> VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
> "default",
> "native",
> @@ -782,6 +788,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
> VIR_FREE(def->dst);
> VIR_FREE(def->driverName);
> VIR_FREE(def->driverType);
> + VIR_FREE(def->auth.username);
> + if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
> + VIR_FREE(def->auth.secret.usage);
> virStorageEncryptionFree(def->encryption);
> virDomainDeviceInfoClear(&def->info);
>
> @@ -2298,7 +2307,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> unsigned int flags)
> {
> virDomainDiskDefPtr def;
> - xmlNodePtr cur, host;
> + xmlNodePtr cur, child;
> char *type = NULL;
> char *device = NULL;
> char *snapshot = NULL;
> @@ -2319,6 +2328,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> char *devaddr = NULL;
> virStorageEncryptionPtr encryption = NULL;
> char *serial = NULL;
> + char *authUsername = NULL;
> + char *authUsage = NULL;
> + char *authUUID = NULL;
> + char *usageType = NULL;
>
> if (VIR_ALLOC(def) < 0) {
> virReportOOMError();
> @@ -2374,10 +2387,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> _("missing name for disk source"));
> goto error;
> }
> - host = cur->children;
> - while (host != NULL) {
> - if (host->type == XML_ELEMENT_NODE &&
> - xmlStrEqual(host->name, BAD_CAST "host")) {
> + child = cur->children;
> + while (child != NULL) {
> + if (child->type == XML_ELEMENT_NODE &&
> + xmlStrEqual(child->name, BAD_CAST "host")) {
> if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
> virReportOOMError();
> goto error;
> @@ -2386,20 +2399,20 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> hosts[nhosts].port = NULL;
> nhosts++;
>
> - hosts[nhosts - 1].name = virXMLPropString(host, "name");
> + hosts[nhosts - 1].name = virXMLPropString(child, "name");
> if (!hosts[nhosts - 1].name) {
> virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> "%s", _("missing name for host"));
> goto error;
> }
> - hosts[nhosts - 1].port = virXMLPropString(host, "port");
> + hosts[nhosts - 1].port = virXMLPropString(child, "port");
> if (!hosts[nhosts - 1].port) {
> virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> "%s", _("missing port for host"));
> goto error;
> }
> }
> - host = host->next;
> + child = child->next;
> }
> break;
> default:
> @@ -2436,6 +2449,58 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> iotag = virXMLPropString(cur, "io");
> ioeventfd = virXMLPropString(cur, "ioeventfd");
> event_idx = virXMLPropString(cur, "event_idx");
> + } else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
> + authUsername = virXMLPropString(cur, "username");
> + if (authUsername == NULL) {
> + virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> + _("missing username for auth"));
> + goto error;
> + }
> +
> + def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_NONE;
> + child = cur->children;
> + while (child != NULL) {
> + if (child->type == XML_ELEMENT_NODE &&
> + xmlStrEqual(child->name, BAD_CAST "secret")) {
> + usageType = virXMLPropString(child, "type");
> + if (usageType == NULL) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("missing type for secret"));
> + goto error;
> + }
> + if (virSecretUsageTypeTypeFromString(usageType) !=
> + VIR_SECRET_USAGE_TYPE_CEPH) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("invalid secret type %s"),
> + usageType);
> + goto error;
> + }
> +
> + authUUID = virXMLPropString(child, "uuid");
> + authUsage = virXMLPropString(child, "usage");
> +
> + if (authUUID != NULL && authUsage != NULL) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("only one of uuid and usage can be specfied"));
> + goto error;
> + }
> + if (authUUID != NULL) {
> + def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_UUID;
> + if (virUUIDParse(authUUID,
> + def->auth.secret.uuid) < 0) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("malformed uuid %s"),
> + authUUID);
> + goto error;
> + }
> + } else if (authUsage != NULL) {
> + def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_USAGE;
> + def->auth.secret.usage = authUsage;
> + authUsage = NULL;
> + }
> + }
> + child = child->next;
> + }
> } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
> def->readonly = 1;
> } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
> @@ -2654,6 +2719,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> hosts = NULL;
> def->nhosts = nhosts;
> nhosts = 0;
> + def->auth.username = authUsername;
> + authUsername = NULL;
> def->driverName = driverName;
> driverName = NULL;
> def->driverType = driverType;
> @@ -2690,6 +2757,10 @@ cleanup:
> VIR_FREE(hosts);
> VIR_FREE(protocol);
> VIR_FREE(device);
> + VIR_FREE(authUsername);
> + VIR_FREE(usageType);
> + VIR_FREE(authUUID);
> + VIR_FREE(authUsage);
> VIR_FREE(driverType);
> VIR_FREE(driverName);
> VIR_FREE(cachetag);
> @@ -9176,6 +9247,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
> const char *iomode = virDomainDiskIoTypeToString(def->iomode);
> const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd);
> const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
>
> if (!type) {
> virDomainReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -9234,6 +9306,23 @@ virDomainDiskDefFormat(virBufferPtr buf,
> virBufferAsprintf(buf, "/>\n");
> }
>
> + if (def->auth.username) {
> + virBufferAsprintf(buf, " <auth username='%s'>\n",
> + def->auth.username);
> + if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) {
> + virUUIDFormat(def->auth.secret.uuid, uuidstr);
> + virBufferAsprintf(buf,
> + " <secret type='passphrase' uuid='%s'/>\n",
> + uuidstr);
> + }
> + if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE) {
> + virBufferAsprintf(buf,
> + " <secret type='passphrase' usage='%s'/>\n",
> + def->auth.secret.usage);
> + }
> + virBufferAsprintf(buf, " </auth>\n");
> + }
> +
> if (def->src || def->nhosts > 0) {
> switch (def->type) {
> case VIR_DOMAIN_DISK_TYPE_FILE:
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 2119b5a..0d08040 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -269,6 +269,14 @@ enum virDomainSnapshotState {
> VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
> };
>
> +enum virDomainDiskSecretType {
> + VIR_DOMAIN_DISK_SECRET_TYPE_NONE,
> + VIR_DOMAIN_DISK_SECRET_TYPE_UUID,
> + VIR_DOMAIN_DISK_SECRET_TYPE_USAGE,
> +
> + VIR_DOMAIN_DISK_SECRET_TYPE_LAST
> +};
> +
> /* Stores the virtual disk configuration */
> typedef struct _virDomainDiskDef virDomainDiskDef;
> typedef virDomainDiskDef *virDomainDiskDefPtr;
> @@ -281,6 +289,14 @@ struct _virDomainDiskDef {
> int protocol;
> int nhosts;
> virDomainDiskHostDefPtr hosts;
> + struct {
> + char *username;
> + int secretType;
> + union {
> + unsigned char uuid[VIR_UUID_BUFLEN];
> + char *usage;
> + } secret;
> + } auth;
> char *driverName;
> char *driverType;
> char *serial;
> @@ -1868,6 +1884,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
> VIR_ENUM_DECL(virDomainDiskErrorPolicy)
> VIR_ENUM_DECL(virDomainDiskProtocol)
> VIR_ENUM_DECL(virDomainDiskIo)
> +VIR_ENUM_DECL(virDomainDiskSecretType)
> VIR_ENUM_DECL(virDomainDiskSnapshot)
> VIR_ENUM_DECL(virDomainIoEventFd)
> VIR_ENUM_DECL(virDomainVirtioEventIdx)
ACK with the Makefile.am hunk dropped
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
13 years, 1 month