Skip to content

Commit

Permalink
Merge pull request #12330 from monstermunchkin/fixes/12325-zfs-regres…
Browse files Browse the repository at this point in the history
…sion

patches: Remove invalid block settings from existing volumes
  • Loading branch information
tomponline authored Sep 27, 2023
2 parents faf9192 + f71bd5d commit a978626
Showing 1 changed file with 91 additions and 0 deletions.
91 changes: 91 additions & 0 deletions lxd/patches.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var patches = []patch{
{name: "storage_prefix_bucket_names_with_project", stage: patchPostDaemonStorage, run: patchGenericStorage},
{name: "storage_move_custom_iso_block_volumes", stage: patchPostDaemonStorage, run: patchStorageRenameCustomISOBlockVolumes},
{name: "zfs_set_content_type_user_property", stage: patchPostDaemonStorage, run: patchZfsSetContentTypeUserProperty},
{name: "storage_zfs_unset_invalid_block_settings", stage: patchPostDaemonStorage, run: patchStorageZfsUnsetInvalidBlockSettings},
}

type patch struct {
Expand Down Expand Up @@ -916,4 +917,94 @@ func patchZfsSetContentTypeUserProperty(name string, d *Daemon) error {
return nil
}

// patchStorageZfsUnsetInvalidBlockSettings removes invalid block settings from volumes.
func patchStorageZfsUnsetInvalidBlockSettings(_ string, d *Daemon) error {
s := d.State()

// Get all storage pool names.
pools, err := s.DB.Cluster.GetStoragePoolNames()
if err != nil {
// Skip the rest of the patch if no storage pools were found.
if api.StatusErrorCheck(err, http.StatusNotFound) {
return nil
}

return fmt.Errorf("Failed getting storage pool names: %w", err)
}

volTypeCustom := db.StoragePoolVolumeTypeCustom
volTypeVM := db.StoragePoolVolumeTypeVM

poolIDNameMap := make(map[int64]string, 0)
poolVolumes := make(map[int64][]*db.StorageVolume, 0)

err = s.DB.Cluster.Transaction(s.ShutdownCtx, func(ctx context.Context, tx *db.ClusterTx) error {
for _, pool := range pools {
// Get storage pool ID.
poolID, err := tx.GetStoragePoolID(ctx, pool)
if err != nil {
return fmt.Errorf("Failed getting storage pool ID of pool %q: %w", pool, err)
}

driverName, err := tx.GetStoragePoolDriver(ctx, poolID)
if err != nil {
return fmt.Errorf("Failed getting storage pool driver of pool %q: %w", pool, err)
}

if driverName != "zfs" {
continue
}

// Get the pool's custom storage volumes.
volumes, err := tx.GetStoragePoolVolumes(ctx, poolID, false, db.StorageVolumeFilter{Type: &volTypeCustom}, db.StorageVolumeFilter{Type: &volTypeVM})
if err != nil {
return fmt.Errorf("Failed getting custom storage volumes of pool %q: %w", pool, err)
}

if poolVolumes[poolID] == nil {
poolVolumes[poolID] = []*db.StorageVolume{}
}

poolIDNameMap[poolID] = pool
poolVolumes[poolID] = append(poolVolumes[poolID], volumes...)
}

return nil
})
if err != nil {
return err
}

var volType int

for pool, volumes := range poolVolumes {
for _, vol := range volumes {
config := vol.Config

if shared.IsTrue(config["zfs.block_mode"]) {
continue
}

delete(config, "block.filesystem")
delete(config, "block.mount_options")

if vol.Type == db.StoragePoolVolumeTypeNameVM {
volType = volTypeVM
} else if vol.Type == db.StoragePoolVolumeTypeNameCustom {
volType = volTypeCustom
} else {
// Should not happen.
continue
}

err = s.DB.Cluster.UpdateStoragePoolVolume(vol.Project, vol.Name, volType, pool, vol.Description, config)
if err != nil {
return fmt.Errorf("Failed updating volume %q in project %q on pool %q: %w", vol.Name, vol.Project, poolIDNameMap[pool], err)
}
}
}

return nil
}

// Patches end here

0 comments on commit a978626

Please sign in to comment.