[libvirt] [PATCH] qemu: Adjust size for qcow2/qed if not on sector boundary
by John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1002813
If qemuDomainBlockResize() is passed a size not on a KiB boundary - that
is passed a size based in bytes (VIR_DOMAIN_BLOCK_RESIZE_BYTES), then
depending on the source format (qcow2 or qed), the value passed must
be on a sector (or 512 byte) boundary. Since other libvirt code quietly
adjusts the capacity values, then do so here as well - of course ensuring
that adjustment still fits.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/qemu/qemu_driver.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4bb4819..3e407d7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9421,6 +9421,7 @@ qemuDomainBlockResize(virDomainPtr dom,
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
int ret = -1, idx;
+ unsigned long long size_up;
char *device = NULL;
virDomainDiskDefPtr disk = NULL;
@@ -9441,6 +9442,12 @@ qemuDomainBlockResize(virDomainPtr dom,
return -1;
}
size *= 1024;
+ size_up = size;
+ } else {
+ /* For 'qcow2' and 'qed', qemu resize blocks expects values
+ * on sector boundary, so round our value up to prepare
+ */
+ size_up = VIR_ROUND_UP(size, 512);
}
if (!(vm = qemuDomObjFromDomain(dom)))
@@ -9467,6 +9474,21 @@ qemuDomainBlockResize(virDomainPtr dom,
}
disk = vm->def->disks[idx];
+ /* qcow2 and qed must be sized appropriately, so be sure our value
+ * is sized appropriately and will fit
+ */
+ if (size != size_up &&
+ (disk->src.format == VIR_STORAGE_FILE_QCOW2 ||
+ disk->src.format == VIR_STORAGE_FILE_QED)) {
+ if (size_up > ULLONG_MAX) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("size must be less than %llu KiB"),
+ ULLONG_MAX / 1024);
+ goto endjob;
+ }
+ size = size_up;
+ }
+
if (virAsprintf(&device, "%s%s", QEMU_DRIVE_HOST_PREFIX,
disk->info.alias) < 0)
goto endjob;
--
1.9.0
10 years, 7 months
[libvirt] LibvirtError: Operation not supported : JSON monitor is required
by xeon_feng
Hi
Thanks for chenhanxiao(a)cn.fujitsu.com help , I have resole the problem (libvirt 1.2.4 and virt-manager 0.9.0 are not incompatible)..but when I created VM by virt-manager ,it reported :
unable to complete install: 'Opertation not supported: JSON monitor is required.'
Traceback(most recent call last):
File "/usr/share/virt-manager/virtManager/asyncjob.py",line 44, in cb_wrapper callback(asyncjob, *args, **kwargs)
......
LibvirtError: Operation not supported : JSON monitor is required.
what is wrong ?
Please help me....... Tanks a lot ....
Xeon.Feng
last problem: libvirt 1.2.4 and virt-manager 0.9.0 are not incompatible
""""""""""
Hello everyone
I encountered a problem when I completed the update of libvirt from 0.10 to 1.2.4 .
The problem was that virt-manager(version 0.9.0) could not start and reported error : "ImportError: /usr/lib64/libvirt.so.0: version 'LIBVIRT_PRIVIATE_0.10.2' not found (required by /usr/lib64/python2.6/site-packages/libvirtmod.so)".
I found the libvirt.so.0 link file just in the /usr/lib64/ directory , but it was linking to libvirt.so.0.1002.4 .not to the libvirt.so.0.10.2
I made libvirt.so.0 to link to libvirt.so.0.10.2 and restarted virt-manager , virt-manager started normally then restarted libvirtd failure, reporting error:l “ibvirtd: /usr/lib64/libvirt.so.0: version 'LIBVIRT_1.2.3' not found (require by libvirtd) .....”
I made libvirt.so.0 to link to libvirt.so.0.1002.4 and restart libvirtd , libvirtd started normally again.
Please help me to resolve the problem and give me some advise....
Thanks a lot..
Xeon.Feng
"""""""
10 years, 7 months
[libvirt] [PATCH] LXC: don't doubly link /dev/console
by Dwight Engen
When a console is configured, /dev/console and /dev/tty1 are created as
symlinks to the same underlying pts. This causes problems since a
separate getty will be spawned for /dev/console and /dev/tty1, but they
are each controlling the same device.
This patch makes it so that /dev/console is the sole symlink to the first
console, /dev/tty1 to the second, /dev/tty2 to the third and so on.
Signed-off-by: Dwight Engen <dwight.engen(a)oracle.com>
---
src/lxc/lxc_container.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index fd8ab16..dcc6b17 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1034,23 +1034,25 @@ static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths)
}
for (i = 0; i < nttyPaths; i++) {
- char *tty;
- if (virAsprintf(&tty, "/dev/tty%zu", i+1) < 0)
- return -1;
- if (symlink(ttyPaths[i], tty) < 0) {
- virReportSystemError(errno,
- _("Failed to symlink %s to %s"),
- ttyPaths[i], tty);
+ if (i == 0) {
+ if (symlink(ttyPaths[i], "/dev/console") < 0) {
+ virReportSystemError(errno,
+ _("Failed to symlink %s to /dev/console"),
+ ttyPaths[i]);
+ return -1;
+ }
+ } else {
+ char *tty;
+ if (virAsprintf(&tty, "/dev/tty%zu", i) < 0)
+ return -1;
+ if (symlink(ttyPaths[i], tty) < 0) {
+ virReportSystemError(errno,
+ _("Failed to symlink %s to %s"),
+ ttyPaths[i], tty);
+ VIR_FREE(tty);
+ return -1;
+ }
VIR_FREE(tty);
- return -1;
- }
- VIR_FREE(tty);
- if (i == 0 &&
- symlink(ttyPaths[i], "/dev/console") < 0) {
- virReportSystemError(errno,
- _("Failed to symlink %s to /dev/console"),
- ttyPaths[i]);
- return -1;
}
}
return 0;
--
1.9.0
10 years, 7 months
[libvirt] [PATCH 0/4] parallels: a set of fixes
by Dmitry Guryanov
Hello,
I'd like to continue working on the parallels driver. So here
is a set of patches, which resolves some problems.
Now Parallels has a definite goal with this driver: we want
OpenStack to be working with Parallels Cloud Server (PCS) over
libvirt, and we a ready to implement all needed API calls
in libvirt's driver and make necessary changes in PCS.
P.S.
I appreciate greatly effort needed to support the driver in
compilable state and a lot of refactoring made by libvirt
team, thanks!
Dmitry Guryanov (4):
parallels: fix virDomainDef.features comparison
parallels: don't enable VNC when we define a new domain
parallels: don't add domain to the list twice
parallels: add a set of trivial functions
src/parallels/parallels_driver.c | 57 ++++++++++++++++++++++------------------
1 file changed, 31 insertions(+), 26 deletions(-)
--
1.9.0
10 years, 7 months
[libvirt] [PATCH 1/5] virerror: Fix an error message typo
by Cole Robinson
---
src/util/virerror.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virerror.h b/src/util/virerror.h
index 2de04f4..fe0e15e 100644
--- a/src/util/virerror.h
+++ b/src/util/virerror.h
@@ -99,7 +99,7 @@ void virReportSystemErrorFull(int domcode,
#argname, \
NULL, \
0, 0, \
- _("%s in %s must greater than zero"), \
+ _("%s in %s must be greater than zero"), \
#argname, __FUNCTION__)
# define virReportInvalidNonZeroArg(argname) \
virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
--
1.9.0
10 years, 7 months
[libvirt] [PATCH 0/2] Fix bug on buildVol error path
by John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1092882
Changes as a result of commit id '0c2305b3', see:
http://www.redhat.com/archives/libvir-list/2014-April/msg00375.html
Resulted in a regression when there was a failure to buildVol the
volume wasn't removed from the storage driver list because the wrong
local storage pointer was passed to the DeleteInternal routine.
Additionally a preexisting condition where if deleteVol didn't exist
or failed, the volume would not be removed from volumes.objs[] even
though it doesn't exist. This results in virsh vol-list and vol-info
not finding the volume and emitting error messages.
John Ferlan (2):
storage: Need to ensure removal of voldef from driver list
storage: Resolve issues in failure path
src/storage/storage_driver.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--
1.9.0
10 years, 7 months
[libvirt] [RESEND PATCH] Add support for timestamping QEMU logs
by Ján Tomko
QEMU commit 5e2ac51 added a boolean '-msg timestamp=[on|off]'
option, which can enable timestamps on errors:
$ qemu-system-x86_64 -msg timestamp=on zghhdorf
2014-04-09T13:25:46.779484Z qemu-system-x86_64: -msg timestamp=on: could
not open disk image zghhdorf: Could not open 'zghhdorf': No such file or
directory
Enable this timestamp if the QEMU binary supports it.
Add a 'log_timestamp' option to qemu.conf for disabling this behavior.
---
Rebased to latest master, this time with the test files added.
previous posting of the patch:
https://www.redhat.com/archives/libvir-list/2014-April/msg00422.html
src/qemu/libvirtd_qemu.aug | 3 ++
src/qemu/qemu.conf | 8 ++++++
src/qemu/qemu_capabilities.c | 5 ++++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 4 +++
src/qemu/qemu_conf.c | 4 +++
src/qemu/qemu_conf.h | 2 ++
src/qemu/test_libvirtd_qemu.aug.in | 1 +
tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 +
.../qemuxml2argv-minimal-msg-timestamp.args | 6 ++++
.../qemuxml2argv-minimal-msg-timestamp.xml | 32 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
13 files changed, 69 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.xml
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index a9ff421..e985d22 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -85,6 +85,8 @@ module Libvirtd_qemu =
| int_entry "migration_port_min"
| int_entry "migration_port_max"
+ let log_entry = bool_entry "log_timestamp"
+
(* Each entry in the config is one of the following ... *)
let entry = vnc_entry
| spice_entry
@@ -96,6 +98,7 @@ module Libvirtd_qemu =
| device_entry
| rpc_entry
| network_entry
+ | log_entry
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
let empty = [ label "#empty" . eol ]
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index f0e802f..42f812d 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -465,3 +465,11 @@
#
#migration_port_min = 49152
#migration_port_max = 49215
+
+
+
+# Timestamp QEMU's log messages (if QEMU supports it)
+#
+# Defaults to 1.
+#
+#log_timestamp = 0
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8343258..0d08e20 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -255,6 +255,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"usb-kbd", /* 165 */
"host-pci-multidomain",
+ "msg-timestamp",
);
@@ -1146,6 +1147,9 @@ virQEMUCapsComputeCmdFlags(const char *help,
if (strstr(help, "-machine"))
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);
+ if (strstr(help, "-msg timestamp"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP);
+
/*
* Handling of -incoming arg with varying features
* -incoming tcp (kvm >= 79, qemu >= 0.10.0)
@@ -2378,6 +2382,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
{ "boot-opts", "strict", QEMU_CAPS_BOOT_STRICT },
{ "boot-opts", "reboot-timeout", QEMU_CAPS_REBOOT_TIMEOUT },
{ "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE },
+ { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP },
};
static int
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 26400d2..d755caa 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -205,6 +205,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_CHARDEV_SPICEPORT = 164, /* -chardev spiceport */
QEMU_CAPS_DEVICE_USB_KBD = 165, /* -device usb-kbd */
QEMU_CAPS_HOST_PCI_MULTIDOMAIN = 166, /* support domain > 0 in host pci address */
+ QEMU_CAPS_MSG_TIMESTAMP = 167, /* -msg timestamp */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 29ae8e4..dd8e40a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9742,6 +9742,10 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandSetMaxMemLock(cmd, memKB * 1024);
}
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
+ cfg->logTimestamp)
+ virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL);
+
virObjectUnref(cfg);
return cmd;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 198ee2f..e487f5e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -255,6 +255,8 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
cfg->keepAliveCount = 5;
cfg->seccompSandbox = -1;
+ cfg->logTimestamp = true;
+
return cfg;
error:
@@ -576,6 +578,8 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
GET_VALUE_STR("migration_address", cfg->migrationAddress);
+ GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
+
ret = 0;
cleanup:
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index a36ea63..5d2983a 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -167,6 +167,8 @@ struct _virQEMUDriverConfig {
char *migrationAddress;
int migrationPortMin;
int migrationPortMax;
+
+ bool logTimestamp;
};
/* Main driver state */
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index b2328d3..30a4257 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -72,3 +72,4 @@ module Test_libvirtd_qemu =
{ "migration_address" = "127.0.0.1" }
{ "migration_port_min" = "49152" }
{ "migration_port_max" = "49215" }
+{ "log_timestamp" = "0" }
diff --git a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
index 7b86c3b..ca2c236 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps
@@ -143,4 +143,5 @@
<flag name='spiceport'/>
<flag name='usb-kbd'/>
<flag name='host-pci-multidomain'/>
+ <flag name='msg-timestamp'/>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
index 10b8251..32bccdb 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
+++ b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps
@@ -141,4 +141,5 @@
<flag name='spiceport'/>
<flag name='usb-kbd'/>
<flag name='host-pci-multidomain'/>
+ <flag name='msg-timestamp'/>
</qemuCaps>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.args b/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.args
new file mode 100644
index 0000000..f85aae9
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.args
@@ -0,0 +1,6 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-usb -hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none -msg timestamp=on
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.xml b/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.xml
new file mode 100644
index 0000000..4a938b3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal-msg-timestamp.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <title>A description of the test machine.</title>
+ <description>
+ A test of qemu's minimal configuration.
+ This test also tests the description and title elements.
+ </description>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' cpuset='1-4,8-20,525'>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' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ad5e2cd..1ea7bf8 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -578,6 +578,7 @@ mymain(void)
unsetenv("SDL_AUDIODRIVER");
DO_TEST("minimal", QEMU_CAPS_NAME);
+ DO_TEST("minimal-msg-timestamp", QEMU_CAPS_NAME, QEMU_CAPS_MSG_TIMESTAMP);
DO_TEST("minimal-s390", QEMU_CAPS_NAME);
DO_TEST("machine-aliases1", NONE);
DO_TEST("machine-aliases2", QEMU_CAPS_KVM);
--
1.8.3.2
10 years, 7 months
[libvirt] [PATCH RFC 00/22] Support for walking backing chains on remote volumes (especially gluster)
by Peter Krempa
This series adds support for waliking (detecting) of backing chain on
remote storage and implements the needed callbacks for the gluster
storage system via native library.
The last patch in the series mocks up path canonicalization on gluster as I'm
working on that but this series is getting tedious to rebase and handle so I'd
like to start reviews.
Peter Krempa (22):
qemu: Make qemuDomainPrepareDiskChainElement aware of remote storage
storage: Store gluster volume name separately
storage: Rework debugging of storage file access through storage
driver
conf: Fix domain disk path iterator to work with networked storage
storage: Add NONE protocol type for network disks
storage: Add support for access to files using provided uid/gid
storage: Add storage file API to read file headers
storage: backend: Add unique id retrieval API
storage: Add API to check accessibility of storage volumes
storage: Move virStorageFileGetMetadata to the storage driver
storage: Determine the local storage type right away
test: storage: Initialize storage source to correct type
storage: backend: Add possibility to suppress errors from backend
lookup
storage: Switch metadata crawler to use storage driver to get unique
path
storage: Switch metadata crawler to use storage driver to read headers
storage: Switch metadata crawler to use storage driver file access
check
storage: Add infrastructure to parse remote network backing names
storage: Change to new backing store parser
storage: Traverse backing chains of network disks
qemu: Add support for networked disks for block pull/block rebase
qemu: Add support for networked disks for block commit
[DO NOT APPLY UPSTREAM] storage: gluster: mock up path
canonicalization
cfg.mk | 2 +-
src/Makefile.am | 2 +
src/conf/domain_conf.c | 70 +++-
src/libvirt_private.syms | 3 +-
src/qemu/qemu_command.c | 21 +-
src/qemu/qemu_domain.c | 10 +-
src/qemu/qemu_driver.c | 116 +++++--
src/security/virt-aa-helper.c | 2 +
src/storage/storage_backend.c | 16 +-
src/storage/storage_backend.h | 22 +-
src/storage/storage_backend_fs.c | 127 +++++++-
src/storage/storage_backend_gluster.c | 141 ++++++--
src/storage/storage_driver.c | 329 ++++++++++++++++++-
src/storage/storage_driver.h | 15 +-
src/util/virstoragefile.c | 596 +++++++++++++++++++++-------------
src/util/virstoragefile.h | 16 +-
tests/Makefile.am | 7 +-
tests/virstoragetest.c | 26 +-
18 files changed, 1162 insertions(+), 359 deletions(-)
--
1.9.2
10 years, 7 months
[libvirt] [question]qemu: migrate and destory vm immediately on destination causes libvirt deadlock or segment fault
by Wangrui (K)
Hi everyone,
I do ram migration operation in KVM environment(libvirt1.2.4 qemu1.5.1).
I encountered libvirtd deadlock or segmentfault when I destroy the
migration VM on destination.
I got the problem by flowing steps:
step 1: migrate VM.
step 2: execute "virsh destroy [VMName]" to destroy the migration VM on
destination immediately.
step 3: the destination libvirtd will be probably deadlock or segmentfault.
Deadlock stack as followed:
#0 0x00007fb5c18132d4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007fb5c180e659 in _L_lock_1008 () from /lib64/libpthread.so.0
#2 0x00007fb5c180e46e in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007fb5c45d175f in virMutexLock (m=0x7fb5b0066ed0) at util/virthread.c:88
#4 0x00007fb5c45b6b04 in virObjectLock (anyobj=0x7fb5b0066ec0) at
util/virobject.c:323
#5 0x00007fb5b8f4842a in qemuMonitorEmitEvent (mon=0x7fb5b0066ec0,
event=0x7fb5b00688d0 "SHUTDOWN", seconds=1399374472, micros=509994,
details=0x0) at qemu/qemu_monitor.c:1185
#6 0x00007fb5b8f62af2 in qemuMonitorJSONIOProcessEvent (mon=0x7fb5b0066ec0,
obj=0x7fb5b0069080) at qemu/qemu_monitor_json.c:158
#7 0x00007fb5b8f62d25 in qemuMonitorJSONIOProcessLine (mon=0x7fb5b0066ec0,
line=0x7fb5b005bbe0 "{\"timestamp\": {\"seconds\": 1399374472,
\"microseconds\": 509994}, \"event\": \"SHUTDOWN\"}",msg=0x7fb5bd873c80)
at qemu/qemu_monitor_json.c:195
#8 0x00007fb5b8f62f85 in qemuMonitorJSONIOProcess (mon=0x7fb5b0066ec0,
data=0x7fb5b0060770 "{\"timestamp\": {\"seconds\": 1399374472,
\"microseconds\": 509994},\"event\": \"SHUTDOWN\"}\r\n", len=85,
msg=0x7fb5bd873c80) at qemu/qemu_monitor_json.c:237
#9 0x00007fb5b8f49aa0 in qemuMonitorIOProcess (mon=0x7fb5b0066ec0)
at qemu/qemu_monitor.c:402
#10 0x00007fb5b8f4a09b in qemuMonitorIO (watch=20, fd=24, events=0,
opaque=0x7fb5b0066ec0) at qemu/qemu_monitor.c:651
#11 0x00007fb5c458c4d9 in virEventPollDispatchHandles (nfds=17, fds=0x7fb5b0068a60)
at util/vireventpoll.c:510
#12 0x00007fb5c458decf in virEventPollRunOnce () at util/vireventpoll.c:659
#13 0x00007fb5c458bfcc in virEventRunDefaultImpl () at util/virevent.c:308
#14 0x00007fb5c51a17a9 in virNetServerRun (srv=0x7fb5c5411d70)
at rpc/virnetserver.c:1139
#15 0x00007fb5c5157f63 in main (argc=3, argv=0x7fff7fc04f48) at libvirtd.c:150
After analysis, I found it may be caused by multithreaded simultaneously
access to the global variables "vm->privateData->mon".
When problems occur,there are three libvirtd threads at work on destination
host,suppose:
ThreadA: migration thread,do qemuProcessStart.
ThreadB: destroy thread,do qemuDoaminDestroy -> qemuProcessStop.
ThreadC:Monitor Thread,do IOWrite、IORead and some other operations according to
the mon->msg when mon->fd change. When threadB destroy happpens, this thread would
handle the SUHTDOWN event.
In threadA, when it sends QMP command to Qemu, it will operate the vm->privateData->mon
lock. Such as the operation "qemuDomainObjEnterMonitor -> qemuMonitorSetBalloon ->
qemuDomainObjExitMonitor", but it's not an atomic operation. If "virsh destroy [VMName]"
happens during this operation, threadB will set the lock vm->privateData->mon to NULL in
qemuProcessStop. And then in threadA, the function qemuDomainObjExitMonitor will fail to
unlock vm->privateData->mon as it's NULL. So, threadC will never acquire the
vm->privateData->mon lock and the deadlock problem happened.
what was worse, if qemuMonitorSetBalloon perform succeed in threadA.
ThreadA will coutinue to execute till it enter the function qemuMonitorSetDomainLog,
it would cause segmentfault at VIR_FORCE_CLOSE(mon->logfd) due to mon is NULL.
I could not find a good way to sovle this problem. Does anyone have good ideas?
Thanks.
Ps:
I find an easy way to reproduce this problem more probably by following steps:
step 1: Fault Injection, fit into this patch and update the libvirtd on destination host:
--- src/qemu/qemu_process.c 2014-05-06 19:06:00.000000000 +0800
+++ src/qemu/qemu_process.c 2014-05-06 19:07:12.000000000 +0800
@@ -4131,6 +4131,8 @@
vm->def->mem.cur_balloon);
goto cleanup;
}
+ VIR_DEBUG("Fault Injection, sleep 3 seconds.");
+ sleep(3);
qemuDomainObjEnterMonitor(driver, vm);
if (vm->def->memballoon && vm->def->memballoon->period)
qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon->period);
step 2: migrate VM.
step 3: execute "virsh destroy [VMName]" to destroy the migration VM on destination
when log prints "Fault Injection, sleep 3 seconds."
step 4: the libvirtd deadlock stack occurs as above mentioned.
Regards
10 years, 7 months