[libvirt] [PATCH v2] conf: Generate address for scsi host device automatically
by Osier Yang
With unknown good reasons, the attribute "bus" of scsi device
address is always set to 0, same for attribute "target". (See
virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus"
and "target" too, that's a different issue. The address generator
for scsi host device in this patch just follows the unknown
good reasons, only considering the "controller" and "unit".
It walks through all scsi controllers and their units, to see
if the address $controller:0:0:$unit can be used, if found
one, it sits on it, otherwise, it creates a new controller
(actually the controller is implicitly created by someone
else), and sits on $new_controller:0:0:0 instead.
---
v1 - v2:
* A new helper virDomainSCSIDriveAddressIsUsed
* Move virDomainDefMaybeAddHostdevSCSIcontroller
* More comments
* Add testing.
* problems fixed with the testing:
1) s/nscsi_controllers + 1/nscsi_controllers/,
2) Add the controller implicitly after a scsi hostdev def
parsing, as it can use a new scsi controller index
(nscsi_controllers), which should be added implicitly.
---
src/conf/domain_conf.c | 209 ++++++++++++++++++---
.../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++
...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++
tests/qemuxml2xmltest.c | 2 +
4 files changed, 382 insertions(+), 30 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ad5550c..86d743b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3782,6 +3782,148 @@ cleanup:
return ret;
}
+/* Check if a drive type address $controller:0:0:$unit is already
+ * taken by a disk or not.
+ */
+static bool
+virDomainDriveAddressIsUsedByDisk(virDomainDefPtr def,
+ enum virDomainDiskBus type,
+ unsigned int controller,
+ unsigned int unit)
+{
+ virDomainDiskDefPtr disk;
+ int i;
+
+ for (i = 0; i < def->ndisks; i++) {
+ disk = def->disks[i];
+
+ if (disk->bus != type ||
+ disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
+ continue;
+
+ if (disk->info.addr.drive.controller == controller &&
+ disk->info.addr.drive.unit == unit &&
+ disk->info.addr.drive.bus == 0 &&
+ disk->info.addr.drive.target == 0)
+ return true;
+ }
+
+ return false;
+}
+
+/* Check if a drive type address $controller:0:0:$unit is already
+ * taken by a host device or not.
+ */
+static bool
+virDomainDriveAddressIsUsedByHostdev(virDomainDefPtr def,
+ enum virDomainHostdevSubsysType type,
+ unsigned int controller,
+ unsigned int unit)
+{
+ virDomainHostdevDefPtr hostdev;
+ int i;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ hostdev = def->hostdevs[i];
+
+ if (hostdev->source.subsys.type != type)
+ continue;
+
+ if (hostdev->info->addr.drive.controller == controller &&
+ hostdev->info->addr.drive.unit == unit &&
+ hostdev->info->addr.drive.bus == 0 &&
+ hostdev->info->addr.drive.target == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+virDomainSCSIDriveAddressIsUsed(virDomainDefPtr def,
+ unsigned int controller,
+ unsigned int unit)
+{
+ /* In current implementation, the maximum unit number of a controller
+ * is either 16 or 7 (narrow SCSI bus), and if the maximum unit number
+ * is 16, the controller itself is on unit 7 */
+ if (unit == 7)
+ return true;
+
+ if (virDomainDriveAddressIsUsedByDisk(def, VIR_DOMAIN_DISK_BUS_SCSI,
+ controller, unit) ||
+ virDomainDriveAddressIsUsedByHostdev(def, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI,
+ controller, unit))
+ return true;
+
+ return false;
+}
+
+/* Find out the next usable "unit" of a specific controller */
+static int
+virDomainControllerSCSINextUnit(virDomainDefPtr def,
+ unsigned int max_unit,
+ unsigned int controller)
+{
+ int i;
+
+ for (i = 0; i < max_unit; i++) {
+ if (!virDomainSCSIDriveAddressIsUsed(def, controller, i))
+ return i;
+ }
+
+ return -1;
+}
+
+#define SCSI_WIDE_BUS_MAX_CONT_UNIT 16
+#define SCSI_NARROW_BUS_MAX_CONT_UNIT 7
+
+static int
+virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt,
+ virDomainDefPtr def,
+ virDomainHostdevDefPtr hostdev)
+{
+ int next_unit;
+ unsigned nscsi_controllers = 0;
+ bool found = false;
+ int i;
+
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
+ return -1;
+
+ for (i = 0; i < def->ncontrollers; i++) {
+ if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
+ continue;
+
+ nscsi_controllers++;
+ next_unit = virDomainControllerSCSINextUnit(def,
+ xmlopt->config.hasWideScsiBus ?
+ SCSI_WIDE_BUS_MAX_CONT_UNIT :
+ SCSI_NARROW_BUS_MAX_CONT_UNIT,
+ def->controllers[i]->idx);
+ if (next_unit >= 0) {
+ found = true;
+ break;
+ }
+ }
+
+ hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
+
+ if (found) {
+ hostdev->info->addr.drive.controller = def->controllers[i]->idx;
+ hostdev->info->addr.drive.bus = 0;
+ hostdev->info->addr.drive.target = 0;
+ hostdev->info->addr.drive.unit = next_unit;
+ } else {
+ hostdev->info->addr.drive.controller = nscsi_controllers;
+ hostdev->info->addr.drive.bus = 0;
+ hostdev->info->addr.drive.target = 0;
+ hostdev->info->addr.drive.unit = 0;
+ }
+
+ return 0;
+}
+
static int
virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
xmlXPathContextPtr ctxt,
@@ -8802,7 +8944,9 @@ error:
}
static virDomainHostdevDefPtr
-virDomainHostdevDefParseXML(const xmlNodePtr node,
+virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
+ virDomainDefPtr vmdef,
+ const xmlNodePtr node,
xmlXPathContextPtr ctxt,
virHashTablePtr bootHash,
unsigned int flags)
@@ -8862,7 +9006,9 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
}
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
- if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+ virDomainHostdevAssignAddress(xmlopt, vmdef, def) < 0) {
+
virReportError(VIR_ERR_XML_ERROR, "%s",
_("SCSI host devices must have address specified"));
goto error;
@@ -9271,8 +9417,8 @@ virDomainDeviceDefParse(const char *xmlStr,
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) {
dev->type = VIR_DOMAIN_DEVICE_HOSTDEV;
- if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, ctxt, NULL,
- flags)))
+ if (!(dev->data.hostdev = virDomainHostdevDefParseXML(xmlopt, def, node,
+ ctxt, NULL, flags)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "controller")) {
dev->type = VIR_DOMAIN_DEVICE_CONTROLLER;
@@ -10255,6 +10401,30 @@ error:
return NULL;
}
+static int
+virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def)
+{
+ /* Look for any hostdev scsi dev */
+ int i;
+ int maxController = -1;
+ virDomainHostdevDefPtr hostdev;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ hostdev = def->hostdevs[i];
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
+ (int)hostdev->info->addr.drive.controller > maxController) {
+ maxController = hostdev->info->addr.drive.controller;
+ }
+ }
+
+ for (i = 0; i <= maxController; i++) {
+ if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0)
+ return -1;
+ }
+
+ return 0;
+}
static virDomainDefPtr
virDomainDefParseXML(xmlDocPtr xml,
@@ -11618,7 +11788,8 @@ virDomainDefParseXML(xmlDocPtr xml,
for (i = 0; i < n; i++) {
virDomainHostdevDefPtr hostdev;
- hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags);
+ hostdev = virDomainHostdevDefParseXML(xmlopt, def, nodes[i],
+ ctxt, bootHash, flags);
if (!hostdev)
goto error;
@@ -11631,6 +11802,9 @@ virDomainDefParseXML(xmlDocPtr xml,
}
def->hostdevs[def->nhostdevs++] = hostdev;
+
+ if (virDomainDefMaybeAddHostdevSCSIcontroller(def) < 0)
+ goto error;
}
VIR_FREE(nodes);
@@ -13232,31 +13406,6 @@ virDomainDefMaybeAddSmartcardController(virDomainDefPtr def)
return 0;
}
-static int
-virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def)
-{
- /* Look for any hostdev scsi dev */
- int i;
- int maxController = -1;
- virDomainHostdevDefPtr hostdev;
-
- for (i = 0; i < def->nhostdevs; i++) {
- hostdev = def->hostdevs[i];
- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
- (int)hostdev->info->addr.drive.controller > maxController) {
- maxController = hostdev->info->addr.drive.controller;
- }
- }
-
- for (i = 0; i <= maxController; i++) {
- if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0)
- return -1;
- }
-
- return 0;
-}
-
/*
* Based on the declared <address/> info for any devices,
* add necessary drive controllers which are not already present
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml
new file mode 100644
index 0000000..21f112b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml
@@ -0,0 +1,95 @@
+<domain type='qemu'>
+ <name>QEMUGuest2</name>
+ <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='scsi' index='0' model='virtio-scsi'/>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host0'/>
+ <address bus='0' target='0' unit='0'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host1'/>
+ <address bus='0' target='0' unit='1'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host2'/>
+ <address bus='0' target='0' unit='2'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host3'/>
+ <address bus='0' target='0' unit='3'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host4'/>
+ <address bus='0' target='0' unit='4'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host5'/>
+ <address bus='0' target='0' unit='5'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host6'/>
+ <address bus='0' target='0' unit='6'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host7'/>
+ <address bus='0' target='0' unit='7'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host8'/>
+ <address bus='0' target='0' unit='8'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host9'/>
+ <address bus='0' target='0' unit='9'/>
+ </source>
+ <address type='drive' controller='1' bus='0' target='0' unit='5'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host10'/>
+ <address bus='0' target='0' unit='10'/>
+ </source>
+ </hostdev>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
new file mode 100644
index 0000000..e416654
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
@@ -0,0 +1,106 @@
+<domain type='qemu'>
+ <name>QEMUGuest2</name>
+ <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='scsi' index='0' model='virtio-scsi'/>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='scsi' index='1'/>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host0'/>
+ <address bus='0' target='0' unit='0'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host1'/>
+ <address bus='0' target='0' unit='1'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='1'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host2'/>
+ <address bus='0' target='0' unit='2'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='2'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host3'/>
+ <address bus='0' target='0' unit='3'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='3'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host4'/>
+ <address bus='0' target='0' unit='4'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='4'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host5'/>
+ <address bus='0' target='0' unit='5'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='5'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host6'/>
+ <address bus='0' target='0' unit='6'/>
+ </source>
+ <address type='drive' controller='0' bus='0' target='0' unit='6'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host7'/>
+ <address bus='0' target='0' unit='7'/>
+ </source>
+ <address type='drive' controller='1' bus='0' target='0' unit='0'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host8'/>
+ <address bus='0' target='0' unit='8'/>
+ </source>
+ <address type='drive' controller='1' bus='0' target='0' unit='1'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host9'/>
+ <address bus='0' target='0' unit='9'/>
+ </source>
+ <address type='drive' controller='1' bus='0' target='0' unit='5'/>
+ </hostdev>
+ <hostdev mode='subsystem' type='scsi' managed='yes'>
+ <source>
+ <adapter name='scsi_host10'/>
+ <address bus='0' target='0' unit='10'/>
+ </source>
+ <address type='drive' controller='1' bus='0' target='0' unit='2'/>
+ </hostdev>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 64a271c..06e4206 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -298,6 +298,8 @@ mymain(void)
DO_TEST("hostdev-scsi-shareable");
DO_TEST("hostdev-scsi-sgio");
+ DO_TEST_DIFFERENT("hostdev-scsi-autogen-address");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
--
1.8.1.4
11 years, 6 months
[libvirt] DTD or Schema for VM definition file
by Jorge Fábregas
Hi there,
Is there any DTD or Schema for the VM's XML file? I found an
interesting doc called "Domain XML Format", on the libvirt website,
which explains all the elements but didn't find any reference to a
Schema or DTD.
Thanks,
Jorge
11 years, 6 months
[libvirt] [PATCH] build: use correct rpc.h for lockd
by Eric Blake
On cygwin, the build failed with:
In file included from ./rpc/virnetmessage.h:24:0,
from ./rpc/virnetclient.h:29,
from locking/lock_driver_lockd.c:31:
./rpc/virnetprotocol.h:9:21: fatal error: rpc/rpc.h: No such file or directory
* src/Makefile.am (lockd_la_CFLAGS): Add XDR_CFLAGS.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under build-breaker rule.
src/Makefile.am | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 430a356..7c404b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1727,7 +1727,9 @@ lockd_la_SOURCES = \
$(LOCK_DRIVER_LOCKD_SOURCES) \
$(LOCK_PROTOCOL_GENERATED) \
$(NULL)
-lockd_la_CFLAGS = -I$(top_srcdir)/src/conf $(AM_CFLAGS)
+lockd_la_CFLAGS = -I$(top_srcdir)/src/conf \
+ $(XDR_CFLAGS) \
+ $(AM_CFLAGS)
lockd_la_LDFLAGS = -module -avoid-version
lockd_la_LIBADD = ../gnulib/lib/libgnu.la libvirt-net-rpc.la libvirt-net-rpc-client.la
augeas_DATA += locking/libvirt_lockd.aug
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] build: work around cygwin header bug
by Eric Blake
A bug in Cygwin [1] and poor error messages from gcc [2] lead
to this confusing compilation error:
qemu/qemu_monitor.c:418:9: error: passing argument 2 of 'sendmsg' from incmpatible pointer type
/usr/include/sys/socket.h:42:11: note: expected 'const struct msghdr *' but argument is of type 'struct msghdr *'
[1] http://cygwin.com/ml/cygwin/2013-05/msg00451.html
[2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57475
* src/qemu/qemu_monitor.c (includes): Include <sys/socket.h>
before <sys/un.h>.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule.
src/qemu/qemu_monitor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 4e35f79..ad326c5 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -24,6 +24,7 @@
#include <config.h>
#include <poll.h>
+#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
--
1.8.1.4
11 years, 6 months
[libvirt] Entering freeze for libvirt-1.0.6
by Daniel Veillard
As planned, I just tagged the rc1 release in git and pushed
tarball and rpms to the FTP repository:
ftp://libvirt.org/
So focuse should be given to bug fixes this week, and if everything
goes well I will make the release on Monday 3, a week from now.
I gave a bit of testing to the rc1 rpms, seems to work okay for KVM on
Fedora but further testing would be a good idea, on other
distro/platforms and also other hypervisor, especially with VirtualBox
as the driver was mdified to now rely on the daemon for support of
that hypervisor.
thanks in advance,
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
11 years, 6 months
[libvirt] VFIO device groups and libvirt
by Laine Stump
VFIO device assignment has a concept of device "groups"; each group is a
set of devices that must all be assigned to the same guest (alternately,
unassigned devices can be attached to the vfio stub driver). This is to
prevent cross-guest (or guest-host) contamination of devices that share
DMA mapping or some such thing and thus can't be completely isolated
from each other.
The vfio support currently in libvirt works with no problems if no other
devices are in the same "group" as a device being assigned to a guest.
If there are other devices in the group, it fails with a message noting
that the other devices in the group must also be attached to the vfio
stub driver (so that the host can't use them).
I am now adding code to libvirt that, when receiving a request to attach
a device in a group to the vfio stub, will notice the other devices in
the group and attach them to the stub as well; it will then allow
attaching all of these devices to the guest, but not to any other guest.
This will be nice for those who *want* this behavior, but I think that
very often a person trying to assign a device that's in a group doesn't
even realize that it's in a group, and if they knew it was in a group,
they *wouldn't* want to lose all those devices just to assign one (once
a single device in a group is assigned to the guest, none of the other
devices in the group are usable by the host).
An example of this was encountered by Cole the other day. He had a
non-SRIOV network card plugged into his system that he wanted to assign
with VFIO, but it turned out that due to the hardware layout of his
motherboard, this plugin network card was placed in a group with 2
devices that were part of the motherboard chipset. When this occurs, a
user might want to take one of three different courses:
1) attach all those onboard devices to the vfio stub driver too (making
them inaccessible to the host, but allowing the assignment of the target
device via VFIO)
2) use legacy KVM device assignment instead (which is less secure, but
will allow assigning one of the devices while the rest remain available
to the host)
3) try plugging the card they want to assign into a different slot
(which may remove the device from this group and place it in another,
possibly empty, group)
It's difficult to say which the user will want, so I don't want the new
"attach all devices in the group to the stub" code to be automatic.
Instead, I think it should only take effect if some option is specified
in the device's <driver> element. For example:
<hostdev managed='yes'>
<driver name='vfio' group='allow'/>
...
</hostdev>
Without that xml option, the same error message logged now will continue
to be logged. With that xml option, all the devices in the group will be
attached to the vfio stub driver.
Likewise, in virNodeDeviceDetachFlags(), a VIR_NODE_DEVICE_DETACH_GROUP
flag will have the following effect:
Single device in group - no effect
Multiple devices, no flag - detach will fail
Multiple devices, flag set - all devices in the same group as
specified device will be detached by one call.
Does this sound reasonable?
11 years, 6 months
[libvirt] [PATCH 00/12] A bunch of extensions to libxl driver
by Marek Marczykowski
This are some additional features to libxl driver. Some of them require change
in domain config structures/syntax. Details described with each patch.
The last two patches are bugfix for deadlock during daemon startup.
Marek Marczykowski (12):
libxl: allow script for any network interface, not only bridge
libxl: PCI passthrough support
libxl: nodeDevice* support for PCI devices
libxl: populate xenstore memory entries at startup
conf: add 'script' attribute to disk specification
libxl: use disk 'script' attribute
conf: support backend domain name in disk and network devices
libxl: support backend domain setting for disk and net devices
libxl: fill HVM SDL and VNC settings based on <graphics/> entries
RFC: libxl: special 'stubdom-dm' emulator to use qemu in stub domain
conf: virDomainObjListRemoveLocked function
libxl: fix deadlock in libxlReconnectDomain
docs/schemas/domaincommon.rng | 14 ++
src/conf/domain_conf.c | 54 ++++++++
src/conf/domain_conf.h | 5 +
src/libvirt_private.syms | 1 +
src/libxl/libxl_conf.c | 297 +++++++++++++++++++++++++++++++++---------
src/libxl/libxl_conf.h | 6 +-
src/libxl/libxl_driver.c | 253 +++++++++++++++++++++++++++++++----
7 files changed, 545 insertions(+), 85 deletions(-)
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] build: port qemu to cygwin
by Eric Blake
A cygwin build of the qemu driver fails with:
qemu/qemu_process.c: In function 'qemuPrepareCpumap':
qemu/qemu_process.c:1803:31: error: 'CPU_SETSIZE' undeclared (first use in this function)
CPU_SETSIZE is a Linux extension in <sched.h>; a bit more portable
is using sysconf if _SC_NPROCESSORS_CONF is defined (several platforms
have it, including Cygwin). Ultimately, I would have preferred to
use gnulib's 'nproc' module, but it is currently under an incompatible
license.
* src/qemu/qemu_conf.h (QEMUD_CPUMASK_LEN): Provide definition on
cygwin.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
I'll wait for a review on this one, particularly since I'm still
trying to solve another qemu failure on cygwin:
qemu/qemu_monitor.c:418:9: error: passing argument 2 of 'sendmsg' from incmpatible pointer type
/usr/include/sys/socket.h:42:11: note: expected 'const struct msghdr *' but argument is of type 'struct msghdr *'
src/qemu/qemu_conf.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index df0791e..42566b4 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -45,7 +45,13 @@
# include "locking/lock_manager.h"
# include "qemu_capabilities.h"
-# define QEMUD_CPUMASK_LEN CPU_SETSIZE
+# ifdef CPU_SETSIZE /* Linux */
+# define QEMUD_CPUMASK_LEN CPU_SETSIZE
+# elif defined(_SC_NPROCESSORS_CONF) /* Cygwin */
+# define QEMUD_CPUMASK_LEN (sysconf(_SC_NPROCESSORS_CONF))
+# else
+# error "Port me"
+# endif
typedef struct _virQEMUCloseCallbacks virQEMUCloseCallbacks;
typedef virQEMUCloseCallbacks *virQEMUCloseCallbacksPtr;
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] build: cast [ug]id_t when printing
by Eric Blake
This is a recurring problem for cygwin :)
For example, see commit 23a4df88.
qemu/qemu_driver.c: In function 'qemuStateInitialize':
qemu/qemu_driver.c:691:13: error: format '%d' expects type 'int', but argument 8 has type 'uid_t' [-Wformat]
* src/qemu/qemu_driver.c (qemuStateInitialize): Add casts.
* daemon/remote.c (remoteDispatchAuthList): Likewise.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule.
daemon/remote.c | 4 ++--
src/qemu/qemu_driver.c | 16 ++++++++++------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 0e253bf..47267c2 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1,7 +1,7 @@
/*
* remote.c: handlers for RPC method calls
*
- * Copyright (C) 2007-2012 Red Hat, Inc.
+ * Copyright (C) 2007-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -2354,7 +2354,7 @@ remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED,
} else if (callerUid == 0) {
char *ident;
if (virAsprintf(&ident, "pid:%lld,uid:%d",
- (long long) callerPid, callerUid) < 0) {
+ (long long) callerPid, (int) callerUid) < 0) {
virReportOOMError();
goto cleanup;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4a76f14..d0dee14 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -690,25 +690,29 @@ qemuStateInitialize(bool privileged,
if (chown(cfg->libDir, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership of '%s' to user %d:%d"),
- cfg->libDir, cfg->user, cfg->group);
+ cfg->libDir, (int) cfg->user,
+ (int) cfg->group);
goto error;
}
if (chown(cfg->cacheDir, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership of '%s' to %d:%d"),
- cfg->cacheDir, cfg->user, cfg->group);
+ cfg->cacheDir, (int) cfg->user,
+ (int) cfg->group);
goto error;
}
if (chown(cfg->saveDir, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership of '%s' to %d:%d"),
- cfg->saveDir, cfg->user, cfg->group);
+ cfg->saveDir, (int) cfg->user,
+ (int) cfg->group);
goto error;
}
if (chown(cfg->snapshotDir, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership of '%s' to %d:%d"),
- cfg->snapshotDir, cfg->user, cfg->group);
+ cfg->snapshotDir, (int) cfg->user,
+ (int) cfg->group);
goto error;
}
run_uid = cfg->user;
@@ -752,8 +756,8 @@ qemuStateInitialize(bool privileged,
if (chown(mempath, cfg->user, cfg->group) < 0) {
virReportSystemError(errno,
_("unable to set ownership on %s to %d:%d"),
- mempath, cfg->user,
- cfg->group);
+ mempath, (int) cfg->user,
+ (int) cfg->group);
goto error;
}
}
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] build: port vbox to cygwin
by Eric Blake
I have no idea if a Cygwin app can be made to directly interact with
VBoxXPCOMC.dll, but this at least lets compilation of vbox finish
rather than requiring me to ./configure --without-vbox.
* src/vbox/vbox_XPCOMCGlue.c (DYNLIB_NAME): Assume .dll under cygwin.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Although I'm tempted to push this under the build-breaker rule, and
although I suspect no one else is trying to build libvirt on cygwin,
I'll wait for a review on this one. An alternative, more conservative,
patch might be to hack configure.ac to declare vbox and cygwin as
incompatible.
src/vbox/vbox_XPCOMCGlue.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c
index 9719014..9cc41b0 100644
--- a/src/vbox/vbox_XPCOMCGlue.c
+++ b/src/vbox/vbox_XPCOMCGlue.c
@@ -3,6 +3,7 @@
*/
/*
+ * Copyright (C) 2013 Red Hat, Inc.
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
*
* This file is part of a free software library; you can redistribute
@@ -54,7 +55,7 @@
# define DYNLIB_NAME "VBoxXPCOMC.so"
#elif defined(__APPLE__)
# define DYNLIB_NAME "VBoxXPCOMC.dylib"
-#elif defined(_MSC_VER) || defined(__OS2__)
+#elif defined(_MSC_VER) || defined(__OS2__) || defined(__CYGWIN__)
# define DYNLIB_NAME "VBoxXPCOMC.dll"
#else
# error "Port me"
--
1.8.1.4
11 years, 6 months