The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8225

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Fixes issue when copying from ceph to zfs pools, the zfs volumes were being rounded to the nearest 8192 bytes, which sometimes meant the volume size created was just too small to accommodate the source ceph volume (which doesn't round to nearest 8192 bytes).

This modifies the ZFS volumes to round up to nearest 8192 bytes.

From 23835ab8cc0a8b7334fff5a185b97e67a5920f86 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:56:13 +0000
Subject: [PATCH 1/8] lxd/storage/drivers/utils: Modifies
 roundVolumeBlockFileSizeBytes to round up

Ensures that the returned bytes is always greater than or equal to the input 
bytes.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/utils.go | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index a64635bbc2..3a216852c7 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -310,16 +310,24 @@ func ensureSparseFile(filePath string, sizeBytes int64) 
error {
        return nil
 }
 
-// roundVolumeBlockFileSizeBytes parses the supplied size string and then 
rounds it to the nearest 8k bytes.
-func roundVolumeBlockFileSizeBytes(sizeBytes int64) (int64, error) {
+// roundVolumeBlockFileSizeBytes parses the supplied size string and then 
rounds it to the nearest multiple of
+// MinBlockBoundary bytes that is equal to or larger than sizeBytes.
+func roundVolumeBlockFileSizeBytes(sizeBytes int64) int64 {
        // Qemu requires image files to be in traditional storage block 
boundaries.
        // We use 8k here to ensure our images are compatible with all of our 
backend drivers.
        if sizeBytes < MinBlockBoundary {
                sizeBytes = MinBlockBoundary
        }
 
+       roundedSizeBytes := int64(sizeBytes/MinBlockBoundary) * MinBlockBoundary
+
+       // Ensure the rounded size is at least the size specified in sizeBytes.
+       if roundedSizeBytes < sizeBytes {
+               roundedSizeBytes += MinBlockBoundary
+       }
+
        // Round the size to closest MinBlockBoundary bytes to avoid qemu 
boundary issues.
-       return int64(sizeBytes/MinBlockBoundary) * MinBlockBoundary, nil
+       return roundedSizeBytes
 }
 
 // ensureVolumeBlockFile creates new block file or enlarges the raw block file 
for a volume to the specified size.

From f1a1b13c5acbd16969c5f3186d1c7cc74e2d3636 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:56:55 +0000
Subject: [PATCH 2/8] lxd/storage/drivers/utils: roundVolumeBlockFileSizeBytes
 usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/utils.go | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index 3a216852c7..b922e12160 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -339,10 +339,7 @@ func ensureVolumeBlockFile(vol Volume, path string, 
sizeBytes int64) (bool, erro
        }
 
        // Get rounded block size to avoid qemu boundary issues.
-       sizeBytes, err := roundVolumeBlockFileSizeBytes(sizeBytes)
-       if err != nil {
-               return false, err
-       }
+       sizeBytes = roundVolumeBlockFileSizeBytes(sizeBytes)
 
        if shared.PathExists(path) {
                fi, err := os.Stat(path)
@@ -384,7 +381,7 @@ func ensureVolumeBlockFile(vol Volume, path string, 
sizeBytes int64) (bool, erro
 
        // If path doesn't exist, then there has been no filler function 
supplied to create it from another source.
        // So instead create an empty volume (use for PXE booting a VM).
-       err = ensureSparseFile(path, sizeBytes)
+       err := ensureSparseFile(path, sizeBytes)
        if err != nil {
                return false, errors.Wrapf(err, "Failed creating disk image %q 
as size %d", path, sizeBytes)
        }

From 8e7d36e48fa423424b37e5b08fb31f0025ac47f3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:57:16 +0000
Subject: [PATCH 3/8] lxd/storage/drivers/driver/zfs/utils: Use
 roundVolumeBlockFileSizeBytes in createVolume

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/driver_zfs_utils.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/storage/drivers/driver_zfs_utils.go 
b/lxd/storage/drivers/driver_zfs_utils.go
index 13e59cb80f..555a71b7ab 100644
--- a/lxd/storage/drivers/driver_zfs_utils.go
+++ b/lxd/storage/drivers/driver_zfs_utils.go
@@ -55,7 +55,7 @@ func (d *zfs) createDataset(dataset string, options 
...string) error {
 }
 
 func (d *zfs) createVolume(dataset string, size int64, options ...string) 
error {
-       size = (size / MinBlockBoundary) * MinBlockBoundary
+       size = roundVolumeBlockFileSizeBytes(size)
 
        args := []string{"create", "-s", "-V", fmt.Sprintf("%d", size)}
        for _, option := range options {

From 6f74c97fa2c0ed9def4ae8ff7b10849eb564f099 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:57:38 +0000
Subject: [PATCH 4/8] lxd/storage/drivers/driver/zfs/volumes: Use
 roundVolumeBlockFileSizeBytes in CreateVolume

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/driver_zfs_volumes.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/storage/drivers/driver_zfs_volumes.go 
b/lxd/storage/drivers/driver_zfs_volumes.go
index 78152519e9..8053a8a5f6 100644
--- a/lxd/storage/drivers/driver_zfs_volumes.go
+++ b/lxd/storage/drivers/driver_zfs_volumes.go
@@ -73,7 +73,7 @@ func (d *zfs) CreateVolume(vol Volume, filler *VolumeFiller, 
op *operations.Oper
                        }
 
                        // Round to block boundary.
-                       poolVolSizeBytes = (poolVolSizeBytes / 
MinBlockBoundary) * MinBlockBoundary
+                       poolVolSizeBytes = 
roundVolumeBlockFileSizeBytes(poolVolSizeBytes)
 
                        // If the cached volume size is different than the pool 
volume size, then we can't use the
                        // deleted cached image volume and instead we will 
rename it to a random UUID so it can't

From 9ac20b24b9151559d7eae3efa0112fb774863cfb Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:57:56 +0000
Subject: [PATCH 5/8] lxd/storage/drivers/driver/zfs/volumes: Use
 roundVolumeBlockFileSizeBytes in SetVolumeQuota

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/driver_zfs_volumes.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/storage/drivers/driver_zfs_volumes.go 
b/lxd/storage/drivers/driver_zfs_volumes.go
index 8053a8a5f6..29e38998d8 100644
--- a/lxd/storage/drivers/driver_zfs_volumes.go
+++ b/lxd/storage/drivers/driver_zfs_volumes.go
@@ -921,7 +921,7 @@ func (d *zfs) SetVolumeQuota(vol Volume, size string, op 
*operations.Operation)
                        return nil
                }
 
-               sizeBytes = (sizeBytes / MinBlockBoundary) * MinBlockBoundary
+               sizeBytes = roundVolumeBlockFileSizeBytes(sizeBytes)
 
                oldSizeBytesStr, err := d.getDatasetProperty(d.dataset(vol, 
false), "volsize")
                if err != nil {

From d5e2a01d02e55871905ebdba7858fda3f3f42025 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:58:23 +0000
Subject: [PATCH 6/8] lxd/storage/backend/lxd: Use revert in
 CreateInstanceFromCopy

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/backend_lxd.go | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index 344de2b4d4..36854abcb7 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -744,13 +744,8 @@ func (b *lxdBackend) CreateInstanceFromCopy(inst 
instance.Instance, src instance
        // We don't need to use the source instance's root disk config, so set 
to nil.
        srcVol := b.newVolume(volType, contentType, srcVolStorageName, nil)
 
-       revert := true
-       defer func() {
-               if !revert {
-                       return
-               }
-               b.DeleteInstance(inst, op)
-       }()
+       revert := revert.New()
+       defer revert.Fail()
 
        srcPool, err := GetPoolByInstance(b.state, src)
        if err != nil {
@@ -767,6 +762,8 @@ func (b *lxdBackend) CreateInstanceFromCopy(inst 
instance.Instance, src instance
                defer src.Unfreeze()
        }
 
+       revert.Add(func() { b.DeleteInstance(inst, op) })
+
        if b.Name() == srcPool.Name() {
                logger.Debug("CreateInstanceFromCopy same-pool mode detected")
                err = b.driver.CreateVolumeFromCopy(vol, srcVol, snapshots, op)
@@ -876,7 +873,7 @@ func (b *lxdBackend) CreateInstanceFromCopy(inst 
instance.Instance, src instance
                return err
        }
 
-       revert = false
+       revert.Success()
        return nil
 }
 

From a281aaa8ac06314338d7b6b8fdbba0d8bd89b969 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:58:39 +0000
Subject: [PATCH 7/8] lxd/storage/backend/lxd: Don't fail in DeleteInstance if
 DB record already removed

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/backend_lxd.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index 36854abcb7..245f6c8015 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -1471,7 +1471,7 @@ func (b *lxdBackend) DeleteInstance(inst 
instance.Instance, op *operations.Opera
 
        // Remove the volume record from the database.
        err = b.state.Cluster.RemoveStoragePoolVolume(inst.Project(), 
inst.Name(), volDBType, b.ID())
-       if err != nil {
+       if err != nil && errors.Cause(err) != db.ErrNoSuchObject {
                return errors.Wrapf(err, "Error deleting storage volume from 
database")
        }
 

From 4335cb1a745ab97bfad29fbc3b7793cc978057c1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 8 Dec 2020 12:59:04 +0000
Subject: [PATCH 8/8] lxd/instance: Use revert in instanceCreateAsCopy

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance.go | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/lxd/instance.go b/lxd/instance.go
index 11325fcaef..7d14be5be8 100644
--- a/lxd/instance.go
+++ b/lxd/instance.go
@@ -181,16 +181,11 @@ func instanceCreateFromImage(d *Daemon, args 
db.InstanceArgs, hash string, op *o
 }
 
 func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst 
instance.Instance, instanceOnly bool, refresh bool, op *operations.Operation) 
(instance.Instance, error) {
-       var inst, revertInst instance.Instance
+       var inst instance.Instance
        var err error
 
-       defer func() {
-               if revertInst == nil {
-                       return
-               }
-
-               revertInst.Delete(true)
-       }()
+       revert := revert.New()
+       defer revert.Fail()
 
        if refresh {
                // Load the target instance.
@@ -211,7 +206,8 @@ func instanceCreateAsCopy(s *state.State, args 
db.InstanceArgs, sourceInst insta
                if err != nil {
                        return nil, errors.Wrap(err, "Failed creating instance 
record")
                }
-               revertInst = inst
+
+               revert.Add(func() { inst.Delete(true) })
        }
 
        // At this point we have already figured out the parent container's 
root disk device so we
@@ -326,7 +322,7 @@ func instanceCreateAsCopy(s *state.State, args 
db.InstanceArgs, sourceInst insta
                return nil, err
        }
 
-       revertInst = nil
+       revert.Success()
        return inst, nil
 }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to