[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