[libvirt PATCH 1/3] util: make locking versions of virNetDevMacVLan(Reserve|Release)Name()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When these functions are called from within virnetdevmacvlan.c, they
are usually called with virNetDevMacVLanCreateMutex held, but when
virNetDevMacVLanReserveName() is called from other places (hypervisor
drivers keeping track of already-in-use macvlan/macvtap devices) the
lock isn't acquired. This could lead to a situation where one thread
is setting a bit in the bitmap to notify of a device already in-use,
while another thread is checking/setting/clearing a bit while creating
a new macvtap device.

In practice this *probably* doesn't happen, because the external calls
to virNetDevMacVLan() only happen during hypervisor driver init
routines when libvirtd is restarted, but there's no harm in protecting
ourselves.

(NB: virNetDevMacVLanReleaseName() is actually never called from
outside virnetdevmacvlan.c, so it could just as well be static, but
I'm leaving it as-is for now. This locking version *is* called
from within virnetdevmacvlan.c, since there are a couple places that
we used to call the unlocked version after the lock was already
released.)

Signed-off-by: Laine Stump <laine@xxxxxxxxxx>
---
 src/util/virnetdevmacvlan.c | 42 ++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index dcea93a5fe..69a9c784bb 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -196,7 +196,7 @@ virNetDevMacVLanReleaseID(int id, unsigned int flags)
 
 
 /**
- * virNetDevMacVLanReserveName:
+ * virNetDevMacVLanReserveNameInternal:
  *
  *  @name: already-known name of device
  *  @quietFail: don't log an error if this name is already in-use
@@ -208,8 +208,8 @@ virNetDevMacVLanReleaseID(int id, unsigned int flags)
  *  Returns reserved ID# on success, -1 on failure, -2 if the name
  *  doesn't fit the auto-pattern (so not reserveable).
  */
-int
-virNetDevMacVLanReserveName(const char *name, bool quietFail)
+static int
+virNetDevMacVLanReserveNameInternal(const char *name, bool quietFail)
 {
     unsigned int id;
     unsigned int flags = 0;
@@ -237,8 +237,21 @@ virNetDevMacVLanReserveName(const char *name, bool quietFail)
 }
 
 
+int
+virNetDevMacVLanReserveName(const char *name, bool quietFail)
+{
+    /* Call the internal function after locking the macvlan mutex */
+    int ret;
+
+    virMutexLock(&virNetDevMacVLanCreateMutex);
+    ret = virNetDevMacVLanReserveNameInternal(name, quietFail);
+    virMutexUnlock(&virNetDevMacVLanCreateMutex);
+    return ret;
+}
+
+
 /**
- * virNetDevMacVLanReleaseName:
+ * virNetDevMacVLanReleaseNameInternal:
  *
  *  @name: already-known name of device
  *
@@ -248,8 +261,8 @@ virNetDevMacVLanReserveName(const char *name, bool quietFail)
  *
  *  returns 0 on success, -1 on failure
  */
-int
-virNetDevMacVLanReleaseName(const char *name)
+static int
+virNetDevMacVLanReleaseNameInternal(const char *name)
 {
     unsigned int id;
     unsigned int flags = 0;
@@ -277,6 +290,19 @@ virNetDevMacVLanReleaseName(const char *name)
 }
 
 
+int
+virNetDevMacVLanReleaseName(const char *name)
+{
+    /* Call the internal function after locking the macvlan mutex */
+    int ret;
+
+    virMutexLock(&virNetDevMacVLanCreateMutex);
+    ret = virNetDevMacVLanReleaseNameInternal(name);
+    virMutexUnlock(&virNetDevMacVLanCreateMutex);
+    return ret;
+}
+
+
 /**
  * virNetDevMacVLanIsMacvtap:
  * @ifname: Name of the interface
@@ -967,7 +993,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
             return -1;
         }
         if (isAutoName &&
-            (reservedID = virNetDevMacVLanReserveName(ifnameRequested, true)) < 0) {
+            (reservedID = virNetDevMacVLanReserveNameInternal(ifnameRequested, true)) < 0) {
             reservedID = -1;
             goto create_name;
         }
@@ -975,7 +1001,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
         if (virNetDevMacVLanCreate(ifnameRequested, type, macaddress,
                                    linkdev, macvtapMode, &do_retry) < 0) {
             if (isAutoName) {
-                virNetDevMacVLanReleaseName(ifnameRequested);
+                virNetDevMacVLanReleaseNameInternal(ifnameRequested);
                 reservedID = -1;
                 goto create_name;
             }
-- 
2.26.2




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux