[libvirt] [PATCH]: Fix allocation of tapfds when starting qemu
Jim Meyering
jim at meyering.net
Thu Jun 19 10:41:02 UTC 2008
Chris Lalancette <clalance at redhat.com> wrote:
> All,
> When doing the conversion to danpb's new memory API, a small bug was
> introduced into the qemudNetworkIfaceConnect() function. In particular, there
> is a call:
>
> if (VIR_ALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
> goto no_memory;
>
> However, the tapfds structure is used to track *all* of the tap fds, and is
> called once for each network that is being attached to the domain. VIR_ALLOC_N
> maps to calloc(). So the first network would work just fine, but if you had
> more than one network, subsequent calls to this function would blow away the
> stored fd's that were already there and fill them all in with zeros. This
> causes multiple problems, from the qemu domains not starting properly to
> improper cleanup on shutdown. The attached patch just changes the VIR_ALLOC_N()
> to a VIR_REALLOC_N(), and everything is happy again.
>
> Signed-off-by: Chris Lalancette <clalance at redhat.com>
> Index: src/qemu_conf.c
> ===================================================================
> RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
> retrieving revision 1.78
> diff -u -r1.78 qemu_conf.c
> --- a/src/qemu_conf.c 13 Jun 2008 07:56:59 -0000 1.78
> +++ b/src/qemu_conf.c 19 Jun 2008 10:01:53 -0000
> @@ -2317,7 +2317,7 @@
> if (!(retval = strdup(tapfdstr)))
> goto no_memory;
>
> - if (VIR_ALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
> + if (VIR_REALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
> goto no_memory;
>
> vm->tapfds[vm->ntapfds++] = tapfd;
Yow. Another good catch.
That's obviously the right fix.
ACK.
I went looking for similar bugs and actually found one!
$ g show d3470efcda15f59549ac0aaa76cd25df319c217b \
|grep -A2 realloc|grep VIR_ALLOC
+ if (VIR_ALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
+ if (VIR_ALLOC_N(buf, alloc) < 0) {
That's in the fread_file_lim function, and the fix is the same.
To demonstrate, make virsh read a file containing more than
BUFSIZ bytes, e.g.,
Create a legit definition, but with enough spaces
at the end to push the size over the limit:
{ ./virsh -c test:///default dumpxml 1; printf %9000s ' ' } > t
Demonstrate that virsh-0.4.2 reads/parses it fine:
$ virsh --version
0.4.2
$ virsh --connect test:///default define t
Domain test defined from t
Show that just-built (pre-patch) virsh fails:
$ ./virsh --version
0.4.3
$ ./virsh --connect test:///default define t
libvir: Test error : XML description for domain is not well formed or invalid error: Failed to define domain from t
[Exit 1]
Show that patched, it works fine:
$ ./virsh --connect test:///default define t
Domain test defined from t
$
Here's the patch I'll push soon:
>From 02172b2c2e529a0afd04d5880ff8f32ad480ed9d Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering at redhat.com>
Date: Thu, 19 Jun 2008 12:36:36 +0200
Subject: [PATCH] virsh fails to read files larger than BUFSIZ bytes
* src/util.c (fread_file_lim): Use VIR_REALLOC_N, not VIR_ALLOC_N.
Bug introduced in d3470efcda15f59549ac0aaa76cd25df319c217b
---
src/util.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/util.c b/src/util.c
index ad7683d..5e50ef2 100644
--- a/src/util.c
+++ b/src/util.c
@@ -306,7 +306,7 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
if (alloc < size + BUFSIZ + 1)
alloc = size + BUFSIZ + 1;
- if (VIR_ALLOC_N(buf, alloc) < 0) {
+ if (VIR_REALLOC_N(buf, alloc) < 0) {
save_errno = errno;
break;
}
@@ -797,4 +797,3 @@ int virDiskNameToIndex(const char *name) {
return idx;
}
-
--
1.5.6.rc3.23.gc3bdd
More information about the libvir-list
mailing list