[libvirt] [PATCH] qemu: detect multi-head qxl via more than version check
by Eric Blake
Multi-head QXL support is so useful that distros have started to
backport it to qemu earlier than 1.2. After discussion with
Alon Levy, we determined that the existence of the qxl-vga.surfaces
property is a reliable indicator of whether '-device qxl-vga' works,
or whether we have to stick to the older '-vga qxl'. I'm leaving
in the existing check for QEMU_CAPS_DEVICE_VIDEO_PRIMARY tied to
qemu 1.2 and newer (in case qemu is built without qxl support),
but for those distros that backport qxl, this additional capability
check will allow the correct command line for both RHEL 6.3 (which
lacks the feature) and RHEL 6.4 (where qemu still claims to be
version 0.12.2.x, but has backported multi-head qxl).
* src/qemu/qemu_capabilities.c (virQEMUCapsObjectPropsQxlVga): New
property test.
(virQEMUCapsExtractDeviceStr): Probe for backport of new
capability to qemu earlier than 1.2.
* tests/qemuhelpdata/qemu-kvm-1.2.0-device: Update test.
* tests/qemuhelpdata/qemu-1.2.0-device: Likewise.
* tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device:
Likewise.
---
src/qemu/qemu_capabilities.c | 7 +++++++
tests/qemuhelpdata/qemu-1.2.0-device | 16 ++++++++++++++++
tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device | 10 ++++++++++
tests/qemuhelpdata/qemu-kvm-1.2.0-device | 16 ++++++++++++++++
4 files changed, 49 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 79cfdb3..17747c1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1383,6 +1383,10 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUsbHost[] = {
{ "bootindex", QEMU_CAPS_USB_HOST_BOOTINDEX },
};
+static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQxlVga[] = {
+ { "surfaces", QEMU_CAPS_DEVICE_VIDEO_PRIMARY },
+};
+
struct virQEMUCapsObjectTypeProps {
const char *type;
struct virQEMUCapsStringFlags *props;
@@ -1416,6 +1420,8 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
ARRAY_CARDINALITY(virQEMUCapsObjectPropsUsbRedir) },
{ "usb-host", virQEMUCapsObjectPropsUsbHost,
ARRAY_CARDINALITY(virQEMUCapsObjectPropsUsbHost) },
+ { "qxl-vga", virQEMUCapsObjectPropsQxlVga,
+ ARRAY_CARDINALITY(virQEMUCapsObjectPropsQxlVga) },
};
@@ -1613,6 +1619,7 @@ virQEMUCapsExtractDeviceStr(const char *qemu,
"-device", "usb-redir,?",
"-device", "ide-drive,?",
"-device", "usb-host,?",
+ "-device", "qxl-vga,?",
NULL);
/* qemu -help goes to stdout, but qemu -device ? goes to stderr. */
virCommandSetErrorBuffer(cmd, &output);
diff --git a/tests/qemuhelpdata/qemu-1.2.0-device b/tests/qemuhelpdata/qemu-1.2.0-device
index 5613e00..027d99a 100644
--- a/tests/qemuhelpdata/qemu-1.2.0-device
+++ b/tests/qemuhelpdata/qemu-1.2.0-device
@@ -208,3 +208,19 @@ usb-host.bootindex=int32
usb-host.pipeline=on/off
usb-host.port=string
usb-host.full-path=on/off
+qxl-vga.ram_size=uint32
+qxl-vga.vram_size=uint32
+qxl-vga.revision=uint32
+qxl-vga.debug=uint32
+qxl-vga.guestdebug=uint32
+qxl-vga.cmdlog=uint32
+qxl-vga.ram_size_mb=uint32
+qxl-vga.vram_size_mb=uint32
+qxl-vga.vram64_size_mb=uint32
+qxl-vga.vgamem_mb=uint32
+qxl-vga.surfaces=int32
+qxl-vga.addr=pci-devfn
+qxl-vga.romfile=string
+qxl-vga.rombar=uint32
+qxl-vga.multifunction=on/off
+qxl-vga.command_serr_enable=on/off
diff --git a/tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device b/tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device
index ee0fd78..5eab539 100644
--- a/tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device
+++ b/tests/qemuhelpdata/qemu-kvm-0.12.1.2-rhel62-beta-device
@@ -118,3 +118,13 @@ virtio-net-pci.addr=pci-devfn
virtio-net-pci.romfile=string
virtio-net-pci.rombar=uint32
virtio-net-pci.multifunction=on/off
+qxl-vga.ram_size=uint32
+qxl-vga.vram_size=uint32
+qxl-vga.revision=uint32
+qxl-vga.debug=uint32
+qxl-vga.guestdebug=uint32
+qxl-vga.cmdlog=uint32
+qxl-vga.addr=pci-devfn
+qxl-vga.romfile=string
+qxl-vga.rombar=uint32
+qxl-vga.multifunction=on/off
diff --git a/tests/qemuhelpdata/qemu-kvm-1.2.0-device b/tests/qemuhelpdata/qemu-kvm-1.2.0-device
index 879a049..ebc27f0 100644
--- a/tests/qemuhelpdata/qemu-kvm-1.2.0-device
+++ b/tests/qemuhelpdata/qemu-kvm-1.2.0-device
@@ -220,3 +220,19 @@ usb-host.bootindex=int32
usb-host.pipeline=on/off
usb-host.port=string
usb-host.full-path=on/off
+qxl-vga.ram_size=uint32
+qxl-vga.vram_size=uint32
+qxl-vga.revision=uint32
+qxl-vga.debug=uint32
+qxl-vga.guestdebug=uint32
+qxl-vga.cmdlog=uint32
+qxl-vga.ram_size_mb=uint32
+qxl-vga.vram_size_mb=uint32
+qxl-vga.vram64_size_mb=uint32
+qxl-vga.vgamem_mb=uint32
+qxl-vga.surfaces=int32
+qxl-vga.addr=pci-devfn
+qxl-vga.romfile=string
+qxl-vga.rombar=uint32
+qxl-vga.multifunction=on/off
+qxl-vga.command_serr_enable=on/off
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH libvirt-glib v2 1/2] Add gvir_config_object_replace_child_with_attribute_enum()
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
Internal libvirt-gconfig helper to replace enum XML attributes.
---
libvirt-gconfig/libvirt-gconfig-object-private.h | 5 +++++
libvirt-gconfig/libvirt-gconfig-object.c | 14 ++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 830517c..91355fb 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -74,6 +74,11 @@ void gvir_config_object_replace_child_with_attribute(GVirConfigObject *object,
const char *child_name,
const char *attr_name,
const char *attr_value);
+void gvir_config_object_replace_child_with_attribute_enum(GVirConfigObject *object,
+ const char *child_name,
+ const char *attr_name,
+ GType attr_type,
+ unsigned int attr_value);
void gvir_config_object_delete_child(GVirConfigObject *object,
const char *child_name,
const char *ns_href);
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index ac0545c..c4e4271 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -459,6 +459,20 @@ gvir_config_object_replace_child_with_attribute(GVirConfigObject *object,
g_object_unref(G_OBJECT(child));
}
+G_GNUC_INTERNAL void
+gvir_config_object_replace_child_with_attribute_enum(GVirConfigObject *object,
+ const char *child_name,
+ const char *attr_name,
+ GType attr_type,
+ unsigned int attr_value)
+{
+ GVirConfigObject *child;
+
+ child = gvir_config_object_replace_child(object, child_name);
+ gvir_config_object_set_attribute_with_type(child, attr_name, attr_type, attr_value, NULL);
+ g_object_unref(G_OBJECT(child));
+}
+
struct NodeMatch {
const char *name;
const char *ns;
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] Fix deps for generating RPC dispatch code
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The src/lxc/lxc_*_dispatch.h files only had deps on the
RPC generator script & the XDR definition file. So when
the Makefile.am args passed to the generator were change,
the disaptch code was not re-generated. This caused a
build failure
CC libvirt_lxc-lxc_controller.o
lxc/lxc_controller.c: In function 'virLXCControllerSetupServer':
lxc/lxc_controller.c:718:47: error: 'virLXCMonitorProcs' undeclared (first use in this function)
lxc/lxc_controller.c:718:47: note: each undeclared identifier is reported only once for each function it appears in
lxc/lxc_controller.c:719:47: error: 'virLXCMonitorNProcs' undeclared (first use in this function)
make[3]: *** [libvirt_lxc-lxc_controller.o] Error 1
For added fun, the generated files were not listed in
CLEANFILES, so only a 'git clean -f' would fix the build
Pushed as a build break fix
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/Makefile.am | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 0c0dfb3..8b591d2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -295,17 +295,17 @@ QEMU_PROTOCOL = $(srcdir)/remote/qemu_protocol.x
REMOTE_DRIVER_PROTOCOL = $(REMOTE_PROTOCOL) $(QEMU_PROTOCOL) $(LXC_PROTOCOL)
$(srcdir)/remote/remote_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
- $(REMOTE_PROTOCOL)
+ $(REMOTE_PROTOCOL) Makefile.am
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-k remote REMOTE $(REMOTE_PROTOCOL) > $@
$(srcdir)/remote/lxc_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
- $(LXC_PROTOCOL)
+ $(LXC_PROTOCOL) Makefile.am
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-k lxc LXC $(LXC_PROTOCOL) > $@
$(srcdir)/remote/qemu_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
- $(QEMU_PROTOCOL)
+ $(QEMU_PROTOCOL) Makefile.am
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-k qemu QEMU $(QEMU_PROTOCOL) > $@
@@ -458,12 +458,12 @@ LXC_GENERATED = \
LXC_MONITOR_PROTOCOL = $(srcdir)/lxc/lxc_monitor_protocol.x
$(srcdir)/lxc/lxc_monitor_dispatch.h: $(srcdir)/rpc/gendispatch.pl \
- $(LXC_MONITOR_PROTOCOL)
+ $(LXC_MONITOR_PROTOCOL) Makefile.am
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-k virLXCMonitor VIR_LXC_MONITOR $(LXC_MONITOR_PROTOCOL) > $@
$(srcdir)/lxc/lxc_controller_dispatch.h: $(srcdir)/rpc/gendispatch.pl \
- $(REMOTE_PROTOCOL)
+ $(REMOTE_PROTOCOL) Makefile.am
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-b virLXCMonitor VIR_LXC_MONITOR $(LXC_MONITOR_PROTOCOL) > $@
@@ -474,6 +474,8 @@ EXTRA_DIST += \
BUILT_SOURCES += $(LXC_GENERATED)
+CLEANFILES += $(LXC_GENERATED)
+
LXC_DRIVER_SOURCES = \
$(LXC_MONITOR_PROTOCOL_GENERATED) \
$(LXC_MONITOR_GENERATED) \
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] Fix size probing for VDI images
by Ján Tomko
Commit 027bf2ea used the wrong offset: the text field at the start
of the header has 64 bytes, not 68. [1]
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=921452
[1] https://forums.virtualbox.org/viewtopic.php?p=29267#p29267
---
Relevant for v1.0.3-maint.
src/util/virstoragefile.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index cbcab5c..aabb5c8 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -199,7 +199,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
[VIR_STORAGE_FILE_VDI] = {
64, "\x7f\x10\xda\xbe", ".vdi",
LV_LITTLE_ENDIAN, 68, 0x00010001,
- 68 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL},
+ 64 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL},
/* Not direct file formats, but used for various drivers */
[VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
--
1.8.1.5
11 years, 7 months
[libvirt] Libvirt + LXC terminals
by Purcareata Bogdan-B43198
Hello all,
I am looking for a way to start a container with libvirt and bind multiple consoles to it. My container is running busybox, the filesystem created using the LXC package (0.8.0). My libvirt version is 0.10.1.
Configuration of the filesystem:
- in the container rootfs, /dev contains 2 devices - /dev/console and /dev/tty1
- the inittab file looks like this:
::sysinit:/etc/init.d/rcS
tty1::respawn:/bin/getty -L tty1 115200 vt100
console::askfirst:/bin/sh
- it will link the /bin/sh process to /dev/console and the /bin/getty process to /dev/tty
- when starting the container with lxc-start, each of these processes gets his own local /dev/pts device:
25609 ? Ss 0:00 lxc-start -n foo -d
25612 ? Ss 0:00 \_ init
25684 ? Ss 0:00 \_ /bin/syslogd
25686 pts/3 Ss+ 0:00 \_ /bin/getty -L tty1 115200 vt100
25687 pts/4 Ss+ 0:00 \_ init
Here is the container.xml file I use to run with libvirt (you may ignore the console devices, since I don't know how much sense they make right now):
<domain type='lxc'>
<name>foo</name>
<memory>500000</memory>
<os>
<type>exe</type>
<init>/bin/init</init>
</os>
<vcpu>1</vcpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/libvirt_lxc</emulator>
<filesystem type="mount">
<source dir="/usr/var/lib/lxc/foo/rootfs" />
<target dir="/" />
</filesystem>
<interface type="bridge">
<source bridge="br0" />
<name>eth0</name>
<ip address="10.171.73.128" netmask="255.255.255.0" />
</interface>
<console type='pty' tty='/dev/pts/3'>
<source path='/dev/pts/3' />
<target path='/dev/console' />
</console>
<serial type='pty' tty='/dev/pts/4'>
<source path='/dev/pts/4' />
<target path='/dev/tty1' />
</serial>
</devices>
</domain>
When starting the container with virsh start foo, the firt init process gets a local /dev/pts device, and it is inherited by its children:
[root@everest][~]# ps axf
25858 ? Ss 0:00 /usr/libexec/libvirt_lxc --name foo --console 20 --security=selinux --handshake 23 --background --veth veth1
25859 pts/0 Ss+ 0:00 \_ init
25870 ? Ss 0:00 \_ /bin/syslogd
25872 ? Ss 0:00 \_ /bin/getty -L tty1 115200 vt100
25873 ? Ss 0:00 \_ init
[root@everest][~]# ls -l /proc/25872/fd
total 0
lrwx------. 1 root root 64 Mar 14 07:09 0 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 14 07:09 1 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 14 07:09 2 -> /dev/pts/0
[root@everest][~]# ls -l /proc/25873/fd
total 0
lrwx------. 1 root root 64 Mar 14 07:09 0 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 14 07:09 1 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 14 07:09 2 -> /dev/pts/0
What I tried to do in the .xml, and I would need, is a way to bind a local /dev/pts devices to child processes in the container. Explicitly:
- bind /dev/pts/3 to <container_rootfs>/dev/console
- bind /dev/pts/4 to <container_rootfs>/dev/tty1
I've found some documentation at [1], hence my trials in the presented .xml. Is my scenario possible / supported?
Thank you very much,
Bogdan P.
[1] http://libvirt.org/formatdomain.html#elementsConsole
11 years, 7 months
[libvirt] [PATCHv6] virtio-rng: Add rate limiting options for virtio-RNG
by Peter Krempa
Qemu's implementation of virtio RNG supports rate limiting of the
entropy used. This patch exposes the option to tune this functionality.
This patch is based on qemu commit 904d6f588063fb5ad2b61998acdf1e73fb4
The rate limiting is exported in the XML as:
<devices>
...
<rng model='virtio'>
<rate period='1234'>4321</rate>
<backend model='random'/>
</rng>
...
---
Notes:
Version 6:
- use just attributes in XML instead of mixed attribute/contents
- switch rate unit to bytes
- tweak the rest to comply with the changes
Version 5:
- adjust after forbiding arbitrary name passthrough
- rebase to master
Version 4:
- Reword docs
- state it is available since 1.0.4 as the tree is frozen and this was actually never acked before
Version 3:
- State the time unit in docs
Version 2:
- qemu uses bytes/period, adapt the value according to that
docs/formatdomain.html.in | 13 +++++++++++++
docs/schemas/domaincommon.rng | 21 ++++++++++++++++++++-
src/conf/domain_conf.c | 19 +++++++++++++++++++
src/conf/domain_conf.h | 2 ++
src/qemu/qemu_command.c | 8 ++++++++
.../qemuxml2argv-virtio-rng-random.args | 2 +-
.../qemuxml2argv-virtio-rng-random.xml | 1 +
7 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 35b47f2..1ef80b0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4294,6 +4294,7 @@ qemu-kvm -net nic,model=? /dev/null
...
<devices>
<rng model='virtio'>
+ <rate period="2000" bytes="1234"/>
<backend model='random'>/dev/random</backend>
<!-- OR -->
<backend model='egd' type='udp'>
@@ -4316,6 +4317,18 @@ qemu-kvm -net nic,model=? /dev/null
<li>'virtio' — supported by qemu and virtio-rng kernel module</li>
</ul>
</dd>
+ <dt><code>rate</code></dt>
+ <dd>
+ <p>
+ The optional <code>rate</code> element allows limiting the rate at
+ which entropy can be consumed from the source. The mandatory
+ attribute <code>bytes</code> specifies how many bytes are permitted
+ to be consumed per period. An optional <code>period</code> attribute
+ specifies the duration of a period in milliseconds; if omitted, the
+ period is taken as 1000 milliseconds (1 second).
+ <span class='since'>Since 1.0.4</span>
+ </p>
+ </dd>
<dt><code>backend</code></dt>
<dd>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c40263c..9792065 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3522,7 +3522,12 @@
<value>virtio</value>
</choice>
</attribute>
- <ref name="rng-backend"/>
+ <interleave>
+ <ref name="rng-backend"/>
+ <optional>
+ <ref name="rng-rate"/>
+ </optional>
+ </interleave>
</element>
</define>
@@ -3550,6 +3555,20 @@
</element>
</define>
+ <define name="rng-rate">
+ <element name="rate">
+ <attribute name="bytes">
+ <ref name="positiveInteger"/>
+ </attribute>
+ <optional>
+ <attribute name="period">
+ <ref name="positiveInteger"/>
+ </attribute>
+ </optional>
+ <empty/>
+ </element>
+ </define>
+
<define name="usbmaster">
<element name="master">
<attribute name="startport">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 95d2ff2..3278e9c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7570,6 +7570,19 @@ virDomainRNGDefParseXML(const xmlNodePtr node,
ctxt->node = node;
+ if (virXPathUInt("string(./rate/@bytes)", ctxt, &def->rate) < -1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid RNG rate bytes value"));
+ goto error;
+ }
+
+ if (def->rate > 0 &&
+ virXPathUInt("string(./rate/@period)", ctxt, &def->period) < -1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid RNG rate period value"));
+ goto error;
+ }
+
if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0)
goto error;
@@ -13897,6 +13910,12 @@ virDomainRNGDefFormat(virBufferPtr buf,
const char *backend = virDomainRNGBackendTypeToString(def->backend);
virBufferAsprintf(buf, " <rng model='%s'>\n", model);
+ if (def->rate) {
+ virBufferAsprintf(buf, " <rate bytes='%u'", def->rate);
+ if (def->period)
+ virBufferAsprintf(buf, " period='%u'", def->period);
+ virBufferAddLit(buf, "/>\n");
+ }
virBufferAsprintf(buf, " <backend model='%s'", backend);
switch ((enum virDomainRNGBackend) def->backend) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0fe43c5..96f11ba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1736,6 +1736,8 @@ enum virDomainRNGBackend {
struct _virDomainRNGDef {
int model;
int backend;
+ unsigned int rate; /* bytes per period */
+ unsigned int period; /* milliseconds */
union {
char *file; /* file name for 'random' source */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e7f2325..78c5cfc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4492,6 +4492,14 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd,
virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
+ if (dev->rate > 0) {
+ virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate);
+ if (dev->period)
+ virBufferAsprintf(&buf, ",period=%u", dev->period);
+ else
+ virBufferAddLit(&buf, ",period=1000");
+ }
+
if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
goto cleanup;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args
index 7ab9dbc..5d296e8 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args
@@ -3,4 +3,4 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \
-object rng-random,id=rng0,filename=/dev/hwrng \
--device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4
+-device virtio-rng-pci,rng=rng0,max-bytes=123,period=1234,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml
index 1e2c4be..354ae42 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml
@@ -17,6 +17,7 @@
<controller type='usb' index='0'/>
<memballoon model='virtio'/>
<rng model='virtio'>
+ <rate bytes='123' period='1234'/>
<backend model='random'>/dev/hwrng</backend>
</rng>
</devices>
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH v7 0/3] DEVICE_DELETED event
by Michael S. Tsirkin
libvirt has a long-standing bug: when removing the device,
it can request removal but does not know when the
removal completes. Add an event so we can fix this in a robust way.
First patch only adds the event with ID, second patch adds a path field.
Split this way for ease of backport (stable downstreams without QOM
would want to only take the first patch).
Event without fields is still useful as management can use it to
poll device list to figure out which device was removed.
Signed-off-by: Michael S. Tsirkin <mst(a)redhat.com>
Changes from v6:
- make empty event use data: {}, Markus prefers this
Changes from v5:
- Emit an empty event on unnamed devices in patch 1/3, as suggested by Markus
Changes from v4:
- Add extra triggers and extra fields as requested by Markus
Changes from v3:
- Document that we only emit events for devices with
and ID, as suggested by Markus
Changes from v2:
- move event toward the end of device_unparent,
so that parents are reported after their children,
as suggested by Paolo
Changes from v1:
- move to device_unparent
- address comments by Andreas and Eric
--
Anthony Liguori
Michael S. Tsirkin (2):
qdev: DEVICE_DELETED event
qom: pass original path to unparent method
Stefan Hajnoczi (1):
exec: assert that RAMBlock size is non-zero
QMP/qmp-events.txt | 18 ++++++++++++++++++
exec.c | 2 ++
hw/qdev.c | 15 +++++++++++++--
include/monitor/monitor.h | 1 +
include/qom/object.h | 3 ++-
monitor.c | 1 +
qapi-schema.json | 4 +++-
qom/object.c | 4 +++-
8 files changed, 43 insertions(+), 5 deletions(-)
--
MST
11 years, 7 months
[libvirt] [PATCH] json: add stream parser
by Dmitry Guryanov
Add function virJSONValueFromStream, which reads data from
a stream and passes it to json parser. When end of the object
is reached, it returns this object.
To avoid reading from the stream by single bytes it reads to
a buffer (in a structure virJSONStreamParserState), which should
be passed to a consequent call of this function. So if the end
of one object and the beginning of the next object have been
read by a single system call - virJSONValueFromStream handle
it correctly.
example of usage:
virJSONValuePtr v;
virJSONStreamParserState state;
memset(&state, 0, sizeof(state));
while (1) {
v = virJSONValueFromStream(mon->fd, &state);
if (v == (void *)-1)
/* error */
break;
if (v == NULL)
/* file descriptor has been closed */
break;
/* handle object 'v' */
}
I need such function for the parallels driver. It caches info
about domains and needs some mechanism to update this cache.
There is a "prlsrvctl monitor" command which waits for events
forever and prints info about events to stdout in json format.
So parallels driver could start separate thread which will
read from prlsrvctl's stdout and update cache accordingly.
There is the same task in qemu_monitor_json, but each json object
is printed in a separate line there. It's not possible in my case,
because some fields could have line endings.
Signed-off-by: Dmitry Guryanov <dguryanov(a)parallels.com>
---
src/util/virjson.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virjson.h | 8 ++++
2 files changed, 118 insertions(+), 0 deletions(-)
diff --git a/src/util/virjson.c b/src/util/virjson.c
index e6a3b1b..d5c5a8c 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -990,6 +990,116 @@ cleanup:
return ret;
}
+/*
+ * Read single JSON object from the stream. Store data, which
+ * have already been read from the stream, but belongs to the
+ * next object to the virJSONStreamParserState structure. So that
+ * consequent call to this function will parse it and return that
+ * object.
+ *
+ * @fd: file descriptor, opened for reading
+ * @state: pointer to the structure with buffer for data, read from fd.
+ *
+ * Return (void *)-1 in case of error, NULL when eof reached,
+ * pointer to the virJSONValuePtr in case of success.
+ */
+
+virJSONValuePtr virJSONValueFromStream(int fd, virJSONStreamParserStatePtr state)
+{
+ yajl_handle hand;
+ virJSONParser parser = { NULL, NULL, 0 };
+ virJSONValuePtr value = (void *)-1;
+# ifndef WITH_YAJL2
+ yajl_parser_config cfg = { 1, 1 };
+# endif
+ ssize_t len;
+ int ret = 0;
+ bool done = false;
+
+# ifdef WITH_YAJL2
+ hand = yajl_alloc(&parserCallbacks, NULL, &parser);
+ if (hand) {
+ yajl_config(hand, yajl_allow_comments, 1);
+ yajl_config(hand, yajl_dont_validate_strings, 0);
+ yajl_config(hand, yajl_allow_trailing_garbage, 1);
+ }
+# else
+ hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
+# endif
+ if (!hand) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to create JSON parser"));
+ goto cleanup;
+ }
+
+ do {
+ if (state->pos == 0 || strlen(&state->buf[state->pos]) == 0) {
+ state->pos = 0;
+ memset(state->buf, 0, sizeof(state->buf));
+ len = read(fd, state->buf, sizeof(state->buf) - 1);
+
+ if (len < 0) {
+ virReportSystemError(errno, _("cannot read from fd '%d'"), fd);
+ virJSONValueFree(parser.head);
+ goto cleanup;
+ }
+
+ if (len == 0) {
+ value = NULL;
+ goto cleanup;
+ }
+ }
+
+ for (;state->pos < strlen(state->buf); state->pos++) {
+ unsigned char *buf = (unsigned char *)&state->buf[state->pos];
+ /*
+ * New yaml library has useful function yajl_get_bytes_consumed
+ * which allows parsing by larger chunks. But rhel-6 has 1.0.7
+ * version, which doesn't have it.
+ */
+ ret = yajl_parse(hand, buf, 1);
+# ifdef WITH_YAJL2
+ if (ret == 0 && yajl_get_bytes_consumed(hand) == 0) {
+ done = true;
+ /* state->pos points to the first symbol after current
+ * object */
+ break;
+ } else if (ret != 0) {
+# else
+ if (ret == 0) {
+ done = true;
+ /* state->pos points to the last symbol of the
+ * current object */
+ state->pos++;
+ break;
+ } else if (ret != yajl_status_insufficient_data) {
+# endif
+ unsigned char *errstr = yajl_get_error(hand, 1, buf, 1);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse json: %s"),
+ (const char*) errstr);
+ VIR_FREE(errstr);
+ virJSONValueFree(parser.head);
+ goto cleanup;
+ }
+ }
+ } while (!done);
+
+ value = parser.head;
+
+cleanup:
+ yajl_free(hand);
+
+ if (parser.nstate) {
+ int i;
+ for (i = 0 ; i < parser.nstate ; i++) {
+ VIR_FREE(parser.state[i].key);
+ }
+ }
+
+ VIR_DEBUG("result=%p", parser.head);
+ return value;
+}
static int virJSONValueToStringOne(virJSONValuePtr object,
yajl_gen g)
diff --git a/src/util/virjson.h b/src/util/virjson.h
index 67f4398..aeb25ef 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -48,6 +48,8 @@ typedef virJSONObjectPair *virJSONObjectPairPtr;
typedef struct _virJSONArray virJSONArray;
typedef virJSONArray *virJSONArrayPtr;
+typedef struct _virJSONStreamParserState virJSONStreamParserState;
+typedef virJSONStreamParserState *virJSONStreamParserStatePtr;
struct _virJSONObjectPair {
char *key;
@@ -77,6 +79,11 @@ struct _virJSONValue {
} data;
};
+struct _virJSONStreamParserState {
+ char buf[1024];
+ size_t pos;
+};
+
void virJSONValueFree(virJSONValuePtr value);
virJSONValuePtr virJSONValueNewString(const char *data);
@@ -134,5 +141,6 @@ int virJSONValueObjectAppendNull(virJSONValuePtr object, const char *key);
virJSONValuePtr virJSONValueFromString(const char *jsonstring);
char *virJSONValueToString(virJSONValuePtr object,
bool pretty);
+virJSONValuePtr virJSONValueFromStream(int fd, virJSONStreamParserStatePtr state);
#endif /* __VIR_JSON_H_ */
--
1.7.1
11 years, 7 months
[libvirt] [PATCH] Prevent streams from becoming libvirtd controlling TTY
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When opening a stream to a device which is a TTY, that device
may become the controlling TTY of libvirtd, if libvirtd was
daemonized. This in turn means when the other end of the stream
closes, libvirtd gets SIGHUP, causing it to reload its config.
Prevent this by forcing O_NOCTTY on all streams that are opened
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/fdstream.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/fdstream.c b/src/fdstream.c
index cc2dfe9..9a6f042 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -582,6 +582,8 @@ virFDStreamOpenFileInternal(virStreamPtr st,
VIR_DEBUG("st=%p path=%s oflags=%x offset=%llu length=%llu mode=%o",
st, path, oflags, offset, length, mode);
+ oflags |= O_NOCTTY;
+
if (oflags & O_CREAT)
fd = open(path, oflags, mode);
else
--
1.8.1.4
11 years, 7 months