mirror of
https://github.com/lxc/incus
synced 2026-08-02 05:26:46 +00:00
incusd/instance/qemu: Resize metadata image on disk size change
The newly introduced QCOW2 metadata file wasn't getting resized during a VM offline resize event. This got caught by our daily VM tests. Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
This commit is contained in:
parent
bf08b404f9
commit
5645b80efb
@ -4684,15 +4684,30 @@ func (d *qemu) ensureMetadataImage(rawPath string, devName string) (string, stri
|
||||
|
||||
// If we already have metadata image, then just use it
|
||||
if util.PathExists(qcow2Path) {
|
||||
isQcow2, err := d.isQCOW2(qcow2Path)
|
||||
imgInfo, err := storageDrivers.Qcow2Info(qcow2Path)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if !isQcow2 {
|
||||
if imgInfo.Format != storageDrivers.BlockVolumeTypeQcow2 {
|
||||
return "", "", fmt.Errorf("Existing metadata image %q is not qcow2", qcow2Path)
|
||||
}
|
||||
|
||||
// Get size of disk block device.
|
||||
blockDiskSize, err := storageDrivers.BlockDiskSizeBytes(rawPath)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("Error getting block device size %q: %w", rawPath, err)
|
||||
}
|
||||
|
||||
// Keep the metadata image in sync with the disk size as the volume
|
||||
// may have been resized while the instance was stopped.
|
||||
if int64(imgInfo.VirtualSize) != blockDiskSize {
|
||||
err = d.resizeMetadataImage(qcow2Path, rawPath, blockDiskSize, int64(imgInfo.VirtualSize))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
}
|
||||
|
||||
return qcow2Path, rawPath, nil
|
||||
}
|
||||
|
||||
@ -4734,6 +4749,40 @@ func (d *qemu) ensureMetadataImage(rawPath string, devName string) (string, stri
|
||||
return qcow2Path, rawPath, nil
|
||||
}
|
||||
|
||||
// resizeMetadataImage resizes the qcow2 metadata image to match the raw disk size.
|
||||
// The data-file has to be overridden as the one recorded in the image no longer exists.
|
||||
func (d *qemu) resizeMetadataImage(qcow2Path string, rawPath string, newSize int64, oldSize int64) error {
|
||||
fInfo, err := os.Stat(rawPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rawDriver := "file"
|
||||
if linux.IsBlockdev(fInfo.Mode()) {
|
||||
rawDriver = "host_device"
|
||||
}
|
||||
|
||||
escape := func(s string) string {
|
||||
return strings.ReplaceAll(s, ",", ",,")
|
||||
}
|
||||
|
||||
args := []string{"resize"}
|
||||
if newSize < oldSize {
|
||||
args = append(args, "--shrink")
|
||||
} else {
|
||||
args = append(args, "--preallocation=metadata")
|
||||
}
|
||||
|
||||
args = append(args, "--image-opts", fmt.Sprintf("driver=qcow2,file.filename=%s,data-file.driver=%s,data-file.filename=%s", escape(qcow2Path), rawDriver, escape(rawPath)), fmt.Sprintf("%d", newSize))
|
||||
|
||||
_, err = subprocess.RunCommand("qemu-img", args...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed resizing qcow2 metadata image %q: %w", qcow2Path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// addRootDriveConfig adds the qemu config required for adding the root drive.
|
||||
func (d *qemu) addRootDriveConfig(qemuDev map[string]any, mountInfo *storagePools.MountInfo, bootIndexes map[string]int, rootDriveConf deviceConfig.MountEntryItem) (monitorHook, error) {
|
||||
if rootDriveConf.TargetPath != "/" {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user