The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7436
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) === Merges `genericVFSResizeBlockFile` into `ensureVolumeBlockFile`.
From da07c97c13a5ea70f1b3bf29ba607dbf0dc2da97 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 18 May 2020 13:41:46 +0100 Subject: [PATCH 1/3] lxd/storage/drivers/utils: Updates ensureVolumeBlockFile to reject unsafe volume shrinking Signed-off-by: Thomas Parrott <thomas.parr...@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 db44b7f1132098c11f0a3f2004ef8303d52497ee Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 18 May 2020 13:40:51 +0100 Subject: [PATCH 2/3] lxd/storage/drivers/geneirc/vfs: Removes genericVFSResizeBlockFile Signed-off-by: Thomas Parrott <thomas.parr...@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 0c731f5982f541cd3e8deffa96e979cedbee1bbd Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 26 May 2020 15:34:02 +0100 Subject: [PATCH 3/3] lxd/storage/drivers: ensureVolumeBlockFile usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_btrfs_volumes.go | 4 ++-- lxd/storage/drivers/driver_dir_volumes.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go index 8367af8775..9251c586cc 100644 --- a/lxd/storage/drivers/driver_btrfs_volumes.go +++ b/lxd/storage/drivers/driver_btrfs_volumes.go @@ -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 } @@ -661,7 +661,7 @@ 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 } diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go index a980940e6e..1dc752e580 100644 --- a/lxd/storage/drivers/driver_dir_volumes.go +++ b/lxd/storage/drivers/driver_dir_volumes.go @@ -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 } @@ -275,7 +275,7 @@ 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 }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel