[libvirt] [PATCH] rpc: Fix client crash when server drops connection
by Jiri Denemark
Despite of the comment stating virNetClientIncomingEvent handler should
never be called with either client->haveTheBuck or client->wantClose
set, there is a sequence of events that may lead to both booleans being
true when virNetClientIncomingEvent is called. However, when that
happens, we must not immediately close the socket as there are other
threads waiting for the buck and they would cause SIGSEGV once they are
woken up after the socket was closed. Another thing is we should clear
all remaining calls in the queue after closing the socket.
The situation that can lead to the crash involves three threads, one of
them running event loop and the other two calling libvirt APIs. The
event loop threads detects an event on client->sock and calls
virNetClientIncomingEvent handler. But before the handler gets a chance
to lock client, the other two threads (T1 and T2) start calling some
APIs. T1 gets the buck and detects EOF on client->sock while processing
its RPC call. Since T2 is waiting for its own call, T1 passes the buck
onto it and unlocks client. But before T2 gets the signal, the event
loop thread wakes up, does its job and closes client->sock. The crash
happens when T2 actually wakes up and tries to do its job using a closed
client->sock.
---
src/rpc/virnetclient.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 1379078..010c5c3 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1825,7 +1825,6 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
if (!client->sock)
goto done;
- /* This should be impossible, but it doesn't hurt to check */
if (client->haveTheBuck || client->wantClose)
goto done;
@@ -1858,8 +1857,12 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
virNetClientIOUpdateCallback(client, true);
done:
- if (client->wantClose)
+ if (client->wantClose && !client->haveTheBuck) {
virNetClientCloseLocked(client);
+ virNetClientCallRemovePredicate(&client->waitDispatch,
+ virNetClientIOEventLoopRemoveAll,
+ NULL);
+ }
virObjectUnlock(client);
}
--
1.8.1.5
11 years, 7 months
[libvirt] Unable to start container on Fedora 17 with kernel 3.8.0
by Purcareata Bogdan-B43198
Hello,
I've had some trouble starting a Linux Container with libvirt. Here's my setup:
1. I've downloaded libvirt-1.0.3.tar.gz from [1] and issued:
- ./configure --prefix=/usr
- make
- make install
- ldconfig
2. I've started the libvirtd service:
- sudo service libvirtd start
Starting libvirtd (via systemctl): Warning: Unit file of created job changed on disk, 'systemctl --system daemon-reload' recommended.
[ OK ]
3. I've defined the lxc domain:
<domain type='lxc'>
<name>foo</name>
<uuid>2d1fa65a-0dbf-46e3-3a5c-ebc53e3d0c25</uuid>
<memory unit='KiB'>500000</memory>
<currentMemory unit='KiB'>500000</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64'>exe</type>
<init>/bin/init</init>
</os>
<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' accessmode='passthrough'>
<source dir='/usr/var/lib/lxc/foo/rootfs'/>
<target dir='/'/>
</filesystem>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<console type='pty'>
<target type='serial' port='1'/>
</console>
<console type='pty'>
<target type='serial' port='2'/>
</console>
<console type='pty'>
<target type='serial' port='3'/>
</console>
</devices>
</domain>
When issuing virsh -c lxc:/// start foo I get the following error:
error: Failed to start domain foo
error: internal error guest failed to start: PATH=/bin:/sbin TERM=linux container=lxc-libvirt container_uuid=2d1fa65a-0dbf-46e3-3a5c-ebc53e3d0c25 LIBVIRT_LXC_UUID=2d1fa65a-0dbf-46e3-3a5c-ebc53e3d0c25 LIBVIRT_LXC_NAME=foo /bin/init
2013-03-26 17:09:34.186+0000: 1: info : libvirt version: 1.0.3
2013-03-26 17:09:34.186+0000: 1: error : lxcContainerMountBasicFS:563 : Failed to mount /selinux on /selinux type selinuxfs flags=e opts=(null): No such device
2013-03-26 17:09:34.186+0000: 8087: info : libvirt version: 1.0.3
2013-03-26 17:09:34.186+0000: 8087: error : virLXCControllerRun:1468 : error receiving signal from container: Input/output error
Same message is present in /var/log/libvirt/lxc/foo.log. No errors shown in /var/log/messages.
Machine: Linux everest 3.8.0 #1 SMP Mon Mar 25 19:29:56 EET 2013 x86_64 x86_64 x86_64 GNU/Linux
Can you please provide me some more info on the issue?
Thank you very much,
Bogdan P.
[1] http://libvirt.org/sources/libvirt-1.0.3.tar.gz
11 years, 7 months
[libvirt] [PATCH] conf: fix a failure when detaching a usb device
by Guannan Ren
#virsh detach-device $guest usb.xml
error: Failed to detach device from usb2.xml
error: operation failed: host usb device vendor=0x0951 \
product=0x1625 not found
This regresstion is due to a typo in matching function. The first
argument is always the usb device that we are checking for. If the
usb xml file provided by user contains bus and device info, we try
to search it by them, otherwise, we use vendor and product info.
The bug occurred only when detaching a usb device with no bus and
device info provided in the usb xml file.
---
src/conf/domain_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4cae0d3..2b2f35c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8541,7 +8541,7 @@ static int
virDomainHostdevMatchSubsysUSB(virDomainHostdevDefPtr a,
virDomainHostdevDefPtr b)
{
- if (b->source.subsys.u.usb.bus && b->source.subsys.u.usb.device) {
+ if (a->source.subsys.u.usb.bus && a->source.subsys.u.usb.device) {
/* specified by bus location on host */
if (a->source.subsys.u.usb.bus == b->source.subsys.u.usb.bus &&
a->source.subsys.u.usb.device == b->source.subsys.u.usb.device)
--
1.7.11.2
11 years, 7 months
[libvirt] [PATCH] qemu: Set migration FD blocking
by Michal Privoznik
Since we switched from direct host migration scheme to the one,
where we connect to the destination and then just pass a FD to a
qemu, we have uncovered a qemu bug. Qemu expects migration FD to
block. However, we are passing a nonblocking one which results in
cryptic error messages like:
qemu: warning: error while loading state section id 2
load of migration failed
The bug is already known to Qemu folks, but we should workaround
already released Qemus. Patch has been originally proposed by Stefan
Hajnoczi <stefanha(a)gmail.com>
---
src/qemu/qemu_migration.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 537b834..15f3cef 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2657,6 +2657,13 @@ qemuMigrationConnect(virQEMUDriverPtr driver,
spec->dest.fd.qemu == -1)
goto cleanup;
+ /* Migration expects a blocking FD */
+ if (virSetBlocking(spec->dest.fd.qemu, true) < 0) {
+ virReportSystemError(errno, _("Unable to set FD %d blocking"),
+ spec->dest.fd.qemu);
+ goto cleanup;
+ }
+
ret = 0;
cleanup:
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] qemu: Don't set type too earla during virtio disk hotplug
by Guido Günther
f946462e14ac036357b7c11ce5c23f94a3ee4e49 changed behaviour by settings
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI upfront. If we do so before invoking
qemuDomainPCIAddressEnsureAddr we merely try to set the PCI slot via
qemuDomainPCIAddressReserveSlot instead reserving a new address via
qemuDomainPCIAddressSetNextAddr which fails with
$ ~/run-tck-test domain/200-disk-hotplug.t
./scripts/domain/200-disk-hotplug.t .. # Creating a new transient domain
./scripts/domain/200-disk-hotplug.t .. 1/5 # Attaching the new disk /var/lib/jenkins/jobs/libvirt-tck-build/workspace/scratchdir/200-disk-hotplug/extra.img
# Failed test 'disk has been attached'
# at ./scripts/domain/200-disk-hotplug.t line 67.
# died: Sys::Virt::Error (libvirt error code: 1, message: internal error unable to reserve PCI address 0:0:0.0
# )
---
This unbreaks libvirt-tck on debian wheezy.
Cheers,
-- Guido
src/qemu/qemu_hotplug.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 044f8cd..576738b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -226,7 +226,6 @@ int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
- else disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
@@ -253,7 +252,8 @@ int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
if (qemuDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
!disk->info.addr.ccw.assigned) < 0)
goto error;
- } else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ } else if (!disk->info.type ||
+ disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
goto error;
}
@@ -291,14 +291,17 @@ int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
}
}
}
- } else if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI){
+ } else if (!disk->info.type ||
+ disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
virDevicePCIAddress guestAddr = disk->info.addr.pci;
ret = qemuMonitorAddPCIDisk(priv->mon,
disk->src,
type,
&guestAddr);
- if (ret == 0)
+ if (ret == 0) {
+ disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
+ }
}
qemuDomainObjExitMonitor(driver, vm);
--
1.7.10.4
11 years, 7 months
[libvirt] [PATCH] Correct DESCRIPTION for virsh help blockcopy
by Yanbing Du
Signed-off-by: Yanbing Du <ydu(a)redhat.com>
---
tools/virsh-domain.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 592a6e8..fc5cb1e 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1603,7 +1603,7 @@ static const vshCmdInfo info_block_copy[] = {
.data = N_("Start a block copy operation.")
},
{.name = "desc",
- .data = N_("Populate a disk from its backing image.")
+ .data = N_("Copy a disk backing image chain to dest.")
},
{.name = NULL}
};
--
1.7.1
11 years, 7 months
[libvirt] [PATCH] virsh: error out on non-numeric timeout values
by Ján Tomko
Some block commands and migrate ignored incorrect values.
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=927495
---
tools/virsh-domain.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 592a6e8..12bdd58 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1495,14 +1495,14 @@ cmdBlockCommit(vshControl *ctl, const vshCmd *cmd)
const char *path = NULL;
bool quit = false;
int abort_flags = 0;
+ int rv;
if (blocking) {
- if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
- if (timeout < 1) {
- vshError(ctl, "%s", _("invalid timeout"));
- return false;
- }
-
+ if ((rv = vshCommandOptInt(cmd, "timeout", &timeout)) < 0 ||
+ (rv > 0 && timeout < 1)) {
+ vshError(ctl, "%s", _("invalid timeout"));
+ return false;
+ } else if (rv > 0) {
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("timeout is too big"));
@@ -1685,18 +1685,18 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
const char *path = NULL;
bool quit = false;
int abort_flags = 0;
+ int rv;
if (blocking) {
if (pivot && finish) {
vshError(ctl, "%s", _("cannot mix --pivot and --finish"));
return false;
}
- if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
- if (timeout < 1) {
- vshError(ctl, "%s", _("invalid timeout"));
- return false;
- }
-
+ if ((rv = vshCommandOptInt(cmd, "timeout", &timeout)) < 0 ||
+ (rv > 0 && timeout < 1)) {
+ vshError(ctl, "%s", _("invalid timeout"));
+ return false;
+ } else if (rv > 0) {
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("timeout is too big"));
@@ -1962,14 +1962,14 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
const char *path = NULL;
bool quit = false;
int abort_flags = 0;
+ int rv;
if (blocking) {
- if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
- if (timeout < 1) {
- vshError(ctl, "%s", _("invalid timeout"));
- return false;
- }
-
+ if ((rv = vshCommandOptInt(cmd, "timeout", &timeout)) < 0 ||
+ (rv > 0 && timeout < 1)) {
+ vshError(ctl, "%s", _("invalid timeout"));
+ return false;
+ } else if (rv > 0) {
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("timeout is too big"));
@@ -8456,6 +8456,7 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
int timeout = 0;
bool live_flag = false;
vshCtrlData data;
+ int rv;
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
@@ -8465,18 +8466,17 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "live"))
live_flag = true;
- if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
+ if ((rv = vshCommandOptInt(cmd, "timeout", &timeout)) < 0 ||
+ (rv > 0 && timeout < 1)) {
+ vshError(ctl, "%s", _("migrate: Invalid timeout"));
+ goto cleanup;
+ } else if (rv > 0) {
if (! live_flag) {
vshError(ctl, "%s",
_("migrate: Unexpected timeout for offline migration"));
goto cleanup;
}
- if (timeout < 1) {
- vshError(ctl, "%s", _("migrate: Invalid timeout"));
- goto cleanup;
- }
-
/* Ensure that we can multiply by 1000 without overflowing. */
if (timeout > INT_MAX / 1000) {
vshError(ctl, "%s", _("migrate: Timeout is too big"));
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] Fix virConnectOpen.*() name requirements
by Martin Kletzander
virConnectOpenAuth didn't require 'name' to be specified (VIR_DEBUG
used NULLSTR() for the output) and by default, if name == NULL, the
default connection uri is used. This was not indicated in the
documentation and wasn't checked for in other API's VIR_DEBUG outputs.
---
Thanks to Guannan's patch, this makes the following possible in python:
conn = libvirt.open()
which I personally find pretty nice.
---
src/libvirt.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 1624776..4b9ea75 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1334,7 +1334,7 @@ failed:
/**
* virConnectOpen:
- * @name: URI of the hypervisor
+ * @name: (optional) URI of the hypervisor
*
* This function should be called first to get a connection to the
* Hypervisor and xen store
@@ -1362,7 +1362,7 @@ virConnectOpen(const char *name)
if (virInitialize() < 0)
goto error;
- VIR_DEBUG("name=%s", name);
+ VIR_DEBUG("name=%s", NULLSTR(name));
virResetLastError();
ret = do_open(name, NULL, 0);
if (!ret)
@@ -1376,7 +1376,7 @@ error:
/**
* virConnectOpenReadOnly:
- * @name: URI of the hypervisor
+ * @name: (optional) URI of the hypervisor
*
* This function should be called first to get a restricted connection to the
* library functionalities. The set of APIs usable are then restricted
@@ -1397,7 +1397,7 @@ virConnectOpenReadOnly(const char *name)
if (virInitialize() < 0)
goto error;
- VIR_DEBUG("name=%s", name);
+ VIR_DEBUG("name=%s", NULLSTR(name));
virResetLastError();
ret = do_open(name, NULL, VIR_CONNECT_RO);
if (!ret)
@@ -1411,7 +1411,7 @@ error:
/**
* virConnectOpenAuth:
- * @name: URI of the hypervisor
+ * @name: (optional) URI of the hypervisor
* @auth: Authenticate callback parameters
* @flags: bitwise-OR of virConnectFlags
*
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] virsh: Let the compiler check usage of all fields in vshCmdOptType enum
by Peter Krempa
Get rid of the "default" labels to do so.
---
tools/virsh.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index b574d7e..0a9ac6f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1172,8 +1172,6 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
case VSH_OT_ALIAS:
/* aliases are intentionally undocumented */
continue;
- default:
- assert(0);
}
fputc(' ', stdout);
fprintf(stdout, fmt, opt->name);
@@ -1215,8 +1213,6 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname)
break;
case VSH_OT_ALIAS:
continue;
- default:
- assert(0);
}
fprintf(stdout, " %-15s %s\n", buf, _(opt->help));
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] python: set default value to optional arguments
by Guannan Ren
When prefixing with string (optional) or optional in the description
of arguments to libvirt C APIs, in python, these arguments will be
set as optional arugments, for example:
* virDomainSaveFlags:
* @domain: a domain object
* @to: path for the output file
* @dxml: (optional) XML config for adjusting guest xml used on restore
* @flags: bitwise-OR of virDomainSaveRestoreFlags
the corresponding python APIs is
restoreFlags(self, frm, dxml=None, flags=0)
The following python APIs are changed to:
blockCommit(self, disk, base, top, bandwidth=0, flags=0)
blockPull(self, disk, bandwidth=0, flags=0)
blockRebase(self, disk, base, bandwidth=0, flags=0)
migrate(self, dconn, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, dconn, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
migrateToURI(self, duri, flags=0, dname=None, bandwidth=0)
migrateToURI2(self, dconnuri=None, miguri=None, dxml=None, flags=0, \
dname=None, bandwidth=0)
saveFlags(self, to, dxml=None, flags=0)
migrate(self, domain, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, domain, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
restoreFlags(self, frm, dxml=None, flags=0)
---
python/generator.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/python/generator.py b/python/generator.py
index 0237374..7586ffc 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -1005,6 +1005,8 @@ functions_int_default_test = "%s == -1"
def is_integral_type (name):
return not re.search ("^(unsigned)? ?(int|long)$", name) is None
+def is_optional_arg(info):
+ return not re.search("^\(?\optional\)?", info) is None
# Functions returning lists which need special rules to check for errors
# and raise exceptions.
functions_list_exception_test = {
@@ -1488,9 +1490,12 @@ def buildWrappers(module):
for arg in args:
if n != index:
classes.write(", %s" % arg[0])
+ if arg[0] == "flags" or is_optional_arg(arg[2]):
+ if is_integral_type(arg[1]):
+ classes.write("=0")
+ else:
+ classes.write("=None")
n = n + 1
- if arg[0] == "flags":
- classes.write("=0")
classes.write("):\n")
writeDoc(module, name, args, ' ', classes)
n = 0
--
1.7.11.2
11 years, 7 months