The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7460
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) === Works around issues unpacking images on loopback files that causes kernel hangs on ZFS and slow downs on LVM.
From deef1786e9d93037c366bf24de5ffc82f467bd20 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 28 May 2020 12:20:59 +0100 Subject: [PATCH 1/4] lxd/storage/utils: Removes duplicated qemu-img call in ImageUnpack Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/utils.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index e4b0d2f146..8e0c2b3107 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -576,12 +576,6 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo if err != nil { return -1, err } - - // Convert the qcow2 format to a raw block device. - _, err = shared.RunCommand("qemu-img", "convert", "-O", "raw", imageRootfsFile, destBlockFile) - if err != nil { - return -1, fmt.Errorf("Failed converting image to raw at %s: %v", destBlockFile, err) - } } else { // Dealing with unified tarballs require an initial unpack to a temporary directory. tempDir, err := ioutil.TempDir(shared.VarPath("images"), "lxd_image_unpack_") From b29fb09d3aa123374d4f1dd4a68263d090294609 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 28 May 2020 12:20:26 +0100 Subject: [PATCH 2/4] lxd/storage/utils: Switch to qemu-img dd mode in ImageUnpack To avoid issues with storage pools on loopback devices. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/utils.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index 8e0c2b3107..66b1aed6ec 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -553,8 +553,10 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo } } - // Convert the qcow2 format to a raw block device. - _, err = shared.RunCommand("qemu-img", "convert", "-f", "qcow2", "-O", "raw", imgPath, dstPath) + // Convert the qcow2 format to a raw block device using qemu's dd mode to avoid issues with + // loop backed storage pools. Use the MinBlockBoundary block size to speed up conversion. + logger.Debugf("Converting qcow2 image %q to raw disk %q", imgPath, dstPath) + _, err = shared.RunCommand("qemu-img", "dd", "-f", "qcow2", "-O", "raw", fmt.Sprintf("bs=%d", drivers.MinBlockBoundary), fmt.Sprintf("if=%s", imgPath), fmt.Sprintf("of=%s", dstPath)) if err != nil { return -1, errors.Wrapf(err, "Failed converting image to raw at %q", dstPath) } From ba6635a6980738f5ba1415ea19121f4519418611 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 28 May 2020 12:21:30 +0100 Subject: [PATCH 3/4] lxd/storage/drivers/utils: Exports MinBlockBoundary For use with ImageUnpack Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 85ae62d885..381ce190ad 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -18,7 +18,8 @@ import ( "github.com/lxc/lxd/shared/idmap" ) -const minBlockBoundary = 8192 +// MinBlockBoundary minimum block boundary size to use. +const MinBlockBoundary = 8192 // wipeDirectory empties the contents of a directory, but leaves it in place. func wipeDirectory(path string) error { From 23ef563b75a2d8dbe61ff2d460d8ae4ce72da820 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 28 May 2020 12:21:50 +0100 Subject: [PATCH 4/4] lxd/storage/drivers: MinBlockBoundary usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_zfs_utils.go | 2 +- lxd/storage/drivers/driver_zfs_volumes.go | 4 ++-- lxd/storage/drivers/utils.go | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lxd/storage/drivers/driver_zfs_utils.go b/lxd/storage/drivers/driver_zfs_utils.go index 9cdd6c127e..62619abf6d 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 = (size / MinBlockBoundary) * MinBlockBoundary args := []string{"create", "-s", "-V", fmt.Sprintf("%d", size)} for _, option := range options { diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go index 316dfc1780..43caa00a55 100644 --- a/lxd/storage/drivers/driver_zfs_volumes.go +++ b/lxd/storage/drivers/driver_zfs_volumes.go @@ -72,7 +72,7 @@ func (d *zfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper } // Round to block boundary. - poolVolSizeBytes = (poolVolSizeBytes / minBlockBoundary) * minBlockBoundary + poolVolSizeBytes = (poolVolSizeBytes / MinBlockBoundary) * MinBlockBoundary // If the cached volume is larger 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 @@ -886,7 +886,7 @@ func (d *zfs) SetVolumeQuota(vol Volume, size string, op *operations.Operation) return nil } - sizeBytes = (sizeBytes / minBlockBoundary) * minBlockBoundary + sizeBytes = (sizeBytes / MinBlockBoundary) * MinBlockBoundary oldSizeBytesStr, err := d.getDatasetProperty(d.dataset(vol, false), "volsize") if err != nil { diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 381ce190ad..5a974baf5f 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -317,12 +317,12 @@ func createSparseFile(filePath string, sizeBytes int64) error { func roundVolumeBlockFileSizeBytes(sizeBytes int64) (int64, error) { // 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 + if sizeBytes < MinBlockBoundary { + sizeBytes = MinBlockBoundary } - // Round the size to closest minBlockBoundary bytes to avoid qemu boundary issues. - return int64(sizeBytes/minBlockBoundary) * minBlockBoundary, nil + // Round the size to closest MinBlockBoundary bytes to avoid qemu boundary issues. + return int64(sizeBytes/MinBlockBoundary) * MinBlockBoundary, nil } // ensureVolumeBlockFile creates new block file or enlarges the raw block file for a volume to the specified size.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel