Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage: Fix ZFS incorrect VM cached image volume regeneration when zfs.block_mode enabled #12077

Merged
merged 6 commits into from
Jul 25, 2023
23 changes: 11 additions & 12 deletions lxd/storage/backend_lxd.go
Original file line number Diff line number Diff line change
Expand Up @@ -1603,7 +1603,7 @@ func (b *lxdBackend) imageFiller(fingerprint string, op *operations.Operation) f
}

imageFile := shared.VarPath("images", fingerprint)
return ImageUnpack(imageFile, vol, rootBlockPath, b.driver.Info().BlockBacking, b.state.OS, allowUnsafeResize, tracker)
return ImageUnpack(imageFile, vol, rootBlockPath, b.state.OS, allowUnsafeResize, tracker)
}
}

Expand Down Expand Up @@ -3161,15 +3161,6 @@ func (b *lxdBackend) UnmountInstanceSnapshot(inst instance.Instance, op *operati
return err
}

// poolBlockFilesystem returns the filesystem used for new block device filesystems.
func (b *lxdBackend) poolBlockFilesystem() string {
if b.db.Config["volume.block.filesystem"] != "" {
return b.db.Config["volume.block.filesystem"]
}

return drivers.DefaultFilesystem
}

// EnsureImage creates an optimized volume of the image if supported by the storage pool driver and the volume
// doesn't already exist. If the volume already exists then it is checked to ensure it matches the pools current
// volume settings ("volume.size" and "block.filesystem" if applicable). If not the optimized volume is removed
Expand Down Expand Up @@ -3222,15 +3213,23 @@ func (b *lxdBackend) EnsureImage(fingerprint string, op *operations.Operation) e
// If not we need to delete the existing cached image volume and re-create using new filesystem.
// We need to do this for VM block images too, as they create a filesystem based config volume too.
if imgDBVol != nil {
// Generate a temporary volume instance that represents how a new volume using pool defaults would
// be configured.
tmpImgVol := imgVol.Clone()
err := b.Driver().FillVolumeConfig(tmpImgVol)
if err != nil {
return err
}

// Add existing image volume's config to imgVol.
imgVol = b.GetVolume(drivers.VolumeTypeImage, contentType, fingerprint, imgDBVol.Config)

// Check if the volume's block backed mode differs from the pool's current setting for new volumes.
blockModeChanged := b.Driver().Info().BlockBacking != imgVol.IsBlockBacked()
blockModeChanged := tmpImgVol.IsBlockBacked() != imgVol.IsBlockBacked()

// Check if the volume is block backed and its filesystem is different from the pool's current
// setting for new volumes.
blockFSChanged := imgVol.IsBlockBacked() && imgVol.Config()["block.filesystem"] != b.poolBlockFilesystem()
blockFSChanged := imgVol.IsBlockBacked() && imgVol.Config()["block.filesystem"] != tmpImgVol.Config()["block.filesystem"]

// If the existing image volume no longer matches the pool's settings for new volumes then we need
// to delete and re-create it.
Expand Down
2 changes: 1 addition & 1 deletion lxd/storage/drivers/driver_zfs_volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -3215,7 +3215,7 @@ func (d *zfs) FillVolumeConfig(vol Volume) error {

// Copy volume.* configuration options from pool.
// If vol has a source, ignore the block mode related config keys from the pool.
if vol.hasSource {
if vol.hasSource || vol.IsVMBlock() {
excludedKeys = []string{"zfs.block_mode", "block.filesystem", "block.mount_options"}
}

Expand Down
2 changes: 1 addition & 1 deletion lxd/storage/drivers/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ func (v Volume) ConfigSize() string {

// If volume size isn't defined in either volume or pool config, then for block volumes or block-backed
// volumes return the defaultBlockSize.
if (size == "" || size == "0") && (v.contentType == ContentTypeBlock || v.driver.Info().BlockBacking) {
if (size == "" || size == "0") && (v.contentType == ContentTypeBlock || v.IsBlockBacked()) {
return DefaultBlockSize
}

Expand Down
10 changes: 5 additions & 5 deletions lxd/storage/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ func validateVolumeCommonRules(vol drivers.Volume) map[string]func(string) error
// VM Format A: Separate metadata tarball and root qcow2 file.
// - Unpack metadata tarball into mountPath.
// - Check rootBlockPath is a file and convert qcow2 file into raw format in rootBlockPath.
func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blockBackend bool, sysOS *sys.OS, allowUnsafeResize bool, tracker *ioprogress.ProgressTracker) (int64, error) {
func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, sysOS *sys.OS, allowUnsafeResize bool, tracker *ioprogress.ProgressTracker) (int64, error) {
l := logger.Log.AddContext(logger.Ctx{"imageFile": imageFile, "volName": vol.Name()})
l.Info("Image unpack started")
defer l.Info("Image unpack stopped")
Expand All @@ -522,7 +522,7 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo
rootfsPath := filepath.Join(destPath, "rootfs")

// Unpack the main image file.
err := archive.Unpack(imageFile, destPath, blockBackend, sysOS, tracker)
err := archive.Unpack(imageFile, destPath, vol.IsBlockBacked(), sysOS, tracker)
if err != nil {
return -1, err
}
Expand All @@ -534,7 +534,7 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo
return -1, fmt.Errorf("Error creating rootfs directory")
}

err = archive.Unpack(imageRootfsFile, rootfsPath, blockBackend, sysOS, tracker)
err = archive.Unpack(imageRootfsFile, rootfsPath, vol.IsBlockBacked(), sysOS, tracker)
if err != nil {
return -1, err
}
Expand Down Expand Up @@ -663,7 +663,7 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo

if shared.PathExists(imageRootfsFile) {
// Unpack the main image file.
err := archive.Unpack(imageFile, destPath, blockBackend, sysOS, tracker)
err := archive.Unpack(imageFile, destPath, vol.IsBlockBacked(), sysOS, tracker)
if err != nil {
return -1, err
}
Expand All @@ -683,7 +683,7 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo
defer func() { _ = os.RemoveAll(tempDir) }()

// Unpack the whole image.
err = archive.Unpack(imageFile, tempDir, blockBackend, sysOS, tracker)
err = archive.Unpack(imageFile, tempDir, vol.IsBlockBacked(), sysOS, tracker)
if err != nil {
return -1, err
}
Expand Down
Loading