From 8d5ceb0b73c923464ec75f13d39b548ea5f8cf7c Mon Sep 17 00:00:00 2001 From: wanyaoqi <18528551+wanyaoqi@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:45:53 +0800 Subject: [PATCH] Automated cherry pick of #15475: fix(host): convert migrate set downtime value to float64 (#15476) * fix(host): convert migrate set downtime value to float64 * fix(host): live migration optimize Qemu will send `STOP` event on start last time migration, but this moment migration not completed. So we need wait magration complete. Configurable Auto converge max cpu throttle. --- pkg/hostman/guestman/guesttasks.go | 26 +++++++++++++++++++++++--- pkg/hostman/guestman/qemu-kvm.go | 4 +--- pkg/hostman/monitor/hmp.go | 2 +- pkg/hostman/monitor/monitor.go | 2 +- pkg/hostman/monitor/qmp.go | 2 +- pkg/hostman/options/options.go | 3 ++- 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/pkg/hostman/guestman/guesttasks.go b/pkg/hostman/guestman/guesttasks.go index 1544dbf83d..b0be1e9e25 100644 --- a/pkg/hostman/guestman/guesttasks.go +++ b/pkg/hostman/guestman/guesttasks.go @@ -1130,6 +1130,7 @@ func (s *SGuestLiveMigrateTask) startMigrateStatusCheck(res string) { func (s *SGuestLiveMigrateTask) onGetMigrateStats(stats *monitor.MigrationInfo, err error) { if err != nil { log.Errorf("%s get migrate stats failed %s", s.GetName(), err) + s.migrateFailed(fmt.Sprintf("%s get migrate stats failed %s", s.GetName(), err)) return } s.onGetMigrateStatus(stats) @@ -1177,8 +1178,7 @@ func (s *SGuestLiveMigrateTask) onGetMigrateStatus(stats *monitor.MigrationInfo) return } - if *stats.CPUThrottlePercentage < 99 { - // TODO: configureable tolerate cpu throttle percentage + if *stats.CPUThrottlePercentage < options.HostOptions.LiveMigrateCpuThrottleMax { return } @@ -1201,7 +1201,7 @@ func (s *SGuestLiveMigrateTask) onGetMigrateStatus(stats *monitor.MigrationInfo) log.Errorf("failed set migrate downtime %s", res) } } - s.Monitor.MigrateSetDowntime(float32(*stats.ExpectedDowntime/1000.0), cb) + s.Monitor.MigrateSetDowntime(float64(*stats.ExpectedDowntime)/1000.0, cb) } } } @@ -1216,6 +1216,25 @@ func (s *SGuestLiveMigrateTask) onMigrateStartPostcopy(res string) { } } +func (s *SGuestLiveMigrateTask) onMigrateReceivedStopEvent() { + s.Monitor.GetMigrateStats(func(stats *monitor.MigrationInfo, err error) { + if err != nil { + log.Errorf("%s get migrate stats failed %s", s.GetName(), err) + return + } + + switch *stats.Status { + case "completed": + s.migrateComplete(jsonutils.Marshal(stats)) + case "failed", "cancelled": + s.migrateFailed(fmt.Sprintf("Query migrate got status: %s", *stats.Status)) + case "active": + time.Sleep(10 * time.Millisecond) + s.onMigrateReceivedStopEvent() + } + }) +} + func (s *SGuestLiveMigrateTask) migrateComplete(stats jsonutils.JSONObject) { s.MigrateTask = nil if s.c != nil { @@ -1229,6 +1248,7 @@ func (s *SGuestLiveMigrateTask) migrateComplete(stats jsonutils.JSONObject) { res.Set("migration_info", stats) } hostutils.TaskComplete(s.ctx, res) + hostutils.UpdateServerProgress(context.Background(), s.Id, 0.0, 0) } func (s *SGuestLiveMigrateTask) migrateFailed(msg string) { diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 58ad546970..f8a62e48b6 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -756,10 +756,8 @@ func (s *SKVMGuestInstance) onReceiveQMPEvent(event *monitor.Event) { s.eventGuestPaniced(event) case event.Event == `"STOP"`: if s.MigrateTask != nil { - // migrating complete - s.MigrateTask.migrateComplete(nil) + s.MigrateTask.onMigrateReceivedStopEvent() } - hostutils.UpdateServerProgress(context.Background(), s.Id, 0.0, 0) } } diff --git a/pkg/hostman/monitor/hmp.go b/pkg/hostman/monitor/hmp.go index 45159051a2..36834b91d9 100644 --- a/pkg/hostman/monitor/hmp.go +++ b/pkg/hostman/monitor/hmp.go @@ -293,7 +293,7 @@ func (m *HmpMonitor) DeviceAdd(dev string, params map[string]string, callback St m.Query(fmt.Sprintf("device_add %s,%s", dev, strings.Join(paramsKvs, ",")), callback) } -func (m *HmpMonitor) MigrateSetDowntime(dtSec float32, callback StringCallback) { +func (m *HmpMonitor) MigrateSetDowntime(dtSec float64, callback StringCallback) { m.Query(fmt.Sprintf("migrate_set_downtime %f", dtSec), callback) } diff --git a/pkg/hostman/monitor/monitor.go b/pkg/hostman/monitor/monitor.go index cffd0607cc..1c5bf77d2c 100644 --- a/pkg/hostman/monitor/monitor.go +++ b/pkg/hostman/monitor/monitor.go @@ -224,7 +224,7 @@ type Monitor interface { BlockReopenImage(drive, newImagePath, format string, cb StringCallback) SnapshotBlkdev(drive, newImagePath, format string, reuse bool, cb StringCallback) - MigrateSetDowntime(dtSec float32, callback StringCallback) + MigrateSetDowntime(dtSec float64, callback StringCallback) MigrateSetCapability(capability, state string, callback StringCallback) MigrateSetParameter(key string, val interface{}, callback StringCallback) MigrateIncoming(address string, callback StringCallback) diff --git a/pkg/hostman/monitor/qmp.go b/pkg/hostman/monitor/qmp.go index afad974337..ddfd9f7565 100644 --- a/pkg/hostman/monitor/qmp.go +++ b/pkg/hostman/monitor/qmp.go @@ -611,7 +611,7 @@ func (m *QmpMonitor) DeviceAdd(dev string, params map[string]string, callback St // m.Query(cmd, cb) } -func (m *QmpMonitor) MigrateSetDowntime(dtSec float32, callback StringCallback) { +func (m *QmpMonitor) MigrateSetDowntime(dtSec float64, callback StringCallback) { m.HumanMonitorCommand(fmt.Sprintf("migrate_set_downtime %f", dtSec), callback) } diff --git a/pkg/hostman/options/options.go b/pkg/hostman/options/options.go index b56883b4a7..4acf7a0659 100644 --- a/pkg/hostman/options/options.go +++ b/pkg/hostman/options/options.go @@ -28,7 +28,8 @@ type SHostBaseOptions struct { DisableSecurityGroup bool `help:"disable security group" default:"false"` - HostCpuPassthrough bool `default:"true" help:"if it is true, set qemu cpu type as -cpu host, otherwise, qemu64. default is true"` + HostCpuPassthrough bool `default:"true" help:"if it is true, set qemu cpu type as -cpu host, otherwise, qemu64. default is true"` + LiveMigrateCpuThrottleMax int64 `default:"99" help:"live migrate auto converge cpu throttle max"` DefaultQemuVersion string `help:"Default qemu version" default:"4.2.0"`