[libvirt] [PATCH 0/6 v2] Allow debug dump in case of crashes
by Daniel Veillard
Changes in v2 based on danpb feedback:
- make libvirtd.log the default instead of syslog
- do not open the libvirtd.log directly
- create a new API to dump debug buffer to file output
- use that new API now in the fatal signal handler
This patch set main goal is to allow dumping
of full debug informations for operations occuring
in libvirt daemon before a crash.
The principle is to save all logs to a round-robbin memory
buffer (which we already do, except we never use that
buffer), save the general daemon logs to a libvirtd.log
file and upon reception of a fatal signal, save the memory
buffer directly to the log file(s) or stderr.
There is quite a few remarks about this, we already have
that buffer but we don't log everything in, only what's
output, that's what patch 1 changes, then we need to
provide a function to dump it in emergency from signal
handler so this also adds a new API for it.
We also need to be cautious about what
system call we operate from the signal handler, but
basically we should limit ourselves here to write and
sigaction which are safe there dixit POSIX.
Something like killall -USR2 libvirtd allows to see the
kind of output one get, an idle libvirtd is quiet, but
handle/timer/fdpolls tend to be very verbose,
Maybe now that this part is well debugged some of those
could be suppressed or commented off.
Also the buffer is a statically allocated 64KB, this
should be made more flexible based on a configuration
entry but it's left for another patch.
Daniel
13 years, 8 months
[libvirt] qemuDomainMonitorCommand
by Anthony Liguori
Hi,
I've been looking at the qemuDomainMonitorCommand interface and I see a
few issues with it.
The current interface can take a JSON string and return a JSON string
but it only works for successful commands. I'd like to hook this
interface up to libqmp but it would mean dropping all of the error
messages. Errors are extremely important because certain workflows
require parsing specific error output (like changing a device with an
encrypted disk) in the normal execution path.
Additionally, there's no way to get QMP events. With QMP events, it's
important to expose the timestamp and tag fields too.
Is there a reason the raw QMP session wasn't exposed?
With registered events, we should be able to distinguish events meant
for libvirt with events registered by QMP passthrough so perhaps we can
also expose events in a new interface?
Regards,
Anthony Liguori
13 years, 8 months
[libvirt] Next release schedule
by Daniel Veillard
So the goal is to get a release by the end of the month. I usually try
to push those on Friday, but somehow I would feel better to avoid April
1st espcially as we try to make a 0.9.0 release :-)
Let's try to start the freeze on Thu 24, to get a release one week
later on March 31, so this means we have 2.5 weeks to push new features
in for 0.9.0,
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/
13 years, 8 months
[libvirt] [PATCHv3 00/10] outgoing migration via fd: rather than exec:
by Eric Blake
Still not quite complete (I need to hook up compression to
benefit from fd:), but in much better shape (this series could
be applied as-is, if it receives ACKs, and I can do the compression
improvements separately).
Changes in v3: add lots of intermediate patches, to make fd passing
much easier.
Eric Blake (10):
qemu: use lighter-weight fd:n on incoming tunneled migration
qemu: support migration to fd
util: use SCM_RIGHTS in virFileOperation when needed
qemu: allow simple domain save to use fd: protocol
qemu: simplify domain save fd handling
storage: simplify fd handling
util: rename virFileOperation to virFileOpenAs
util: adjust indentation in previous patch
qemu, storage: improve type safety
qemu: improve efficiency of dd during snapshots
src/libvirt_private.syms | 2 +-
src/qemu/qemu_driver.c | 105 ++++++++++++++-------------
src/qemu/qemu_migration.c | 45 ++++--------
src/qemu/qemu_monitor.c | 22 ++++++
src/qemu/qemu_monitor.h | 4 +
src/qemu/qemu_monitor_json.c | 24 ++++++-
src/qemu/qemu_monitor_json.h | 6 ++-
src/qemu/qemu_monitor_text.c | 27 ++++++-
src/qemu/qemu_monitor_text.h | 6 ++-
src/storage/storage_backend.c | 77 ++++++++++----------
src/util/util.c | 161 ++++++++++++++++++++++++++++-------------
src/util/util.h | 15 ++--
12 files changed, 310 insertions(+), 184 deletions(-)
--
1.7.4
13 years, 8 months
[libvirt] [PATCH 1/2] virsh: Change integer option parsing functions to return tri-state information.
by Michal Privoznik
This is needed to detect situations when optional argument was
specified with non-integer value: '--int-opt foo'.
---
tools/virsh.c | 46 +++++++++++++++++++++++++++-------------------
1 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 62fca17..e5093a2 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -252,13 +252,14 @@ static const vshCmdGrp *vshCmdGrpSearch(const char *grpname);
static int vshCmdGrpHelp(vshControl *ctl, const char *name);
static vshCmdOpt *vshCommandOpt(const vshCmd *cmd, const char *name);
-static int vshCommandOptInt(const vshCmd *cmd, const char *name, int *found);
+static int vshCommandOptInt(const vshCmd *cmd, const char *name, int *found,
+ int *opt_found);
static unsigned long vshCommandOptUL(const vshCmd *cmd, const char *name,
- int *found);
+ int *found, int *opt_found);
static char *vshCommandOptString(const vshCmd *cmd, const char *name,
int *found);
static long long vshCommandOptLongLong(const vshCmd *cmd, const char *name,
- int *found);
+ int *found, int *opt_found);
static int vshCommandOptBool(const vshCmd *cmd, const char *name);
static char *vshCommandOptArgv(const vshCmd *cmd, int count);
@@ -1602,7 +1603,7 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd,
param->type == VIR_DOMAIN_SCHED_FIELD_UINT &&
vshCommandOptBool(cmd, "weight")) {
int val;
- val = vshCommandOptInt(cmd, "weight", &found);
+ val = vshCommandOptInt(cmd, "weight", &found, NULL);
if (!found) {
vshError(ctl, "%s", _("Invalid value of weight"));
return -1;
@@ -1617,7 +1618,7 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd,
param->type == VIR_DOMAIN_SCHED_FIELD_UINT &&
vshCommandOptBool(cmd, "cap")) {
int val;
- val = vshCommandOptInt(cmd, "cap", &found);
+ val = vshCommandOptInt(cmd, "cap", &found, NULL);
if (!found) {
vshError(ctl, "%s", _("Invalid value of cap"));
return -1;
@@ -2300,7 +2301,7 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
if (!vshConnectionUsability(ctl, ctl->conn))
return FALSE;
- cell = vshCommandOptInt(cmd, "cellno", &cell_given);
+ cell = vshCommandOptInt(cmd, "cellno", &cell_given, NULL);
all_given = vshCommandOptBool(cmd, "all");
if (all_given && cell_given) {
@@ -2726,7 +2727,7 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return FALSE;
- vcpu = vshCommandOptInt(cmd, "vcpu", &vcpufound);
+ vcpu = vshCommandOptInt(cmd, "vcpu", &vcpufound, NULL);
if (!vcpufound) {
vshError(ctl, "%s", _("vcpupin: Invalid or missing vCPU number."));
virDomainFree(dom);
@@ -2862,7 +2863,7 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return FALSE;
- count = vshCommandOptInt(cmd, "count", &count);
+ count = vshCommandOptInt(cmd, "count", &count, NULL);
if (!flags) {
if (virDomainSetVcpus(dom, count) != 0) {
@@ -2927,7 +2928,7 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return FALSE;
- kilobytes = vshCommandOptUL(cmd, "kilobytes", NULL);
+ kilobytes = vshCommandOptUL(cmd, "kilobytes", NULL, NULL);
if (kilobytes <= 0) {
virDomainFree(dom);
vshError(ctl, _("Invalid value of %lu for memory size"), kilobytes);
@@ -2984,7 +2985,7 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return FALSE;
- kilobytes = vshCommandOptInt(cmd, "kilobytes", &kilobytes);
+ kilobytes = vshCommandOptInt(cmd, "kilobytes", &kilobytes, NULL);
if (kilobytes <= 0) {
virDomainFree(dom);
vshError(ctl, _("Invalid value of %d for memory size"), kilobytes);
@@ -3056,22 +3057,22 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
return FALSE;
hard_limit =
- vshCommandOptLongLong(cmd, "hard-limit", NULL);
+ vshCommandOptLongLong(cmd, "hard-limit", NULL, NULL);
if (hard_limit)
nparams++;
soft_limit =
- vshCommandOptLongLong(cmd, "soft-limit", NULL);
+ vshCommandOptLongLong(cmd, "soft-limit", NULL, NULL);
if (soft_limit)
nparams++;
swap_hard_limit =
- vshCommandOptLongLong(cmd, "swap-hard-limit", NULL);
+ vshCommandOptLongLong(cmd, "swap-hard-limit", NULL, NULL);
if (swap_hard_limit)
nparams++;
min_guarantee =
- vshCommandOptLongLong(cmd, "min-guarantee", NULL);
+ vshCommandOptLongLong(cmd, "min-guarantee", NULL, NULL);
if (min_guarantee)
nparams++;
@@ -3670,7 +3671,7 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool (cmd, "live"))
live_flag = TRUE;
- timeout = vshCommandOptInt(cmd, "timeout", &found);
+ timeout = vshCommandOptInt(cmd, "timeout", &found, NULL);
if (found) {
if (! live_flag) {
vshError(ctl, "%s", _("migrate: Unexpected timeout for offline migration"));
@@ -3807,7 +3808,7 @@ cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return FALSE;
- downtime = vshCommandOptLongLong(cmd, "downtime", &found);
+ downtime = vshCommandOptLongLong(cmd, "downtime", &found, NULL);
if (!found || downtime < 1) {
vshError(ctl, "%s", _("migrate: Invalid downtime"));
goto done;
@@ -10796,7 +10797,7 @@ vshCommandOpt(const vshCmd *cmd, const char *name)
* Returns option as INT
*/
static int
-vshCommandOptInt(const vshCmd *cmd, const char *name, int *found)
+vshCommandOptInt(const vshCmd *cmd, const char *name, int *found, int *opt_found)
{
vshCmdOpt *arg = vshCommandOpt(cmd, name);
int res = 0, num_found = FALSE;
@@ -10811,11 +10812,13 @@ vshCommandOptInt(const vshCmd *cmd, const char *name, int *found)
}
if (found)
*found = num_found;
+ if (opt_found)
+ *opt_found = arg ? TRUE : FALSE;
return res;
}
static unsigned long
-vshCommandOptUL(const vshCmd *cmd, const char *name, int *found)
+vshCommandOptUL(const vshCmd *cmd, const char *name, int *found, int *opt_found)
{
vshCmdOpt *arg = vshCommandOpt(cmd, name);
unsigned long res = 0;
@@ -10831,6 +10834,8 @@ vshCommandOptUL(const vshCmd *cmd, const char *name, int *found)
}
if (found)
*found = num_found;
+ if (opt_found)
+ *opt_found = arg ? TRUE : FALSE;
return res;
}
@@ -10858,7 +10863,8 @@ vshCommandOptString(const vshCmd *cmd, const char *name, int *found)
* Returns option as long long
*/
static long long
-vshCommandOptLongLong(const vshCmd *cmd, const char *name, int *found)
+vshCommandOptLongLong(const vshCmd *cmd, const char *name, int *found,
+ int *opt_found)
{
vshCmdOpt *arg = vshCommandOpt(cmd, name);
int num_found = FALSE;
@@ -10869,6 +10875,8 @@ vshCommandOptLongLong(const vshCmd *cmd, const char *name, int *found)
num_found = !virStrToLong_ll(arg->data, &end_p, 10, &res);
if (found)
*found = num_found;
+ if (opt_found)
+ *opt_found = arg ? TRUE : FALSE;
return res;
}
--
1.7.4
13 years, 8 months
[libvirt] Fixes for several memory leaks
by Phil Petty (phpetty)
Index: libvirt/src/conf/secret_conf.c
===================================================================
***************
*** 154,160 ****
_("invalid value of 'private'"));
goto cleanup;
}
- VIR_FREE(prop);
}
uuidstr = virXPathString("string(./uuid)", ctxt);
--- 154,159 ----
***************
*** 170,176 ****
"%s", _("malformed uuid element"));
goto cleanup;
}
- VIR_FREE(uuidstr);
}
def->description = virXPathString("string(./description)", ctxt);
--- 169,174 ----
***************
*** 181,187 ****
def = NULL;
cleanup:
! VIR_FREE(prop);
virSecretDefFree(def);
xmlXPathFreeContext(ctxt);
return ret;
--- 179,190 ----
def = NULL;
cleanup:
! if (prop) {
! VIR_FREE(prop);
! }
! if (uuidstr) {
! VIR_FREE(uuidstr);
! }
virSecretDefFree(def);
xmlXPathFreeContext(ctxt);
return ret;
Index: libvirt/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
***************
*** 662,673 ****
}
virNWFilterUnlockIface(ifname);
-
- VIR_FREE(ptrs);
}
err_exit:
virNWFilterUnlockFilterUpdates();
for (j = 0; j < nEntries; j++)
--- 662,675 ----
}
virNWFilterUnlockIface(ifname);
}
err_exit:
+ if (ptrs) {
+ VIR_FREE(ptrs);
+ }
+
virNWFilterUnlockFilterUpdates();
for (j = 0; j < nEntries; j++)
Index: libvirt/src/remote/remote_driver.c
===================================================================
***************
*** 474,495 ****
--- 474,510 ----
for (i = 0; i < vars->n; i++) {
var = &vars->p[i];
if (STRCASEEQ (var->name, "name")) {
+ if (name) {
+ VIR_FREE(name);
+ }
name = strdup (var->value);
if (!name) goto out_of_memory;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "command")) {
+ if (command) {
+ VIR_FREE(command);
+ }
command = strdup (var->value);
if (!command) goto out_of_memory;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "socket")) {
+ if (sockname) {
+ VIR_FREE(sockname);
+ }
sockname = strdup (var->value);
if (!sockname) goto out_of_memory;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "auth")) {
+ if (authtype) {
+ VIR_FREE(authtype);
+ }
authtype = strdup (var->value);
if (!authtype) goto out_of_memory;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "netcat")) {
+ if (netcat) {
+ VIR_FREE(netcat);
+ }
netcat = strdup (var->value);
if (!netcat) goto out_of_memory;
var->ignore = 1;
Index: libvirt/src/util/conf.c
===================================================================
***************
*** 651,656 ****
--- 651,657 ----
SKIP_BLANKS;
if (CUR != '=') {
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting an
assignment"));
+ VIR_FREE(name);
return(-1);
}
NEXT;
Index: libvirt/src/util/storage_file.c
===================================================================
***************
*** 742,747 ****
--- 742,748 ----
if (format < 0 ||
format >= VIR_STORAGE_FILE_LAST) {
virReportSystemError(EINVAL, _("unknown storage file format
%d"), format);
+ VIR_FREE(head);
return -1;
}
Index: libvirt/src/util/xml.c
===================================================================
***************
*** 107,113 ****
virXMLError(VIR_ERR_INTERNAL_ERROR,
_("\'%s\' value longer than %Zd bytes in
virXPathStringLimit()"),
xpath, maxlen);
! return NULL;
}
return tmp;
--- 107,114 ----
virXMLError(VIR_ERR_INTERNAL_ERROR,
_("\'%s\' value longer than %Zd bytes in
virXPathStringLimit()"),
xpath, maxlen);
! VIR_FREE(tmp);
! return NULL;
}
return tmp;
Index: libvirt/tools/virsh.c
===================================================================
***************
*** 8697,8702 ****
--- 8697,8703 ----
{
const char *dir;
int found;
+ int dir_root = FALSE;
if (!ctl->imode) {
vshError(ctl, "%s", _("cd: command valid only in interactive
mode"));
***************
*** 8708,8721 ****
uid_t uid = geteuid();
dir = virGetUserDirectory(uid);
}
! if (!dir)
dir = "/";
if (chdir (dir) == -1) {
vshError(ctl, _("cd: %s: %s"), strerror(errno), dir);
return FALSE;
}
return TRUE;
}
--- 8709,8730 ----
uid_t uid = geteuid();
dir = virGetUserDirectory(uid);
}
! if (!dir) {
dir = "/";
+ dir_root = TRUE;
+ }
if (chdir (dir) == -1) {
vshError(ctl, _("cd: %s: %s"), strerror(errno), dir);
+ if (!dir_root) {
+ VIR_FREE(dir);
+ }
return FALSE;
}
+ if (!dir_root) {
+ VIR_FREE(dir);
+ }
return TRUE;
}
Kind regards,
Phil Petty
13 years, 8 months
[libvirt] Network Filter not working on RHEL-6
by Shi Jin
Hi there,
I have been testing the Network Filter [1] feature of libvirt with KVM on RHEL-5.6 and RHEL-6. On RHEL-5.6, it works well except the $IP variable is not supported thus cannot use the clean-filter.
The major problem I found on RHEL-6 is that the iptables rules introduced by nwfilter does not prevent any traffic. The problem is that all traffic going to the VM virtual NIC interface goes through the INPUT chain of the iptables instead of the supposed-to-be FORWARD chain (this is what the nwfilter rules are working on) so that none of the rules have any effect.
I am not sure whether this is a libvirt problem or iptables problem. But it seems to me that changing from RHEL-5.6 to RHEL-6, the network traffic works differently.
Has anyone had similar experience? Any suggestion or comments are welcome.
Thank you very much.
Shi
[1] http://libvirt.org/formatnwfilter.html
--
Shi Jin, PhD
13 years, 8 months
[libvirt] [PATCH] qemu: Support vram for video of qxl type
by Osier Yang
For qemu names the primary vga as "qxl-vga":
1) if vram is specified for 2nd qxl device:
-vga qxl -global qxl-vga.vram_size=$SIZE \
-device qxl,id=video1,vram_size=$SIZE,...
2) if vram is not specified for 2nd qxl device, (use the default
set by global):
-vga qxl -global qxl-vga.vram_size=$SIZE \
-device qxl,id=video1,...
For qemu names all qxl devices as "qxl":
1) if vram is specified for 2nd qxl device:
-vga qxl -global qxl.vram_size=$SIZE \
-device qxl,id=video1,vram_size=$SIZE ...
2) if vram is not specified for 2nd qxl device:
-vga qxl -global qxl-vga.vram_size=$SIZE \
-device qxl,id=video1,...
"-global" is the only way to define vram_size for the primary qxl
device, regardless of how qemu names it, (It's not good a good
way, as original idea of "-global" is to set a global default for
a driver property, but to specify vram for first qxl device, we
have to use it).
For other qxl devices, as they are represented by "-device", could
specify it directly and seperately for each, and it overrides the
default set by "-global" if specified.
---
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 16 +++++++++
tests/qemuhelptest.c | 1 +
.../qemuxml2argv-graphics-spice-qxl-vga.args | 7 ++++
.../qemuxml2argv-graphics-spice-qxl-vga.xml | 36 ++++++++++++++++++++
.../qemuxml2argv-graphics-spice.args | 4 +-
tests/qemuxml2argvtest.c | 4 ++
tests/qemuxml2xmltest.c | 1 +
9 files changed, 70 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5f08a20..cce6b5f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1118,6 +1118,8 @@ qemuCapsParseDeviceStr(const char *str, unsigned long long *flags)
}
if (strstr(str, "virtio-net-pci.tx="))
*flags |= QEMUD_CMD_FLAG_VIRTIO_TX_ALG;
+ if (strstr(str, "name \"qxl-vga\""))
+ *flags |= QEMUD_CMD_FLAG_DEVICE_QXL_VGA;
return 0;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 63cbbb3..f36c3ab 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -93,6 +93,7 @@ enum qemuCapsFlags {
QEMUD_CMD_FLAG_CHARDEV_SPICEVMC = (1LL << 56), /* newer -chardev spicevmc */
QEMUD_CMD_FLAG_DEVICE_SPICEVMC = (1LL << 57), /* older -device spicevmc*/
QEMUD_CMD_FLAG_VIRTIO_TX_ALG = (1LL << 58), /* -device virtio-net-pci,tx=string */
+ QEMUD_CMD_FLAG_DEVICE_QXL_VGA = (1LL << 59), /* Is the primary and vga compatible qxl device named qxl-vga? */
};
virCapsPtr qemuCapsInit(virCapsPtr old_caps);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0db2843..c0bc343 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1928,6 +1928,10 @@ qemuBuildVideoDevStr(virDomainVideoDefPtr video,
virBufferVSprintf(&buf, "%s", model);
virBufferVSprintf(&buf, ",id=%s", video->info.alias);
+
+ if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL && video->vram)
+ virBufferVSprintf(&buf, ",vram_size=%u", video->vram);
+
if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCmdFlags) < 0)
goto error;
@@ -4023,6 +4027,18 @@ qemuBuildCommandLine(virConnectPtr conn,
}
virCommandAddArgList(cmd, "-vga", vgastr, NULL);
+
+ if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
+ if (def->videos[0]->vram &&
+ (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE_QXL_VGA)
+ virCommandAddArgFormat(cmd, "-global qxl-vga.vram_size=%u",
+ def->videos[0]->vram);
+ else
+ virCommandAddArgFormat(cmd, "-global qxl.vram_size=%u",
+ def->videos[0]->vram);
+ }
+ }
}
} else {
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 11890ab..202888d 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -481,6 +481,7 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_DRIVE_AIO |
QEMUD_CMD_FLAG_CCID_PASSTHRU |
QEMUD_CMD_FLAG_CHARDEV_SPICEVMC |
+ QEMUD_CMD_FLAG_DEVICE_QXL_VGA |
QEMUD_CMD_FLAG_VIRTIO_TX_ALG,
12001, 1, 0);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.args
new file mode 100644
index 0000000..efc51d1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.args
@@ -0,0 +1,7 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor \
+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 -vga \
+qxl -global qxl-vga.vram_size=65536 -device qxl,id=video1,vram_size=65536,bus=pci.0,addr=0x4 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
new file mode 100644
index 0000000..fc9f3fe
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
@@ -0,0 +1,36 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219136</memory>
+ <currentMemory>219136</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </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'>
+ <channel name='main' mode='secure'/>
+ <channel name='inputs' mode='insecure'/>
+ </graphics>
+ <video>
+ <model type='qxl' vram='65536' heads='1'/>
+ </video>
+ <video>
+ <model type='qxl' vram='65536' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
index a8fb243..f7109b0 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
@@ -3,5 +3,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \
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 -vga \
-qxl -device qxl,id=video1,bus=pci.0,addr=0x4 -device virtio-balloon-pci,\
-id=balloon0,bus=pci.0,addr=0x3
+qxl -global qxl.vram_size=65536 -device qxl,id=video1,vram_size=65536,bus=pci.0,addr=0x4 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 4817d51..d5b240e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -354,6 +354,10 @@ mymain(int argc, char **argv)
DO_TEST("graphics-spice",
QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_VGA_QXL |
QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_SPICE, false);
+ DO_TEST("graphics-spice-qxl-vga",
+ QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_VGA_QXL |
+ QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_SPICE |
+ QEMUD_CMD_FLAG_DEVICE_QXL_VGA, false);
DO_TEST("input-usbmouse", 0, false);
DO_TEST("input-usbtablet", 0, false);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 67e721b..c0c36ad 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -152,6 +152,7 @@ mymain(int argc, char **argv)
DO_TEST("graphics-sdl");
DO_TEST("graphics-sdl-fullscreen");
DO_TEST("graphics-spice");
+ DO_TEST("graphics-spice-qxl-vga");
DO_TEST("input-usbmouse");
DO_TEST("input-usbtablet");
DO_TEST("input-xen");
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] util: Allow removing hash entries in virHashForEach
by Jiri Denemark
This fixes a possible crash of libvirtd during its startup. When qemu
driver reconnects to running domains, it iterates over all domain
objects in a hash. When reconnecting to an associated qemu monitor
fails and the domain is transient, it's immediately removed from the
hash. Despite the fact that it's explicitly forbidden to do so. If
libvirtd is lucky enough, virHashForEach will access random memory when
the callback finishes and the deamon will crash.
Since it's trivial to fix virHashForEach to allow removal of hash
entries while iterating through them, I went this way instead of fixing
qemuReconnectDomain callback (and possibly others) to avoid deleting the
entries.
---
src/util/hash.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/util/hash.c b/src/util/hash.c
index 92ee234..2a9a9cf 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -548,9 +548,8 @@ virHashRemoveEntry(virHashTablePtr table, const void *name)
* @data: opaque data to pass to the iterator
*
* Iterates over every element in the hash table, invoking the
- * 'iter' callback. The callback must not call any other virHash*
- * functions, and in particular must not attempt to remove the
- * element.
+ * 'iter' callback. The callback is allowed to remove the element using
+ * virHashRemoveEntry but calling other virHash* functions is prohibited.
*
* Returns number of items iterated over upon completion, -1 on failure
*/
@@ -563,11 +562,12 @@ int virHashForEach(virHashTablePtr table, virHashIterator iter, void *data) {
for (i = 0 ; i < table->size ; i++) {
virHashEntryPtr entry = table->table + i;
while (entry) {
+ virHashEntryPtr next = entry->next;
if (entry->valid) {
iter(entry->payload, entry->name, data);
count++;
}
- entry = entry->next;
+ entry = next;
}
}
return (count);
--
1.7.4.1
13 years, 8 months
[libvirt] [RFC PATCHv2 0/3] outgoing migration via fd: rather than exec:
by Eric Blake
Posted as an RFC because there are still two open bugs to be solved.
I've tested that with this installed, I was able to do 'virsh save
domain file' without compression to a local file using qemu fd:
migration.
1. I'm working on making virFileOperation use SCM_RIGHTS so that we
can pass an arbitrary fd from the child back to the parent. This is
necessary for supporting root-squash NFS domain save via fd, since a
child cannot consistently modify the appropriate locks necessary to
issue a monitor command (the current virFileOperation implementation
guarantees that the hook will execute on the right fd, but does not
guarantee whether the operation is in the parent or a child, and thus
the operation is not permitted to modify any state in the parent other
than by its return value). The current state of the patch just falls
back to exec: migration if the parent process can't reopen the fd.
2. I also need to test for qemu capabilities, as qemu 0.11.0 does
_not_ support fd: migration, so the old exec: migration path must
remain. But checking for capabilities is a bear in itself, since we
should be caching qemu capabilities when a domain is started, and not
calling 'qemu -help' for every subsequent command that needs to know.
Eric Blake (3):
qemu: use lighter-weight fd:n on incoming tunneled migration
qemu: support migration to fd
qemu: allow simple domain save to use fd: protocol
src/qemu/qemu_driver.c | 16 ++++++++++++--
src/qemu/qemu_migration.c | 44 +++++++++++------------------------------
src/qemu/qemu_monitor.c | 22 +++++++++++++++++++++
src/qemu/qemu_monitor.h | 4 +++
src/qemu/qemu_monitor_json.c | 21 +++++++++++++++++++-
src/qemu/qemu_monitor_json.h | 6 ++++-
src/qemu/qemu_monitor_text.c | 24 +++++++++++++++++++++-
src/qemu/qemu_monitor_text.h | 6 ++++-
8 files changed, 103 insertions(+), 40 deletions(-)
--
1.7.4
13 years, 8 months