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

[Libguestfs] [PATCH 2/2] appliance: Make appliance building thread-safe (RHBZ#790721).



From: "Richard W.M. Jones" <rjones redhat com>

Appliance building can be called from multiple processes, but this is
only safe if each process holds a lock on the 'checksum' file.
However threads within a process are not excluded by a file lock, and
so this strategy completely failed for a multithreaded program calling
guestfs_launch in parallel.

Since it makes no sense for threads in a single program to race each
other to try to create the appliance, add a lock around appliance
building.

This serialises building the appliance, but the rest of guestfs_launch
(eg. starting up qemu) can run in parallel.
---
 src/launch.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/src/launch.c b/src/launch.c
index 4e2fba9..124e758 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -477,6 +477,13 @@ guestfs__launch (guestfs_h *g)
   }
 }
 
+/* RHBZ#790721: It makes no sense to have multiple threads racing to
+ * build the appliance from within a single process, and the code
+ * isn't safe for that anyway.  Therefore put a thread lock around
+ * appliance building.
+ */
+gl_lock_define_initialized (static, building_lock);
+
 static int
 launch_appliance (guestfs_h *g)
 {
@@ -501,8 +508,12 @@ launch_appliance (guestfs_h *g)
 
   /* Locate and/or build the appliance. */
   char *kernel = NULL, *initrd = NULL, *appliance = NULL;
-  if (guestfs___build_appliance (g, &kernel, &initrd, &appliance) == -1)
+  gl_lock_lock (building_lock);
+  if (guestfs___build_appliance (g, &kernel, &initrd, &appliance) == -1) {
+    gl_lock_unlock (building_lock);
     return -1;
+  }
+  gl_lock_unlock (building_lock);
 
   TRACE0 (launch_build_appliance_end);
 
-- 
1.7.9


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