On 09/02/2013 04:25 PM, Michal Privoznik wrote: > Currently, kernel supports up to 8 queues for a multiqueue tap device. > However, if user tries to enter a huge number (e.g. one million) the tap > allocation fails, as expected. But what is not expected is the log full > of warnings: > > warning : virFileClose:83 : Tried to close invalid fd 0 > > The problem is, upon error we iterate over an array of FDs (handlers to > queues) and VIR_FORCE_CLOSE() over each item. However, the array is > pre-filled with zeros. Hence, we repeatedly close stdin. Ouch. > But there's more. The queues allocation is done in virNetDevTapCreate() > which cleans up the FDs in case of error. Then, its caller, the > virNetDevTapCreateInBridgePort() iterates over the FD array and tries to > close them too. And so does qemuNetworkIfaceConnect() and > qemuBuildInterfaceCommandLine(). > > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > src/qemu/qemu_command.c | 10 +++++++--- > src/util/virnetdevtap.c | 4 ++-- > 2 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index f8fccea..73a13b3 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -405,7 +405,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, > cleanup: > if (ret < 0) { > size_t i; > - for (i = 0; i < *tapfdSize; i++) > + for (i = 0; i < *tapfdSize && tapfd[i] >= 0; i++) > VIR_FORCE_CLOSE(tapfd[i]); > if (template_ifname) > VIR_FREE(net->ifname); > @@ -7241,6 +7241,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > VIR_ALLOC_N(tapfdName, tapfdSize) < 0) > goto cleanup; > > + memset(tapfd, -1, tapfdSize * sizeof(tapfd[0])); > + > if (qemuNetworkIfaceConnect(def, conn, driver, net, > qemuCaps, tapfd, &tapfdSize) < 0) > goto cleanup; > @@ -7268,6 +7270,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > VIR_ALLOC_N(vhostfdName, vhostfdSize)) > goto cleanup; > > + memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0])); > + Just a question; are these non-standard settings necessary when we close only non-zero fds? > if (qemuOpenVhostNet(def, net, qemuCaps, vhostfd, &vhostfdSize) < 0) > goto cleanup; > } > @@ -7329,13 +7333,13 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > cleanup: > if (ret < 0) > virDomainConfNWFilterTeardown(net); > - for (i = 0; tapfd && i < tapfdSize; i++) { > + for (i = 0; tapfd && i < tapfdSize && tapfd[i] >= 0; i++) { > if (ret < 0) > VIR_FORCE_CLOSE(tapfd[i]); > if (tapfdName) > VIR_FREE(tapfdName[i]); > } > - for (i = 0; vhostfd && i < vhostfdSize; i++) { > + for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) { > if (ret < 0) > VIR_FORCE_CLOSE(vhostfd[i]); > if (vhostfdName) > diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c > index 42e8dfe..dc2c224 100644 > --- a/src/util/virnetdevtap.c > +++ b/src/util/virnetdevtap.c > @@ -498,8 +498,8 @@ int virNetDevTapCreateInBridgePort(const char *brname, > return 0; > > error: > - while (tapfdSize) > - VIR_FORCE_CLOSE(tapfd[--tapfdSize]); > + while (tapfdSize && tapfd[--tapfdSize] >= 0) > + VIR_FORCE_CLOSE(tapfd[tapfdSize]); This will not close anything in case the array looks like this: [ 4, 5, 6, 7, 0, 0, 0, 0 ] I suggest modifying it to the same for as in those other cases. ACK with that fixed, Martin -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list