[lxc-devel] [lxd/master] Storage: Support VM image unpack size greater than volume size

tomponline on Github lxc-bot at linuxcontainers.org
Mon May 18 12:53:00 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 590 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200518/b99df8c4/attachment-0001.bin>
-------------- next part --------------
From 51b8879f617926ca57a5c543a57ee53385bce77d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:20:48 +0100
Subject: [PATCH 1/8] lxd/rsync: Adds optional rsync arguments to LocalCopy

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/rsync/rsync.go | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lxd/rsync/rsync.go b/lxd/rsync/rsync.go
index 6b18c743e1..8f811ff4f8 100644
--- a/lxd/rsync/rsync.go
+++ b/lxd/rsync/rsync.go
@@ -19,7 +19,7 @@ import (
 )
 
 // LocalCopy copies a directory using rsync (with the --devices option).
-func LocalCopy(source string, dest string, bwlimit string, xattrs bool) (string, error) {
+func LocalCopy(source string, dest string, bwlimit string, xattrs bool, rsyncArgs ...string) (string, error) {
 	err := os.MkdirAll(dest, 0755)
 	if err != nil {
 		return "", err
@@ -52,10 +52,15 @@ func LocalCopy(source string, dest string, bwlimit string, xattrs bool) (string,
 		args = append(args, "--bwlimit", bwlimit)
 	}
 
+	if len(rsyncArgs) > 0 {
+		args = append(args, rsyncArgs...)
+	}
+
 	args = append(args,
 		rsyncVerbosity,
 		shared.AddSlash(source),
 		dest)
+
 	msg, err := shared.RunCommand("rsync", args...)
 	if err != nil {
 		runError, ok := err.(shared.RunError)

From 54c54b7603e3d8c66fe7e20adf98042c6dbada67 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:22:02 +0100
Subject: [PATCH 2/8] lxd/storage/utils: Fixes ImageUnpack to not erase
 generated rootfs block file when doing rsync

If the storage driver was either `dir` or `btrfs` then the generated rootfs block file was removed when unpacking unified tarballs.

This was silently erroring because the storage driver then went ahead and created a blank rootfs block file, but the resulting VM wasn't bootable.

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

diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 587cc4b4c5..9ebcef3531 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -514,8 +514,9 @@ func ImageUnpack(imageFile, destPath, destBlockFile string, blockBackend, runnin
 			return errors.Wrapf(err, "Failed to remove %q", imgPath)
 		}
 
-		// Transfer the content.
-		_, err = rsync.LocalCopy(tempDir, destPath, "", true)
+		// Transfer the content excluding the destBlockFile name so that we don't delete the block file
+		// created above if the storage driver stores image files in the same directory as destPath.
+		_, err = rsync.LocalCopy(tempDir, destPath, "", true, "--exclude", filepath.Base(destBlockFile))
 		if err != nil {
 			return err
 		}

From 9763529cc6b0961ca1416cc4517ede91ffd2e379 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:40:51 +0100
Subject: [PATCH 3/8] lxd/storage/drivers/geneirc/vfs: Removes
 genericVFSResizeBlockFile

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/generic_vfs.go | 38 ------------------------------
 1 file changed, 38 deletions(-)

diff --git a/lxd/storage/drivers/generic_vfs.go b/lxd/storage/drivers/generic_vfs.go
index b08e691df7..bc583aa936 100644
--- a/lxd/storage/drivers/generic_vfs.go
+++ b/lxd/storage/drivers/generic_vfs.go
@@ -777,44 +777,6 @@ func genericVFSBackupUnpack(d Driver, vol Volume, snapshots []string, srcData io
 	return postHook, revertExternal.Fail, nil
 }
 
-// genericVFSResizeBlockFile resizes an existing block file to the specified size. Returns true if resize took
-// place, false if not. Both requested size and existing file size are rounded to nearest block size using
-// roundVolumeBlockFileSizeBytes() before decision whether to resize is taken.
-func genericVFSResizeBlockFile(filePath string, sizeBytes int64) (bool, error) {
-	if sizeBytes <= 0 {
-		return false, fmt.Errorf("Size cannot be zero")
-	}
-
-	fi, err := os.Stat(filePath)
-	if err != nil {
-		return false, err
-	}
-
-	oldSizeBytes := fi.Size()
-
-	// Round the supplied size the same way the block files created are so its accurate comparison.
-	newSizeBytes, err := roundVolumeBlockFileSizeBytes(sizeBytes)
-	if err != nil {
-		return false, err
-	}
-
-	if newSizeBytes < oldSizeBytes {
-		return false, errors.Wrap(ErrCannotBeShrunk, "You cannot shrink block volumes")
-	}
-
-	if newSizeBytes == oldSizeBytes {
-		return false, nil
-	}
-
-	// Resize block file.
-	err = ensureVolumeBlockFile(filePath, sizeBytes)
-	if err != nil {
-		return false, err
-	}
-
-	return true, nil
-}
-
 // genericVFSCopyVolume copies a volume and its snapshots using a non-optimized method.
 // initVolume is run against the main volume (not the snapshots) and is often used for quota initialization.
 func genericVFSCopyVolume(d Driver, initVolume func(vol Volume) (func(), error), vol Volume, srcVol Volume, srcSnapshots []Volume, refresh bool, op *operations.Operation) error {

From 1a11dd605de95981239d1dcb725baf680e2fccb1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:41:46 +0100
Subject: [PATCH 4/8] lxd/storage/drivers/utils: Updates ensureVolumeBlockFile
 to reject unsafe volume shrinking

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/utils.go | 43 +++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index a2cf4dfa7f..af426c864d 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -324,34 +324,51 @@ func roundVolumeBlockFileSizeBytes(sizeBytes int64) (int64, error) {
 	return int64(sizeBytes/minBlockBoundary) * minBlockBoundary, nil
 }
 
-// ensureVolumeBlockFile creates or resizes the raw block file for a volume to the specified size.
-func ensureVolumeBlockFile(path string, sizeBytes int64) error {
+// ensureVolumeBlockFile creates new block file or resizes the raw block file for a volume to the specified size.
+// Returns true if resize took place, false if not. Requested size is rounded to nearest block size using
+// roundVolumeBlockFileSizeBytes() before decision whether to resize is taken.
+func ensureVolumeBlockFile(path string, sizeBytes int64) (bool, error) {
 	if sizeBytes <= 0 {
-		return fmt.Errorf("Size cannot be zero")
+		return false, fmt.Errorf("Size cannot be zero")
 	}
 
 	// Get rounded block size to avoid qemu boundary issues.
 	sizeBytes, err := roundVolumeBlockFileSizeBytes(sizeBytes)
 	if err != nil {
-		return err
+		return false, err
 	}
 
 	if shared.PathExists(path) {
-		_, err = shared.RunCommand("qemu-img", "resize", "-f", "raw", path, fmt.Sprintf("%d", sizeBytes))
+		fi, err := os.Stat(path)
 		if err != nil {
-			return errors.Wrapf(err, "Failed resizing disk image %q to size %d", path, sizeBytes)
+			return false, err
 		}
-	} else {
-		// 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 = shared.RunCommand("qemu-img", "create", "-f", "raw", path, fmt.Sprintf("%d", sizeBytes))
+
+		oldSizeBytes := fi.Size()
+		if sizeBytes < oldSizeBytes {
+			return false, errors.Wrap(ErrCannotBeShrunk, "You cannot shrink block volumes")
+		}
+
+		if sizeBytes == oldSizeBytes {
+			return false, nil
+		}
+
+		_, err = shared.RunCommand("qemu-img", "resize", "-f", "raw", path, fmt.Sprintf("%d", sizeBytes))
 		if err != nil {
-			return errors.Wrapf(err, "Failed creating disk image %q as size %d", path, sizeBytes)
+			return false, errors.Wrapf(err, "Failed resizing disk image %q to size %d", path, sizeBytes)
 		}
+
+		return true, nil
 	}
 
-	return nil
+	// 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 = shared.RunCommand("qemu-img", "create", "-f", "raw", path, fmt.Sprintf("%d", sizeBytes))
+	if err != nil {
+		return false, errors.Wrapf(err, "Failed creating disk image %q as size %d", path, sizeBytes)
+	}
+
+	return false, nil
 }
 
 // mkfsOptions represents options for filesystem creation.

From 975832f77b468c2d66444b1b3cae30e47b90b204 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:42:27 +0100
Subject: [PATCH 5/8] lxd/storage/drivers/volume: Adds SetQuota function

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/volume.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lxd/storage/drivers/volume.go b/lxd/storage/drivers/volume.go
index 07ff0d433c..ab13e100e7 100644
--- a/lxd/storage/drivers/volume.go
+++ b/lxd/storage/drivers/volume.go
@@ -326,3 +326,8 @@ func (v Volume) NewVMBlockFilesystemVolume() Volume {
 
 	return NewVolume(v.driver, v.pool, v.volType, ContentTypeFS, v.name, newConf, v.poolConfig)
 }
+
+// SetQuota calls SetVolumeQuota on the Volume's driver.
+func (v Volume) SetQuota(size string, op *operations.Operation) error {
+	return v.driver.SetVolumeQuota(v, size, op)
+}

From f454b5df07c2c7c55304b4123e82376761d9db31 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:47:58 +0100
Subject: [PATCH 6/8] lxd/storage/utils: Updates ImageUnpack to detect too
 small volume for qcow2 image and increase size before unpack

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/utils.go | 64 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 9ebcef3531..dab0b6a0b0 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -1,6 +1,7 @@
 package storage
 
 import (
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -426,9 +427,10 @@ func validateVolumeCommonRules(vol drivers.Volume) map[string]func(string) error
 // VM Format A: Separate metadata tarball and root qcow2 file.
 // 	- Unpack metadata tarball into mountPath.
 //	- Check rootBlockPath is a file and convert qcow2 file into raw format in rootBlockPath.
-func ImageUnpack(imageFile, destPath, destBlockFile string, blockBackend, runningInUserns bool, tracker *ioprogress.ProgressTracker) error {
+func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blockBackend, runningInUserns bool, tracker *ioprogress.ProgressTracker) error {
 	// For all formats, first unpack the metadata (or combined) tarball into destPath.
 	imageRootfsFile := imageFile + ".rootfs"
+	destPath := vol.MountPath()
 
 	// If no destBlockFile supplied then this is a container image unpack.
 	if destBlockFile == "" {
@@ -475,6 +477,53 @@ func ImageUnpack(imageFile, destPath, destBlockFile string, blockBackend, runnin
 		return fmt.Errorf("Root block path isn't a file: %s", destBlockFile)
 	}
 
+	// convertBlockImage converts the qcow2 block image file into a raw block device. If needed it will attempt
+	// to enlarge the destination volume to accomodate the unpacked qcow2 image file.
+	convertBlockImage := func(v drivers.Volume, imgPath string, dstPath string) error {
+		// Get info about qcow2 file.
+		imgJSON, err := shared.RunCommand("qemu-img", "info", "--output=json", imgPath)
+		if err != nil {
+			return errors.Wrapf(err, "Failed reading image info %q", dstPath)
+		}
+
+		imgInfo := struct {
+			Format      string `json:"format"`
+			VirtualSize int64  `json:"virtual-size"`
+		}{}
+
+		err = json.Unmarshal([]byte(imgJSON), &imgInfo)
+		if err != nil {
+			return err
+		}
+
+		if imgInfo.Format != "qcow2" {
+			return fmt.Errorf("Unexpected image format %q", imgInfo.Format)
+		}
+
+		if shared.PathExists(dstPath) {
+			volSizeBytes, err := drivers.BlockDevSizeBytes(dstPath)
+			if err != nil {
+				return errors.Wrapf(err, "Error getting current size")
+			}
+
+			if volSizeBytes < imgInfo.VirtualSize {
+				logger.Debugf("Increasing %q volume size from %d to %d to accomodate image %q unpack", dstPath, volSizeBytes, imgInfo.VirtualSize, imgPath)
+				err = vol.SetQuota(fmt.Sprintf("%d", imgInfo.VirtualSize), nil)
+				if err != nil {
+					return errors.Wrapf(err, "Error increasing volume size")
+				}
+			}
+		}
+
+		// Convert the qcow2 format to a raw block device.
+		_, err = shared.RunCommand("qemu-img", "convert", "-f", "qcow2", "-O", "raw", imgPath, dstPath)
+		if err != nil {
+			return errors.Wrapf(err, "Failed converting image to raw at %q", dstPath)
+		}
+
+		return nil
+	}
+
 	if shared.PathExists(imageRootfsFile) {
 		// Unpack the main image file.
 		err := shared.Unpack(imageFile, destPath, blockBackend, runningInUserns, tracker)
@@ -482,6 +531,12 @@ func ImageUnpack(imageFile, destPath, destBlockFile string, blockBackend, runnin
 			return err
 		}
 
+		// Convert the qcow2 format to a raw block device.
+		err = convertBlockImage(vol, imageRootfsFile, destBlockFile)
+		if err != nil {
+			return err
+		}
+
 		// Convert the qcow2 format to a raw block device.
 		_, err = shared.RunCommand("qemu-img", "convert", "-O", "raw", imageRootfsFile, destBlockFile)
 		if err != nil {
@@ -501,11 +556,12 @@ func ImageUnpack(imageFile, destPath, destBlockFile string, blockBackend, runnin
 			return err
 		}
 
-		// Convert the qcow2 format to a raw block device.
 		imgPath := filepath.Join(tempDir, "rootfs.img")
-		_, err = shared.RunCommand("qemu-img", "convert", "-O", "raw", imgPath, destBlockFile)
+
+		// Convert the qcow2 format to a raw block device.
+		err = convertBlockImage(vol, imgPath, destBlockFile)
 		if err != nil {
-			return fmt.Errorf("Failed converting image to raw at %s: %v", destBlockFile, err)
+			return err
 		}
 
 		// Delete the qcow2.

From 815de9d5d1eda3250b4faa1d84a7d7093bc31d13 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:49:10 +0100
Subject: [PATCH 7/8] lxd/storage/drivers/driver/types: Updates VolumeFiller
 Fill function to take a Volume

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

diff --git a/lxd/storage/drivers/driver_types.go b/lxd/storage/drivers/driver_types.go
index 700eca1cd6..2b1e106b6d 100644
--- a/lxd/storage/drivers/driver_types.go
+++ b/lxd/storage/drivers/driver_types.go
@@ -19,7 +19,7 @@ type Info struct {
 
 // VolumeFiller provides a struct for filling a volume.
 type VolumeFiller struct {
-	Fill func(mountPath, rootBlockPath string) error // Function to fill the volume.
+	Fill func(vol Volume, rootBlockPath string) error // Function to fill the volume.
 
 	Fingerprint string // If the Filler will unpack an image, it should be this fingerprint.
 }

From d1f2481422d0fdd0abb283dd9363c925da69f799 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 18 May 2020 13:49:56 +0100
Subject: [PATCH 8/8] lxd/storage: Updates volume filler usage to supply Volume
 rather than mount path

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/backend_lxd.go                   | 6 +++---
 lxd/storage/drivers/driver_btrfs_volumes.go  | 8 ++++----
 lxd/storage/drivers/driver_ceph_volumes.go   | 4 ++--
 lxd/storage/drivers/driver_cephfs_volumes.go | 2 +-
 lxd/storage/drivers/driver_dir_volumes.go    | 8 ++++----
 lxd/storage/drivers/driver_lvm_volumes.go    | 4 ++--
 lxd/storage/drivers/driver_zfs_volumes.go    | 4 ++--
 7 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index c09492e812..4070d809ee 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -932,8 +932,8 @@ func (b *lxdBackend) RefreshInstance(inst instance.Instance, src instance.Instan
 // imageFiller returns a function that can be used as a filler function with CreateVolume().
 // The function returned will unpack the specified image archive into the specified mount path
 // provided, and for VM images, a raw root block path is required to unpack the qcow2 image into.
-func (b *lxdBackend) imageFiller(fingerprint string, op *operations.Operation) func(mountPath, rootBlockPath string) error {
-	return func(mountPath, rootBlockPath string) error {
+func (b *lxdBackend) imageFiller(fingerprint string, op *operations.Operation) func(vol drivers.Volume, rootBlockPath string) error {
+	return func(vol drivers.Volume, rootBlockPath string) error {
 		var tracker *ioprogress.ProgressTracker
 		if op != nil { // Not passed when being done as part of pre-migration setup.
 			metadata := make(map[string]interface{})
@@ -944,7 +944,7 @@ func (b *lxdBackend) imageFiller(fingerprint string, op *operations.Operation) f
 				}}
 		}
 		imageFile := shared.VarPath("images", fingerprint)
-		return ImageUnpack(imageFile, mountPath, rootBlockPath, b.driver.Info().BlockBacking, b.state.OS.RunningInUserNS, tracker)
+		return ImageUnpack(imageFile, vol, rootBlockPath, b.driver.Info().BlockBacking, b.state.OS.RunningInUserNS, tracker)
 	}
 }
 
diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go
index 7b7d472d90..f3b934e72d 100644
--- a/lxd/storage/drivers/driver_btrfs_volumes.go
+++ b/lxd/storage/drivers/driver_btrfs_volumes.go
@@ -56,7 +56,7 @@ func (d *btrfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Op
 
 	// Run the volume filler function if supplied.
 	if filler != nil && filler.Fill != nil {
-		err = filler.Fill(volPath, rootBlockPath)
+		err = filler.Fill(vol, rootBlockPath)
 		if err != nil {
 			return err
 		}
@@ -71,7 +71,7 @@ func (d *btrfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Op
 			return err
 		}
 
-		err = ensureVolumeBlockFile(rootBlockPath, sizeBytes)
+		_, err = ensureVolumeBlockFile(rootBlockPath, sizeBytes)
 		if err != nil {
 			return err
 		}
@@ -660,13 +660,13 @@ func (d *btrfs) SetVolumeQuota(vol Volume, size string, op *operations.Operation
 			return err
 		}
 
-		resized, err := genericVFSResizeBlockFile(rootBlockPath, sizeBytes)
+		resized, err := ensureVolumeBlockFile(rootBlockPath, sizeBytes)
 		if err != nil {
 			return err
 		}
 
 		// Move the GPT alt header to end of disk if needed and resize has taken place (not needed in
-		// unsafe resize mode as it is  expected the caller will do all necessary post resize actions
+		// unsafe resize mode as it is expected the caller will do all necessary post resize actions
 		// themselves).
 		if vol.IsVMBlock() && resized && !vol.allowUnsafeResize {
 			err = d.moveGPTAltHeader(rootBlockPath)
diff --git a/lxd/storage/drivers/driver_ceph_volumes.go b/lxd/storage/drivers/driver_ceph_volumes.go
index 3884998869..988cd7d911 100644
--- a/lxd/storage/drivers/driver_ceph_volumes.go
+++ b/lxd/storage/drivers/driver_ceph_volumes.go
@@ -165,7 +165,7 @@ func (d *ceph) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Ope
 	err = vol.MountTask(func(mountPath string, op *operations.Operation) error {
 		if filler != nil && filler.Fill != nil {
 			if vol.contentType == ContentTypeFS {
-				return filler.Fill(mountPath, "")
+				return filler.Fill(vol, "")
 			}
 
 			devPath, err := d.GetVolumeDiskPath(vol)
@@ -173,7 +173,7 @@ func (d *ceph) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Ope
 				return err
 			}
 
-			err = filler.Fill(mountPath, devPath)
+			err = filler.Fill(vol, devPath)
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage/drivers/driver_cephfs_volumes.go b/lxd/storage/drivers/driver_cephfs_volumes.go
index 5fc5a48686..4282d5e90f 100644
--- a/lxd/storage/drivers/driver_cephfs_volumes.go
+++ b/lxd/storage/drivers/driver_cephfs_volumes.go
@@ -48,7 +48,7 @@ func (d *cephfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.O
 	// Fill the volume.
 	if filler != nil && filler.Fill != nil {
 		d.logger.Debug("Running filler function", log.Ctx{"path": volPath})
-		err = filler.Fill(volPath, "")
+		err = filler.Fill(vol, "")
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go
index 1618cd7680..28a4740c5c 100644
--- a/lxd/storage/drivers/driver_dir_volumes.go
+++ b/lxd/storage/drivers/driver_dir_volumes.go
@@ -57,7 +57,7 @@ func (d *dir) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 	// Run the volume filler function if supplied.
 	if filler != nil && filler.Fill != nil {
 		d.logger.Debug("Running filler function", log.Ctx{"path": volPath})
-		err = filler.Fill(volPath, rootBlockPath)
+		err = filler.Fill(vol, rootBlockPath)
 		if err != nil {
 			return err
 		}
@@ -72,7 +72,7 @@ func (d *dir) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 			return err
 		}
 
-		err = ensureVolumeBlockFile(rootBlockPath, sizeBytes)
+		_, err = ensureVolumeBlockFile(rootBlockPath, sizeBytes)
 		if err != nil {
 			return err
 		}
@@ -270,13 +270,13 @@ func (d *dir) SetVolumeQuota(vol Volume, size string, op *operations.Operation)
 			return err
 		}
 
-		resized, err := genericVFSResizeBlockFile(rootBlockPath, sizeBytes)
+		resized, err := ensureVolumeBlockFile(rootBlockPath, sizeBytes)
 		if err != nil {
 			return err
 		}
 
 		// Move the GPT alt header to end of disk if needed and resize has taken place (not needed in
-		// unsafe resize mode as it is  expected the caller will do all necessary post resize actions
+		// unsafe resize mode as it is expected the caller will do all necessary post resize actions
 		// themselves).
 		if vol.IsVMBlock() && resized && !vol.allowUnsafeResize {
 			err = d.moveGPTAltHeader(rootBlockPath)
diff --git a/lxd/storage/drivers/driver_lvm_volumes.go b/lxd/storage/drivers/driver_lvm_volumes.go
index bead2cf8c7..f65f24d0e6 100644
--- a/lxd/storage/drivers/driver_lvm_volumes.go
+++ b/lxd/storage/drivers/driver_lvm_volumes.go
@@ -56,7 +56,7 @@ func (d *lvm) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 		if filler != nil && filler.Fill != nil {
 			if vol.contentType == ContentTypeFS {
 				d.logger.Debug("Running filler function", log.Ctx{"path": volPath})
-				err = filler.Fill(mountPath, "")
+				err = filler.Fill(vol, "")
 				if err != nil {
 					return err
 				}
@@ -69,7 +69,7 @@ func (d *lvm) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 
 				// Run the filler.
 				d.logger.Debug("Running filler function", log.Ctx{"dev": devPath, "path": volPath})
-				err = filler.Fill(mountPath, devPath)
+				err = filler.Fill(vol, devPath)
 				if err != nil {
 					return err
 				}
diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go
index 77bd91634c..95151970ce 100644
--- a/lxd/storage/drivers/driver_zfs_volumes.go
+++ b/lxd/storage/drivers/driver_zfs_volumes.go
@@ -176,7 +176,7 @@ func (d *zfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 		if filler != nil && filler.Fill != nil {
 			if vol.contentType == ContentTypeFS {
 				// Run the filler.
-				err := filler.Fill(mountPath, "")
+				err := filler.Fill(vol, "")
 				if err != nil {
 					return err
 				}
@@ -188,7 +188,7 @@ func (d *zfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
 				}
 
 				// Run the filler.
-				err = filler.Fill(mountPath, devPath)
+				err = filler.Fill(vol, devPath)
 				if err != nil {
 					return err
 				}


More information about the lxc-devel mailing list