[lxc-devel] [lxd/master] VM: Use qemu-img dd mode instead of convert
tomponline on Github
lxc-bot at linuxcontainers.org
Thu May 28 11:26:57 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 410 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200528/4c946f4b/attachment.bin>
-------------- next part --------------
From deef1786e9d93037c366bf24de5ffc82f467bd20 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.
More information about the lxc-devel
mailing list