The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8220
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 image volume resize errors.
From c622519f3cc9260dda192811626696b8e9283c5b Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 7 Dec 2020 19:27:15 +0000 Subject: [PATCH 1/4] lxd/storage/backend/lxd: Comment typo fix Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 79a72c541e..0259328829 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2201,8 +2201,8 @@ func (b *lxdBackend) EnsureImage(fingerprint string, op *operations.Operation) e imgVol.SetConfigSize(newVolSize) - // Try applying the current size policy to the existin volume. If it is the same the driver - // should make no changes, and if not then attempt to resize it to the new policy. + // Try applying the current size policy to the existing volume. If it is the same the + // driver should make no changes, and if not then attempt to resize it to the new policy. logger.Debug("Setting image volume size", "size", imgVol.ConfigSize()) err = b.driver.SetVolumeQuota(imgVol, imgVol.ConfigSize(), op) if errors.Cause(err) == drivers.ErrCannotBeShrunk || errors.Cause(err) == drivers.ErrNotSupported { From f245258acf7e23b74d6d16e050ab9656bde99c18 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 7 Dec 2020 19:27:38 +0000 Subject: [PATCH 2/4] lxd/storage/drivers/driver/btrfs/volumes: Enable allowUnsafeResize in CreateVolume when creating initial image volume This is so the image volume can be resized to desired size after filler has run but before readonly snapshot is created. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_btrfs_volumes.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go index 3de65c5c78..687c935138 100644 --- a/lxd/storage/drivers/driver_btrfs_volumes.go +++ b/lxd/storage/drivers/driver_btrfs_volumes.go @@ -68,6 +68,13 @@ func (d *btrfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Op return err } + // Allow unsafe resize of image volumes as filler won't have been able to resize the volume to the + // target size as volume file didn't exist then (and we can't create in advance because qemu-img + // truncates the file to image size). + if vol.volType == VolumeTypeImage { + vol.allowUnsafeResize = true + } + _, err = ensureVolumeBlockFile(vol, rootBlockPath, sizeBytes) // Ignore ErrCannotBeShrunk as this just means the filler has needed to increase the volume size. From 059863e24bcca4e9f53cff413541553e8a3d6f39 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 7 Dec 2020 19:29:02 +0000 Subject: [PATCH 3/4] lxd/storage/drivers/utils: Updates ensureVolumeBlockFile to return unsupported when trying to resize image volume without allowUnsafeResize enabled This is so the correct error response is returned to trigger backendLXD to regenerate cached BTRFS image volume when pool's volume.size changes. Doesn't affect dir pools (which also use this function) as they do not have cached image volumes. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/utils.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 646d10c4a4..a64635bbc2 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -347,6 +347,13 @@ func ensureVolumeBlockFile(vol Volume, path string, sizeBytes int64) (bool, erro return false, nil } + // Block image volumes cannot be resized because they can have a readonly snapshot that doesn't get + // updated when the volume's size is changed, and this is what instances are created from. + // During initial volume fill allowUnsafeResize is enabled because snapshot hasn't been taken yet. + if !vol.allowUnsafeResize && vol.volType == VolumeTypeImage { + return false, ErrNotSupported + } + // Only perform pre-resize sanity checks if we are not in "unsafe" mode. // In unsafe mode we expect the caller to know what they are doing and understand the risks. if !vol.allowUnsafeResize { From a751c6045ddb3052e8d98a88639c3adab077b3d3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 7 Dec 2020 19:30:32 +0000 Subject: [PATCH 4/4] lxd/storage/utils: Ensure pool's volume.size is checked when unpacking images to pools that use file based images Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/utils.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index cf79c49af1..adc6de91d3 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -512,28 +512,28 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo return -1, fmt.Errorf("Unexpected image format %q", imgInfo.Format) } + // Check whether image is allowed to be unpacked into pool volume. Create a partial image volume + // struct and then use it to check that target volume size can be set as needed. + imgVolConfig := map[string]string{ + "volatile.rootfs.size": fmt.Sprintf("%d", imgInfo.VirtualSize), + } + imgVol := drivers.NewVolume(nil, "", drivers.VolumeTypeImage, drivers.ContentTypeBlock, "", imgVolConfig, nil) + + logger.Debug("Checking image unpack size") + newVolSize, err := vol.ConfigSizeFromSource(imgVol) + if err != nil { + return -1, err + } + if shared.PathExists(dstPath) { volSizeBytes, err := drivers.BlockDiskSizeBytes(dstPath) if err != nil { return -1, errors.Wrapf(err, "Error getting current size of %q", dstPath) } + // If the target volume's size is smaller than the image unpack size, then we need to + // increase the target volume's size. if volSizeBytes < imgInfo.VirtualSize { - // If the target volume's size is smaller than the image unpack size, then we need - // to check whether it is inline with the pool's settings to allow us to increase - // the target volume's size. Create a partial image volume struct and then use it - // to check that target volume size can be set as needed. - imgVolConfig := map[string]string{ - "volatile.rootfs.size": fmt.Sprintf("%d", imgInfo.VirtualSize), - } - imgVol := drivers.NewVolume(nil, "", drivers.VolumeTypeImage, drivers.ContentTypeBlock, "", imgVolConfig, nil) - - logger.Debug("Checking image unpack size") - newVolSize, err := vol.ConfigSizeFromSource(imgVol) - if err != nil { - return -1, err - } - logger.Debug("Increasing volume size", log.Ctx{"imgPath": imgPath, "dstPath": dstPath, "oldSize": volSizeBytes, "newSize": newVolSize}) err = vol.SetQuota(newVolSize, nil) if err != nil {
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel