[lxc-devel] [lxd/master] storage: bugfixes + improvements

brauner on Github lxc-bot at linuxcontainers.org
Thu Feb 16 11:27:07 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170216/5cc2502d/attachment.bin>
-------------- next part --------------
From 13bb200194d276d4da68d1c17271a6edad830f44 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 16 Feb 2017 12:05:27 +0100
Subject: [PATCH 1/2] storage: rename and add opcode functions

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 45 +++++++++++++++++++++++++++------
 lxd/storage_btrfs.go | 70 +++++++++++++++++++++++++++++++++++++++++++++-------
 lxd/storage_lvm.go   | 54 ++++++++++++++++++++--------------------
 lxd/storage_zfs.go   | 54 ++++++++++++++++++++--------------------
 4 files changed, 153 insertions(+), 70 deletions(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index 9023031..d7fc441 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -22,10 +22,44 @@ import (
 	log "gopkg.in/inconshreveable/log15.v2"
 )
 
-var lxdStorageLockMap = map[string]chan bool{}
-var lxdStorageLock sync.Mutex
+// lxdStorageLockMap is a hashmap that allows functions to check whether the
+// operation they are about to perform is already in progress. If it is the
+// channel can be used to wait for the operation to finish. If it is not, the
+// function that wants to perform the operation should store its code in the
+// hashmap.
+// Note that any access to this map must be done while holding a lock.
+var lxdStorageOngoingOperationMap = map[string]chan bool{}
 
-/* Some interesting filesystems */
+// lxdStorageMapLock is used to access lxdStorageOngoingOperationMap.
+var lxdStorageMapLock sync.Mutex
+
+// The following functions are used to construct simple operation codes that are
+// unique.
+func getPoolMountLockID(poolName string) string {
+	return fmt.Sprintf("mount/pool/%s", poolName)
+}
+
+func getPoolUmountLockID(poolName string) string {
+	return fmt.Sprintf("umount/pool/%s", poolName)
+}
+
+func getImageMountLockID(poolName string, fingerprint string) string {
+	return fmt.Sprintf("mount/image/%s/%s", poolName, fingerprint)
+}
+
+func getImageUmountLockID(poolName string, fingerprint string) string {
+	return fmt.Sprintf("umount/image/%s/%s", poolName, fingerprint)
+}
+
+func getContainerMountLockID(poolName string, containerName string) string {
+	return fmt.Sprintf("mount/container/%s/%s", poolName, containerName)
+}
+
+func getContainerUmountLockID(poolName string, containerName string) string {
+	return fmt.Sprintf("umount/container/%s/%s", poolName, containerName)
+}
+
+// Filesystem magic numbers
 const (
 	filesystemSuperMagicTmpfs = 0x01021994
 	filesystemSuperMagicExt4  = 0xEF53
@@ -34,10 +68,7 @@ const (
 	filesystemSuperMagicZfs   = 0x2fc12fc1
 )
 
-/*
- * filesystemDetect returns the filesystem on which
- * the passed-in path sits
- */
+// filesystemDetect returns the filesystem on which the passed-in path sits.
 func filesystemDetect(path string) (string, error) {
 	fs := syscall.Statfs_t{}
 
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index ed3fa6b..dcae1f3 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -304,6 +304,32 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
+	poolMountLockID := fmt.Sprintf("mount/pool/%s", s.pool.Name)
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
+		lxdStorageMapLock.Unlock()
+		if _, ok := <-waitChannel; ok {
+			shared.LogWarnf("Value transmitted over image lock semaphore?")
+		}
+		// Give the benefit of the doubt and assume that the other
+		// thread actually succeeded in mounting the storage pool.
+		return false, nil
+	}
+
+	lxdStorageOngoingOperationMap[poolMountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
+
+	removeLockFromMap := func() {
+		lxdStorageMapLock.Lock()
+		if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
+			close(waitChannel)
+			delete(lxdStorageOngoingOperationMap, poolMountLockID)
+		}
+		lxdStorageMapLock.Unlock()
+	}
+
+	defer removeLockFromMap()
+
 	// Check whether the mount poolMntPoint exits.
 	if !shared.PathExists(poolMntPoint) {
 		err := os.MkdirAll(poolMntPoint, 0711)
@@ -360,6 +386,32 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
+	poolUmountLockID := fmt.Sprintf("umount/pool/%s", s.pool.Name)
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
+		lxdStorageMapLock.Unlock()
+		if _, ok := <-waitChannel; ok {
+			shared.LogWarnf("Value transmitted over image lock semaphore?")
+		}
+		// Give the benefit of the doubt and assume that the other
+		// thread actually succeeded in unmounting the storage pool.
+		return false, nil
+	}
+
+	lxdStorageOngoingOperationMap[poolUmountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
+
+	removeLockFromMap := func() {
+		lxdStorageMapLock.Lock()
+		if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
+			close(waitChannel)
+			delete(lxdStorageOngoingOperationMap, poolUmountLockID)
+		}
+		lxdStorageMapLock.Unlock()
+	}
+
+	defer removeLockFromMap()
+
 	if shared.IsMountPoint(poolMntPoint) {
 		err := syscall.Unmount(poolMntPoint, 0)
 		if err != nil {
@@ -571,27 +623,27 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	// ${LXD_DIR}/images/<fingerprint>
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
 	} else {
-		lxdStorageLockMap[imageStoragePoolLockID] = make(chan bool)
-		lxdStorageLock.Unlock()
+		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
+		lxdStorageMapLock.Unlock()
 
 		var imgerr error
 		if !shared.PathExists(imageMntPoint) || !s.isBtrfsPoolVolume(imageMntPoint) {
 			imgerr = s.ImageCreate(fingerprint)
 		}
 
-		lxdStorageLock.Lock()
-		if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Lock()
+		if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 			close(waitChannel)
-			delete(lxdStorageLockMap, imageStoragePoolLockID)
+			delete(lxdStorageOngoingOperationMap, imageStoragePoolLockID)
 		}
-		lxdStorageLock.Unlock()
+		lxdStorageMapLock.Unlock()
 
 		if imgerr != nil {
 			return imgerr
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index c2f64f2..ca69b4a 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -543,27 +543,27 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 	imageLvmDevPath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointImages, fingerprint)
 
 	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
 	} else {
-		lxdStorageLockMap[imageStoragePoolLockID] = make(chan bool)
-		lxdStorageLock.Unlock()
+		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
+		lxdStorageMapLock.Unlock()
 
 		var imgerr error
 		if !shared.PathExists(imageMntPoint) || !shared.PathExists(imageLvmDevPath) {
 			imgerr = s.ImageCreate(fingerprint)
 		}
 
-		lxdStorageLock.Lock()
-		if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Lock()
+		if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 			close(waitChannel)
-			delete(lxdStorageLockMap, imageStoragePoolLockID)
+			delete(lxdStorageOngoingOperationMap, imageStoragePoolLockID)
 		}
-		lxdStorageLock.Unlock()
+		lxdStorageMapLock.Unlock()
 
 		if imgerr != nil {
 			return imgerr
@@ -761,9 +761,9 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 
 	containerMountLockID := fmt.Sprintf("mount/%s/%s", s.pool.Name, name)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerMountLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
@@ -772,8 +772,8 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 		return false, nil
 	}
 
-	lxdStorageLockMap[containerMountLockID] = make(chan bool)
-	lxdStorageLock.Unlock()
+	lxdStorageOngoingOperationMap[containerMountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
 
 	var imgerr error
 	ourMount := false
@@ -782,12 +782,12 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 		ourMount = true
 	}
 
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerMountLockID]; ok {
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		close(waitChannel)
-		delete(lxdStorageLockMap, containerMountLockID)
+		delete(lxdStorageOngoingOperationMap, containerMountLockID)
 	}
-	lxdStorageLock.Unlock()
+	lxdStorageMapLock.Unlock()
 
 	if imgerr != nil {
 		return false, imgerr
@@ -800,9 +800,9 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 
 	containerUmountLockID := fmt.Sprintf("umount/%s/%s", s.pool.Name, name)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerUmountLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
@@ -811,8 +811,8 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 		return false, nil
 	}
 
-	lxdStorageLockMap[containerUmountLockID] = make(chan bool)
-	lxdStorageLock.Unlock()
+	lxdStorageOngoingOperationMap[containerUmountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
 
 	var imgerr error
 	ourUmount := false
@@ -821,12 +821,12 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 		ourUmount = true
 	}
 
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerUmountLockID]; ok {
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		close(waitChannel)
-		delete(lxdStorageLockMap, containerUmountLockID)
+		delete(lxdStorageOngoingOperationMap, containerUmountLockID)
 	}
-	lxdStorageLock.Unlock()
+	lxdStorageMapLock.Unlock()
 
 	if imgerr != nil {
 		return false, imgerr
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 40751ed..9ee8191 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -399,9 +399,9 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
 	containerMountLockID := fmt.Sprintf("mount/%s/%s", s.pool.Name, name)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerMountLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
@@ -410,8 +410,8 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 		return false, nil
 	}
 
-	lxdStorageLockMap[containerMountLockID] = make(chan bool)
-	lxdStorageLock.Unlock()
+	lxdStorageOngoingOperationMap[containerMountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
 
 	var imgerr error
 	ourMount := false
@@ -420,12 +420,12 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 		ourMount = true
 	}
 
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerMountLockID]; ok {
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		close(waitChannel)
-		delete(lxdStorageLockMap, containerMountLockID)
+		delete(lxdStorageOngoingOperationMap, containerMountLockID)
 	}
-	lxdStorageLock.Unlock()
+	lxdStorageMapLock.Unlock()
 
 	if imgerr != nil {
 		return false, imgerr
@@ -439,9 +439,9 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
 	containerUmountLockID := fmt.Sprintf("umount/%s/%s", s.pool.Name, name)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerUmountLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
@@ -450,8 +450,8 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 		return false, nil
 	}
 
