Skip to content

Commit b691ad5

Browse files
committed
limactl disk: Do not use qemu-img for raw disks
Fix `limactl disk create` and `limactl disk resize` to use nativeimgutil for creating and resizing disks using raw format. There are special cases (using direct I/O on certain file systems) when creating a raw image should be done with qemu-img, but these are not relevant to lima on macOS. With this change we have no dependency on qemu when using VZ instance. This change does not fix the issue of default "qcow2" disk format. Users must specify the disk format when creating additional disks for VZ instance: limactl disk create --format raw Unfinished: - Needs tests for nativeimgutil and disk command Fixes: #2853 Signed-off-by: Nir Soffer <[email protected]>
1 parent 77204d8 commit b691ad5

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

cmd/limactl/disk.go

+17-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"text/tabwriter"
1010

1111
"github.com/docker/go-units"
12+
"github.com/lima-vm/lima/pkg/nativeimgutil"
1213
"github.com/lima-vm/lima/pkg/qemu"
1314
"github.com/lima-vm/lima/pkg/store"
1415
"github.com/sirupsen/logrus"
@@ -101,7 +102,13 @@ func diskCreateAction(cmd *cobra.Command, args []string) error {
101102
return err
102103
}
103104

104-
if err := qemu.CreateDataDisk(diskDir, format, int(diskSize)); err != nil {
105+
// qemu may not be available, use it only if needed.
106+
if format == "raw" {
107+
err = nativeimgutil.CreateRawDataDisk(diskDir, int(diskSize))
108+
} else {
109+
err = qemu.CreateDataDisk(diskDir, format, int(diskSize))
110+
}
111+
if err != nil {
105112
rerr := os.RemoveAll(diskDir)
106113
if rerr != nil {
107114
err = errors.Join(err, fmt.Errorf("failed to remove a directory %q: %w", diskDir, rerr))
@@ -390,9 +397,17 @@ func diskResizeAction(cmd *cobra.Command, args []string) error {
390397
}
391398
}
392399
}
393-
if err := qemu.ResizeDataDisk(disk.Dir, disk.Format, int(diskSize)); err != nil {
400+
401+
// qemu may not be available, use it only if needed.
402+
if disk.Format == "raw" {
403+
err = nativeimgutil.ResizeRawDataDisk(disk.Dir, int(diskSize))
404+
} else {
405+
err = qemu.ResizeDataDisk(disk.Dir, disk.Format, int(diskSize))
406+
}
407+
if err != nil {
394408
return fmt.Errorf("failed to resize disk %q: %w", diskName, err)
395409
}
410+
396411
logrus.Infof("Resized disk %q (%q)", diskName, disk.Dir)
397412
return nil
398413
}

pkg/nativeimgutil/nativeimgutil.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,44 @@
22
package nativeimgutil
33

44
import (
5+
"errors"
56
"fmt"
67
"io"
8+
"io/fs"
79
"os"
810
"path/filepath"
911

10-
"github.com/containerd/continuity/fs"
12+
containerdfs "github.com/containerd/continuity/fs"
1113
"github.com/docker/go-units"
1214
"github.com/lima-vm/go-qcow2reader"
1315
"github.com/lima-vm/go-qcow2reader/convert"
1416
"github.com/lima-vm/go-qcow2reader/image/qcow2"
1517
"github.com/lima-vm/go-qcow2reader/image/raw"
1618
"github.com/lima-vm/lima/pkg/progressbar"
19+
"github.com/lima-vm/lima/pkg/store/filenames"
1720
"github.com/sirupsen/logrus"
1821
)
1922

23+
// CreateRawDataDisk creates an empty raw data disk.
24+
func CreateRawDataDisk(dir string, size int) error {
25+
dataDisk := filepath.Join(dir, filenames.DataDisk)
26+
if _, err := os.Stat(dataDisk); err == nil || !errors.Is(err, fs.ErrNotExist) {
27+
return err
28+
}
29+
f, err := os.Create(dataDisk)
30+
if err != nil {
31+
return err
32+
}
33+
defer f.Close()
34+
return f.Truncate(int64(size))
35+
}
36+
37+
// CreateRawDataDisk resizes a raw data disk.
38+
func ResizeRawDataDisk(dir string, size int) error {
39+
dataDisk := filepath.Join(dir, filenames.DataDisk)
40+
return os.Truncate(dataDisk, int64(size))
41+
}
42+
2043
// ConvertToRaw converts a source disk into a raw disk.
2144
// source and dest may be same.
2245
// ConvertToRaw is a NOP if source == dest, and no resizing is needed.
@@ -106,7 +129,7 @@ func ConvertToRaw(source, dest string, size *int64, allowSourceWithBackingFile b
106129
func convertRawToRaw(source, dest string, size *int64) error {
107130
if source != dest {
108131
// continuity attempts clonefile
109-
if err := fs.CopyFile(dest, source); err != nil {
132+
if err := containerdfs.CopyFile(dest, source); err != nil {
110133
return fmt.Errorf("failed to copy %q into %q: %w", source, dest, err)
111134
}
112135
}

0 commit comments

Comments
 (0)