Re: [libvirt] feature suggestion: migration network
by Dan Kenigsberg
On Thu, Jan 10, 2013 at 10:45:42AM +0800, Mark Wu wrote:
> On 01/08/2013 10:46 PM, Yaniv Kaul wrote:
> >On 08/01/13 15:04, Dan Kenigsberg wrote:
> >>There's talk about this for ages, so it's time to have proper discussion
> >>and a feature page about it: let us have a "migration" network role, and
> >>use such networks to carry migration data
> >>
> >>When Engine requests to migrate a VM from one node to another, the VM
> >>state (Bios, IO devices, RAM) is transferred over a TCP/IP connection
> >>that is opened from the source qemu process to the destination qemu.
> >>Currently, destination qemu listens for the incoming connection on the
> >>management IP address of the destination host. This has serious
> >>downsides: a "migration storm" may choke the destination's management
> >>interface; migration is plaintext and ovirtmgmt includes Engine which
> >>sits may sit the node cluster.
> >>
> >>With this feature, a cluster administrator may grant the "migration"
> >>role to one of the cluster networks. Engine would use that network's IP
> >>address on the destination host when it requests a migration of a VM.
> >>With proper network setup, migration data would be separated to that
> >>network.
> >>
> >>=== Benefit to oVirt ===
> >>* Users would be able to define and dedicate a separate network for
> >> migration. Users that need quick migration would use nics with high
> >> bandwidth. Users who want to cap the bandwidth consumed by migration
> >> could define a migration network over nics with bandwidth limitation.
> >>* Migration data can be limited to a separate network, that has no
> >> layer-2 access from Engine
> >>
> >>=== Vdsm ===
> >>The "migrate" verb should be extended with an additional parameter,
> >>specifying the address that the remote qemu process should listen on. A
> >>new argument is to be added to the currently-defined migration
> >>arguments:
> >>* vmId: UUID
> >>* dst: management address of destination host
> >>* dstparams: hibernation volumes definition
> >>* mode: migration/hibernation
> >>* method: rotten legacy
> >>* ''New'': migration uri, according to
> >>http://libvirt.org/html/libvirt-libvirt.html#virDomainMigrateToURI2
> >>such as tcp://<ip of migration network on remote node>
> >>
> >>=== Engine ===
> >>As usual, complexity lies here, and several changes are required:
> >>
> >>1. Network definition.
> >>1.1 A new network role - not unlike "display network" should be
> >> added.Only one migration network should be defined on a cluster.
> >>1.2 If none is defined, the legacy "use ovirtmgmt for migration"
> >> behavior would apply.
> >>1.3 A migration network is more likely to be a ''required'' network, but
> >> a user may opt for non-required. He may face unpleasant
> >>surprises if he
> >> wants to migrate his machine, but no candidate host has the network
> >> available.
> >>1.4 The "migration" role can be granted or taken on-the-fly, when hosts
> >> are active, as long as there are no currently-migrating VMs.
> >>
> >>2. Scheduler
> >>2.1 when deciding which host should be used for automatic
> >> migration, take into account the existence and availability of the
> >> migration network on the destination host.
> >>2.2 For manual migration, let user migrate a VM to a host with no
> >> migration network - if the admin wants to keep jamming the
> >> management network with migration traffic, let her.
> >>
> >>3. VdsBroker migration verb.
> >>3.1 For the a modern cluster level, with migration network defined on
> >> the destination host, an additional ''miguri'' parameter
> >>should be added
> >> to the "migrate" command
> >>
> >>_______________________________________________
> >>Arch mailing list
> >>Arch(a)ovirt.org
> >>http://lists.ovirt.org/mailman/listinfo/arch
> >
> >How is the authentication of the peers handled? Do we need a cert
> >per each source/destination logical interface?
> >Y.
> In my understanding, using a separate migration network doesn't
> change the current peers authentication. We still use the URI
> ''qemu+tls://remoeHost/system' to connect the target libvirt service
> if ssl enabled, and the remote host should be the ip address of
> management interface. But we can choose other interfaces except the
> manage interface to transport the migration data. We just change the
> migrateURI, so the current authentication mechanism should still
> work for this new feature.
vdsm-vdsm and libvirt-libvirt communication is authenticated, but I am
not sure at all that qemu-qemu communication is.
After qemu is sprung up on the destination with
-incoming <some ip>:<some port> , anything with access to that
address could hijack the process. Our migrateURI starts with "tcp://"
with all the consequences of this. That a good reason to make sure
<some ip> has as limited access as possible.
But maybe I'm wrong here, and libvir-list can show me the light.
Dan.
11 years, 11 months
[libvirt] [PATCH] libvirt: lxc: fix incorrect parameter of lxcContainerMountProcFuse
by Gao feng
when we have no host's src mapped to container's root.
there is not .oldroot dir,we should pass "/" to
lxcContainerMountProcFuse in function
lxcContainerSetupExtraMounts.
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
src/lxc/lxc_container.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index d234426..09a4365 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -2059,7 +2059,7 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef,
goto cleanup;
/* Mounts /proc/meminfo etc sysinfo */
- if (lxcContainerMountProcFuse(vmDef, "/.oldroot") < 0)
+ if (lxcContainerMountProcFuse(vmDef, "/") < 0)
goto cleanup;
/* Now we can re-mount the cgroups controllers in the
--
1.7.11.7
11 years, 11 months
[libvirt] libvirt RPC error
by Parakkal, Navin S
Hi,
I'm using qemu+ssh://username@hostname/system as the remote URI. Libvirt seems to be communicating fine until some 2 minutes (we poll every 5 seconds) and then it throws up RPC error and many counters are wrong. But if I collect on localhost the counters seems to be coming fine. Test and testvm are guests on the local machine where as Win8 and Ubuntu* are remote URI's connected through ssh.
What causes this error "libvir: RPC error : End of file while reading data: : Input/output error"
and how do we fix it ?
I've pasted the logfile inline.
Localhost from which we are connecting:
uname -aLinux iwf0044110 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
root@iwf0044110:/home1/parakkal/COLLABNET_11.10_NEW/hpsw-oa/PA/numsVob/linux/2.2/Linux2.6_64_debug# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04 LTS"
root@iwf0044110:/home1/parakkal/COLLABNET_11.10_NEW/hpsw-oa/PA/numsVob/linux/2.2/Linux2.6_64_debug# virsh version
Compiled against library: libvir 0.9.8
Using library: libvir 0.9.8
Using API: QEMU 0.9.8
Running hypervisor: QEMU 1.0.0
Remote host:
root@iwf004461:/home1/parakkal/COLLABNET_11.10_NEW/hpsw-oa/PA/numsVob/linux/2.2# uname -a
Linux iwf004461 3.0.0-12-server #20-Ubuntu SMP Fri Oct 7 16:36:30 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
root@iwf004461:/home1/parakkal/COLLABNET_11.10_NEW/hpsw-oa/PA/numsVob/linux/2.2# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.10
DISTRIB_CODENAME=oneiric
DISTRIB_DESCRIPTION="Ubuntu 11.10"
root@iwf004461:/home1/parakkal/COLLABNET_11.10_NEW/hpsw-oa/PA/numsVob/linux/2.2# virsh version
Compiled against library: libvir 0.9.2
Using library: libvir 0.9.2
Using API: QEMU 0.9.2
Running hypervisor: QEMU 0.14.1
Note: libvirt.so not present, using /usr/lib/libvirt.so.0
libvir: error : no connection driver available for No connection for URI xen:///
No Xen on this system
NOTE: 1 memory stats available out of 8
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: QEMU error : Requested operation is not valid: cgroup CPU controller is not mounted
NOTE: scheduler type not available
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:07 | testvm | Running
04:23:07 | test | Running
04:23:07 | Win8 | Running
04:23:07 | Ubuntu11.10 | Running
04:23:07 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:18 | testvm | Running
04:23:18 | test | Running
04:23:18 | Win8 | Running
04:23:18 | Ubuntu11.10 | Running
04:23:18 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:25 | testvm | Running
04:23:25 | test | Running
04:23:25 | Win8 | Running
04:23:25 | Ubuntu11.10 | Running
04:23:25 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:32 | testvm | Running
04:23:32 | test | Running
04:23:32 | Win8 | Running
04:23:32 | Ubuntu11.10 | Running
04:23:32 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:40 | testvm | Running
04:23:40 | test | Running
04:23:40 | Win8 | Running
04:23:40 | Ubuntu11.10 | Running
04:23:40 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:47 | testvm | Running
04:23:47 | test | Running
04:23:47 | Win8 | Running
04:23:47 | Ubuntu11.10 | Running
04:23:47 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:23:55 | testvm | Running
04:23:55 | test | Running
04:23:55 | Win8 | Running
04:23:55 | Ubuntu11.10 | Running
04:23:55 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:02 | testvm | Running
04:24:02 | test | Running
04:24:02 | Win8 | Running
04:24:02 | Ubuntu11.10 | Running
04:24:02 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:10 | testvm | Running
04:24:10 | test | Running
04:24:10 | Win8 | Running
04:24:10 | Ubuntu11.10 | Running
04:24:10 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:17 | testvm | Running
04:24:17 | test | Running
04:24:17 | Win8 | Running
04:24:17 | Ubuntu11.10 | Running
04:24:17 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:24 | testvm | Running
04:24:24 | test | Running
04:24:24 | Win8 | Running
04:24:24 | Ubuntu11.10 | Running
04:24:24 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:32 | testvm | Running
04:24:32 | test | Running
04:24:32 | Win8 | Running
04:24:32 | Ubuntu11.10 | Running
04:24:32 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:39 | testvm | Running
04:24:39 | test | Running
04:24:39 | Win8 | Running
04:24:39 | Ubuntu11.10 | Running
04:24:39 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:46 | testvm | Running
04:24:46 | test | Running
04:24:46 | Win8 | Running
04:24:46 | Ubuntu11.10 | Running
04:24:46 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:24:54 | testvm | Running
04:24:54 | test | Running
04:24:54 | Win8 | Running
04:24:54 | Ubuntu11.10 | Running
04:24:54 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:25:01 | testvm | Running
04:25:01 | test | Running
04:25:01 | Win8 | Running
04:25:01 | Ubuntu11.10 | Running
04:25:01 | Ubuntu12.04 | Running
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
libvir: error : internal error getaddrinfo failed for 'iwf004461': Name or service not known
04:25:09 | testvm | Running
04:25:09 | test | Running
04:25:09 | Win8 | Running
04:25:09 | Ubuntu11.10 | Running
04:25:09 | Ubuntu12.04 | Running
libvir: RPC error : End of file while reading data: : Input/output error
04:25:16 | testvm | Running
04:25:16 | test | Running
04:25:16 | Win8 | Nostate
04:25:16 | Ubuntu11.10 | Nostate
04:25:16 | Ubuntu12.04 | Nostate
libvir: RPC error : End of file while reading data: : Input/output error
04:25:20 | testvm | Running
04:25:20 | test | Running
04:25:20 | Win8 | Nostate
04:25:20 | Ubuntu11.10 | Nostate
04:25:20 | Ubuntu12.04 | Nostate
libvir: RPC error : End of file while reading data: : Input/output error
04:25:25 | testvm | Running
04:25:25 | test | Running
04:25:25 | Win8 | Nostate
04:25:25 | Ubuntu11.10 | Nostate
04:25:25 | Ubuntu12.04 | Nostate
Regards,
Navin
P.S. Please use reply all as I'm not subscribed to this list .
11 years, 11 months
[libvirt] [PATCH 2/2] libxl: support pci passthrough
by Chunyan Liu
Support PCI passthrough in libxl driver.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
src/libxl/libxl_conf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_conf.h | 5 ++++-
src/libxl/libxl_driver.c | 16 ++++++++++++++++
3 files changed, 64 insertions(+), 1 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 2705e65..223f7cb 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -814,6 +814,46 @@ error:
return -1;
}
+static int
+libxlMakePciList(virDomainDefPtr def, libxl_domain_config *d_config)
+{
+ virDomainHostdevDefPtr *l_hostdevs = def->hostdevs;
+ int nhostdevs = def->nhostdevs;
+ libxl_device_pci *x_pcidevs;
+ int i;
+
+ if (nhostdevs == 0)
+ return 0;
+
+ if (VIR_ALLOC_N(x_pcidevs, nhostdevs) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ d_config->num_pcidevs = 0;
+ d_config->pcidevs = x_pcidevs;
+
+ for (i = 0 ; i < nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = l_hostdevs[i];
+ libxl_device_pci pcidev;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ pcidev.domain = hostdev->source.subsys.u.pci.domain;
+ pcidev.bus = hostdev->source.subsys.u.pci.bus;
+ pcidev.dev = hostdev->source.subsys.u.pci.slot;
+ pcidev.func = hostdev->source.subsys.u.pci.function;
+
+ d_config->pcidevs[d_config->num_pcidevs] = pcidev;
+ d_config->num_pcidevs ++;
+ }
+
+ return 0;
+}
+
virCapsPtr
libxlMakeCapabilities(libxl_ctx *ctx)
{
@@ -863,6 +903,10 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
goto error;
}
+ if (libxlMakePciList(def, d_config) < 0) {
+ goto error;
+ }
+
d_config->on_reboot = def->onReboot;
d_config->on_poweroff = def->onPoweroff;
d_config->on_crash = def->onCrash;
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index c8808a1..704d8b8 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -35,7 +35,7 @@
# include "capabilities.h"
# include "configmake.h"
# include "virbitmap.h"
-
+# include "pci.h"
# define LIBXL_VNC_PORT_MIN 5900
# define LIBXL_VNC_PORT_MAX 65535
@@ -76,6 +76,9 @@ struct _libxlDriverPrivate {
char *stateDir;
char *libDir;
char *saveDir;
+
+ pciDeviceList *activePciHostdevs;
+ pciDeviceList *inactivePciHostdevs;
};
typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a956188..4670fee 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -42,6 +42,7 @@
#include "libxl.h"
#include "libxl_driver.h"
#include "libxl_conf.h"
+#include "libxl_hostdev.h"
#include "xen_xm.h"
#include "virtypedparam.h"
#include "viruri.h"
@@ -514,6 +515,8 @@ libxlVmReap(libxlDriverPrivatePtr driver,
return -1;
}
+ libxlDomainReAttachHostDevices(driver, vm->def);
+
libxlVmCleanup(driver, vm, reason);
return 0;
}
@@ -756,6 +759,10 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
VIR_FREE(managed_save_path);
}
+ VIR_DEBUG("Preparing host PCI devices");
+ if (libxlPrepareHostDevices(driver, vm->def) < 0)
+ goto error;
+
libxl_domain_config_init(&d_config);
if (libxlBuildDomainConfig(driver, vm->def, &d_config) < 0)
@@ -931,6 +938,8 @@ libxlShutdown(void)
VIR_FREE(libxl_driver->stateDir);
VIR_FREE(libxl_driver->libDir);
VIR_FREE(libxl_driver->saveDir);
+ pciDeviceListFree(libxl_driver->activePciHostdevs);
+ pciDeviceListFree(libxl_driver->inactivePciHostdevs);
virDomainEventStateFree(libxl_driver->domainEventState);
@@ -1077,6 +1086,12 @@ libxlStartup(bool privileged,
libxl_driver->caps->privateDataAllocFunc = libxlDomainObjPrivateAlloc;
libxl_driver->caps->privateDataFreeFunc = libxlDomainObjPrivateFree;
+ if ((libxl_driver->activePciHostdevs = pciDeviceListNew()) == NULL)
+ goto error;
+
+ if ((libxl_driver->inactivePciHostdevs = pciDeviceListNew()) == NULL)
+ goto error;
+
/* Load running domains first. */
if (virDomainLoadAllConfigs(libxl_driver->caps,
&libxl_driver->domains,
@@ -1549,6 +1564,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
/* vm is marked shutoff (or removed from domains list if not persistent)
* in shutdown event handler.
*/
+ libxlDomainReAttachHostDevices(driver, vm->def);
ret = 0;
cleanup:
--
1.7.3.4
11 years, 11 months
[libvirt] [PATCH 1/2] libxl: add APIs to prepare/release host pci device
by Chunyan Liu
Handle preparing and releasing host pci devices for PCI passthrough. Preparing
host pci devices will be used before vm is started, while releasing (or,
reattaching) will be used after vm is shut off.
Code refers to qemu driver, so add Red Hat copyright.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/libxl/libxl_hostdev.c | 600 +++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_hostdev.h | 44 ++++
4 files changed, 646 insertions(+), 0 deletions(-)
create mode 100644 src/libxl/libxl_hostdev.c
create mode 100644 src/libxl/libxl_hostdev.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 95619f9..a2b8d6b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -66,6 +66,7 @@ src/lxc/lxc_monitor.c
src/lxc/lxc_process.c
src/libxl/libxl_driver.c
src/libxl/libxl_conf.c
+src/libxl/libxl_hostdev.c
src/network/bridge_driver.c
src/node_device/node_device_driver.c
src/node_device/node_device_hal.c
diff --git a/src/Makefile.am b/src/Makefile.am
index da571c7..d7149b5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -531,6 +531,7 @@ XENAPI_DRIVER_SOURCES = \
LIBXL_DRIVER_SOURCES = \
libxl/libxl_conf.c libxl/libxl_conf.h \
+ libxl/libxl_hostdev.c libxl/libxl_hostdev.h \
libxl/libxl_driver.c libxl/libxl_driver.h
UML_DRIVER_SOURCES = \
diff --git a/src/libxl/libxl_hostdev.c b/src/libxl/libxl_hostdev.c
new file mode 100644
index 0000000..19c6d82
--- /dev/null
+++ b/src/libxl/libxl_hostdev.c
@@ -0,0 +1,600 @@
+/*---------------------------------------------------------------------------*/
+/* Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ * Copyright (C) 2011 Univention GmbH.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ * Chunyan Liu <cyliu(a)suse.com>
+ */
+/*---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "libxl_hostdev.h"
+#include "logging.h"
+#include "virterror_internal.h"
+#include "memory.h"
+#include "pci.h"
+#include "virnetdev.h"
+
+#define VIR_FROM_THIS VIR_FROM_LIBXL
+
+static pciDeviceList *
+libxlGetActivePciHostDeviceList(libxlDriverPrivatePtr driver,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs)
+{
+ pciDeviceList *list;
+ int i;
+
+ if (!(list = pciDeviceListNew()))
+ return NULL;
+
+ for (i = 0 ; i < nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = hostdevs[i];
+ pciDevice *dev;
+ pciDevice *activeDev;
+
+ 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) {
+ pciDeviceListFree(list);
+ return NULL;
+ }
+
+ if ((activeDev = pciDeviceListFind(driver->activePciHostdevs, dev))) {
+ if (pciDeviceListAdd(list, activeDev) < 0) {
+ pciFreeDevice(dev);
+ pciDeviceListFree(list);
+ return NULL;
+ }
+ }
+
+ pciFreeDevice(dev);
+ }
+
+ return list;
+}
+
+static pciDeviceList *
+libxlGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs)
+{
+ pciDeviceList *list;
+ int i;
+
+ if (!(list = pciDeviceListNew()))
+ return NULL;
+
+ for (i = 0 ; i < nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = hostdevs[i];
+ pciDevice *dev;
+
+ 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) {
+ pciDeviceListFree(list);
+ return NULL;
+ }
+
+ if (pciDeviceListAdd(list, dev) < 0) {
+ pciFreeDevice(dev);
+ pciDeviceListFree(list);
+ return NULL;
+ }
+
+ pciDeviceSetManaged(dev, hostdev->managed);
+ }
+
+ return list;
+}
+
+void libxlReattachPciDevice(pciDevice *dev, libxlDriverPrivatePtr driver)
+{
+ /* If the device is not managed and was attached to guest
+ * successfully, it must have been inactive.
+ */
+ if (!pciDeviceGetManaged(dev)) {
+ pciDeviceListAdd(driver->inactivePciHostdevs, dev);
+ return;
+ }
+
+ if (pciReAttachDevice(dev, driver->activePciHostdevs,
+ driver->inactivePciHostdevs, "pciback") < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to re-attach PCI device: %s"),
+ err ? err->message : _("unknown error"));
+ virResetError(err);
+ }
+}
+
+static int
+libxlDomainHostdevPciSysfsPath(virDomainHostdevDefPtr hostdev, char **sysfs_path)
+{
+ struct pci_config_address config_address;
+
+ config_address.domain = hostdev->source.subsys.u.pci.domain;
+ config_address.bus = hostdev->source.subsys.u.pci.bus;
+ config_address.slot = hostdev->source.subsys.u.pci.slot;
+ config_address.function = hostdev->source.subsys.u.pci.function;
+
+ return pciConfigAddressToSysfsFile(&config_address, sysfs_path);
+}
+
+static int
+libxlDomainHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
+{
+ char *sysfs_path = NULL;
+ int ret = -1;
+
+ if (libxlDomainHostdevPciSysfsPath(hostdev, &sysfs_path) < 0)
+ return ret;
+
+ ret = pciDeviceIsVirtualFunction(sysfs_path);
+
+ VIR_FREE(sysfs_path);
+
+ return ret;
+}
+
+static int
+libxlDomainHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
+ int *vf)
+{
+ int ret = -1;
+ char *sysfs_path = NULL;
+
+ if (libxlDomainHostdevPciSysfsPath(hostdev, &sysfs_path) < 0)
+ return ret;
+
+ if (pciDeviceIsVirtualFunction(sysfs_path) == 1) {
+ if (pciDeviceGetVirtualFunctionInfo(sysfs_path, linkdev,
+ vf) < 0)
+ goto cleanup;
+ } else {
+ if (pciDeviceNetName(sysfs_path, linkdev) < 0)
+ goto cleanup;
+ *vf = -1;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(sysfs_path);
+
+ return ret;
+}
+
+static int
+libxlDomainHostdevNetConfigVirtPortProfile(const char *linkdev, int vf,
+ virNetDevVPortProfilePtr virtPort,
+ const virMacAddrPtr macaddr,
+ const unsigned char *uuid,
+ int associate)
+{
+ int ret = -1;
+
+ if (!virtPort)
+ return ret;
+
+ switch (virtPort->virtPortType) {
+ case VIR_NETDEV_VPORT_PROFILE_NONE:
+ case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
+ case VIR_NETDEV_VPORT_PROFILE_8021QBG:
+ case VIR_NETDEV_VPORT_PROFILE_LAST:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("virtualport type %s is "
+ "currently not supported on interfaces of type "
+ "hostdev"),
+ virNetDevVPortTypeToString(virtPort->virtPortType));
+ break;
+
+ case VIR_NETDEV_VPORT_PROFILE_8021QBH:
+ if (associate)
+ ret = virNetDevVPortProfileAssociate(NULL, virtPort, macaddr,
+ linkdev, vf, uuid,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE, false);
+ else
+ ret = virNetDevVPortProfileDisassociate(NULL, virtPort,
+ macaddr, linkdev, vf,
+ VIR_NETDEV_VPORT_PROFILE_OP_DESTROY);
+ break;
+ }
+
+ return ret;
+}
+
+static int
+libxlDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
+ const unsigned char *uuid,
+ char *stateDir)
+{
+ char *linkdev = NULL;
+ virNetDevVlanPtr vlan;
+ virNetDevVPortProfilePtr virtPort;
+ int ret = -1;
+ int vf = -1;
+ int vlanid = -1;
+ int port_profile_associate = 1;
+ int isvf;
+
+ isvf = libxlDomainHostdevIsVirtualFunction(hostdev);
+ if (isvf <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Interface type hostdev is currently supported on"
+ " SR-IOV Virtual Functions only"));
+ return ret;
+ }
+
+ if (libxlDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
+ return ret;
+
+ vlan = virDomainNetGetActualVlan(hostdev->parent.data.net);
+ virtPort = virDomainNetGetActualVirtPortProfile(
+ hostdev->parent.data.net);
+ if (virtPort) {
+ if (vlan) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("direct setting of the vlan tag is not allowed "
+ "for hostdev devices using %s mode"),
+ virNetDevVPortTypeToString(virtPort->virtPortType));
+ goto cleanup;
+ }
+ ret = libxlDomainHostdevNetConfigVirtPortProfile(linkdev, vf,
+ virtPort, &hostdev->parent.data.net->mac, uuid,
+ port_profile_associate);
+ } else {
+ /* Set only mac and vlan */
+ if (vlan) {
+ if (vlan->nTags != 1 || vlan->trunk) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vlan trunking is not supported "
+ "by SR-IOV network devices"));
+ goto cleanup;
+ }
+ if (vf == -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("vlan can only be set for SR-IOV VFs, but "
+ "%s is not a VF"), linkdev);
+ goto cleanup;
+ }
+ vlanid = vlan->tag[0];
+ } else if (vf >= 0) {
+ vlanid = 0; /* assure any current vlan tag is reset */
+ }
+
+ ret = virNetDevReplaceNetConfig(linkdev, vf,
+ &hostdev->parent.data.net->mac,
+ vlanid, stateDir);
+ }
+cleanup:
+ VIR_FREE(linkdev);
+ return ret;
+}
+
+static int
+libxlDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
+ char *stateDir)
+{
+ char *linkdev = NULL;
+ virNetDevVPortProfilePtr virtPort;
+ int ret = -1;
+ int vf = -1;
+ int port_profile_associate = 0;
+ int isvf;
+
+ isvf = libxlDomainHostdevIsVirtualFunction(hostdev);
+ if (isvf <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Interface type hostdev is currently supported on"
+ " SR-IOV Virtual Functions only"));
+ return ret;
+ }
+
+ if (libxlDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
+ return ret;
+
+ virtPort = virDomainNetGetActualVirtPortProfile(
+ hostdev->parent.data.net);
+ if (virtPort)
+ ret = libxlDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort,
+ &hostdev->parent.data.net->mac, NULL,
+ port_profile_associate);
+ else
+ ret = virNetDevRestoreNetConfig(linkdev, vf, stateDir);
+
+ VIR_FREE(linkdev);
+
+ return ret;
+}
+
+void libxlDomainReAttachHostdevPciDevices(libxlDriverPrivatePtr driver,
+ const char *name,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs)
+{
+ pciDeviceList *pcidevs;
+ int i;
+
+ if (!(pcidevs = libxlGetActivePciHostDeviceList(driver,
+ hostdevs,
+ nhostdevs))) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to allocate pciDeviceList: %s"),
+ err ? err->message : _("unknown error"));
+ virResetError(err);
+ return;
+ }
+
+ /* Again 4 loops; mark all devices as inactive before reset
+ * them and reset all the devices before re-attach.
+ * Attach mac and port profile parameters to devices
+ */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ pciDevice *activeDev = NULL;
+
+ /* Never delete the dev from list driver->activePciHostdevs
+ * if it's used by other domain.
+ */
+ activeDev = pciDeviceListFind(driver->activePciHostdevs, dev);
+ if (activeDev &&
+ STRNEQ_NULLABLE(name, pciDeviceGetUsedBy(activeDev))) {
+ pciDeviceListSteal(pcidevs, dev);
+ continue;
+ }
+
+ /* pciDeviceListFree() will take care of freeing the dev. */
+ pciDeviceListSteal(driver->activePciHostdevs, dev);
+ }
+
+ /*
+ * For SRIOV net host devices, unset mac and port profile before
+ * reset and reattach device
+ */
+ for (i = 0; i < nhostdevs; i++) {
+ 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;
+ if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
+ hostdev->parent.data.net) {
+ libxlDomainHostdevNetConfigRestore(hostdev, driver->stateDir);
+ }
+ }
+
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ if (pciResetDevice(dev, driver->activePciHostdevs,
+ driver->inactivePciHostdevs) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to reset PCI device: %s"),
+ err ? err->message : _("unknown error"));
+ virResetError(err);
+ }
+ }
+
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ libxlReattachPciDevice(dev, driver);
+ }
+
+ pciDeviceListFree(pcidevs);
+}
+
+void libxlDomainReAttachHostDevices(libxlDriverPrivatePtr driver,
+ virDomainDefPtr def)
+{
+ if (!def->nhostdevs)
+ return;
+
+ libxlDomainReAttachHostdevPciDevices(driver, def->name, def->hostdevs,
+ def->nhostdevs);
+}
+
+int libxlPrepareHostdevPCIDevices(libxlDriverPrivatePtr driver,
+ const char *name,
+ const unsigned char *uuid,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs)
+{
+ pciDeviceList *pcidevs;
+ int last_processed_hostdev_vf = -1;
+ int i;
+ int ret = -1;
+
+ if (!(pcidevs = libxlGetPciHostDeviceList(hostdevs, nhostdevs)))
+ return -1;
+
+ /* Loop 1: validate that non-managed device isn't in use */
+
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ pciDevice *other;
+
+ /* The device is in use by other active domain if
+ * the dev is in list driver->activePciHostdevs.
+ */
+ if ((other = pciDeviceListFind(driver->activePciHostdevs, dev))) {
+ const char *other_name = pciDeviceGetUsedBy(other);
+
+ if (other_name)
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("PCI device %s is in use by domain %s"),
+ pciDeviceGetName(dev), other_name);
+ else
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("PCI device %s is already in use"),
+ pciDeviceGetName(dev));
+ goto cleanup;
+ }
+ }
+
+ /* Loop 2: detach managed devices */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ if (pciDeviceGetManaged(dev) &&
+ pciDettachDevice(dev, driver->activePciHostdevs, NULL, "pciback") < 0)
+ goto reattachdevs;
+ }
+
+ /* Loop 3: Now that all the PCI hostdevs have been detached, we
+ * can safely reset them */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ if (pciResetDevice(dev, driver->activePciHostdevs,
+ driver->inactivePciHostdevs) < 0)
+ goto reattachdevs;
+ }
+
+ /* Loop 4: For SRIOV network devices, Now that we have detached the
+ * the network device, set the netdev config */
+ for (i = 0; i < nhostdevs; i++) {
+ 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;
+ if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
+ hostdev->parent.data.net) {
+ if (libxlDomainHostdevNetConfigReplace(hostdev, uuid,
+ driver->stateDir) < 0) {
+ goto resetvfnetconfig;
+ }
+ }
+ last_processed_hostdev_vf = i;
+ }
+
+ /* Loop 5: Now mark all the devices as active */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ if (pciDeviceListAdd(driver->activePciHostdevs, dev) < 0) {
+ pciFreeDevice(dev);
+ goto inactivedevs;
+ }
+ }
+
+ /* Loop 6: Now remove the devices from inactive list. */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ pciDeviceListDel(driver->inactivePciHostdevs, dev);
+ }
+
+ /* Loop 7: Now set the used_by_domain of the device in
+ * driver->activePciHostdevs as domain name.
+ */
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev, *activeDev;
+
+ dev = pciDeviceListGet(pcidevs, i);
+ activeDev = pciDeviceListFind(driver->activePciHostdevs, dev);
+
+ pciDeviceSetUsedBy(activeDev, name);
+ }
+
+ /* Loop 8: 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 9: Now steal all the devices from pcidevs */
+ while (pciDeviceListCount(pcidevs) > 0) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, 0);
+ pciDeviceListSteal(pcidevs, dev);
+ }
+
+ ret = 0;
+ goto cleanup;
+
+inactivedevs:
+ /* Only steal all the devices from driver->activePciHostdevs. We will
+ * free them in pciDeviceListFree().
+ */
+ while (pciDeviceListCount(pcidevs) > 0) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, 0);
+ pciDeviceListSteal(driver->activePciHostdevs, dev);
+ }
+
+resetvfnetconfig:
+ for (i = 0; i < last_processed_hostdev_vf; i++) {
+ virDomainHostdevDefPtr hostdev = hostdevs[i];
+ if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
+ hostdev->parent.data.net) {
+ libxlDomainHostdevNetConfigRestore(hostdev, driver->stateDir);
+ }
+ }
+
+reattachdevs:
+ for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+ pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ pciReAttachDevice(dev, driver->activePciHostdevs, NULL, "pciback");
+ }
+
+cleanup:
+ pciDeviceListFree(pcidevs);
+ return ret;
+}
+
+int
+libxlPrepareHostDevices(libxlDriverPrivatePtr driver,
+ virDomainDefPtr def)
+{
+ return libxlPrepareHostdevPCIDevices(driver, def->name, def->uuid,
+ def->hostdevs, def->nhostdevs);
+}
diff --git a/src/libxl/libxl_hostdev.h b/src/libxl/libxl_hostdev.h
new file mode 100644
index 0000000..e5a5058
--- /dev/null
+++ b/src/libxl/libxl_hostdev.h
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*/
+/* Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Chunyan Liu <cyliu(a)suse.com>
+ */
+/*---------------------------------------------------------------------------*/
+
+#ifndef __LIBXL_HOSTDEV_H__
+# define __LIBXL_HOSTDEV_H__
+
+# include "libxl_conf.h"
+# include "domain_conf.h"
+
+int libxlPrepareHostdevPCIDevices(libxlDriverPrivatePtr driver,
+ const char *name,
+ const unsigned char *uuid,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs);
+int libxlPrepareHostDevices(libxlDriverPrivatePtr driver,
+ virDomainDefPtr def);
+void libxlReattachPciDevice(pciDevice *dev, libxlDriverPrivatePtr driver);
+void libxlDomainReAttachHostdevPciDevices(libxlDriverPrivatePtr driver,
+ const char *name,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs);
+void libxlDomainReAttachHostDevices(libxlDriverPrivatePtr driver,
+ virDomainDefPtr def);
+
+#endif /* __LIBXL_HOSTDEV_H__ */
--
1.7.3.4
11 years, 11 months
[libvirt] [PATCH qom-cpu 0/7] disable kvm_mmu + -cpu "enforce" fixes (v3)
by Eduardo Habkost
Changes on v3:
- Patches 3-9 from v2 are now already on qom-cpu tree
- Remove CONFIG_KVM #ifdefs by declaring fake KVM_* #defines on sysemu/kvm.h
- Refactor code that uses the feature word arrays
(to make it easier to add a new feature name array)
- Add feature name array for CPUID leaf 0xC0000001
Changes on v2:
- Now both the kvm_mmu-disable and -cpu "enforce" changes are on the same
series
- Coding style fixes
Git tree for reference:
git://github.com/ehabkost/qemu-hacks.git cpu-enforce-all.v3
https://github.com/ehabkost/qemu-hacks/tree/cpu-enforce-all.v3
The changes are a bit intrusive, but:
- The longer we take to make "enforce" strict as it should (and make libvirt
finally use it), more users will have VMs with migration-unsafe unpredictable
guest ABIs. For this reason, I would like to get this into QEMU 1.4.
- The changes in this series should affect only users that are already using
the "enforce" flag, and I believe whoever is using the "enforce" flag really
want the strict behavior introduced by this series.
Eduardo Habkost (7):
kvm: Add fake KVM constants to avoid #ifdefs on KVM-specific code
target-i386: Don't set any KVM flag by default if KVM is disabled
target-i386: Disable kvm_mmu by default
target-i386/cpu: Introduce FeatureWord typedefs
target-i386: kvm_check_features_against_host(): Use feature_word_info
target-i386/cpu.c: Add feature name array for ext4_features
target-i386: check/enforce: Check all feature words
include/sysemu/kvm.h | 14 ++++
target-i386/cpu.c | 193 ++++++++++++++++++++++++++++++++-------------------
target-i386/cpu.h | 15 ++++
3 files changed, 150 insertions(+), 72 deletions(-)
--
1.7.11.7
11 years, 11 months
[libvirt] [PATCH] build: require avahi instead of avahi-libs on rhel5.
by Yufang Zhang
On rhel5, libs of avahi are packaged into avahi instead of avahi-libs.
Actually, there is no avahi-libs package shipped with rhel5. This patch
fixes this by requiring avahi on rhel5.
---
libvirt.spec.in | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index d095eac..3362d3f 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -615,8 +615,12 @@ Requires: module-init-tools
# for /sbin/ip & /sbin/tc
Requires: iproute
%if %{with_avahi}
+%if 0%{?rhel} == 5
+Requires: avahi
+%else
Requires: avahi-libs
%endif
+%endif
%if %{with_network}
Requires: dnsmasq >= 2.41
Requires: radvd
--
1.7.4.1
11 years, 11 months
[libvirt] another tarball tweak
by Eric Blake
I tried sending this twice yesterday, but either it's stuck in some long
queue, or got eaten along the way by an overactive spam filter, as it
hasn't seemed to hit the list yet. Hopefully by sending by hand instead
of my normal 'git send-email', I can see it get through.
I'll push this under the build-breaker rule (yes, it's a bit of a
stretch, since extra files don't really hurt, but I want to avoid the
situation of a tarball being generated differently merely because of
different configure options).
From daa886b635e4a4f46782c8ac6274de1623e12f67 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake(a)redhat.com>
Date: Wed, 9 Jan 2013 15:07:30 -0700
Subject: [PATCH] maint: don't distribute generated .def files
I ran 'make dist' in the directory left over from ./autobuild.sh
(which was configured for a mingw cross build); the resulting
tarball had more files than 'make dist' on a normal Linux build.
I traced it to the fact that we were distributing a generated
file, but only when configure said the end user had to generate
the file in the first place. In the process, I noticed that
we had some difference in symbol file names; I added a comment
explaining why the difference exists (after first trying to
normalize the names and hitting VPATH build failures).
* configure.ac (LIBVIRT_QEMU_SYMBOL_FILE): Add some comments.
* src/Makefile.am (EXTRA_DIST): No need to ship a generated file;
particularly since which file is built depends on configure results.
---
configure.ac | 2 ++
src/Makefile.am | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 5acba9b..dd28401 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2676,6 +2676,8 @@ CYGWIN_EXTRA_LIBADD=
CYGWIN_EXTRA_PYTHON_LIBADD=
MINGW_EXTRA_LDFLAGS=
WIN32_EXTRA_CFLAGS=
+dnl libvirt.syms is generated in builddir, but libvirt_qemu.syms is in git;
+dnl hence the asymmetric naming of these two symbol files.
LIBVIRT_SYMBOL_FILE=libvirt.syms
LIBVIRT_QEMU_SYMBOL_FILE='$(srcdir)/libvirt_qemu.syms'
MSCOM_LIBS=
diff --git a/src/Makefile.am b/src/Makefile.am
index da571c7..8a4731b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1564,7 +1564,6 @@ libvirt_qemu_la_LDFLAGS =
$(VERSION_SCRIPT_FLAGS)$(LIBVIRT_QEMU_SYMBOL_FILE) \
$(AM_LDFLAGS)
libvirt_qemu_la_CFLAGS = $(AM_CFLAGS)
libvirt_qemu_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD)
-EXTRA_DIST += $(LIBVIRT_QEMU_SYMBOL_FILE)
lockdriverdir = $(libdir)/libvirt/lock-driver
lockdriver_LTLIBRARIES =
--
1.8.0.2
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
11 years, 11 months
[libvirt] [PATCH 0/2] spec file cleanups
by Eric Blake
While working on recent tarball issues, I noticed the spec file
was hard to read. In developing the second patch for my own
sanity, I found some cleanups that I separated out to the first
patch. I don't know if you want to apply the second patch, and
even if you do, it might be nice if 'cppi' could be enhanced to
enforce indentation rules in spec files the same way it does
for preprocessor rules in .c files (maybe even by using a
judicious tr to turn %if into #if of a temporary file, so that
existing cppi could do it); without enforcement, I'm afraid the
second patch will be quickly fall back into hard-to-read status.
Eric Blake (2):
spec: remove redundant %if
spec: indent %if to make it easier to see conditions
libvirt.spec.in | 864 ++++++++++++++++++++++++++++----------------------------
1 file changed, 428 insertions(+), 436 deletions(-)
--
1.8.0.2
11 years, 11 months
[libvirt] [PATCH] docs: fix typo in isa-serial additions
by Laine Stump
This was preventing make rpm from completing.
---
Pushed under the build breaker rule.
docs/formatdomain.html.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 90f8abe..bb0b199 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3693,7 +3693,7 @@ qemu-kvm -net nic,model=? /dev/null
specifies the port number. Ports are numbered starting from 0. There are
usually 0, 1 or 2 serial ports. There is also an optional
<code>type</code> attribute <span class="since">since 1.0.2</span>
- which has two choices for its value, one is< code>isa-serial</code>,
+ which has two choices for its value, one is <code>isa-serial</code>,
the other is <code>usb-serial</code>. If <code>type</code> is missing,
<code>isa-serial</code> will be used by default. For <code>usb-serial</code>
an optional sub-element <code><address></code> with
--
1.7.11.7
11 years, 11 months