-	lxdStorageLockMap[containerUmountLockID] = make(chan bool)
-	lxdStorageLock.Unlock()
+	lxdStorageOngoingOperationMap[containerUmountLockID] = make(chan bool)
+	lxdStorageMapLock.Unlock()
 
 	var imgerr error
 	ourUmount := false
@@ -460,12 +460,12 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 		ourUmount = true
 	}
 
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[containerUmountLockID]; ok {
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		close(waitChannel)
-		delete(lxdStorageLockMap, containerUmountLockID)
+		delete(lxdStorageOngoingOperationMap, containerUmountLockID)
 	}
-	lxdStorageLock.Unlock()
+	lxdStorageMapLock.Unlock()
 
 	if imgerr != nil {
 		return false, imgerr
@@ -524,27 +524,27 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 	fsImage := fmt.Sprintf("images/%s", fingerprint)
 
 	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
-	lxdStorageLock.Lock()
-	if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
-		lxdStorageLock.Unlock()
+	lxdStorageMapLock.Lock()
+	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
 			shared.LogWarnf("Value transmitted over image lock semaphore?")
 		}
 	} else {
-		lxdStorageLockMap[imageStoragePoolLockID] = make(chan bool)
-		lxdStorageLock.Unlock()
+		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
+		lxdStorageMapLock.Unlock()
 
 		var imgerr error
 		if !s.zfsPoolVolumeExists(fsImage) {
 			imgerr = s.ImageCreate(fingerprint)
 		}
 
-		lxdStorageLock.Lock()
-		if waitChannel, ok := lxdStorageLockMap[imageStoragePoolLockID]; ok {
+		lxdStorageMapLock.Lock()
+		if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 			close(waitChannel)
-			delete(lxdStorageLockMap, imageStoragePoolLockID)
+			delete(lxdStorageOngoingOperationMap, imageStoragePoolLockID)
 		}
-		lxdStorageLock.Unlock()
+		lxdStorageMapLock.Unlock()
 
 		if imgerr != nil {
 			return imgerr

From e52c4b9eafac2200a9a48c203469e3b227999829 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 16 Feb 2017 12:12:04 +0100
Subject: [PATCH 2/2] storage: use unified operation ids when locking

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go       | 8 ++------
 lxd/storage_btrfs.go | 6 +++---
 lxd/storage_lvm.go   | 6 +++---
 lxd/storage_zfs.go   | 6 +++---
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index d7fc441..971cea6 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -43,12 +43,8 @@ func getPoolUmountLockID(poolName string) string {
 	return fmt.Sprintf("umount/pool/%s", poolName)
 }
 
-func getImageMountLockID(poolName string, fingerprint string) string {
-	return fmt.Sprintf("mount/image/%s/%s", poolName, fingerprint)
-}
-
-func getImageUmountLockID(poolName string, fingerprint string) string {
-	return fmt.Sprintf("umount/image/%s/%s", poolName, fingerprint)
+func getImageCreateLockID(poolName string, fingerprint string) string {
+	return fmt.Sprintf("create/image/%s/%s", poolName, fingerprint)
 }
 
 func getContainerMountLockID(poolName string, containerName string) string {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index dcae1f3..34f0b89 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -304,7 +304,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
-	poolMountLockID := fmt.Sprintf("mount/pool/%s", s.pool.Name)
+	poolMountLockID := getPoolMountLockID(s.pool.Name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -386,7 +386,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
-	poolUmountLockID := fmt.Sprintf("umount/pool/%s", s.pool.Name)
+	poolUmountLockID := getPoolUmountLockID(s.pool.Name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -622,7 +622,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	// Mountpoint of the image:
 	// ${LXD_DIR}/images/<fingerprint>
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
-	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
+	imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index ca69b4a..656288e 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -542,7 +542,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	imageLvmDevPath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointImages, fingerprint)
 
-	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
+	imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -760,7 +760,7 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 	mountOptions := s.volume.Config["block.mount_options"]
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 
-	containerMountLockID := fmt.Sprintf("mount/%s/%s", s.pool.Name, name)
+	containerMountLockID := getContainerMountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -799,7 +799,7 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 
-	containerUmountLockID := fmt.Sprintf("umount/%s/%s", s.pool.Name, name)
+	containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 9ee8191..c5f1fe2 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -398,7 +398,7 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
-	containerMountLockID := fmt.Sprintf("mount/%s/%s", s.pool.Name, name)
+	containerMountLockID := getContainerMountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -438,7 +438,7 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
-	containerUmountLockID := fmt.Sprintf("umount/%s/%s", s.pool.Name, name)
+	containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
@@ -523,7 +523,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 
 	fsImage := fmt.Sprintf("images/%s", fingerprint)
 
-	imageStoragePoolLockID := fmt.Sprintf("%s/%s", s.pool.Name, fingerprint)
+	imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()


More information about the lxc-devel mailing list