[libvirt] [PATCH] random: don't mix RAND_MAX with random_r
by Eric Blake
FreeBSD 10 recently changed their definition of RAND_MAX, to try
and cover the fact that their evenly distributed results really are
a smaller range than a full power of 2. As a result, I did some
investigation, and learned:
1. POSIX requires random() to be evenly distributed across exactly
31 bits. glibc also guarantees this for rand(), but the two are
unrelated, and POSIX only associates RAND_MAX with rand().
Avoiding RAND_MAX altogether thus avoids a build failure on
FreeBSD 10.
2. Concatenating random bits from a PRNG will NOT provide uniform
coverage over the larger value UNLESS the period of the original
PRNG is at least as large as the number of bits being concatenated.
Simple example: suppose that RAND_MAX were 1 with a period of 2**1
(which means that the PRNG merely alternates between 0 and 1).
Concatenating two successive rand() calls would then invariably
result in 01 or 10, which is a rather non-uniform distribution
(00 and 11 are impossible) and an even worse period (2**0, since
our second attempt will get the same number as our first attempt).
But a RAND_MAX of 1 with a period of 2**2 (alternating between
0, 1, 1, 0) provides sane coverage of all four values, if properly
tempered. (Back-to-back calls would still only see half the values
if we don't do some tempering). We therefore want to guarantee a
period of at least 2**64, preferably larger (as a tempering factor);
POSIX only makes this guarantee for random() with 256 bytes of info.
* src/util/virrandom.c (virRandomBits): Use constants that are
accurate for the PRNG we are using, not an unrelated PRNG.
(randomState): Ensure the period of our PRNG exceeds our usage.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/util/virrandom.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/src/util/virrandom.c b/src/util/virrandom.c
index c233732..0e368b0 100644
--- a/src/util/virrandom.c
+++ b/src/util/virrandom.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -36,7 +36,7 @@
#define VIR_FROM_THIS VIR_FROM_NONE
-static char randomState[128];
+static char randomState[256];
static struct random_data randomData;
static virMutex randomLock;
@@ -70,0 +70,0 @@ virRandomOnceInit(void)
VIR_ONCE_GLOBAL_INIT(virRandom)
-/* The algorithm of virRandomBits requires that RAND_MAX == 2^n-1 for
- * some n; gnulib's random_r meets this property. */
-verify(((RAND_MAX + 1U) & RAND_MAX) == 0);
+/* The algorithm of virRandomBits relies on gnulib's guarantee that
+ * random_r() matches the POSIX requirements on random() of being
+ * evenly distributed among exactly [0, 2**31) (that is, we always get
+ * exactly 31 bits). While this happens to be the value of RAND_MAX
+ * on glibc, note that POSIX only requires RAND_MAX to be tied to the
+ * weaker rand(), so there are platforms where RAND_MAX is smaller
+ * than the range of random_r(). For the results to be evenly
+ * distributed among up to 64 bits, we also rely on the period of
+ * random_r() to be at least 2**64. */
+enum {
+ RANDOM_BITS_PER_ITER = 31,
+ RANDOM_BITS_MASK = (1U << RANDOM_BITS_PER_ITER) - 1,
+};
/**
* virRandomBits:
@@ -85,7 +95,6 @@ verify(((RAND_MAX + 1U) & RAND_MAX) == 0);
*/
uint64_t virRandomBits(int nbits)
{
- int bits_per_iter = count_one_bits(RAND_MAX);
uint64_t ret = 0;
int32_t bits;
@@ -98,10 +107,10 @@ uint64_t virRandomBits(int nbits)
virMutexLock(&randomLock);
- while (nbits > bits_per_iter) {
+ while (nbits > RANDOM_BITS_PER_ITER) {
random_r(&randomData, &bits);
- ret = (ret << bits_per_iter) | (bits & RAND_MAX);
- nbits -= bits_per_iter;
+ ret = (ret << RANDOM_BITS_PER_ITER) | (bits & RANDOM_BITS_MASK);
+ nbits -= RANDOM_BITS_PER_ITER;
}
random_r(&randomData, &bits);
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH 00/12] Ensure array bounds checking is present on all RPC calls
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Missing bounds checking on array parameters is a security
issue for libvirtd, since it allows a client to make libvirtd
allocate unbounded memory.
Missing bounds checking on array return values is not a security
issue, but it is a robustness issue. If the RPC stream somehow
got corrupted, the client could end up allocating unbounded
memory.
The first patch in this series fixes the security flaw introduced
in version 1.1.0, and indentified during discussion of this patch:
https://www.redhat.com/archives/libvir-list/2013-August/msg00787.html
The remaining patches address the robustness issues, and add a test
suite to prevent this flaw recurring.
Daniel P. Berrange (12):
Add bounds checking on virDomainMigrate*Params RPC calls
(CVE-2013-4292)
Add bounds checking on virDomainGetJobStats RPC call
Add bounds checking on
virDomain{SnapshotListAllChildren,ListAllSnapshots} RPC calls
Add bounds checking on virConnectListAllDomains RPC call
Add bounds checking on virConnectListAllStoragePools RPC call
Add bounds checking on virStoragePoolListAllVolumes RPC call
Add bounds checking on virConnectListAllNetworks RPC call
Add bounds checking on virConnectListAllInterfaces RPC call
Add bounds checking on virConnectListAllNodeDevices RPC call
Add bounds checking on virConnectListAllNWFilters RPC call
Add bounds checking on virConnectListAllSecrets RPC call
Prohibit unbounded arrays in XDR protocols
cfg.mk | 6 ++
daemon/remote.c | 119 +++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 130 +++++++++++++++++++++++++++++++++++++++++--
src/remote/remote_protocol.x | 108 ++++++++++++++++++-----------------
4 files changed, 304 insertions(+), 59 deletions(-)
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] security: provide supplemental groups even when parsing label (CVE-2013-4291)
by Eric Blake
Commit 29fe5d7 (released in 1.1.1) introduced a latent problem
for any caller of virSecurityManagerSetProcessLabel and where
the domain already had a uid:gid label to be parsed. Such a
setup would collect the list of supplementary groups during
virSecurityManagerPreFork, but then ignores that information,
and thus fails to call setgroups() to adjust the supplementary
groups of the process.
Upstream does not use virSecurityManagerSetProcessLabel for
qemu (it uses virSecurityManagerSetChildProcessLabel instead),
so this problem remained latent until backporting the initial
commit into v0.10.2-maint (commit c061ff5, released in 0.10.2.7),
where virSecurityManagerSetChildProcessLabel has not been
backported. As a result of using a different code path in the
backport, attempts to start a qemu domain that runs as qemu:qemu
will end up with supplementary groups unchanged from the libvirtd
parent process, rather than the desired supplementary groups of
the qemu user. This can lead to failure to start a domain
(typical Fedora setup assigns user 107 'qemu' to both group 107
'qemu' and group 36 'kvm', so a disk image that is only readable
under kvm group rights is locked out). Worse, it is a security
hole (the qemu process will inherit supplemental group rights
from the parent libvirtd process, which means it has access
rights to files owned by group 0 even when such files should
not normally be visible to user qemu).
https://bugzilla.redhat.com/show_bug.cgi?id=964359 first demonstrated
the problem of broken permissions in qemu when using a build based
on 0.10.2.
LXC does not use the DAC security driver, so it is not vulnerable
at this time. Still, it is better to plug the latent hole on
the master branch first, before cherry-picking it to the only
vulnerable branch v0.10.2-maint.
* src/security/security_dac.c (virSecurityDACGetIds): Always populate
groups and ngroups, rather than only when no label is parsed.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/security/security_dac.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8cbb083..6876bd5 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -115,13 +115,13 @@ virSecurityDACGetIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
return -1;
}
- if ((ret = virSecurityDACParseIds(def, uidPtr, gidPtr)) <= 0) {
- if (groups)
- *groups = NULL;
- if (ngroups)
- *ngroups = 0;
+ if (groups)
+ *groups = priv ? priv->groups : NULL;
+ if (ngroups)
+ *ngroups = priv ? priv->ngroups : 0;
+
+ if ((ret = virSecurityDACParseIds(def, uidPtr, gidPtr)) <= 0)
return ret;
- }
if (!priv) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -134,10 +134,6 @@ virSecurityDACGetIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
*uidPtr = priv->user;
if (gidPtr)
*gidPtr = priv->group;
- if (groups)
- *groups = priv->groups;
- if (ngroups)
- *ngroups = priv->ngroups;
return 0;
}
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] Fix a PyList usage mistake
by Guan Qiang
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
Fix PyList usage mistake in Function libvirt_lxc_virDomainLxcOpenNamespace.
https://bugzilla.redhat.com/show_bug.cgi?id=1002383
---
python/libvirt-lxc-override.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/libvirt-lxc-override.c b/python/libvirt-lxc-override.c
index 73685df..fa7e963 100644
--- a/python/libvirt-lxc-override.c
+++ b/python/libvirt-lxc-override.c
@@ -80,7 +80,7 @@ libvirt_lxc_virDomainLxcOpenNamespace(PyObject *self ATTRIBUTE_UNUSED,
if (c_retval < 0)
return VIR_PY_NONE;
- py_retval = PyList_New(c_retval);
+ py_retval = PyList_New(0);
for (i = 0; i < c_retval; i++) {
PyObject *item = NULL;
--
1.7.10.4
11 years, 1 month
[libvirt] [PATCHv2] virNetDevVethCreate: assign container if name based on parent if name
by Oskari Saarenmaa
Replace the loop trying to find a free veth interface name for the container
by assigning the container if name to parent name + 'p' by default.
Interface name selection logic is susceptible to race conditions, so try to
select just one name by default and use that as a template for the second
name. The parent name can also be overriden in domain configuration.
Signed-off-by: Oskari Saarenmaa <os(a)ohmu.fi>
---
v2: generate first name as before (if it wasn't given by the caller), and
use the parent if name as a template for the container if name so that the
caller doesn't have to select two names (which is not possible at the
moment.)
src/util/virnetdevveth.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
index 039767f..91e2829 100644
--- a/src/util/virnetdevveth.c
+++ b/src/util/virnetdevveth.c
@@ -114,20 +114,14 @@ int virNetDevVethCreate(char** veth1, char** veth2)
}
argv[3] = *veth1;
- while (*veth2 == NULL) {
- if ((vethDev = virNetDevVethGetFreeName(veth2, vethDev)) < 0) {
+ if (*veth2 == NULL) {
+ /* Append a 'p' to veth1 if name */
+ if (virAsprintf(veth2, "%sp", *veth1) < 0) {
if (veth1_alloc)
VIR_FREE(*veth1);
goto cleanup;
}
- /* Just make sure they didn't accidentally get same name */
- if (STREQ(*veth1, *veth2)) {
- vethDev++;
- VIR_FREE(*veth2);
- continue;
- }
-
VIR_DEBUG("Assigned guest: %s", *veth2);
veth2_alloc = true;
}
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] autogen.sh: Correctly detect .git as a file
by Michal Privoznik
One of my previous patches 5cfe0d37cd0be tried to handle the case when
libvirt is a submodule of another project. In that case, the .git is
just a link to the parent .git directory (which the autogen.sh script
didn't count on). The fix was missing 'test' though.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
autogen.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/autogen.sh b/autogen.sh
index f7c2022..5aa1990 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -64,7 +64,7 @@ bootstrap_hash()
# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
# the required file po/Makevars.
# Only run bootstrap from a git checkout, never from a tarball.
-if test -d .git || -f .git; then
+if test -d .git || test -f .git; then
curr_status=.git-module-status t=
if test "$no_git"; then
t=no-git
--
1.8.1.5
11 years, 1 month
[libvirt] Question about how to contribute patches
by hzguanqiang@corp.netease.com
Hi exports,
I tried to contribute a patch to fix a bug, following the contributor guidelines
on http://libvirt.org/hacking.html.
After I do the 'git send-email' operation and edit the email content, It returns:
Who should the emails appear to be from? [Guan Qiang <hzguanqiang(a)corp.netease.com>]
Emails will be sent from: Guan Qiang <hzguanqiang(a)corp.netease.com>
Message-ID to be used as In-Reply-To for the first email?
(mbox) Adding cc: Guan Qiang <hzguanqiang(a)corp.netease.com> from line 'From: Guan Qiang <hzguanqiang(a)corp.netease.com>'
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
To: libvir-list(a)redhat.com
Cc: Guan Qiang <hzguanqiang(a)corp.netease.com>
Subject: [PATCH]Fix a PyList usage mistake
Date: Thu, 29 Aug 2013 13:41:38 +0800
Message-Id: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
X-Mailer: git-send-email 1.7.10.4
The Cc list above has been expanded by additional
addresses found in the patch commit message. By default
send-email prompts before sending whenever this occurs.
This behavior is controlled by the sendemail.confirm
configuration setting.
For additional information, run 'git send-email --help'.
To retain the current behavior, but squelch this message,
run 'git config --global sendemail.confirm auto'.
Send this email? ([y]es|[n]o|[q]uit|[a]ll): y
OK. Log says:
Sendmail: /usr/sbin/sendmail -i libvir-list(a)redhat.com hzguanqiang(a)corp.netease.com
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
To: libvir-list(a)redhat.com
Cc: Guan Qiang <hzguanqiang(a)corp.netease.com>
Subject: [PATCH]Fix a PyList usage mistake
Date: Thu, 29 Aug 2013 13:41:38 +0800
Message-Id: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
X-Mailer: git-send-email 1.7.10.4
Result: OK
(mbox) Adding cc: Guan Qiang <hzguanqiang(a)corp.netease.com> from line 'From: Guan Qiang <hzguanqiang(a)corp.netease.com>'
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
To: libvir-list(a)redhat.com
Cc: Guan Qiang <hzguanqiang(a)corp.netease.com>
Subject: [PATCH] Fix a PyList usage mistake
Date: Thu, 29 Aug 2013 13:41:39 +0800
Message-Id: <1377754899-29698-2-git-send-email-hzguanqiang(a)corp.netease.com>
X-Mailer: git-send-email 1.7.10.4
In-Reply-To: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
References: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
Send this email? ([y]es|[n]o|[q]uit|[a]ll): y
OK. Log says:
Sendmail: /usr/sbin/sendmail -i libvir-list(a)redhat.com hzguanqiang(a)corp.netease.com
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
To: libvir-list(a)redhat.com
Cc: Guan Qiang <hzguanqiang(a)corp.netease.com>
Subject: [PATCH] Fix a PyList usage mistake
Date: Thu, 29 Aug 2013 13:41:39 +0800
Message-Id: <1377754899-29698-2-git-send-email-hzguanqiang(a)corp.netease.com>
X-Mailer: git-send-email 1.7.10.4
In-Reply-To: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
References: <1377754899-29698-1-git-send-email-hzguanqiang(a)corp.netease.com>
Result: OK
Does this mean everything is done? Or do I still need to do other thing?
Since I do this operation, It had passed three hours and I still can't find my patch email on 'libvir-list'.
Really appreciate your advice, Thanks.
------------------
Best regards!
GuanQiang
2013-08-29
11 years, 1 month
[libvirt] [PATCH] virNetDevVethCreate: assign names based on mac address by default
by Oskari Saarenmaa
Interface names do not have to be numerical (or veth + number) and trying to
assign them to that format is susceptible to race conditions. Instead,
assign the parent interface name according to the mac address (the last
three bytes) if no name was given by the caller and use the parent interface
name plus 'p' for the container name.
Signed-off-by: Oskari Saarenmaa <os(a)ohmu.fi>
---
src/lxc/lxc_process.c | 2 +-
src/util/virnetdevveth.c | 81 +++++++++---------------------------------------
src/util/virnetdevveth.h | 6 ++--
3 files changed, 19 insertions(+), 70 deletions(-)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 4835bd5..956bbdb 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -243,7 +243,7 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn,
VIR_DEBUG("calling vethCreate()");
parentVeth = net->ifname;
- if (virNetDevVethCreate(&parentVeth, &containerVeth) < 0)
+ if (virNetDevVethCreate(&parentVeth, &containerVeth, &net->mac) < 0)
goto cleanup;
VIR_DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);
diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
index 039767f..c0e3e93 100644
--- a/src/util/virnetdevveth.c
+++ b/src/util/virnetdevveth.c
@@ -38,96 +38,46 @@
/* Functions */
/**
- * virNetDevVethGetFreeName:
- * @veth: pointer to store returned name for veth device
- * @startDev: device number to start at (x in vethx)
- *
- * Looks in /sys/class/net/ to find the first available veth device
- * name.
- *
- * Returns non-negative device number on success or -1 in case of error
- */
-static int virNetDevVethGetFreeName(char **veth, int startDev)
-{
- int devNum = startDev-1;
- char *path = NULL;
-
- VIR_DEBUG("Find free from veth%d", startDev);
- do {
- VIR_FREE(path);
- ++devNum;
- if (virAsprintf(&path, "/sys/class/net/veth%d/", devNum) < 0)
- return -1;
- VIR_DEBUG("Probe %s", path);
- } while (virFileExists(path));
- VIR_FREE(path);
-
- if (virAsprintf(veth, "veth%d", devNum) < 0)
- return -1;
-
- return devNum;
-}
-
-/**
* virNetDevVethCreate:
* @veth1: pointer to name for parent end of veth pair
* @veth2: pointer to return name for container end of veth pair
+ * @mac: mac address of the device
*
* Creates a veth device pair using the ip command:
* ip link add veth1 type veth peer name veth2
- * If veth1 points to NULL on entry, it will be a valid interface on
- * return. veth2 should point to NULL on entry.
*
- * NOTE: If veth1 and veth2 names are not specified, ip will auto assign
- * names. There seems to be two problems here -
- * 1) There doesn't seem to be a way to determine the names of the
- * devices that it creates. They show up in ip link show and
- * under /sys/class/net/ however there is no guarantee that they
- * are the devices that this process just created.
- * 2) Once one of the veth devices is moved to another namespace, it
- * is no longer visible in the parent namespace. This seems to
- * confuse the name assignment causing it to fail with File exists.
- * Because of these issues, this function currently allocates names
- * prior to using the ip command, and returns any allocated names
- * to the caller.
+ * If veth1 or veth2 points to NULL on entry, they will be a valid interface
+ * on return. The name is generated based on the mac address given.
*
* Returns 0 on success or -1 in case of error
*/
-int virNetDevVethCreate(char** veth1, char** veth2)
+int virNetDevVethCreate(char** veth1, char** veth2, const virMacAddrPtr mac)
{
- int rc = -1;
const char *argv[] = {
"ip", "link", "add", NULL, "type", "veth", "peer", "name", NULL, NULL
};
- int vethDev = 0;
bool veth1_alloc = false;
bool veth2_alloc = false;
VIR_DEBUG("Host: %s guest: %s", NULLSTR(*veth1), NULLSTR(*veth2));
if (*veth1 == NULL) {
- if ((vethDev = virNetDevVethGetFreeName(veth1, vethDev)) < 0)
- goto cleanup;
+ /* Use the last three bytes of the mac address as our if name */
+ if (virAsprintf(veth1, "veth%02x%02x%02x",
+ mac->addr[3], mac->addr[4], mac->addr[5]) < 0)
+ return -1;
VIR_DEBUG("Assigned host: %s", *veth1);
veth1_alloc = true;
- vethDev++;
}
argv[3] = *veth1;
- while (*veth2 == NULL) {
- if ((vethDev = virNetDevVethGetFreeName(veth2, vethDev)) < 0) {
+ if (*veth2 == NULL) {
+ /* Append a 'p' to veth1 if name */
+ if (virAsprintf(veth2, "%sp", *veth1) < 0) {
if (veth1_alloc)
VIR_FREE(*veth1);
- goto cleanup;
- }
-
- /* Just make sure they didn't accidentally get same name */
- if (STREQ(*veth1, *veth2)) {
- vethDev++;
- VIR_FREE(*veth2);
- continue;
+ return -1;
}
-
VIR_DEBUG("Assigned guest: %s", *veth2);
veth2_alloc = true;
}
@@ -139,13 +89,10 @@ int virNetDevVethCreate(char** veth1, char** veth2)
VIR_FREE(*veth1);
if (veth2_alloc)
VIR_FREE(*veth2);
- goto cleanup;
+ return -1;
}
- rc = 0;
-
-cleanup:
- return rc;
+ return 0;
}
/**
diff --git a/src/util/virnetdevveth.h b/src/util/virnetdevveth.h
index 4c220c1..175fbfa 100644
--- a/src/util/virnetdevveth.h
+++ b/src/util/virnetdevveth.h
@@ -25,10 +25,12 @@
# define __VIR_NETDEV_VETH_H__
# include "internal.h"
+# include "virmacaddr.h"
/* Function declarations */
-int virNetDevVethCreate(char **veth1, char **veth2)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+int virNetDevVethCreate(char **veth1, char **veth2, const virMacAddrPtr mac)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ ATTRIBUTE_RETURN_CHECK;
int virNetDevVethDelete(const char *veth)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
--
1.8.3.1
11 years, 1 month
[libvirt] [PATCH] bridge_driver: Introduce networkObjFromNetwork
by Michal Privoznik
Similarly to qemu_driver.c, we can join often repeating code of looking
up network into one function: networkObjFromNetwork.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/network/bridge_driver.c | 76 ++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 45 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 62ae0b7..3a8be90 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -112,6 +112,27 @@ static int networkUnplugBandwidth(virNetworkObjPtr net,
static virNetworkDriverStatePtr driverState = NULL;
+static virNetworkObjPtr
+networkObjFromNetwork(virNetworkPtr net)
+{
+ virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
+ virNetworkObjPtr network;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ networkDriverLock(driver);
+ network = virNetworkFindByUUID(&driver->networks, net->uuid);
+ networkDriverUnlock(driver);
+
+ if (!network) {
+ virUUIDFormat(net->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_NETWORK,
+ _("no network with matching uuid '%s' (%s)"),
+ uuidstr, net->name);
+ }
+
+ return network;
+}
+
static char *
networkDnsmasqLeaseFileNameDefault(const char *netname)
{
@@ -2260,20 +2281,14 @@ cleanup:
static int networkIsActive(virNetworkPtr net)
{
- virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
virNetworkObjPtr obj;
int ret = -1;
- networkDriverLock(driver);
- obj = virNetworkFindByUUID(&driver->networks, net->uuid);
- networkDriverUnlock(driver);
- if (!obj) {
- virReportError(VIR_ERR_NO_NETWORK, NULL);
- goto cleanup;
- }
+ if (!(obj = networkObjFromNetwork(net)))
+ return ret;
if (virNetworkIsActiveEnsureACL(net->conn, obj->def) < 0)
goto cleanup;
ret = virNetworkObjIsActive(obj);
@@ -2285,20 +2300,14 @@ cleanup:
static int networkIsPersistent(virNetworkPtr net)
{
- virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
virNetworkObjPtr obj;
int ret = -1;
- networkDriverLock(driver);
- obj = virNetworkFindByUUID(&driver->networks, net->uuid);
- networkDriverUnlock(driver);
- if (!obj) {
- virReportError(VIR_ERR_NO_NETWORK, NULL);
- goto cleanup;
- }
+ if (!(obj = networkObjFromNetwork(net)))
+ return ret;
if (virNetworkIsPersistentEnsureACL(net->conn, obj->def) < 0)
goto cleanup;
ret = obj->persistent;
@@ -2832,30 +2841,22 @@ cleanup:
static char *networkGetXMLDesc(virNetworkPtr net,
unsigned int flags)
{
- virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
virNetworkObjPtr network;
virNetworkDefPtr def;
char *ret = NULL;
virCheckFlags(VIR_NETWORK_XML_INACTIVE, NULL);
- networkDriverLock(driver);
- network = virNetworkFindByUUID(&driver->networks, net->uuid);
- networkDriverUnlock(driver);
-
- if (!network) {
- virReportError(VIR_ERR_NO_NETWORK,
- "%s", _("no network with matching uuid"));
- goto cleanup;
- }
+ if (!(network = networkObjFromNetwork(net)))
+ return ret;
if (virNetworkGetXMLDescEnsureACL(net->conn, network->def) < 0)
goto cleanup;
if ((flags & VIR_NETWORK_XML_INACTIVE) && network->newDef)
def = network->newDef;
else
def = network->def;
ret = virNetworkDefFormat(def, flags);
@@ -2866,29 +2867,21 @@ cleanup:
}
static char *networkGetBridgeName(virNetworkPtr net) {
- virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
virNetworkObjPtr network;
char *bridge = NULL;
- networkDriverLock(driver);
- network = virNetworkFindByUUID(&driver->networks, net->uuid);
- networkDriverUnlock(driver);
-
- if (!network) {
- virReportError(VIR_ERR_NO_NETWORK,
- "%s", _("no network with matching id"));
- goto cleanup;
- }
+ if (!(network = networkObjFromNetwork(net)))
+ return bridge;
if (virNetworkGetBridgeNameEnsureACL(net->conn, network->def) < 0)
goto cleanup;
if (!(network->def->bridge)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' does not have a bridge name."),
network->def->name);
goto cleanup;
}
ignore_value(VIR_STRDUP(bridge, network->def->bridge));
@@ -2900,22 +2893,15 @@ cleanup:
static int networkGetAutostart(virNetworkPtr net,
int *autostart) {
- virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
virNetworkObjPtr network;
int ret = -1;
- networkDriverLock(driver);
- network = virNetworkFindByUUID(&driver->networks, net->uuid);
- networkDriverUnlock(driver);
- if (!network) {
- virReportError(VIR_ERR_NO_NETWORK,
- "%s", _("no network with matching uuid"));
- goto cleanup;
- }
+ if (!(network = networkObjFromNetwork(net)))
+ return ret;
if (virNetworkGetAutostartEnsureACL(net->conn, network->def) < 0)
goto cleanup;
*autostart = network->autostart;
ret = 0;
--
1.8.1.5
11 years, 1 month