[libvirt] [v0.9.12-maint 00/11] Debian's 0.9.12 patches
by Guido Günther
These are the patches Debian is currently carrying on 0.9.12. Most are
straight cherry-picks. Since we're maintaining 0.9.12 for our current
stable release I'm happy to push these to v0.9.12-maint.
Ferenc Wágner (1):
Fix race condition when destroying guests
Guido Günther (1):
Include stdint.h for uint32_t
Jiri Denemark (3):
daemon: Fix crash in virTypedParameterArrayClear
Revert "rpc: Discard non-blocking calls only when necessary"
qemu: Add support for -no-user-config
Luca Tettamanti (1):
Make sure regree is called close to it's usage
Martin Kletzander (1):
security: Fix libvirtd crash possibility
Peter Krempa (4):
qemu: Fix off-by-one error while unescaping monitor strings
rpc: Fix crash on error paths of message dispatching
conf: Remove callback from stream when freeing entries in console hash
conf: Remove console stream callback only when freeing console helper
cfg.mk | 3 +-
daemon/remote.c | 16 +-
src/conf/virconsole.c | 13 ++
src/qemu/qemu_capabilities.c | 7 +-
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 +-
src/qemu/qemu_driver.c | 21 ++-
src/qemu/qemu_monitor.c | 11 +-
src/rpc/virnetclient.c | 21 +--
src/rpc/virnetserverclient.c | 3 +
src/rpc/virnetserverprogram.c | 11 +-
src/storage/storage_backend_logical.c | 5 +-
src/util/virnetlink.h | 2 +
tests/qemuhelpdata/qemu-1.1 | 268 ++++++++++++++++++++++++++++++++++
tests/qemuhelpdata/qemu-1.1-device | 160 ++++++++++++++++++++
tests/qemuhelptest.c | 75 ++++++++++
16 files changed, 586 insertions(+), 42 deletions(-)
create mode 100644 tests/qemuhelpdata/qemu-1.1
create mode 100644 tests/qemuhelpdata/qemu-1.1-device
--
1.8.4.rc3
11 years, 2 months
[libvirt] [v0.9.12-maint 11/11] Fix race condition when destroying guests
by Ferenc Wágner
Backport of 81621f3e6e45e8681cc18ae49404736a0e772a11 and
f1b4021b38f9485c50d386af6f682ecfc8025af5 to fix a race (resulting in a
segfault) when destroying domains.
---
src/qemu/qemu_driver.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0053ed1..c0b4707 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1827,6 +1827,12 @@ qemuDomainDestroyFlags(virDomainPtr dom,
qemuDomainSetFakeReboot(driver, vm, false);
+
+ /* We need to prevent monitor EOF callback from doing our work (and sending
+ * misleading events) while the vm is unlocked inside BeginJob/ProcessKill API
+ */
+ priv->beingDestroyed = true;
+
/* Although qemuProcessStop does this already, there may
* be an outstanding job active. We want to make sure we
* can kill the process even if a job is active. Killing
@@ -1834,19 +1840,20 @@ qemuDomainDestroyFlags(virDomainPtr dom,
*/
if (flags & VIR_DOMAIN_DESTROY_GRACEFUL) {
if (qemuProcessKill(driver, vm, 0) < 0) {
+ priv->beingDestroyed = false;
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("failed to kill qemu process with SIGTERM"));
goto cleanup;
}
} else {
- ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE));
+ if (qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) {
+ priv->beingDestroyed = false;
+ qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("failed to kill qemu process with SIGTERM"));
+ goto cleanup;
+ }
}
- /* We need to prevent monitor EOF callback from doing our work (and sending
- * misleading events) while the vm is unlocked inside BeginJob API
- */
- priv->beingDestroyed = true;
-
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_DESTROY) < 0)
goto cleanup;
--
1.8.4.rc3
11 years, 2 months
[libvirt] [v0.9.12-maint 10/11] conf: Remove console stream callback only when freeing console helper
by Peter Krempa
Commit ba226d334acbc49f6751b430e0c4e00f69eef6bf tried to fix crash of
the daemon when a domain with an open console was destroyed. The fix was
wrong as it tried to remove the callback also when the stream was
aborted, where at that point the fd stream driver was already freed and
removed.
This patch clears the callbacks with a helper right before the hash is
freed, so that it doesn't interfere with other codepaths where the
stream object is freed.
---
src/conf/virconsole.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/conf/virconsole.c b/src/conf/virconsole.c
index e665149..01f1c84 100644
--- a/src/conf/virconsole.c
+++ b/src/conf/virconsole.c
@@ -222,9 +222,6 @@ static void virConsoleHashEntryFree(void *data,
const char *pty = name;
virStreamPtr st = data;
- /* remove callback from stream */
- virFDStreamSetInternalCloseCb(st, NULL, NULL, NULL);
-
/* free stream reference */
virStreamFree(st);
@@ -293,6 +290,18 @@ error:
}
/**
+ * Helper to clear stream callbacks when freeing the hash
+ */
+static void virConsoleFreeClearCallbacks(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ virStreamPtr st = payload;
+
+ virFDStreamSetInternalCloseCb(st, NULL, NULL, NULL);
+}
+
+/**
* Free structures for handling open console streams.
*
* @cons Pointer to the private structure.
@@ -303,6 +312,7 @@ void virConsoleFree(virConsolesPtr cons)
return;
virMutexLock(&cons->lock);
+ virHashForEach(cons->hash, virConsoleFreeClearCallbacks, NULL);
virHashFree(cons->hash);
virMutexUnlock(&cons->lock);
virMutexDestroy(&cons->lock);
--
1.8.4.rc3
11 years, 2 months
[libvirt] [v0.9.12-maint 09/11] conf: Remove callback from stream when freeing entries in console hash
by Peter Krempa
When a domain has a active console connection and is destroyed the
callback is called on private data that no longer exist causing a
segfault.
---
src/conf/virconsole.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/conf/virconsole.c b/src/conf/virconsole.c
index 443d80d..e665149 100644
--- a/src/conf/virconsole.c
+++ b/src/conf/virconsole.c
@@ -222,6 +222,9 @@ static void virConsoleHashEntryFree(void *data,
const char *pty = name;
virStreamPtr st = data;
+ /* remove callback from stream */
+ virFDStreamSetInternalCloseCb(st, NULL, NULL, NULL);
+
/* free stream reference */
virStreamFree(st);
--
1.8.4.rc3
11 years, 2 months
[libvirt] [PATCH] Fix polkit permission names for storage pools, vols & node devices
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The polkit access driver used the wrong permission names for checks
on storage pools, volumes and node devices. This led to them always
being denied access.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/access/viraccessdriverpolkit.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/access/viraccessdriverpolkit.c b/src/access/viraccessdriverpolkit.c
index 4c76e64..b472bc3 100644
--- a/src/access/viraccessdriverpolkit.c
+++ b/src/access/viraccessdriverpolkit.c
@@ -248,7 +248,7 @@ virAccessDriverPolkitCheckNodeDevice(virAccessManagerPtr manager,
};
return virAccessDriverPolkitCheck(manager,
- "nodedevice",
+ "node-device",
virAccessPermNodeDeviceTypeToString(perm),
attrs);
}
@@ -355,7 +355,7 @@ virAccessDriverPolkitCheckStoragePool(virAccessManagerPtr manager,
virUUIDFormat(pool->uuid, uuidstr);
return virAccessDriverPolkitCheck(manager,
- "pool",
+ "storage-pool",
virAccessPermStoragePoolTypeToString(perm),
attrs);
}
@@ -379,7 +379,7 @@ virAccessDriverPolkitCheckStorageVol(virAccessManagerPtr manager,
virUUIDFormat(pool->uuid, uuidstr);
return virAccessDriverPolkitCheck(manager,
- "vol",
+ "storage-vol",
virAccessPermStorageVolTypeToString(perm),
attrs);
}
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] Fix launching of VMs on when only logind part of systemd is present
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Debian systems may run the 'systemd-logind' daemon, which causes the
/sys/fs/cgroup/systemd mount to be setup, but no other cgroup
controllers are created. While the LXC driver considers cgroups to
be mandatory, the QEMU driver is supposed to accept them as optional.
We detect whether they are present by looking in /proc/mounts for
any mounts of type 'cgroups', but this is not sufficient. We need to
skip any named mounts (as seen by a name=XXX string in the mount
options), so that we only detect actual resource controllers.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721979
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/vircgroup.c | 5 +++-
tests/vircgroupmock.c | 40 ++++++++++++++++++++++++---
tests/vircgrouptest.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index a260356..626bbc6 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -91,7 +91,10 @@ virCgroupAvailable(void)
return false;
while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
- if (STREQ(entry.mnt_type, "cgroup")) {
+ /* We're looking for at least one 'cgroup' fs mount,
+ * which is *not* a named mount. */
+ if (STREQ(entry.mnt_type, "cgroup") &&
+ !strstr(entry.mnt_opts, "name=")) {
ret = true;
break;
}
diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
index d83496c..adc1718 100644
--- a/tests/vircgroupmock.c
+++ b/tests/vircgroupmock.c
@@ -124,6 +124,27 @@ const char *proccgroupsallinone =
"devices 6 1 1\n"
"blkio 6 1 1\n";
+const char *procmountslogind =
+ "none /not/really/sys/fs/cgroup tmpfs rw,rootcontext=system_u:object_r:sysfs_t:s0,seclabel,relatime,size=4k,mode=755 0 0\n"
+ "systemd /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0\n";
+
+const char *procselfcgroupslogind =
+ "1:name=systemd:/\n";
+
+const char *proccgroupslogind =
+ "#subsys_name hierarchy num_cgroups enabled\n"
+ "cpuset 0 1 1\n"
+ "cpu 0 1 1\n"
+ "cpuacct 0 1 1\n"
+ "memory 0 1 0\n"
+ "devices 0 1 1\n"
+ "freezer 0 1 1\n"
+ "net_cls 0 1 1\n"
+ "blkio 0 1 1\n"
+ "perf_event 0 1 1\n";
+
+
+
static int make_file(const char *path,
const char *name,
const char *value)
@@ -400,18 +421,25 @@ static void init_sysfs(void)
FILE *fopen(const char *path, const char *mode)
{
const char *mock;
- bool allinone = false;
+ bool allinone = false, logind = false;
init_syms();
mock = getenv("VIR_CGROUP_MOCK_MODE");
- if (mock && STREQ(mock, "allinone"))
- allinone = true;
+ if (mock) {
+ if (STREQ(mock, "allinone"))
+ allinone = true;
+ else if (STREQ(mock, "logind"))
+ logind = true;
+ }
if (STREQ(path, "/proc/mounts")) {
if (STREQ(mode, "r")) {
if (allinone)
return fmemopen((void *)procmountsallinone,
strlen(procmountsallinone), mode);
+ else if (logind)
+ return fmemopen((void *)procmountslogind,
+ strlen(procmountslogind), mode);
else
return fmemopen((void *)procmounts, strlen(procmounts), mode);
} else {
@@ -424,6 +452,9 @@ FILE *fopen(const char *path, const char *mode)
if (allinone)
return fmemopen((void *)proccgroupsallinone,
strlen(proccgroupsallinone), mode);
+ else if (logind)
+ return fmemopen((void *)proccgroupslogind,
+ strlen(proccgroupslogind), mode);
else
return fmemopen((void *)proccgroups, strlen(proccgroups), mode);
} else {
@@ -436,6 +467,9 @@ FILE *fopen(const char *path, const char *mode)
if (allinone)
return fmemopen((void *)procselfcgroupsallinone,
strlen(procselfcgroupsallinone), mode);
+ else if (logind)
+ return fmemopen((void *)procselfcgroupslogind,
+ strlen(procselfcgroupslogind), mode);
else
return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode);
} else {
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index f12587c..570e061 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -109,6 +109,16 @@ const char *mountsAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup",
[VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
};
+const char *mountsLogind[VIR_CGROUP_CONTROLLER_LAST] = {
+ [VIR_CGROUP_CONTROLLER_CPU] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
+ [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
+ [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
+ [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
+ [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/not/really/sys/fs/cgroup/systemd",
+};
const char *links[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu",
@@ -132,6 +142,17 @@ const char *linksAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
[VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
};
+const char *linksLogind[VIR_CGROUP_CONTROLLER_LAST] = {
+ [VIR_CGROUP_CONTROLLER_CPU] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
+ [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
+ [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
+ [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
+ [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
+};
+
static int testCgroupNewForSelf(const void *args ATTRIBUTE_UNUSED)
{
@@ -466,6 +487,48 @@ cleanup:
}
+static int testCgroupNewForSelfLogind(const void *args ATTRIBUTE_UNUSED)
+{
+ virCgroupPtr cgroup = NULL;
+ int ret = -1;
+ const char *placement[VIR_CGROUP_CONTROLLER_LAST] = {
+ [VIR_CGROUP_CONTROLLER_CPU] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
+ [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
+ [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
+ [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
+ [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
+ [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
+ [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/",
+ };
+
+ if (virCgroupNewSelf(&cgroup) < 0) {
+ fprintf(stderr, "Cannot create cgroup for self\n");
+ goto cleanup;
+ }
+
+ ret = validateCgroup(cgroup, "", mountsLogind, linksLogind, placement);
+
+cleanup:
+ virCgroupFree(&cgroup);
+ return ret;
+}
+
+
+static int testCgroupAvailable(const void *args)
+{
+ bool got = virCgroupAvailable();
+ bool want = args == (void*)0x1;
+
+ if (got != want) {
+ fprintf(stderr, "Expected cgroup %savailable, but state was wrong\n",
+ want ? "" : "not ");
+ return -1;
+ }
+
+ return 0;
+}
+
# define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
@@ -505,9 +568,21 @@ mymain(void)
if (virtTestRun("New cgroup for domain partition escaped", 1, testCgroupNewForPartitionDomainEscaped, NULL) < 0)
ret = -1;
+ if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x1) < 0)
+ ret = -1;
+
setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1);
if (virtTestRun("New cgroup for self (allinone)", 1, testCgroupNewForSelfAllInOne, NULL) < 0)
ret = -1;
+ if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x1) < 0)
+ ret = -1;
+ unsetenv("VIR_CGROUP_MOCK_MODE");
+
+ setenv("VIR_CGROUP_MOCK_MODE", "logind", 1);
+ if (virtTestRun("New cgroup for self (logind)", 1, testCgroupNewForSelfLogind, NULL) < 0)
+ ret = -1;
+ if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x0) < 0)
+ ret = -1;
unsetenv("VIR_CGROUP_MOCK_MODE");
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH 0/4] Introduce APIs to extract DHCP leases info
by Nehal J Wani
This API returns the information stored in the DHCP leases file
created by dnsmasq for a given virtual network. It contacts the
bridge network driver, which parses the leases file.
It supports two methods:
1. Return info for all network interfaces connected to a given
virtual network
2. Return information for a particular network interface in a
given virtual network by providing its MAC Address
* The need for these APIs were result of a RFC was proposed on the list.
Refer: http://www.redhat.com/archives/libvir-list/2013-July/msg01603.html
Nehal J Wani (4):
net-dhcp-leases: Implement the public APIs
net-dhcp-leases: Implement the remote protocol
net-dhcp-leases: Private implementation inside network driver
net-dhcp-leases: Add virsh support
daemon/remote.c | 128 +++++++++++++++++++++++++
include/libvirt/libvirt.h.in | 22 +++++
python/generator.py | 3 +
src/driver.h | 13 +++
src/libvirt.c | 166 ++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 7 ++
src/network/bridge_driver.c | 222 +++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 117 +++++++++++++++++++++++
src/remote/remote_protocol.x | 48 +++++++++-
src/remote_protocol-structs | 27 ++++++
src/rpc/gendispatch.pl | 1 +
tools/virsh-network.c | 92 ++++++++++++++++++
tools/virsh.pod | 6 ++
13 files changed, 851 insertions(+), 1 deletion(-)
--
1.7.11.7
11 years, 2 months
[libvirt] cgroups issues when logind is running without systemd acting as init system
by Laurent Bigonville
Hi,
As explained in a bug on the debian BTS[0], I'm getting the following
backtrace on my machine when trying to start a domain:
Erreur lors du démarrage du domaine: At least one cgroup controller is required: No such device or address
Traceback (most recent call last):
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 96, in cb_wrapper
callback(asyncjob, *args, **kwargs)
File "/usr/share/virt-manager/virtManager/asyncjob.py", line 117, in tmpcb
callback(*args, **kwargs)
File "/usr/share/virt-manager/virtManager/domain.py", line 1160, in startup
self._backend.create()
File "/usr/lib/python2.7/dist-packages/libvirt.py", line 697, in create
if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirtError: At least one cgroup controller is required: No such device or address
This is only happening when /sys/fs/cgroup/systemd is being mounted by
logind while systemd is not acting as the init system.
I've been asked by danpb to report the following information on this
mailing list:
$ cat /proc/mounts|grep cgroup
none /sys/fs/cgroup tmpfs rw,rootcontext=system_u:object_r:sysfs_t:s0,seclabel,relatime,size=4k,mode=755 0 0
systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0
$ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 1 1
cpu 0 1 1
cpuacct 0 1 1
memory 0 1 0
devices 0 1 1
freezer 0 1 1
net_cls 0 1 1
blkio 0 1 1
perf_event 0 1 1
$ cat /proc/$(pidof libvirtd)/cgroup
1:name=systemd:/
I hope this will be enough to fix this issue.
Kind regards,
Laurent Bigonville
[0]http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721979
11 years, 2 months
[libvirt] [v0.9.12-maint 06/11] rpc: Fix crash on error paths of message dispatching
by Peter Krempa
This patch resolves CVE-2013-0170:
https://bugzilla.redhat.com/show_bug.cgi?id=893450
When reading and dispatching of a message failed the message was freed
but wasn't removed from the message queue.
After that when the connection was about to be closed the pointer for
the message was still present in the queue and it was passed to
virNetMessageFree which tried to call the callback function from an
uninitialized pointer.
This patch removes the message from the queue before it's freed.
* rpc/virnetserverclient.c: virNetServerClientDispatchRead:
- avoid use after free of RPC messages
(cherry picked from commit 46532e3e8ed5f5a736a02f67d6c805492f9ca720)
---
src/rpc/virnetserverclient.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 67600fd..3838136 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -840,6 +840,7 @@ readmore:
/* Decode the header so we can use it for routing decisions */
if (virNetMessageDecodeHeader(msg) < 0) {
+ virNetMessageQueueServe(&client->rx);
virNetMessageFree(msg);
client->wantClose = true;
return;
@@ -849,6 +850,7 @@ readmore:
* file descriptors */
if (msg->header.type == VIR_NET_CALL_WITH_FDS &&
virNetMessageDecodeNumFDs(msg) < 0) {
+ virNetMessageQueueServe(&client->rx);
virNetMessageFree(msg);
client->wantClose = true;
return; /* Error */
@@ -858,6 +860,7 @@ readmore:
for (i = msg->donefds ; i < msg->nfds ; i++) {
int rv;
if ((rv = virNetSocketRecvFD(client->sock, &(msg->fds[i]))) < 0) {
+ virNetMessageQueueServe(&client->rx);
virNetMessageFree(msg);
client->wantClose = true;
return;
--
1.8.4.rc3
11 years, 2 months