[libvirt] libvirt Driver support Matrix.
by Abhishek K Jha
Hi,
I needed to know if libvirt supports migration via the QEMU/KVM driver. (
virDomainMigrate)
Could someone point me to the latest driver support matrix for libvirt. It
seems the one at http://libvirt.org/hvsupport.html was last updated on
2008-06-05.
Appreciate your help!
Thanks much,
Abhishek Jha.
IBM India Software Labs, Pune
91-20-66592139(Direct)
91-20-26982424 Extn: 2139
15 years, 7 months
[libvirt] 802.1q vlan-tagging support for libvirt
by Klaus Heinrich Kiwi
Are there any plans to support configuring 802.1q VLAN tagging through
libvirt?
My understanding is that libvirt would use vconfig to create tagged
interfaces, while using a physical interface as trunk (e.g., eth0 is the
trunk, eth0.20 the interface with the '20' vlan tag).
Then it would add the tagged interface (eth0.20) to a bridge with the
guest virtual interface.
I don't know how libvirt would need to be extended to be able to
properly 'manage' those 802.1q-enabled virtual switches. Another
question would be how libvirt-CIM would support this.
Is anyone interested/working on this?
Thanks,
-Klaus
--
Klaus Heinrich Kiwi <klausk(a)linux.vnet.ibm.com>
Linux Security Development, IBM Linux Technology Center
15 years, 7 months
[libvirt] Roadmap, beyond 0.6.3
by Daniel Veillard
Okay now that one is out, let's see what's next:
First to try to keep up with monthly releases more or less, I would
suggest a new release around May 25, which would mean entering code
feature freeze around May 18, so that's nearly 4 weeks for development.
I would assume it's 0.6.4 unless something major lands worth indicating
a new level.
There is a number of things we should try to do by then:
- the review and inclusion of OpenNebula driver
- the review and inclusion of Power Hypervisor driver
- the netcf based networking setup APIs, hopefully this could
help on the frequent networking support questions
- finising NPIV now that the interface for node storage create
and destroy is part of the API, maybe other storage devices
could be plugged too
- improve the documentation, it's something we (i.e. Red Hat)
are commited to do, but it need to be a full part of the project
too, rewiewing and increasing documentation will be helpful.
- work on the test suite and augment it, Dan Berrange posted about
libvirt-TCK framework, help augmenting it is welcome
http://www.mail-archive.com/libvir-list@redhat.com/msg12703.html
http://libvirt.org/hg/libvirt-tck
- and there is number of small fixes and buglet we would need to
find and fix but hopefully 0.6.3 is good enough we won't spend
too much time chasing new problems !
If we could get most of this in 4 weeks time that would be
impressive, but let's work on it :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
15 years, 7 months
[libvirt] Release of libvirt-0.6.3
by Daniel Veillard
As planned it has landed on the server at:
ftp://libvirt.org/libvirt/
The main points are the VirtualBox driver and a number of bug fixes:
* New features:
- VirtualBox driver support (Pritesh Kothari)
- virt-xml-validate new command (Daniel Berrange)
* Portability:
- patch to build on Centos (Joseph Shraibman)
- build breakage (Anton Protopopov)
* Documentation:
- Linux Containers documentation (Serge Hallyn)
- improvement and updates of architecture pages
- fix virNodeGetFreeMemory documentation to reflect reality
- man page cleanups (Daniel Berrange)
- man page typo (Robert P. J. Day)
- VirtualBox Documentation (Pritesh Kothari)
* Bug fixes:
- veth off-by-one error (Dan Smith)
- vcpupin to inactive Xen crash (Takahashi Tomohiro)
- virsh ttyconsole return value
- use format= not fmt= on QEmu commandline (Mark McLoughlin)
- use UUID for internal domain lookups (Daniel Berrange)
- remote domain ID related bugs (Daniel Berrange)
- QEmu pidfile handling bugs (Daniel Berrange)
- network config handling on old Xen (Daniel Berrange)
* Improvements:
- add SCSI storage rescan (David Allan)
- rootless LXC containers support improvements (Serge Hallyn)
- getHostname support for LXC (Dan Smith)
- cleanup and logging output of some domain functions (Guido Gunther)
- drop pool lock when allocating volumes (Cole Robinson)
- LXC handle kernel without CLONE_NEWUSER support (Serge Hallyn)
- cpu pinning on defined Xen domains (Takahashi Tomohiro)
- dynamic bridge names support (Soren Hansen)
- LXC use of private /dev/pts when available (Daniel Berrange)
- virNodeDeviceCreateXML and virNodeDeviceDestroy entry points (Dave
Allan)
* Cleanups:
- don't hardcode getgrnam_r buffer to 1024 bytes (Guido Gunther)
- qemudBuildCommandLine API cleanup (Daniel Berrange)
Thanks to everybody who helped with the release, and welcome to the
peple who joined the project recently !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
15 years, 7 months
[libvirt] PATCH: Public API plumbing for virNodeDeviceCreateXML/Destroy
by Daniel P. Berrange
As previously discussed, Dave Allen's reworking the NPIV patches to
do creation/deleation of vports via the node device APIs. Thus, this
patch adds the 2 new APIs required for this approach.
Daniel
diff -r 2d1278bdf31f include/libvirt/libvirt.h
--- a/include/libvirt/libvirt.h Fri Apr 24 11:01:11 2009 +0100
+++ b/include/libvirt/libvirt.h Fri Apr 24 13:06:12 2009 +0100
@@ -1124,6 +1124,12 @@ int virNodeDeviceDet
int virNodeDeviceReAttach (virNodeDevicePtr dev);
int virNodeDeviceReset (virNodeDevicePtr dev);
+virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags);
+
+int virNodeDeviceDestroy (virNodeDevicePtr dev);
+
/*
* Domain Event Notification
*/
diff -r 2d1278bdf31f include/libvirt/libvirt.h.in
--- a/include/libvirt/libvirt.h.in Fri Apr 24 11:01:11 2009 +0100
+++ b/include/libvirt/libvirt.h.in Fri Apr 24 13:06:12 2009 +0100
@@ -1124,6 +1124,12 @@ int virNodeDeviceDet
int virNodeDeviceReAttach (virNodeDevicePtr dev);
int virNodeDeviceReset (virNodeDevicePtr dev);
+virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags);
+
+int virNodeDeviceDestroy (virNodeDevicePtr dev);
+
/*
* Domain Event Notification
*/
diff -r 2d1278bdf31f qemud/remote.c
--- a/qemud/remote.c Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote.c Fri Apr 24 13:06:12 2009 +0100
@@ -4323,6 +4323,54 @@ remoteDispatchNodeDeviceReset (struct qe
}
+static int
+remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_node_device_create_xml_args *args,
+ remote_node_device_create_xml_ret *ret)
+{
+ virNodeDevicePtr dev;
+
+ dev = virNodeDeviceCreateXML (conn, args->xml_desc, args->flags);
+ if (dev == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ make_nonnull_node_device (&ret->dev, dev);
+ virNodeDeviceFree(dev);
+
+ return 0;
+}
+
+
+static int
+remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_node_device_destroy_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virNodeDevicePtr dev;
+
+ dev = virNodeDeviceLookupByName(conn, args->name);
+ if (dev == NULL) {
+ remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
+ return -1;
+ }
+
+ if (virNodeDeviceDestroy(dev) == -1) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ return 0;
+}
+
+
/**************************
* Async Events
**************************/
diff -r 2d1278bdf31f qemud/remote_dispatch_args.h
--- a/qemud/remote_dispatch_args.h Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_dispatch_args.h Fri Apr 24 13:06:12 2009 +0100
@@ -103,3 +103,5 @@
remote_node_device_re_attach_args val_remote_node_device_re_attach_args;
remote_node_device_reset_args val_remote_node_device_reset_args;
remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
+ remote_node_device_create_xml_args val_remote_node_device_create_xml_args;
+ remote_node_device_destroy_args val_remote_node_device_destroy_args;
diff -r 2d1278bdf31f qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_dispatch_prototypes.h Fri Apr 24 13:06:12 2009 +0100
@@ -527,6 +527,20 @@ static int remoteDispatchNetworkUndefine
remote_error *err,
remote_network_undefine_args *args,
void *ret);
+static int remoteDispatchNodeDeviceCreateXml(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_node_device_create_xml_args *args,
+ remote_node_device_create_xml_ret *ret);
+static int remoteDispatchNodeDeviceDestroy(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_node_device_destroy_args *args,
+ void *ret);
static int remoteDispatchNodeDeviceDettach(
struct qemud_server *server,
struct qemud_client *client,
diff -r 2d1278bdf31f qemud/remote_dispatch_ret.h
--- a/qemud/remote_dispatch_ret.h Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_dispatch_ret.h Fri Apr 24 13:06:12 2009 +0100
@@ -88,3 +88,4 @@
remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret;
remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
+ remote_node_device_create_xml_ret val_remote_node_device_create_xml_ret;
diff -r 2d1278bdf31f qemud/remote_dispatch_table.h
--- a/qemud/remote_dispatch_table.h Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_dispatch_table.h Fri Apr 24 13:06:12 2009 +0100
@@ -607,13 +607,23 @@
.args_filter = (xdrproc_t) xdr_remote_node_device_reset_args,
.ret_filter = (xdrproc_t) xdr_void,
},
-{ /* DomainGetSecurityLabel => 118 */
+{ /* DomainGetSecurityLabel => 121 */
.fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel,
.args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args,
.ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret,
},
-{ /* NodeGetSecurityModel => 119 */
+{ /* NodeGetSecurityModel => 122 */
.fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel,
.args_filter = (xdrproc_t) xdr_void,
.ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret,
},
+{ /* NodeDeviceCreateXml => 123 */
+ .fn = (dispatch_fn) remoteDispatchNodeDeviceCreateXml,
+ .args_filter = (xdrproc_t) xdr_remote_node_device_create_xml_args,
+ .ret_filter = (xdrproc_t) xdr_remote_node_device_create_xml_ret,
+},
+{ /* NodeDeviceDestroy => 124 */
+ .fn = (dispatch_fn) remoteDispatchNodeDeviceDestroy,
+ .args_filter = (xdrproc_t) xdr_remote_node_device_destroy_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
diff -r 2d1278bdf31f qemud/remote_protocol.c
--- a/qemud/remote_protocol.c Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_protocol.c Fri Apr 24 13:06:12 2009 +0100
@@ -2230,6 +2230,35 @@ xdr_remote_node_device_reset_args (XDR *
}
bool_t
+xdr_remote_node_device_create_xml_args (XDR *xdrs, remote_node_device_create_xml_args *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->xml_desc))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_create_xml_ret (XDR *xdrs, remote_node_device_create_xml_ret *objp)
+{
+
+ if (!xdr_remote_nonnull_node_device (xdrs, &objp->dev))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_node_device_destroy_args (XDR *xdrs, remote_node_device_destroy_args *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_events_register_ret (XDR *xdrs, remote_domain_events_register_ret *objp)
{
diff -r 2d1278bdf31f qemud/remote_protocol.h
--- a/qemud/remote_protocol.h Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_protocol.h Fri Apr 24 13:06:12 2009 +0100
@@ -1255,6 +1255,22 @@ struct remote_node_device_reset_args {
};
typedef struct remote_node_device_reset_args remote_node_device_reset_args;
+struct remote_node_device_create_xml_args {
+ remote_nonnull_string xml_desc;
+ int flags;
+};
+typedef struct remote_node_device_create_xml_args remote_node_device_create_xml_args;
+
+struct remote_node_device_create_xml_ret {
+ remote_nonnull_node_device dev;
+};
+typedef struct remote_node_device_create_xml_ret remote_node_device_create_xml_ret;
+
+struct remote_node_device_destroy_args {
+ remote_nonnull_string name;
+};
+typedef struct remote_node_device_destroy_args remote_node_device_destroy_args;
+
struct remote_domain_events_register_ret {
int cb_registered;
};
@@ -1397,6 +1413,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_RESET = 120,
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121,
REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
+ REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123,
+ REMOTE_PROC_NODE_DEVICE_DESTROY = 124,
};
typedef enum remote_procedure remote_procedure;
@@ -1629,6 +1647,9 @@ extern bool_t xdr_remote_node_device_li
extern bool_t xdr_remote_node_device_dettach_args (XDR *, remote_node_device_dettach_args*);
extern bool_t xdr_remote_node_device_re_attach_args (XDR *, remote_node_device_re_attach_args*);
extern bool_t xdr_remote_node_device_reset_args (XDR *, remote_node_device_reset_args*);
+extern bool_t xdr_remote_node_device_create_xml_args (XDR *, remote_node_device_create_xml_args*);
+extern bool_t xdr_remote_node_device_create_xml_ret (XDR *, remote_node_device_create_xml_ret*);
+extern bool_t xdr_remote_node_device_destroy_args (XDR *, remote_node_device_destroy_args*);
extern bool_t xdr_remote_domain_events_register_ret (XDR *, remote_domain_events_register_ret*);
extern bool_t xdr_remote_domain_events_deregister_ret (XDR *, remote_domain_events_deregister_ret*);
extern bool_t xdr_remote_domain_event_ret (XDR *, remote_domain_event_ret*);
@@ -1840,6 +1861,9 @@ extern bool_t xdr_remote_node_device_lis
extern bool_t xdr_remote_node_device_dettach_args ();
extern bool_t xdr_remote_node_device_re_attach_args ();
extern bool_t xdr_remote_node_device_reset_args ();
+extern bool_t xdr_remote_node_device_create_xml_args ();
+extern bool_t xdr_remote_node_device_create_xml_ret ();
+extern bool_t xdr_remote_node_device_destroy_args ();
extern bool_t xdr_remote_domain_events_register_ret ();
extern bool_t xdr_remote_domain_events_deregister_ret ();
extern bool_t xdr_remote_domain_event_ret ();
diff -r 2d1278bdf31f qemud/remote_protocol.x
--- a/qemud/remote_protocol.x Fri Apr 24 11:01:11 2009 +0100
+++ b/qemud/remote_protocol.x Fri Apr 24 13:06:12 2009 +0100
@@ -1109,6 +1109,19 @@ struct remote_node_device_reset_args {
remote_nonnull_string name;
};
+struct remote_node_device_create_xml_args {
+ remote_nonnull_string xml_desc;
+ int flags;
+};
+
+struct remote_node_device_create_xml_ret {
+ remote_nonnull_node_device dev;
+};
+
+struct remote_node_device_destroy_args {
+ remote_nonnull_string name;
+};
+
/**
* Events Register/Deregister:
@@ -1270,7 +1283,10 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_RESET = 120,
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121,
- REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
+
+ REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123,
+ REMOTE_PROC_NODE_DEVICE_DESTROY = 124
};
/* Custom RPC structure. */
diff -r 2d1278bdf31f src/driver.h
--- a/src/driver.h Fri Apr 24 11:01:11 2009 +0100
+++ b/src/driver.h Fri Apr 24 13:06:12 2009 +0100
@@ -684,6 +684,11 @@ typedef int (*virDevMonDeviceListCaps)(v
char **const names,
int maxnames);
+typedef virNodeDevicePtr (*virDrvNodeDeviceCreateXML)(virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags);
+typedef int (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
+
/**
* _virDeviceMonitor:
*
@@ -702,6 +707,8 @@ struct _virDeviceMonitor {
virDevMonDeviceGetParent deviceGetParent;
virDevMonDeviceNumOfCaps deviceNumOfCaps;
virDevMonDeviceListCaps deviceListCaps;
+ virDrvNodeDeviceCreateXML deviceCreateXML;
+ virDrvNodeDeviceDestroy deviceDestroy;
};
/*
diff -r 2d1278bdf31f src/libvirt.c
--- a/src/libvirt.c Fri Apr 24 11:01:11 2009 +0100
+++ b/src/libvirt.c Fri Apr 24 13:06:12 2009 +0100
@@ -7491,6 +7491,103 @@ error:
}
+/**
+ * virNodeDeviceCreateXML:
+ * @conn: pointer to the hypervisor connection
+ * @xmlDesc: string containing an XML description of the device to be created
+ * @flags: callers should always pass 0
+ *
+ * Create a new device on the VM host machine, for example, virtual
+ * HBAs created using vport_create.
+ *
+ * Returns a node device object if successful, NULL in case of failure
+ */
+virNodeDevicePtr
+virNodeDeviceCreateXML(virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%d", conn, xmlDesc, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (xmlDesc == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->deviceMonitor->deviceCreateXML) {
+ virNodeDevicePtr dev = conn->deviceMonitor->deviceCreateXML(conn, xmlDesc, flags);
+ if (dev == NULL)
+ goto error;
+ return dev;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+
+/**
+ * virNodeDeviceDestroy:
+ * @dev: a device object
+ *
+ * Destroy the device object. The virtual device is removed from the host operating system.
+ * This function may require privileged access
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virNodeDeviceDestroy(virNodeDevicePtr dev)
+{
+ int retval = 0;
+
+ DEBUG("dev=%p", dev);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+ virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+ return (-1);
+ }
+
+ if (dev->conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(dev->conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (dev->conn->deviceMonitor->deviceDestroy) {
+ retval = dev->conn->deviceMonitor->deviceDestroy(dev);
+ if (retval < 0) {
+ goto error;
+ }
+
+ return 0;
+ }
+
+ virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(dev->conn);
+ return -1;
+}
+
+
/*
* Domain Event Notification
*/
diff -r 2d1278bdf31f src/libvirt_public.syms
--- a/src/libvirt_public.syms Fri Apr 24 11:01:11 2009 +0100
+++ b/src/libvirt_public.syms Fri Apr 24 13:06:12 2009 +0100
@@ -258,4 +258,10 @@ LIBVIRT_0.6.1 {
virNodeGetSecurityModel;
} LIBVIRT_0.6.0;
+LIBVIRT_0.6.3 {
+ global:
+ virNodeDeviceCreateXML;
+ virNodeDeviceDestroy;
+} LIBVIRT_0.6.1;
+
# .... define new API here using predicted next version number ....
diff -r 2d1278bdf31f src/remote_internal.c
--- a/src/remote_internal.c Fri Apr 24 11:01:11 2009 +0100
+++ b/src/remote_internal.c Fri Apr 24 13:06:12 2009 +0100
@@ -4987,6 +4987,59 @@ done:
}
+static virNodeDevicePtr
+remoteNodeDeviceCreateXML(virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags)
+{
+ remote_node_device_create_xml_args args;
+ remote_node_device_create_xml_ret ret;
+ virNodeDevicePtr dev = NULL;
+ struct private_data *priv = conn->privateData;
+
+ remoteDriverLock(priv);
+
+ memset(&ret, 0, sizeof ret);
+ args.xml_desc = (char *)xmlDesc;
+ args.flags = flags;
+
+ if (call(conn, priv, 0, REMOTE_PROC_NODE_DEVICE_CREATE_XML,
+ (xdrproc_t) xdr_remote_node_device_create_xml_args, (char *) &args,
+ (xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret) == -1)
+ goto done;
+
+ dev = get_nonnull_node_device(conn, ret.dev);
+ xdr_free ((xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return dev;
+}
+
+static int
+remoteNodeDeviceDestroy(virNodeDevicePtr dev)
+{
+ int rv = -1;
+ remote_node_device_destroy_args args;
+ struct private_data *priv = dev->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ args.name = dev->name;
+
+ if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_RESET,
+ (xdrproc_t) xdr_remote_node_device_destroy_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+
/*----------------------------------------------------------------------*/
static int
@@ -6991,6 +7044,8 @@ static virDeviceMonitor dev_monitor = {
.deviceGetParent = remoteNodeDeviceGetParent,
.deviceNumOfCaps = remoteNodeDeviceNumOfCaps,
.deviceListCaps = remoteNodeDeviceListCaps,
+ .deviceCreateXML = remoteNodeDeviceCreateXML,
+ .deviceDestroy = remoteNodeDeviceDestroy
};
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months
[libvirt] Xen network interface behavior with 0.6.2
by Kaitlin Rupert
Hi,
I'm using libvirt 0.6.2 to create a Xen guest with a network type
interface (see XML below). When the guest is defined, the interface is
converted to an ethernet type interface. If the guest is started, the
interface is then converted to a bridge type interface.
The progression from network type to ethernet type to bridge type seems
odd to me. With older versions of libvirt, the network type interface
was converted to bridge type during the define, so I'm curious what the
reasoning is here.. Is this the expected behavior?
Also, the XML for the bridge interface in 0.6.2 doesn't include the
source network. This information should be available, so I'm not sure
why its not being set in the XML..
Thanks!
=================
# virsh list --all
Id Name State
----------------------------------
0 Domain-0 running
- rstest_domain shut off
# cat tmp
<domain type="xen">
<name>hd_domain</name>
<on_poweroff>destroy</on_poweroff>
<on_crash>destroy</on_crash>
<uuid>f99fd6b6-1434-4bc2-88e0-1ed9c8c6f8e9</uuid>
<os>
<type>linux</type>
<kernel>/tmp/default-xen-kernel</kernel>
<initrd>/tmp/default-xen-initrd</initrd>
<cmdline/>
</os>
<currentMemory>131072</currentMemory>
<memory>131072</memory>
<vcpu>1</vcpu>
<devices>
<disk type="file" device="disk">
<source file="/tmp/default-xen-dimage"/>
<target dev="xvda"/>
</disk>
<interface type="network">
<mac address="00:11:22:33:44:aa"/>
<source network="default"/>
</interface>
<input type="mouse" bus="xen"/>
<graphics type="vnc" port="-1" listen="127.0.0.1" keymap="en-us"/>
</devices>
</domain>
# virsh define tmp
Domain hd_domain defined from tmp
# virsh list --all
Id Name State
----------------------------------
0 Domain-0 running
- hd_domain shut off
- rstest_domain shut off
[root@elm3b25 cimtest]# virsh dumpxml hd_domain
<domain type='xen'>
<name>hd_domain</name>
<uuid>f99fd6b6-1434-4bc2-88e0-1ed9c8c6f8e9</uuid>
<memory>131072</memory>
<currentMemory>131072</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='xenpv'>linux</type>
<kernel>/tmp/default-xen-kernel</kernel>
<initrd>/tmp/default-xen-initrd</initrd>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file'/>
<source file='/tmp/default-xen-dimage'/>
<target dev='xvda' bus='xen'/>
</disk>
<interface type='ethernet'>
<mac address='00:11:22:33:44:aa'/>
</interface>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='xen'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'
keymap='en-us'/>
</devices>
</domain>
# virsh start hd_domain
Domain hd_domain started
[root@elm3b25 cimtest]# virsh dumpxml hd_domain
<domain type='xen' id='61'>
<name>hd_domain</name>
<uuid>f99fd6b6-1434-4bc2-88e0-1ed9c8c6f8e9</uuid>
<memory>131072</memory>
<currentMemory>131072</currentMemory>
<vcpu>1</vcpu>
<os>
<type>linux</type>
<kernel>/tmp/default-xen-kernel</kernel>
<initrd>/tmp/default-xen-initrd</initrd>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file'/>
<source file='/tmp/default-xen-dimage'/>
<target dev='xvda' bus='xen'/>
</disk>
<interface type='bridge'>
<mac address='00:11:22:33:44:aa'/>
<script path='vif-bridge'/>
<target dev='vif61.0'/>
</interface>
<console type='pty' tty='/dev/pts/4'>
<source path='/dev/pts/4'/>
<target port='0'/>
</console>
<input type='mouse' bus='xen'/>
<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'
keymap='en-us'/>
</devices>
</domain>
--
Kaitlin Rupert
IBM Linux Technology Center
kaitlin(a)linux.vnet.ibm.com
15 years, 7 months
[libvirt] PATCH: Fix mem corruption after detaching Xen device
by Daniel P. Berrange
The XM driver's implementation of the 'detach device' command is causing
memory corruption, but passing the wrong size information to memmove()
by passing number of elements to move, instead of amount of memory to
move. This patch fixes it
Daniel
diff -rup libvirt-0.6.2.orig/src/xm_internal.c libvirt-0.6.2.new/src/xm_internal.c
--- libvirt-0.6.2.orig/src/xm_internal.c 2009-04-03 15:04:28.000000000 +0100
+++ libvirt-0.6.2.new/src/xm_internal.c 2009-04-23 10:53:10.000000000 +0100
@@ -2912,7 +2912,8 @@ xenXMDomainDetachDevice(virDomainPtr dom
if (i < (def->ndisks - 1))
memmove(def->disks + i,
def->disks + i + 1,
- def->ndisks - (i + 1));
+ sizeof(*def->disks) *
+ (def->ndisks - (i + 1)));
break;
}
}
@@ -2929,7 +2930,8 @@ xenXMDomainDetachDevice(virDomainPtr dom
if (i < (def->nnets - 1))
memmove(def->nets + i,
def->nets + i + 1,
- def->nnets - (i + 1));
+ sizeof(*def->nets) *
+ (def->nnets - (i + 1)));
break;
}
}
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 7 months
[libvirt] [PATCH 2/2] Updated & fixed OpenNebula driver, libvirt-0.6.2
by "Abel Míguez Rodríguez"
[PATCH 2/2] ONE Driver source files
Thanks,
-------------------------------------------------------------------------------------
src/opennebula/one_conf.h
-------------------------------------------------------------------------------------
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*-----------------------------------------------------------------------------------*/
#ifndef ONE_CONF_H
#define ONE_CONF_H
#include <config.h>
#include "internal.h"
#include "domain_conf.h"
#include "capabilities.h"
#include "threads.h"
struct one_driver{
virMutex lock;
virCapsPtr caps;
virDomainObjList domains;
int nextid;
};
typedef struct one_driver one_driver_t;
virCapsPtr oneCapsInit(void);
int oneSubmitVM(virConnectPtr conn ,one_driver_t* driver, virDomainObjPtr vm);
char* xmlOneTemplate(virConnectPtr conn,virDomainDefPtr def);
#define oneError(conn, dom, code, fmt...) \
virReportErrorHelper(conn, VIR_FROM_ONE, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
#endif /* ONE_CONF_H */
---------------------------------------------------------------------------------------------------------
src/opennebula/one_conf.c
---------------------------------------------------------------------------------------------------------
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*-----------------------------------------------------------------------------------*/
#include <config.h>
#include <sys/utsname.h>
#include "virterror_internal.h"
#include "one_conf.h"
#include "buf.h"
#include "memory.h"
#include "util.h"
#define VIR_FROM_THIS VIR_FROM_ONE
/* --------------------------------------------------------------------------------- */
/**
* oneCapsInit initialize the driver capabilities
* @return a pointer to the driver capabilities NULL in case of error
*/
virCapsPtr oneCapsInit(void)
{
struct utsname utsname;
virCapsPtr caps;
virCapsGuestPtr guest;
uname(&utsname);
if ((caps = virCapabilitiesNew(utsname.machine,0,0)) == NULL)
{
goto no_memory;
}
virCapabilitiesSetMacPrefix(caps,(unsigned char[]){ 0x52, 0x54, 0x00 });
if ((guest = virCapabilitiesAddGuest(caps,
"hvm",
"i686",
32,
NULL,
NULL,
0,
NULL)) == NULL)
{
goto no_memory;
}
if (virCapabilitiesAddGuestDomain(guest,
"one",
NULL,
NULL,
0,
NULL) == NULL)
{
goto no_memory;
}
if ((guest = virCapabilitiesAddGuest(caps,
"hvm",
"x86_64",
64,
NULL,
NULL,
0,
NULL)) == NULL)
{
goto no_memory;
}
if (virCapabilitiesAddGuestDomain(guest,
"one",
NULL,
NULL,
0,
NULL) == NULL)
{
goto no_memory;
}
return caps;
no_memory:
virCapabilitiesFree(caps);
return NULL;
}
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/**
* oneSubmitVM generates an OpenNebula description file and submits the new VM
* @param driver the OpenNebula driver
* @param vm the virtual machine pointer
* @return the OpenNebula ID for the new VM or -1 in case of error
*/
int oneSubmitVM(virConnectPtr conn,
one_driver_t* driver ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
char* templ;
int oneid;
if((templ=xmlOneTemplate(conn,vm->def))==NULL )
return -1;
if( (oneid=c_oneAllocateTemplate(templ))<0 ){
oneError(conn, NULL, VIR_ERR_OPERATION_FAILED,
"Error submitting virtual machine to OpenNebula");
VIR_FREE(templ);
return -1;
}
VIR_FREE(templ);
return oneid;
}
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/**
* xmlOneTemplate Generate an OpenNebula template to deploy a VM from libvirt
* internal Domain definition.
* @param def Internal libvirt Domain definition
* @return OpenNebula VM template.
*/
char* xmlOneTemplate(virConnectPtr conn,virDomainDefPtr def)
{
int i;
virBuffer buf= VIR_BUFFER_INITIALIZER;
virBufferVSprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
def->name,
def->vcpus,
(def->maxmem)/1024);
/*Optional Booting OpenNebula Information:*/
if( def->os.kernel ){
virBufferVSprintf(&buf,"OS=[ kernel = \"%s\"",def->os.kernel);
if(def->os.initrd)
virBufferVSprintf(&buf,",\n initrd = \"%s\"",def->os.initrd);
if(def->os.cmdline)
virBufferVSprintf(&buf,",\n kernel_cmd = \"%s\"",def->os.cmdline);
if(def->os.root)
virBufferVSprintf(&buf,",\n root = \"%s\"",def->os.root);
virBufferAddLit(&buf," ]\n");
}
/* set Disks & NICS */
for(i=0 ; i<def->ndisks ; i++){
// missing source is only allowed at cdrom and floppy
if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_DISK){
virBufferVSprintf(&buf, "DISK=[ type = disk,\n"
" source = \"%s\",\n",
def->disks[i]->src);
}
else if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_CDROM){
virBufferAddLit(&buf, "DISK=[ type = cdrom,\n");
if(def->disks[i]->src) virBufferVSprintf(&buf, " source = \"%s\",\n",def->disks[i]->src);
}
else if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_FLOPPY){
virBufferAddLit(&buf, "DISK=[ type = floppy,\n");
if(def->disks[i]->src) virBufferVSprintf(&buf, " source = \"%s\",\n",def->disks[i]->src);
}
virBufferVSprintf(&buf, " target = \"%s\",\n"
" readonly =",
def->disks[i]->dst);
if(def->disks[i]->readonly)
virBufferAddLit(&buf,"\"yes\"]\n");
else
virBufferAddLit(&buf,"\"no\"]\n");
}
for(i=0 ; i< def->nnets ; i++)
{
if ( !def->nets[i] ) {
continue;
}
switch(def->nets[i]->type)
{
case VIR_DOMAIN_NET_TYPE_BRIDGE:
virBufferVSprintf(&buf,"NIC=[ bridge =\"%s\",\n",def->nets[i]->data.bridge.brname);
if(def->nets[i]->ifname)
virBufferVSprintf(&buf," target =\"%s\",\n",def->nets[i]->ifname);
virBufferVSprintf(&buf," mac =\"%02x:%02x:%02x:%02x:%02x:%02x\" ]\n",
def->nets[i]->mac[0],def->nets[i]->mac[1],
def->nets[i]->mac[2],def->nets[i]->mac[3],
def->nets[i]->mac[4],def->nets[i]->mac[5]);
break;
case VIR_DOMAIN_NET_TYPE_NETWORK:
virBufferVSprintf(&buf,"NIC=[ network=\"%s\"",def->nets[i]->data.network.name);
if(def->nets[i]->ifname)
virBufferVSprintf(&buf,",\n target =\"%s\"",def->nets[i]->ifname);
virBufferAddLit(&buf," ]\n");
break;
default: break;
}
}
if(def->graphics!=NULL){
if(def->graphics->type==VIR_DOMAIN_GRAPHICS_TYPE_VNC){
virBufferAddLit(&buf,"GRAPHICS = [\n type = \"vnc\"");
if(def->graphics->data.vnc.listenAddr!=NULL)
virBufferVSprintf(&buf,",\n listen = \"%s\"",def->graphics->data.vnc.listenAddr);
if(def->graphics->data.vnc.autoport==0)
virBufferVSprintf(&buf,",\n port = \"%d\"",def->graphics->data.vnc.port);
if(def->graphics->data.vnc.passwd!=NULL)
virBufferVSprintf(&buf,",\n passwd = \"%s\"",def->graphics->data.vnc.passwd);
virBufferAddLit(&buf," ]\n");
}
else //graphics.type==VIR_DOMAIN_GRAPHICS_TYPE_SDL
virBufferAddLit(&buf,"GRAPHICS = [\n type = \"sdl\" ]\n");
}
if (virBufferError(&buf))
goto no_memory;
return virBufferContentAndReset(&buf);
no_memory:
virReportOOMError(conn);
char* tmp = virBufferContentAndReset(&buf);
VIR_FREE(tmp);
return NULL;
};
--------------------------------------------------------------------------------------------------------
src/opennebula/one_driver.h
-------------------------------------------------------------------------------------------------------
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*---------------------------------------------------------------------------*/
#ifndef ONE_DRIVER_H
#define ONE_DRIVER_H
#include <config.h>
#include <OneClient.h>
int oneRegister(void);
#endif /* ONE_DRIVER_H */
--------------------------------------------------------------------------------------------------------
src/opennebula/one_driver.c
-------------------------------------------------------------------------------------------------------
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*---------------------------------------------------------------------------*/
#include <config.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/utsname.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/poll.h>
#include <unistd.h>
#include <wait.h>
#include <sys/time.h>
#include "virterror_internal.h"
#include "logging.h"
#include "datatypes.h"
#include "one_conf.h"
#include "one_driver.h"
#include "memory.h"
#include "util.h"
#include "bridge.h"
#include "veth.h"
#define VIR_FROM_THIS VIR_FROM_ONE
static int oneStartup(void);
static int oneShutdown(void);
static int oneActive(void);
static void oneDriverLock(one_driver_t* driver)
{
virMutexLock(&driver->lock);
}
static void oneDriverUnlock(one_driver_t* driver)
{
virMutexUnlock(&driver->lock);
}
static one_driver_t *one_driver =NULL;
static virDrvOpenStatus oneOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED)
{
/* Verify uri was specified */
if (conn->uri == NULL) {
conn->uri = xmlParseURI("one:///");
if (!conn->uri) {
virReportOOMError(conn);
return VIR_DRV_OPEN_ERROR;
}
} else if (conn->uri->scheme == NULL ||
STRNEQ(conn->uri->scheme, "one")) {
goto declineConnection;
}
conn->privateData = one_driver;
return VIR_DRV_OPEN_SUCCESS;
declineConnection:
return VIR_DRV_OPEN_DECLINED;
}
static int oneClose(virConnectPtr conn)
{
conn->privateData = NULL;
return 0;
}
static virDomainPtr oneDomainLookupByID(virConnectPtr conn,
int id)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainPtr dom = NULL;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static virDomainPtr oneDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainPtr dom = NULL;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static virDomainPtr oneDomainLookupByName(virConnectPtr conn,
const char *name)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainObjPtr vm = NULL;
virDomainPtr dom=NULL;
oneDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static int oneListDomains(virConnectPtr conn, int *ids, int nids)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++){
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver);
return got;
}
static int oneNumDomains(virConnectPtr conn)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++){
virDomainObjLock(driver->domains.objs[i]);
if (virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver);
return n;
}
static int oneListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) {
one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
virReportOOMError(conn);
virDomainObjUnlock(driver->domains.objs[i]);
goto cleanup;
}
}
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver);
return got;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
oneDriverUnlock(driver);
return -1;
}
static int oneNumDefinedDomains(virConnectPtr conn)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++){
virDomainObjLock(driver->domains.objs[i]);
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
virDomainObjUnlock(driver->domains.objs[i]);
}
oneDriverUnlock(driver);
return n;
}
static virDomainPtr oneDomainDefine(virConnectPtr conn, const char *xml)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainDefPtr def;
virDomainObjPtr vm;
virDomainPtr dom=NULL;
oneDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
VIR_DOMAIN_XML_INACTIVE)))
goto return_point;
if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
virDomainDefFree(def);
goto return_point;
}
vm->def->id = -1;
vm->persistent = 1;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
virDomainObjUnlock(vm);
return_point:
oneDriverUnlock(driver);
return dom;
}
static int oneDomainUndefine(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
virDomainObjPtr vm = NULL;
int ret=-1;
oneDriverLock(driver);
vm =virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
oneError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
"no domain with matching uuid");
goto return_point;
}
if (!vm->persistent) {
oneError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
"cannot undefine transient domain");
goto return_point;
}
virDomainRemoveInactive(&driver->domains, vm);
ret=0;
return_point:
oneDriverUnlock(driver);
return ret;
}
static int oneDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
struct timeval tv;
virDomainObjPtr vm;
oneDriverLock(driver);
vm= virDomainFindByUUID(&driver->domains, dom->uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(dom->conn,dom, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return -1;
}
if(gettimeofday(&tv,NULL)<0) {
oneError(dom->conn,dom, VIR_ERR_INTERNAL_ERROR,
"%s",_("getting time of day"));
virDomainObjUnlock(vm);
return -1;
}
if (!virDomainIsActive(vm)) {
info->cpuTime = 0;
} else {
char vm_info[257];
c_oneVmInfo(vm->pid,vm_info,256);
//State:
char* cptr = strstr(vm_info,"STATE");
cptr = index(cptr, ':');
cptr++;
int one_state=atoi(cptr);
switch(one_state) {
case 3: /** running */
if (vm->state!=VIR_DOMAIN_SHUTDOWN)
vm->state=VIR_DOMAIN_RUNNING;
break;
case 5: /** pause */
vm->state=VIR_DOMAIN_PAUSED;
break;
case 6: /** done */
vm->state=VIR_DOMAIN_SHUTOFF;
vm->def->id=-1;
break;
case 7: /** error */
vm->state=VIR_DOMAIN_CRASHED;
break;
default:
break;
};
//Memory:
cptr=strstr(vm_info,"MEMORY");
cptr=index(cptr,':');
cptr++;
vm->def->memory = atoi(cptr);
//run time:
cptr=strstr(vm_info,"START TIME");
cptr=index(cptr,':');
cptr++;
long starttime = atol(cptr);
info->cpuTime = (tv.tv_sec - starttime) *1000ll *1000ll *1000ll;
}
info->state = vm->state;
info->maxMem = vm->def->maxmem;
info->memory = vm->def->memory;
info->nrVirtCpu = vm->def->vcpus;
virDomainObjUnlock(vm);
return 0;
}
static char *oneGetOSType(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm =virDomainFindByUUID(&driver->domains, dom->uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(dom->conn,dom, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return NULL;
}
virDomainObjUnlock(vm);
return strdup(vm->def->os.type);
}
static int oneDomainStart(virDomainPtr dom)
{
virConnectPtr conn = dom->conn;
one_driver_t *driver = (one_driver_t *)(conn->privateData);
virDomainObjPtr vm;
int ret = -1;
int oneid;
oneDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dom->name);
if (!vm) {
oneError(conn, dom, VIR_ERR_INVALID_DOMAIN,
"no domain named %s", dom->name);
goto return_point;
}
if((oneid = oneSubmitVM(dom->conn,driver,vm)) < 0) {
goto return_point;
}
vm->pid=oneid;
vm->def->id=driver->nextid++;
vm->state=VIR_DOMAIN_BLOCKED;
ret=0;
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static virDomainPtr
oneDomainCreateAndStart(virConnectPtr conn,
const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) {
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainObjPtr vm = NULL;
virDomainDefPtr def;
virDomainPtr dom = NULL;
int oneid;
oneDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
VIR_DOMAIN_XML_INACTIVE)))
goto return_point;
vm = virDomainFindByName(&driver->domains, def->name);
if (vm) {
oneError(conn,NULL, VIR_ERR_OPERATION_FAILED,
_("Already an OpenNebula VM active with the name: \"%s\" id: %d "),
def->name,def->id);
goto return_point;
}
if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
virDomainDefFree(def);
goto return_point;
}
if ((oneid = oneSubmitVM(conn, driver, vm)) < 0) {
virDomainRemoveInactive(&driver->domains, vm);
vm=NULL;
goto return_point;
}
vm->def->id=driver->nextid++;
vm->persistent=0;
vm->pid=oneid;
vm->state=VIR_DOMAIN_BLOCKED;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return dom;
}
static int oneDomainShutdown(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t*)dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if((vm=virDomainFindByID(&driver->domains, dom->id))) {
if(!(c_oneShutdown(vm->pid) ) ) {
vm->state=VIR_DOMAIN_SHUTDOWN;
ret= 0;
goto return_point;
}
oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
"Wrong state to perform action");
goto return_point;
}
oneError(dom->conn,dom, VIR_ERR_INVALID_DOMAIN,
_("no domain with id %d"), dom->id);
goto return_point;
if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm);
vm = NULL;
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static int oneDomainDestroy(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t*)dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
vm= virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
oneError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
"no domain with id %d", dom->id);
goto return_point;
}
if(c_oneCancel(vm->pid)) {
/* VM not running, delete the instance at ONE DB */
if(c_oneFinalize(vm->pid)){
oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
"Wrong state to perform action");
goto return_point;
}
}
if(!vm->persistent) {
virDomainRemoveInactive(&driver->domains,vm);
vm=NULL;
}
ret=0;
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static int oneDomainSuspend(virDomainPtr dom)
{
one_driver_t* driver=dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if ((vm=virDomainFindByID(&driver->domains,dom->id))){
if (vm->state == VIR_DOMAIN_RUNNING) {
if( !(c_oneSuspend(vm->pid)) ) {
vm->state=VIR_DOMAIN_PAUSED;
ret=0;
goto return_point;
}
oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
"Wrong state to perform action");
goto return_point;
}
oneError(dom->conn,dom,VIR_ERR_OPERATION_FAILED,
"domain is not running");
} else {
oneError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
"no domain with matching id %d", dom->id);
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
};
static int oneDomainResume(virDomainPtr dom)
{
one_driver_t* driver=dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if ((vm=virDomainFindByID(&driver->domains,dom->id))) {
if (vm->state == VIR_DOMAIN_PAUSED) {
if( !(c_oneResume(vm->pid)) ) {
vm->state=VIR_DOMAIN_RUNNING;
ret=0;
goto return_point;
}
oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
"Wrong state to perform action");
goto return_point;
}
oneError(dom->conn,dom,VIR_ERR_OPERATION_FAILED,
"domain is not paused ");
} else {
oneError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
"no domain with matching id %d", dom->id);
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
};
static int oneStartup(void){
if (VIR_ALLOC(one_driver) < 0) {
return -1;
}
if(virMutexInit(&one_driver->lock)<0){
VIR_FREE(one_driver);
return -1;
}
c_oneStart();
oneDriverLock(one_driver);
one_driver->nextid=1;
if ((one_driver->caps = oneCapsInit()) == NULL) {
oneDriverUnlock(one_driver);
VIR_FREE(one_driver);
return -1;
}
oneDriverUnlock(one_driver);
return 0;
}
static int oneShutdown(void){
if (one_driver == NULL)
return(-1);
oneDriverLock(one_driver);
virDomainObjListFree(&one_driver->domains);
virCapabilitiesFree(one_driver->caps);
oneDriverUnlock(one_driver);
virMutexDestroy(&one_driver->lock);
VIR_FREE(one_driver);
one_driver = NULL;
c_oneFree();
return 0;
}
static int oneActive(void){
unsigned int i;
int active = 0;
if (one_driver == NULL)
return(0);
oneDriverLock(one_driver);
for (i = 0 ; i < one_driver->domains.count ; i++) {
virDomainObjLock(one_driver->domains.objs[i]);
if (virDomainIsActive(one_driver->domains.objs[i]))
active = 1;
virDomainObjUnlock(one_driver->domains.objs[i]);
}
oneDriverUnlock(one_driver);
return active;
}
static int oneVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)
{
*hvVer = 1;
return 0;
}
static int oneGetAutostart(virDomainPtr domain ATTRIBUTE_UNUSED, int *autostart)
{
autostart=0;
return 0;
}
static char* oneGetCapabilities(virConnectPtr conn){
one_driver_t* privconn=conn->privateData;
char *xml;
oneDriverLock(privconn);
if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
virReportOOMError(conn);
oneDriverUnlock(privconn);
return xml;
}
/* Function Tables */
static virDriver oneDriver = {
VIR_DRV_ONE, /* the number virDrvNo */
"one", /* the name of the driver */
oneOpen, /* open */
oneClose, /* close */
NULL, /* supports_feature */
NULL, /* type */
oneVersion, /* version */
NULL, /* getHostname */
NULL, /* getMaxVcpus */
NULL, /* nodeGetInfo */
oneGetCapabilities, /* getCapabilities */
oneListDomains, /* listDomains */
oneNumDomains, /* numOfDomains */
oneDomainCreateAndStart, /* domainCreateXML */
oneDomainLookupByID, /* domainLookupByID */
oneDomainLookupByUUID, /* domainLookupByUUID */
oneDomainLookupByName, /* domainLookupByName */
oneDomainSuspend, /* domainSuspend */
oneDomainResume, /* domainResume */
oneDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
oneDomainDestroy, /* domainDestroy */
oneGetOSType, /* domainGetOSType */
NULL, /* domainGetMaxMemory */
NULL, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
oneDomainGetInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
NULL, /* domainDumpXML */
oneListDefinedDomains, /* listDefinedDomains */
oneNumDefinedDomains, /* numOfDefinedDomains */
oneDomainStart, /* domainCreate */
oneDomainDefine, /* domainDefineXML */
oneDomainUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
oneGetAutostart, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
NULL, /* domainMigratePrepare */
NULL, /* domainMigratePerform */
NULL, /* domainMigrateFinish */
NULL, /* domainBlockStats */
NULL, /* domainInterfaceStats */
NULL, /* domainBlockPeek */
NULL, /* domainMemoryPeek */
NULL, /* nodeGetCellsFreeMemory */
NULL, /* getFreeMemory */
NULL, /* domainEventRegister */
NULL, /* domainEventDeregister */
NULL, /* domainMigratePrepare2 */
NULL, /* domainMigrateFinish2 */
NULL, /* nodeDeviceDettach; */
NULL, /* nodeDeviceReAttach; */
NULL, /* nodeDeviceReset; */
};
static virStateDriver oneStateDriver = {
.initialize = oneStartup,
.cleanup = oneShutdown,
.active = oneActive,
};
int oneRegister(void)
{
virRegisterDriver(&oneDriver);
virRegisterStateDriver(&oneStateDriver);
return 0;
}
Abel Míguez Rodríguez
----
Distributed System Architecture Group
(http://dsa-research.org)
GridWay, http://www.gridway.org
OpenNEbula, http://www.opennebula.org
15 years, 7 months
[libvirt] live-migration is not working with libvirt-0.6.2 on RHEL5.3
by Gerrit Slomma
So i still do not get live migration up and running with libvirt-0.6.2
on RHEL5.3
My setup is as following:
Host#1 rr016: RHEL5.3 2.6.18-128.el5.x86_64; 4 GB RAM; C2D T8300
Host#2 rr017: RHEL5.3 2.6.18-128.el5.x86_64; 3 GB RAM; C2D E6550
on both hosts:
kvm-85 compiled rpms from sourceforge.org (current release)
qemu-0.10.0 (from kvm-85)
qemu-img 0.9.1-11 from EPEL
libvirt-0.6.2 compiled rpms from libvirt.org (current release) + applied
RHEL5-build-patch
Network: bridged network-if eth0 on bridge sw0 via
/etc/sysconfig/network-scripts/ifcfg-eth0 and
/etc/sysconfig/network-scripts/ifcfg-sw0, nothing in
/etc/libvirt/qemu/networks besides the (untouched) default.xml.
iptables: disabled to avoid side-effects
Images: exported from a third host via iscsi and accessible from both
involved hosts
if i bring up a VM on host#2 that is not defined on host#1 this VM comes
up fine and i could ssh into it.
[root@rr017 ~]# virsh dominfo rr019v3
Id: 5
Name: rr019v3
UUID: ff1ba599-5801-fca9-ab33-8962c2dfa46c
OS Typ: hvm
Status: laufend
CPU(s): 2
CPU-Zeit: 26,9s
Max Speicher: 1572864 kB
Verwendeter Speicher: 1572864 kB
Automatischer Start: deaktiviert
if i try to migrate it without URI specified the migration fails with an
"unknown failure" whereas the failure is obvious to me: wrong port
[root@rr017 ~]# virsh migrate rr019v3 qemu+tcp://192.168.1.119:16509/system
Please enter your authentication name:root
Please enter your password:
Fehler: Unknown failure
[root@rr017 ~]# tail -f /var/log/libvirt/qemu/rr019v3.log
info balloon
Using KVM without synchronous MMU, ballooning disabled
stop
migrate "tcp:rr016:49152"
migration failed
cont
[root@rr016 ~]# tail -f /var/log/libvirt/qemu/rr019v3.log
LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/root USER=root
LOGNAME=root /usr/bin/kvm -S -M pc -m 1536 -smp 2 -name rr019v3 -uuid
ff1ba599-5801-fca9-ab33-8962c2dfa46c -monitor pty -pidfile
/var/run/libvirt/qemu//rr019v3.pid -boot c -drive
file=/dev/disk/by-path/ip-192.168.1.1:3260-iscsi-rr010:01-lun-6,if=ide,index=0
-net nic,macaddr=00:16:3e:69:94:05,vlan=0 -net
tap,fd=17,script=,vlan=0,ifname=vnet0 -serial none -parallel none -usb
-vnc 127.0.0.1:0 -k de -incoming tcp:0.0.0.0:49152
char device redirected to /dev/pts/3
info cpus
* CPU #0: pc=0x00000000000ffff0 thread_id=8550
CPU #1: pc=0x00000000000ffff0 thread_id=8551
balloon 1536
trying --live as a parameter the same applies:
[root@rr017 ~]# virsh migrate --live rr019v3
qemu+tcp://192.168.1.119:16509/system
Please enter your authentication name:root
Please enter your password:
Fehler: Unknown failure
[root@rr017 ~]# tail -f /var/log/libvirt/qemu/rr019v3.log
info balloon
Using KVM without synchronous MMU, ballooning disabled
migrate "tcp:rr016:49153"
migration failed
[root@rr016 ~]# tail -f /var/log/libvirt/qemu/rr019v3.log
C_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/root USER=root
LOGNAME=root /usr/bin/kvm -S -M pc -m 1536 -smp 2 -name rr019v3 -uuid
ff1ba599-5801-fca9-ab33-8962c2dfa46c -monitor pty -pidfile
/var/run/libvirt/qemu//rr019v3.pid -boot c -drive
file=/dev/disk/by-path/ip-192.168.1.1:3260-iscsi-rr010:01-lun-6,if=ide,index=0
-net nic,macaddr=00:16:3e:69:94:05,vlan=0 -net
tap,fd=17,script=,vlan=0,ifname=vnet0 -serial none -parallel none -usb
-vnc 127.0.0.1:0 -k de -incoming tcp:0.0.0.0:49153
char device redirected to /dev/pts/3
info cpus
* CPU #0: pc=0x00000000000ffff0 thread_id=8641
CPU #1: pc=0x00000000000ffff0 thread_id=8642
balloon 1536
Specifying the URI migration works, and the VM appears on the target-host
[root@rr017 ~]# virsh migrate rr019v3
qemu+tcp://192.168.1.119:16509/system tcp:192.168.1.119:16509
Please enter your authentication name:root
Please enter your password:
[root@rr016 ~]# virsh list
Id Name Status
----------------------------------
3 rr019v3 laufend
But the status is laufend - that means "running" in english - whereas i
have to suspend and resume the VM to get it up, then it is running on
the target-host.
Backmigration is not possible and hangs endless, the libvirtd must be
restarted on both hosts to get them back up.
Specifying --live as a parameter for the migration does have the same
effect on the VM as omitting the parameter.
When doing the same on the commandline everything works fine, i even
start the VM via ssh from the source-host on the target-host and migrate
over the net with minimal downtime.
Why doesn't this work? Has anybody got a working setup with RHEL5 up and
running?
15 years, 7 months