[libvirt] [PATCH v2] qemu: Ignore libvirt debug messages in qemu log
by Jiri Denemark
qemu driver uses a 4K buffer for reading qemu log file. This is enough
when only qemu's output is present in the log file. However, when
debugging messages are turned on, intermediate libvirt process fills the
log with a bunch of debugging messages before it executes qemu binary.
In such a case the buffer may become too small. However, we are not
really interested in libvirt messages so they can be filtered out from
the buffer.
---
Notes:
Version 2:
- add a comment to virLogFormatString() that this new code relies on the log
message format
- temporarily replace '\n' with '\0' to provide a bound for strstr()
src/qemu/qemu_process.c | 50 +++++++++++++++++++++++++++++++++++++---------
src/util/logging.c | 8 +++++++
2 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e31e1b4..2fc2b6c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -762,11 +762,23 @@ qemuProcessReadLogOutput(virDomainObjPtr vm,
{
int retries = (timeout*10);
int got = 0;
+ char *debug = NULL;
+ int ret = -1;
+ char *filter_next = buf;
+
buf[0] = '\0';
+ /* This relies on log message format generated by virLogFormatString() and
+ * might need to be modified when message format changes. */
+ if (virAsprintf(&debug, ": %d: debug : ", vm->pid) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
while (retries) {
- ssize_t func_ret, ret;
+ ssize_t func_ret, bytes;
int isdead = 0;
+ char *eol;
func_ret = func(vm, buf, fd);
@@ -775,32 +787,47 @@ qemuProcessReadLogOutput(virDomainObjPtr vm,
/* Any failures should be detected before we read the log, so we
* always have something useful to report on failure. */
- ret = saferead(fd, buf+got, buflen-got-1);
- if (ret < 0) {
+ bytes = saferead(fd, buf+got, buflen-got-1);
+ if (bytes < 0) {
virReportSystemError(errno,
_("Failure while reading %s log output"),
what);
- return -1;
+ goto cleanup;
}
- got += ret;
+ got += bytes;
buf[got] = '\0';
+
+ /* Filter out debug messages from intermediate libvirt process */
+ while ((eol = strchr(filter_next, '\n'))) {
+ *eol = '\0';
+ if (strstr(filter_next, debug)) {
+ memmove(filter_next, eol + 1, got - (eol - buf));
+ got -= eol + 1 - filter_next;
+ } else {
+ filter_next = eol + 1;
+ *eol = '\n';
+ }
+ }
+
if (got == buflen-1) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Out of space while reading %s log output: %s"),
what, buf);
- return -1;
+ goto cleanup;
}
if (isdead) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Process exited while reading %s log output: %s"),
what, buf);
- return -1;
+ goto cleanup;
}
- if (func_ret <= 0)
- return func_ret;
+ if (func_ret <= 0) {
+ ret = func_ret;
+ goto cleanup;
+ }
usleep(100*1000);
retries--;
@@ -809,7 +836,10 @@ qemuProcessReadLogOutput(virDomainObjPtr vm,
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Timed out while reading %s log output: %s"),
what, buf);
- return -1;
+
+cleanup:
+ VIR_FREE(debug);
+ return ret;
}
diff --git a/src/util/logging.c b/src/util/logging.c
index 48c0cfd..9d18752 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -660,6 +660,14 @@ virLogFormatString(char **msg,
const char *str)
{
int ret;
+
+ /*
+ * Be careful when changing the following log message formatting, we rely
+ * on it when stripping libvirt debug messages from qemu log files. So when
+ * changing this, you might also need to change the code there.
+ * virLogFormatString() function name is mentioned there so it's sufficient
+ * to just grep for it to find the right place.
+ */
if ((funcname != NULL)) {
ret = virAsprintf(msg, "%02d:%02d:%02d.%03d: %d: %s : %s:%lld : %s\n",
time_info->tm_hour, time_info->tm_min,
--
1.7.4.1
13 years, 7 months
[libvirt] [PATCH] qemu: Fix improper logic of qemuCgroupSetup
by Osier Yang
It throws errors as long as the cgroup controller is not available,
regardless of whether we really want to use it to do setup or not,
which is not what we want, fixing it with throwing error when need
to use the controller.
And change "VIR_WARN" to "qemuReportError" for memory controller
incidentally.
---
src/qemu/qemu_cgroup.c | 78 +++++++++++++++++++++++++----------------------
1 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 8cf45da..7e88a67 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -294,8 +294,8 @@ int qemuSetupCgroup(struct qemud_driver *driver,
}
}
- if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
- if (vm->def->blkio.weight != 0) {
+ if (vm->def->blkio.weight != 0) {
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
rc = virCgroupSetBlkioWeight(cgroup, vm->def->blkio.weight);
if(rc != 0) {
virReportSystemError(-rc,
@@ -303,48 +303,52 @@ int qemuSetupCgroup(struct qemud_driver *driver,
vm->def->name);
goto cleanup;
}
+ } else {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Block I/O tuning is not available on this host"));
}
- } else {
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Block I/O tuning is not available on this host"));
}
- if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
- if (vm->def->mem.hard_limit != 0) {
- rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set memory hard limit for domain %s"),
- vm->def->name);
- goto cleanup;
+ if (vm->def->mem.hard_limit != 0 ||
+ vm->def->mem.soft_limit != 0 ||
+ vm->def->mem.swap_hard_limit != 0) {
+ if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
+ if (vm->def->mem.hard_limit != 0) {
+ rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set memory hard limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
}
- }
- if (vm->def->mem.soft_limit != 0) {
- rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set memory soft limit for domain %s"),
- vm->def->name);
- goto cleanup;
+ if (vm->def->mem.soft_limit != 0) {
+ rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set memory soft limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
}
- }
- if (vm->def->mem.swap_hard_limit != 0) {
- rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set swap hard limit for domain %s"),
- vm->def->name);
- goto cleanup;
+ if (vm->def->mem.swap_hard_limit != 0) {
+ rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set swap hard limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
}
+ } else {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Memory tuning is not available on this host"));
}
- } else {
- VIR_WARN("Memory cgroup is disabled in qemu configuration file: %s",
- vm->def->name);
}
- if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
- if (vm->def->cputune.shares != 0) {
+ if (vm->def->cputune.shares != 0) {
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
rc = virCgroupSetCpuShares(cgroup, vm->def->cputune.shares);
if(rc != 0) {
virReportSystemError(-rc,
@@ -352,10 +356,10 @@ int qemuSetupCgroup(struct qemud_driver *driver,
vm->def->name);
goto cleanup;
}
+ } else {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("CPU tuning is not available on this host"));
}
- } else {
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("CPU tuning is not available on this host"));
}
done:
--
1.7.4
13 years, 7 months
[libvirt] [PATCH] free tmp after unlinking it
by Wen Congyang
---
src/qemu/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dd12dc8..5aa715e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5065,9 +5065,9 @@ endjob:
vm = NULL;
cleanup:
- VIR_FREE(tmp);
VIR_FORCE_CLOSE(fd);
unlink (tmp);
+ VIR_FREE(tmp);
if (vm)
virDomainObjUnlock(vm);
return ret;
--
1.7.1
13 years, 7 months
[libvirt] What about Trusted Virtual Domains???
by Paolo Smiraglia
Hi guys...
I need an opinion from the Libvirt community about the development of
a new possible Libvirt feature: the Trusted Virtual Domains (TVD).
Conceptually, a TVD can be compared to a mix of Virtual Private
Network (VPN) and Virtual LAN (VLAN).
My idea is to define a new Libvirt entity called "tvd" which contains
the information about domains and hosts belonging to the same TVD.
Below is showed a possible XML definition of tvd entity:
<tvd name='tvd1.mycloud' uuid='...'>
<host ip='10.0.0.1' hostname='node1.example.com'>
<domain name='guest1' uuid='...' />
<domain name='guest27' uuid='...' />
</host>
<host ip='10.0.0.2' hostname='node2.example.com'>
<domain name='guest12' uuid='...' />
<domain name='guest2' uuid='...' />
</host>
</tvd>
With the informations contained in the tvd XML definition, Libvirt may
be able to automatically setup, for example, an IPSec tunnel between
node1.example.com and node2.example.com, and VLAN between guest1,
guest2,guest12 and guest27.
In my opinion, this feature may be really useful in a cloud computing scenario.
And you? What about it? It is a crazy idea? ;-)
Thanks in advance for the replies!
Bests,
PAOLO
--
PAOLO SMIRAGLIA
http://portale.isf.polito.it/paolo-smiraglia
13 years, 7 months
[libvirt] [PATCH] Make check_fc_host() and check_vport_capable() usable as rvalues
by Guido Günther
This is needed on non linux ports using HAL in gather_scsi_host_cap.
Noticed while porting to kfreebsd.
O.k. to apply?
-- Guido
---
src/node_device/node_device_driver.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 4721be4..e583c2b 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -78,8 +78,8 @@ int read_wwn_linux(int host, const char *file, char **wwn);
# else /* __linux__ */
-# define check_fc_host(d)
-# define check_vport_capable(d)
+# define check_fc_host(d) (-1)
+# define check_vport_capable(d) (-1)
# define get_physical_function(sysfs_path, d)
# define get_virtual_functions(sysfs_path, d)
# define read_wwn(host, file, wwn)
--
1.7.4.1
13 years, 7 months
[libvirt] RFC: have libvirt track cgroup objects
by Eric Blake
Currently, all qemu domains are created in their own cgroup, but that
cgroup is a direct child of libvirt. So cgroup tunings are all-or-one;
there is no way to group multiple VMs to share a particular resource
without infringing on other VMs.
Just as we can currently track interface, nwfilter, and storage pool
objects as independent xml entities in parallel with domains, it would
be nice to expose a new object, virCgroup. All virCgroup and virDomain
objects would have an optional parent virCgroup object, and anything
without such a parent defaults to the global libvirt cgroup as the
parent. Recent tuning parameters like <memtune>, <blkiotune> that apply
to domains would also apply to a virCgroup XML representation.
That way, you can create a hierarchy of cgroups, such as:
libvirt
|+cgroup1
| |+vm1
| \+vm2
\+vm3
where a <memtune> of cgroup1 is memory that is shared between vm1 and
vm2 (possibly with overcommit, if it is anticipated that both vms will
not simultaneously be using the max memory), which maps nicely to the
fact that cgroups are already hierarchical to the kernel.
I'm not quite sure how this would affect migration, but it would
probably be similar to how <interface> or <nwfilter> setups affect
migration (that is, if a domain refers to a particular host <interface>,
then that interface object better be present with similar
characteristics on both source and destination of the migration).
I'm throwing this out for general thoughts, based on an IRC conversation
(and not necessarily because I plan on implementing it any time soon).
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years, 7 months
[libvirt] [RFC PATCH V1 0/5] Add TPM support to Qemu
by Stefan Berger
The following series of patches add support for TPM to the libvirt's
parser and Qemu driver.
Since the underlying support in Qemu and SeaBIOS are not in repositories
yet, I am posting them as RFCs for now.
If you have feedback, please let me know.
Regards,
Stefan
13 years, 7 months
[libvirt] virsh sechedinfo/memtune with libvirt-0.8.8
by Zvi Dubitzky
Sorry . I have'nt got an answer from the user's list .
I have fedora14 installed with its standard libvirt-0.8.3. I can start
VM
using .xml files and also run: virsh schedinfo. the cgroup CPU
controller is mounted and active . In fact I have the path to the Virtual
machine : /dev/cgroup/cpu/libvirt/qemu/<vm name >
I now upgraded to libvirt-0.8.8 from a tar ball ( configure , make , make
install) . I rebooted , new libvirtd started . virsh is working ok
(I can create a vm) except for the commands : schedinfo and memtune that
e.g.
say upon ' virsh schedinfo <vm name>'
Scheduler : Unknown
error: Requested operation is not valid: cgroup CPU controller is not
mounted
But the CPU controller is mounted because I have the path :
/dev/cgroup/cpu/libvirt/qemu/ .
What I am missing is the <vm_name> group which is not generated despite
that the VM was generated ok by virsh create and I can access it.
Any idea what is missing ?
Zvi Dubitzky
Email:dubi@il.ibm.com
13 years, 7 months
[libvirt] TPM support in libvirt
by Stefan Berger
Hello!
I'd like to start a discussion and get some feedback on support for
TPM (Trusted Platform Module) management in libvirt. I have been posting
patches to the Qemu and SeaBIOS mailing lists that will provide the
ground work for TPM support in Qemu, though I anticipate that it will
take a while until the code goes into those repositories. So everything
I am saying related to command lines etc. can still change.
Nevertheless, the next obvious layer for support is libvirt. Well, and I
do have patches...
First some background: the TPM is a crypto device built into many
modern laptops and desktops. It's a chip connected to the motherboard
and has firmware for running the TPM specifications. I would say it has
a full processor on its own to run this firmware. It also has some very
limited space for persistent storage to permanently store for example
the owner's password (that he can establish with the TPM), store private
keys and it also has some area for NVRAM spaces where the user can put
any data into it he wants to.
So now, on the qemu command line the TPM support (currently) looks as
follows:
... -tpm ?
displays:
Supported TPM types (choose only one):
builtin Qemu's built-in TPM; requires 63kb of block storage
I use this for reading the size of the necessary (QCoW2) blockstorage
from it, 63kb.
To start a VM with TPM support:
... -tpm type=builtin,path=/tmp/tpmstate.bin
The above indicates the type of TPM to use. Currently there is only
one type available, which is the 'builtin' one. It also provides a path
to persistent storage, here /tmp/tpmstate.bin. The persistent storage
file is actually a Qcow2 file so we can properly support snapshotting of
the image and the TPM and go back to different states.
Obviously we are now adding another 'disk' to the VM, so that the TPM
can store its own persistent data. Now a user has to make sure to always
keep his image file and this TPM 'disk' together, particularly once he
stores vital keys in the TPM.
So now for modeling this in libvirt I thought of this XML here for a
user-provided Qcow2 image:
<tpm type='built-in'>
<storage file='/tmp/tpmstate.bin'/>
</tpm>
In this case the user would create the above QCoW2 /tmp/tmpstate.bin
at the appropriate size (63kb).
This XML here is for a libvirt-created QCoW2 image:
<tpm type='built-in'>
<storage/>
</tpm>
This then causes libvirt to create a QCoW2 image of 63kb size (reads
the 63kb from .. tpm ?) once the VM is about to start and produces for
example this command line:
-tpm
type=builtin,path=/var/lib/libvirt/tpm/a4d7cd22-da89-3094-6212-079a48a309a1.bin
The UUID then corresponds to the UUID of the VM. Since only one TPM per
VM is supported, this should work just fine.
Now to support an encrypted QCoW2 image, the following XML could be used:
<tpm type='built-in'>
<storage>
<encryption format='qcow'>
<secret type='passphrase' uuid='13ea49f7-2553-7308-5168-e337ade36232'/>
</encryption>
</storage>
</tpm>
Here the user has created a 'secret' and passes that secret's UUID
into the XML above. So this is similar to how storage is dealt with with
the difference that no path to the storage is provided and also
internally no comparisons for storage paths are being made. I did also
not want to force the user to create storage spaces (volumes) on his
own, but let libvirt handle this implicitly for the TPM (use qemu-img to
create the QCoW2). Also, multiple VMs' TPMs could share the same secret.
Please let me know of any comments regarding this.
I'll post the patches as RFC later on.
Regards,
Stefan
13 years, 7 months
[libvirt] [PATCH] Fix domain events C example on Win32
by Daniel P. Berrange
printf on Win32 does not neccessarily support %lld and we don't
have GNULIBs wrapper for printf(). Switch to use asprintf() for
which we do have a gnulib wrapper with %lld support
* examples/domain-events/events-c/event-test.c: Fix formatting
of %lld on Win32
* cfg.mk: Don't require use of virAsprintf since this is an
example app for out of tree users to follow
---
cfg.mk | 2 +-
examples/domain-events/events-c/event-test.c | 10 ++++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index ac419f7..0440425 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -564,7 +564,7 @@ exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
(^docs|^python/(libvirt-override|typewrappers)\.c$$)
exclude_file_name_regexp--sc_prohibit_asprintf = \
- ^(bootstrap.conf$$|po/|src/util/util\.c$$)
+ ^(bootstrap.conf$$|po/|src/util/util\.c$$|examples/domain-events/events-c/event-test\.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
(\.py$$|^docs/|(src/util/files\.c|src/libvirt\.c)$$)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index 7d05dd8..44e94ec 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -169,8 +169,14 @@ static int myDomainEventRTCChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
long long offset,
void *opaque ATTRIBUTE_UNUSED)
{
- printf("%s EVENT: Domain %s(%d) rtc change %lld\n", __func__, virDomainGetName(dom),
- virDomainGetID(dom), offset);
+ char *str = NULL;
+ /* HACK: use asprintf since we have gnulib's wrapper for %lld on Win32
+ * but don't have a printf() replacement with %lld */
+ if (asprintf(&str, "%s EVENT: Domain %s(%d) rtc change %lld\n", __func__, virDomainGetName(dom),
+ virDomainGetID(dom), offset) < 0)
+ return 0;
+
+ printf("%s", str);
return 0;
}
--
1.7.4
13 years, 7 months