From d504b76e06a2a18baf98b8df63e36e11b23fe97a Mon Sep 17 00:00:00 2001 From: wanyaoqi <18528551+wanyaoqi@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:32:02 +0800 Subject: [PATCH] Automated cherry pick of #19558: Fix/guest image live migrate (#19559) * fix(host): slvm storage active on init * fix(region): guest live migrate cache all of guestimage caches --- pkg/compute/tasks/guest_live_migrate_task.go | 59 +++++++++++++++----- pkg/hostman/storageman/lvmutils/lvmutils.go | 12 ++++ pkg/hostman/storageman/storage_slvm.go | 4 ++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/pkg/compute/tasks/guest_live_migrate_task.go b/pkg/compute/tasks/guest_live_migrate_task.go index 562648472a4..312aaacfb00 100644 --- a/pkg/compute/tasks/guest_live_migrate_task.go +++ b/pkg/compute/tasks/guest_live_migrate_task.go @@ -146,26 +146,55 @@ func (task *GuestMigrateTask) SaveScheduleResult(ctx context.Context, obj ISched body.Set("is_local_storage", jsonutils.JSONFalse) } - task.SetStage("OnCachedImageComplete", body) // prepare disk for migration if len(disk.TemplateId) > 0 && isLocalStorage { - targetStorageCache := targetHost.GetLocalStoragecache() - if targetStorageCache != nil { - input := api.CacheImageInput{ - ImageId: disk.TemplateId, - Format: disk.DiskFormat, - IsForce: false, - SourceHostId: guest.HostId, - ParentTaskId: task.GetTaskId(), - } - err := targetStorageCache.StartImageCacheTask(ctx, task.UserCred, input) - if err != nil { - task.TaskFailed(ctx, guest, jsonutils.NewString(err.Error())) + templates := []string{} + guestdisks, _ := guest.GetDisks() + for i := range guestdisks { + if guestdisks[i].TemplateId != "" { + templates = append(templates, guestdisks[i].TemplateId) } - return } + if len(templates) > 0 { + body.Set("cache_templates", jsonutils.NewStringArray(templates)) + } + } + task.SetStage("OnStartCacheImages", body) + task.OnStartCacheImages(ctx, guest, nil) +} + +func (task *GuestMigrateTask) OnStartCacheImages(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { + templates, _ := task.Params.GetArray("cache_templates") + if len(templates) == 0 { + task.OnCachedImageComplete(ctx, guest, nil) + return + } + + templateId, _ := templates[0].GetString() + task.Params.Set("cache_templates", jsonutils.NewArray(templates[1:]...)) + task.SetStage("OnStartCacheImages", nil) + + targetHostId, _ := task.Params.GetString("target_host_id") + targetHost := models.HostManager.FetchHostById(targetHostId) + targetStorageCache := targetHost.GetLocalStoragecache() + if targetStorageCache != nil { + input := api.CacheImageInput{ + ImageId: templateId, + IsForce: false, + SourceHostId: guest.HostId, + ParentTaskId: task.GetTaskId(), + } + err := targetStorageCache.StartImageCacheTask(ctx, task.UserCred, input) + if err != nil { + task.TaskFailed(ctx, guest, jsonutils.NewString(err.Error())) + } + return } - task.OnCachedImageComplete(ctx, guest, nil) + task.OnStartCacheImages(ctx, guest, nil) +} + +func (task *GuestMigrateTask) OnStartCacheImagesFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { + task.TaskFailed(ctx, guest, data) } // For local storage get disk info diff --git a/pkg/hostman/storageman/lvmutils/lvmutils.go b/pkg/hostman/storageman/lvmutils/lvmutils.go index ec7fa9d9479..8c9a7f600bf 100644 --- a/pkg/hostman/storageman/lvmutils/lvmutils.go +++ b/pkg/hostman/storageman/lvmutils/lvmutils.go @@ -261,3 +261,15 @@ func VgDisplay(vgName string) error { } return nil } + +func VgActive(vgName string, active bool) error { + opts := "-ay" + if !active { + opts = "-an" + } + out, err := procutils.NewRemoteCommandAsFarAsPossible("lvm", "vgchange", opts, vgName).Output() + if err != nil { + return errors.Wrapf(err, "vgchange %s %s failed %s", opts, vgName, out) + } + return nil +} diff --git a/pkg/hostman/storageman/storage_slvm.go b/pkg/hostman/storageman/storage_slvm.go index 5f37075419b..f3e61ffbedb 100644 --- a/pkg/hostman/storageman/storage_slvm.go +++ b/pkg/hostman/storageman/storage_slvm.go @@ -89,6 +89,10 @@ func (s *SSLVMStorage) GetDiskById(diskId string) (IDisk, error) { } func (s *SSLVMStorage) Accessible() error { + if err := lvmutils.VgActive(s.Path, true); err != nil { + return err + } + if err := lvmutils.VgDisplay(s.Path); err != nil { return err }