[libvirt] [libvirt-php] - zend_mm_heap corrupted
by Henrik Jönsson
[libvirt-php]
Hello!
I am using Libvirt-php for a private project, i do however have a problem
that seems to occur when i call any function that returns a domain resource.
I have gotten 3 different errors so far. First i had a problem with php
memory usage going extreme(2gb), then i have had some apache segmentation
fault ending up in apache killing the process. I have also had zend_mm_heap
corrupted which i think is the most common one.
I have tried with Ubuntu 10.04, 10.10 and 11.04 repository versions of
Apache. Other than that i am using libvirt version 0.9.1 and libvirt-php
version 0.4.1. This is within the contexts of Drupal as i am using the code
in a Drupal module.
I have checked out the source code for libvirt-php but since i am no C/C++
developer i have a hard time figuring out what the issue might be. Some help
would be greatly appreciated. :)
Best Regards!
/Henrik
13 years, 5 months
[libvirt] RFC (v3): Add virDomainBlockPull API family to libvirt
by Adam Litke
I didn't receive too many comments on the last round. That probably means
everybody has been busy with the 0.9.2 release. I think this is ready to be
committed but we can wait until the qemu side has gone up (which should happen
any day now).
Changes since V2:
- Rebased
- Ensure error messages are consistent between JSON and Text interfaces
- Added additional tests to the sample test bucket
Changes since V1:
- Rebased to incorporate changes to generator and
removal of static driver structure initializers
- Other small fixups suggested by Matthias Bolte
To help speed the provisioning process for large domains, new QED disks are
created with backing to a template image. These disks are configured with copy
on read such that blocks that are read from the backing file are copied to the
new disk. This reduces I/O over a potentially costly path to the backing
image.
In such a configuration, there is a desire to remove the dependency on the
backing image as the domain runs. To accomplish this, qemu will provide an
interface to perform sequential copy on read operations during normal VM
operation. Once all data has been copied, the disk image's link to the backing
file is removed.
The virDomainBlockPull API family brings this functionality to libvirt.
virDomainBlockPullAll() instructs the hypervisor to stream the entire device in
the background. Progress of this operation can be checked with the function
virDomainBlockPullInfo(). An ongoing stream can be cancelled with
virDomainBlockPullAbort(). If a more controlled IO rate is desired,
virDomainBlockPull() can be used to perform a single increment of IO.
Subsequent calls to this function will automatically stream the appropriate
next increment until the disk has been fully populated.
An event (VIR_DOMAIN_EVENT_ID_BLOCK_PULL) will be emitted when a disk has been
fully populated or if a BlockPullAll() operation was terminated due to an
error. This event is useful to avoid polling on virDomainBlockPullInfo() for
completion and could also be used by the security driver to revoke access to
the backing file when it is no longer needed.
make check: PASS
make syntax-check: PASS
make -C tests valgrind: PASS
I am testing this API with Python Unittest (see the last patch).
[PATCH 1/8] Add new API virDomainBlockPull* to headers
[PATCH 2/8] virDomainBlockPull: Implement the main entry points
[PATCH 3/8] Add virDomainBlockPull support to the remote driver
[PATCH 4/8] Implement virDomainBlockPull for the qemu driver
[PATCH 5/8] Enable the virDomainBlockPull API in virsh
[PATCH 6/8] Enable virDomainBlockPull in the python API.
[PATCH 7/8] Asynchronous event for BlockPull completion
[PATCH 8/8] test: Python Unittests for DomainBlockPull API
13 years, 5 months
[libvirt] [PATCH] spice: add disableCopyPaste property
by Eric Blake
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
>From a security pov copy and paste between the guest and the client is not
always desirable. So we need to be able to enable/disable this. The best place
to do this from an administration pov is on the hypervisor, so the qemu cmdline
is getting a spice disable-copy-paste option, see bug 693645. Example qemu
invocation:
qemu -spice port=5932,disable-ticketing,disable-copy-paste
https://bugzilla.redhat.com/show_bug.cgi?id=693661
---
docs/formatdomain.html.in | 8 +++++++-
docs/schemas/domain.rng | 8 ++++++++
src/conf/domain_conf.c | 11 +++++++++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 2 ++
.../qemuxml2argv-graphics-spice-compression.xml | 2 +-
.../qemuxml2argv-graphics-spice-qxl-vga.xml | 2 +-
.../qemuxml2argv-graphics-spice-timeout.xml | 2 +-
.../qemuxml2argv-graphics-spice.args | 2 +-
.../qemuxml2argv-graphics-spice.xml | 2 +-
10 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 98fb2b4..61af08e 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1833,7 +1833,7 @@ qemu-kvm -net nic,model=? /dev/null
and <span class="since">since 0.8.8</span>: <code>smartcard</code>.
</p>
<pre>
- <graphics type='spice' port='-1' tlsPort='-1' autoport='yes'>
+ <graphics type='spice' port='-1' tlsPort='-1' autoport='yes' disableCopyPaste='no'>
<channel name='main' mode='secure'/>
<channel name='record' mode='insecure'/>
<image compression='auto_glz'/>
@@ -1862,6 +1862,12 @@ qemu-kvm -net nic,model=? /dev/null
of <code>filter</code>, <code>all</code>
or <code>off</code>, <span class="since">since 0.9.2</span>.
</p>
+ <p>
+ Copy & Paste from guest to client (via Spice agent)
+ can be disabled by setting
+ the <code>disableCopyPaste</code> property
+ to <code>yes</code>, <span class="since">since 0.9.2</span>.
+ </>
</dd>
<dt><code>"rdp"</code></dt>
<dd>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 0be0371..b2333d5 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1293,6 +1293,14 @@
<data type="dateTime"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="disableCopyPaste">
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </optional>
<interleave>
<zeroOrMore>
<element name="channel">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 65d4f89..61377c3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4099,6 +4099,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
char *port = virXMLPropString(node, "port");
char *tlsPort;
char *autoport;
+ char *disableCopyPaste;
if (port) {
if (virStrToLong_i(port, NULL, 10, &def->data.spice.port) < 0) {
@@ -4143,6 +4144,13 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
!def->data.spice.listenAddr[0])
VIR_FREE(def->data.spice.listenAddr);
+ if ((disableCopyPaste = virXMLPropString(node, "disableCopyPaste")) != NULL) {
+ if (STREQ(disableCopyPaste, "yes")) {
+ def->data.spice.disableCopyPaste = true;
+ }
+ VIR_FREE(disableCopyPaste);
+ }
+
if (virDomainGraphicsAuthDefParseXML(node, &def->data.spice.auth) < 0)
goto error;
@@ -9190,6 +9198,9 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " keymap='%s'",
def->data.spice.keymap);
+ virBufferAsprintf(buf, " disableCopyPaste='%s'",
+ def->data.spice.disableCopyPaste ? "yes" : "no");
+
virDomainGraphicsAuthDefFormatAttr(buf, &def->data.spice.auth, flags);
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 41c8136..9566d51 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -757,6 +757,7 @@ struct _virDomainGraphicsDef {
int zlib;
int playback;
int streaming;
+ bool disableCopyPaste;
} spice;
} data;
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cb81354..8261088 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4161,6 +4161,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if (def->graphics[0]->data.spice.streaming)
virBufferAsprintf(&opt, ",streaming-video=%s",
virDomainGraphicsSpiceStreamingModeTypeToString(def->graphics[0]->data.spice.streaming));
+ if (def->graphics[0]->data.spice.disableCopyPaste)
+ virBufferAddLit(&opt, ",disable-copy-paste");
virCommandAddArg(cmd, "-spice");
virCommandAddArgBuffer(cmd, &opt);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
index 64a6890..e502216 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
@@ -21,7 +21,7 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1' disableCopyPaste='no'>
<image compression='auto_glz'/>
<jpeg compression='auto'/>
<zlib compression='auto'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
index a38550c..0075d26 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
@@ -21,7 +21,7 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1' disableCopyPaste='no'>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
</graphics>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
index 4c0c57e..6b13d6b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
@@ -71,7 +71,7 @@
</console>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='spice' port='5900' autoport='no' passwd='sercet' passwdValidTo='2011-05-31T16:11:22'/>
+ <graphics type='spice' port='5900' autoport='no' disableCopyPaste='no' passwd='sercet' passwdValidTo='2011-05-31T16:11:22'/>
<sound model='ac97'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</sound>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
index 084a100..c9fdb99 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
@@ -4,6 +4,6 @@ unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
/dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\
x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs,\
image-compression=auto_glz,jpeg-wan-compression=auto,zlib-glz-wan-compression=auto,\
-playback-compression=on,streaming-video=filter -vga \
+playback-compression=on,streaming-video=filter,disable-copy-paste -vga \
qxl -global qxl.vram_size=18874368 -device qxl,id=video1,vram_size=33554432,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
index 0d3dd48..4b5840c 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
@@ -21,7 +21,7 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1' disableCopyPaste='yes'>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
<image compression='auto_glz'/>
--
1.7.1
13 years, 5 months
[libvirt] [PATCHv7 0/12] Add virNodeGet{CPU,Memory}Stats() API
by Minoru Usui
Hi, everyone.
I re-wrote virNodeGetCPUStats(), virNodeGetMemoryStats().
This time, I merged two APIs to same patch series.
Changes
v6->v7
- Add cpuNum/cellNum arguments to return specified cpu/cell statistics only.
v5->v6
- Rename API name to virNodeGetCPUStats()
- virsh nodecpustats subcommand returns raw/absolute cputime value by default,
and add --percent option for printing utilization.
v4->v5
- Rebase latest libvirt GIT tree.
v3->v4
- Rebase this patch like virDomainGetMemoryParameters() from v2 patches.
(drop v3 patches except virsh subcommand)
- Rename API name to virNodeGetCPUTimeParameters()
v2->v3
- Change user I/F. It is able to request what the user want by the @flags.
- Minor change of virsh nodecputime I/F.
v1->v2
- Change user I/F like virDomainGetMemoryStats()
- It can return either cpu utilization or cumulative cpu time of the node
depends on each driver.
Minoru Usui (12):
[v7] virNodeGetCPUStats: Expose new API
[v7] virNodeGetCPUStats: Define internal driver API
[v7] virNodeGetCPUTime: Implement public API
[v7] virNodeGetCPUStats: Implement remote protocol
[v7] virNodeGetCPUStats: Implement virsh support
[v7] virNodeGetCPUStats: Implement linux support
[v2] virNodeGetMemoryStats: Expose new API
[v2] virNodeGetMemoryStats: Define internal driver API
[v2] virNodeGetMemoryStats: Implement public API
[v2] virNodeGetMemoryStats: Implement remote protocol
[v2] virNodeGetMemoryStats: Implement virsh support
[v2] virNodeGetMemoryStats: Implement linux support
daemon/remote.c | 154 ++++++++++++++++++++++
include/libvirt/libvirt.h.in | 153 +++++++++++++++++++++-
src/driver.h | 18 +++
src/libvirt.c | 178 +++++++++++++++++++++++++
src/libvirt_private.syms | 2 +
src/libvirt_public.syms | 6 +
src/lxc/lxc_driver.c | 2 +
src/nodeinfo.c | 299 ++++++++++++++++++++++++++++++++++++++++++
src/nodeinfo.h | 11 ++-
src/qemu/qemu_driver.c | 2 +
src/remote/remote_driver.c | 132 +++++++++++++++++++
src/remote/remote_protocol.x | 42 ++++++-
src/uml/uml_driver.c | 2 +
tools/virsh.c | 196 +++++++++++++++++++++++++++
tools/virsh.pod | 12 ++
15 files changed, 1206 insertions(+), 3 deletions(-)
--
Minoru Usui <usui(a)mxm.nes.nec.co.jp>
13 years, 5 months
[libvirt] [PATCH] Skip nodeinfo test on non intel architectures
by Guido Günther
since the testfiles assume a /proc/cpuinfo specific to this
architecture. We e.g. can't parse the number of cores on other
architectures.
O.k. to apply?
Cheers,
-- Guido
---
tests/nodeinfotest.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/tests/nodeinfotest.c b/tests/nodeinfotest.c
index b4e81b3..71e2926 100644
--- a/tests/nodeinfotest.c
+++ b/tests/nodeinfotest.c
@@ -11,7 +11,9 @@
#include "util.h"
#include "files.h"
-#ifndef __linux__
+#if ! (defined __linux__ && (defined(__x86_64__) || \
+ defined(__amd64__) || \
+ defined(__i386__)))
static int
mymain(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
--
1.7.5.3
13 years, 5 months
[libvirt] [PATCH v2] Fix autostart flag when loading running domains
by Michael Chapman
Drivers load running persistent and transient domain configs before
inactive persistent domain configs, however only the latter would set a
domain's autostart flag. This mismatch between the loaded and on-disk
state could later cause problems with "virsh autostart":
# virsh autostart example
error: Failed to mark domain example as autostarted
error: Failed to create symlink '/etc/libvirt/qemu/autostart/example.xml to '/etc/libvirt/qemu/example.xml': File exists
This patch ensures the autostart flag is set correctly even when the
domain is already defined.
Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=632100
https://bugzilla.redhat.com/show_bug.cgi?id=675319
v1 -> v2:
- free autostartLink
- fixed comment
Signed-off-by: Michael Chapman <mike(a)very.puzzling.org>
---
src/conf/domain_conf.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0d9fef4..aa306fe 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9859,21 +9859,24 @@ static virDomainObjPtr virDomainLoadConfig(virCapsPtr caps,
VIR_DOMAIN_XML_INACTIVE)))
goto error;
- /* if the domain is already in our hashtable, we don't need to do
- * anything further
+ if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL)
+ goto error;
+
+ if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
+ goto error;
+
+ /* if the domain is already in our hashtable, we only need to
+ * update the autostart flag
*/
if ((dom = virDomainFindByUUID(doms, def->uuid))) {
+ dom->autostart = autostart;
+
VIR_FREE(configFile);
+ VIR_FREE(autostartLink);
virDomainDefFree(def);
return dom;
}
- if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL)
- goto error;
-
- if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0)
- goto error;
-
if (!(dom = virDomainAssignDef(caps, doms, def, false)))
goto error;
--
1.7.4.4
13 years, 5 months
[libvirt] [PATCH v2] virsh: Increase device-detach intelligence
by Michal Prívozník
Up to now users have to give a full XML description on input when
device-detaching. If they omitted something it lead to unclear
error messages (like generated MAC wasn't found, etc.).
With this patch users can specify only those information which
specify one device sufficiently precise. Remaining information is
completed from domain.
---
diff to v1:
-rebase to current HEAD
-add a little bit comments
tools/virsh.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 250 insertions(+), 16 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index d98be1c..5c2634c 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -9302,6 +9302,226 @@ cmdAttachDevice(vshControl *ctl, const vshCmd *cmd)
return true;
}
+/**
+ * Check if n1 is superset of n2, meaning n1 contains all elements and
+ * attributes as n2 at lest. Including children.
+ * @n1 first node
+ * @n2 second node
+ * return 1 in case n1 covers n2, 0 otherwise.
+ */
+static int
+vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2) {
+ xmlNodePtr child1, child2;
+ xmlAttrPtr attr1, attr2;
+ int found;
+
+ if (!n1 && !n2)
+ return 1;
+
+ if (!n1 || !n2)
+ return 0;
+
+ if (!xmlStrEqual(n1->name, n2->name))
+ return 0;
+
+ /* Iterate over n2 attributes and check if n1 contains them*/
+ attr2 = n2->properties;
+ while (attr2) {
+ if (attr2->type == XML_ATTRIBUTE_NODE) {
+ attr1 = n1->properties;
+ found = 0;
+ while (attr1) {
+ if (xmlStrEqual(attr1->name, attr2->name)) {
+ found = 1;
+ break;
+ }
+ attr1 = attr1->next;
+ }
+ if (!found)
+ return 0;
+ if (!xmlStrEqual(BAD_CAST virXMLPropString(n1, (const char *) attr1->name),
+ BAD_CAST virXMLPropString(n2, (const char *) attr2->name)))
+ return 0;
+ }
+ attr2 = attr2->next;
+ }
+
+ /* and now iterate over n2 children */
+ child2 = n2->children;
+ while (child2) {
+ if (child2->type == XML_ELEMENT_NODE) {
+ child1 = n1->children;
+ found = 0;
+ while (child1) {
+ if (child1->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(child1->name, child2->name)) {
+ found = 1;
+ break;
+ }
+ child1 = child1->next;
+ }
+ if (!found)
+ return 0;
+ if (!vshNodeIsSuperset(child1, child2))
+ return 0;
+ }
+ child2 = child2->next;
+ }
+
+ return 1;
+}
+
+/**
+ * To given domain and (probably incomplete) device XML specification try to
+ * find such device in domain and complete missing parts. This is however
+ * possible when given device XML is sufficiently precise so it addresses only
+ * one device.
+ * @ctl vshControl for error messages printing
+ * @dom domain
+ * @oldXML device XML before
+ * @newXML and after completion
+ * Returns -2 when no such device exists in domain, -3 when given XML selects many
+ * (is too ambiguous), 0 in case of success. Otherwise returns -1. @newXML
+ * is touched only in case of success.
+ */
+static int
+vshCompleteXMLFromDomain(vshControl *ctl, virDomainPtr dom, char *oldXML,
+ char **newXML) {
+ int funcRet = -1;
+ char *domXML = NULL;
+ xmlDocPtr domDoc = NULL, devDoc = NULL;
+ xmlNodePtr node = NULL;
+ xmlXPathContextPtr domCtxt = NULL, devCtxt = NULL;
+ xmlNodePtr *devices = NULL;
+ xmlSaveCtxtPtr sctxt = NULL;
+ int devices_size;
+ char *xpath;
+ xmlBufferPtr buf = NULL;
+
+ if (!(domXML = virDomainGetXMLDesc(dom, 0))) {
+ vshError(ctl, _("couldn't get XML description of domain %s"),
+ virDomainGetName(dom));
+ goto cleanup;
+ }
+
+ if (!(domDoc = xmlReadDoc(BAD_CAST domXML, "domain.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+ vshError(ctl, "%s", _("could not parse domain XML"));
+ goto cleanup;
+ }
+
+ if (!(devDoc = xmlReadDoc(BAD_CAST oldXML, "device.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+ vshError(ctl, "%s", _("could not parse device XML"));
+ goto cleanup;
+ }
+
+ node = xmlDocGetRootElement(domDoc);
+ if (!node) {
+ vshError(ctl, "%s", _("failed to get domain root element"));
+ goto cleanup;
+ }
+
+ domCtxt = xmlXPathNewContext(domDoc);
+ if (!domCtxt) {
+ vshError(ctl, "%s", _("failed to create context on domain XML"));
+ goto cleanup;
+ }
+ domCtxt->node = node;
+
+ node = xmlDocGetRootElement(devDoc);
+ if (!node) {
+ vshError(ctl, "%s", _("failed to get device root element"));
+ goto cleanup;
+ }
+
+ devCtxt = xmlXPathNewContext(devDoc);
+ if (!devCtxt) {
+ vshError(ctl, "%s", _("failed to create context on device XML"));
+ goto cleanup;
+ }
+ devCtxt->node = node;
+
+ buf = xmlBufferCreate();
+ if (!buf) {
+ vshError(ctl, "%s", _("out of memory"));
+ goto cleanup;
+ }
+
+ xmlBufferCat(buf, BAD_CAST "/domain/devices/");
+ xmlBufferCat(buf, node->name);
+ xpath = (char *) xmlBufferContent(buf);
+ /* Get all possible devices */
+ devices_size = virXPathNodeSet(xpath, domCtxt, &devices);
+ xmlBufferEmpty(buf);
+
+ if (devices_size < 0) {
+ /* error */
+ vshError(ctl, "%s", _("error when selecting nodes"));
+ goto cleanup;
+ } else if (devices_size == 0) {
+ /* no such device */
+ funcRet = -2;
+ goto cleanup;
+ }
+
+ /* and refine */
+ int i = 0;
+ while (i < devices_size) {
+ if (!vshNodeIsSuperset(devices[i], node)) {
+ if (devices_size == 1) {
+ VIR_FREE(devices);
+ devices_size = 0;
+ } else {
+ memmove(devices + i, devices + i + 1,
+ sizeof(*devices) * (devices_size-i-1));
+ devices_size--;
+ if (VIR_REALLOC_N(devices, devices_size) < 0) {
+ /* ignore, harmless */
+ }
+ }
+ } else {
+ i++;
+ }
+ }
+
+ if (!devices_size) {
+ /* no such device */
+ funcRet = -2;
+ goto cleanup;
+ } else if (devices_size > 1) {
+ /* ambiguous */
+ funcRet = -3;
+ goto cleanup;
+ }
+
+ if (newXML) {
+ sctxt = xmlSaveToBuffer(buf, NULL, 0);
+ if (!sctxt) {
+ vshError(ctl, "%s", _("failed to create document saving context"));
+ goto cleanup;
+ }
+
+ xmlSaveTree(sctxt, devices[0]);
+ xmlSaveClose(sctxt);
+ *newXML = (char *) xmlBufferContent(buf);
+ buf->content = NULL;
+ }
+
+ funcRet = 0;
+
+cleanup:
+ xmlBufferFree(buf);
+ VIR_FREE(devices);
+ xmlXPathFreeContext(devCtxt);
+ xmlXPathFreeContext(domCtxt);
+ xmlFreeDoc(devDoc);
+ xmlFreeDoc(domDoc);
+ VIR_FREE(domXML);
+ return funcRet;
+}
/*
* "detach-device" command
@@ -9322,10 +9542,11 @@ static const vshCmdOptDef opts_detach_device[] = {
static bool
cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
{
- virDomainPtr dom;
+ virDomainPtr dom = NULL;
const char *from = NULL;
- char *buffer;
+ char *buffer = NULL, *new_buffer = NULL;
int ret;
+ bool funcRet = false;
unsigned int flags;
if (!vshConnectionUsability(ctl, ctl->conn))
@@ -9334,37 +9555,50 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
- if (vshCommandOptString(cmd, "file", &from) <= 0) {
- virDomainFree(dom);
- return false;
- }
+ if (vshCommandOptString(cmd, "file", &from) <= 0)
+ goto cleanup;
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
virshReportError(ctl);
- virDomainFree(dom);
- return false;
+ goto cleanup;
+ }
+
+ ret = vshCompleteXMLFromDomain(ctl, dom, buffer, &new_buffer);
+ if (ret < 0) {
+ if (ret == -2) {
+ vshError(ctl, _("no such device in %s"), virDomainGetName(dom));
+ } else if (ret == -3) {
+ vshError(ctl, "%s", _("given XML selects too many devices. "
+ "Please, be more specific"));
+ } else {
+ /* vshCompleteXMLFromDomain() already printed error message,
+ * so nothing to do here. */
+ }
+ goto cleanup;
}
if (vshCommandOptBool(cmd, "persistent")) {
flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
if (virDomainIsActive(dom) == 1)
flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE;
- ret = virDomainDetachDeviceFlags(dom, buffer, flags);
+ ret = virDomainDetachDeviceFlags(dom, new_buffer, flags);
} else {
- ret = virDomainDetachDevice(dom, buffer);
+ ret = virDomainDetachDevice(dom, new_buffer);
}
- VIR_FREE(buffer);
if (ret < 0) {
vshError(ctl, _("Failed to detach device from %s"), from);
- virDomainFree(dom);
- return false;
- } else {
- vshPrint(ctl, "%s", _("Device detached successfully\n"));
+ goto cleanup;
}
+ vshPrint(ctl, "%s", _("Device detached successfully\n"));
+ funcRet = true;
+
+cleanup:
+ VIR_FREE(new_buffer);
+ VIR_FREE(buffer);
virDomainFree(dom);
- return true;
+ return funcRet;
}
--
1.7.5.rc3
13 years, 5 months
[libvirt] [PATCH v2] Add support for network filter code in LXC driver
by Daniel P. Berrange
The LXC driver networking uses veth device pairs. These can
be easily hooked into the network filtering code.
* src/lxc/lxc_driver.c: Add calls to setup/teardown nwfilter
New in v2:
- Add missing hooks for automatic rebuild of filters for
online guests
---
src/lxc/lxc_driver.c | 40 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 9ef75f5..e8ad3f0 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -52,7 +52,7 @@
#include "hooks.h"
#include "files.h"
#include "fdstream.h"
-
+#include "domain_nwfilter.h"
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -1027,6 +1027,8 @@ static void lxcVmCleanup(lxc_driver_t *driver,
vethDelete(vm->def->nets[i]->ifname);
}
+ virDomainConfVMNWFilterTeardown(vm);
+
if (driver->cgroup &&
virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0) {
virCgroupRemove(cgroup);
@@ -1146,6 +1148,10 @@ static int lxcSetupInterfaces(virConnectPtr conn,
if (vethInterfaceUpOrDown(parentVeth, 1) < 0)
goto error_exit;
+
+ if (def->nets[i]->filter &&
+ virDomainConfNWFilterInstantiate(conn, def->nets[i]) < 0)
+ goto error_exit;
}
rc = 0;
@@ -1642,8 +1648,10 @@ cleanup:
vethDelete(veths[i]);
VIR_FREE(veths[i]);
}
- if (rc != 0)
+ if (rc != 0) {
VIR_FORCE_CLOSE(priv->monitor);
+ virDomainConfVMNWFilterTeardown(vm);
+ }
VIR_FORCE_CLOSE(parentTty);
VIR_FORCE_CLOSE(handshakefds[0]);
VIR_FORCE_CLOSE(handshakefds[1]);
@@ -2842,6 +2850,33 @@ cleanup:
return ret;
}
+static int
+lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virHashIterator iter, void *data)
+{
+ virHashForEach(lxc_driver->domains.objs, iter, data);
+
+ return 0;
+}
+
+static void
+lxcVMDriverLock(void)
+{
+ lxcDriverLock(lxc_driver);
+}
+
+static void
+lxcVMDriverUnlock(void)
+{
+ lxcDriverUnlock(lxc_driver);
+}
+
+static virNWFilterCallbackDriver lxcCallbackDriver = {
+ .name = "LXC",
+ .vmFilterRebuild = lxcVMFilterRebuild,
+ .vmDriverLock = lxcVMDriverLock,
+ .vmDriverUnlock = lxcVMDriverUnlock,
+};
/* Function Tables */
static virDriver lxcDriver = {
@@ -2911,5 +2946,6 @@ int lxcRegister(void)
{
virRegisterDriver(&lxcDriver);
virRegisterStateDriver(&lxcStateDriver);
+ virNWFilterRegisterCallbackDriver(&lxcCallbackDriver);
return 0;
}
--
1.7.4.4
13 years, 5 months
[libvirt] Request to rename 'destroy' to something milder.
by Kashyap Chamarthy
(please cc me in response as I have not subscribed to this list)
Hi all,
A minor nitpick:
Every-time I suggest someone to do a force shut-down a guest using 'virsh destroy foo' ,
the very first question I get is -- does it _destroy_ my data?
This causes confusion to the inexperienced user and makes him/her suspect that the
data/disk could be destroyed while running 'virsh destroy foo'
Maybe replacing it to a milder name like 'poweroff' or something might help?
Thanks,
Kashyap Chamarthy
13 years, 5 months
Re: [libvirt] [libvirt-users] request to add an application the app listing on libvirt site
by Eric Blake
[adding libvir-list for patch tracking]
On 06/14/2011 10:17 AM, Ohad Levy wrote:
>> the simplest is to actually send a patch against the file docs/
>> apps.html.in
>> in the source tree. I would think "Ruby Objects for libvirt" should be
>> added in the "libraries" section, and "Foreman" in the "provisioning"
>> section. The pages are maintained in the source which also allow to
>> package them easilly, I hope making an HTML patch isn't too complex,
>> if not say so I will do it myself :-)
>>
>> thanks !
>>
>> thanks! see attached patch.
>
Thanks for the patch.
Your mailer sent both plain text and html renderings of the email body;
that is overkill (plain text alone works just fine).
> + <dl>
> + <dt><a href="http://theforeman.org">Foreman</a></dt>
> + <dd>
> + Foreman is an open source web based application aimed to be a Single Address For All Machines Life Cycle Management, Foreman:
> +
That's a long line. I reformatted to break things to 80 columns where
reasonably possible, and added your name to AUTHORS. Let me know if you
prefer an alternate spelling there (for example, the commit was
attributed to your gmail.com address, although I see that you also have
a redhat.com address). Also, I saw some grammar nits.
ACK and pushed as modified:
diff --git i/docs/apps.html.in w/docs/apps.html.in
index 69c9aaa..6b5afdb 100644
--- i/docs/apps.html.in
+++ w/docs/apps.html.in
@@ -15,7 +15,7 @@
To add an application not listed on this page, send a message
to the <a href="contact.html">mailing list</a>, requesting it
be added here, or simply send a patch against the documentation
- in our git docs sub directory.
+ in the libvirt.git docs subdirectory.
If your application uses libvirt as its API,
the following graphic is available for your website to advertise
support for libvirt:
@@ -232,11 +232,11 @@
<dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
Libvirt Object bindings</a></dt>
<dd>
- Virt Allows using simple ruby objects to manipulate
+ Allows using simple ruby objects to manipulate
hypervisors, guests, storage, network etc. It is
based on top of
the <a href="http://libvirt.org/ruby">native ruby
- binding</a>.
+ bindings</a>.
</dd>
</dl>
<h2><a name="livecd">LiveCD / Appliances</a></h2>
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years, 5 months