From 4e5314393f3503221a1535fbdd05d8c0da9c8c1c Mon Sep 17 00:00:00 2001 From: Martin Necas Date: Mon, 7 Oct 2024 16:19:05 +0200 Subject: [PATCH] MTV-1537 | Optimalise the plan scheduler Issue: When we start the warm migration with VM which has a lot of disks we wait for the whole VM to get migrated. We do not ignore the disks that has been already migrated. This can cause that when we have 2 VMs with 10 disks each and on each there is one larger disk the whole scheduler will be halted untill they finish. So even if the left 9 disks will be done no migration will be started. Fix: Subtract the finished disks from the disk count. Fixes: https://issues.redhat.com/browse/MTV-1537 Signed-off-by: Martin Necas --- .../plan/scheduler/vsphere/scheduler.go | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/pkg/controller/plan/scheduler/vsphere/scheduler.go b/pkg/controller/plan/scheduler/vsphere/scheduler.go index 0b2abef98..8c7888ad1 100644 --- a/pkg/controller/plan/scheduler/vsphere/scheduler.go +++ b/pkg/controller/plan/scheduler/vsphere/scheduler.go @@ -107,7 +107,7 @@ func (r *Scheduler) buildInFlight() (err error) { return } if vmStatus.Running() { - r.inFlight[vm.Host] += r.cost(vm) + r.inFlight[vm.Host] += r.cost(vm, vmStatus) } } @@ -153,7 +153,7 @@ func (r *Scheduler) buildInFlight() (err error) { } return err } - r.inFlight[vm.Host] += r.cost(vm) + r.inFlight[vm.Host] += r.cost(vm, vmStatus) } } @@ -174,7 +174,7 @@ func (r *Scheduler) buildPending() (err error) { if !vmStatus.MarkedStarted() && !vmStatus.MarkedCompleted() { pending := &pendingVM{ status: vmStatus, - cost: r.cost(vm), + cost: r.cost(vm, vmStatus), } r.pending[vm.Host] = append(r.pending[vm.Host], pending) } @@ -182,16 +182,32 @@ func (r *Scheduler) buildPending() (err error) { return } -func (r *Scheduler) cost(vm *model.VM) int { +func (r *Scheduler) cost(vm *model.VM, vmStatus *plan.VMStatus) int { if coldLocal, _ := r.Plan.VSphereColdLocal(); coldLocal { /// virt-v2v transfers one disk at a time return 1 } else { // CDI transfers the disks in parallel by different pods - return len(vm.Disks) + return len(vm.Disks) - r.finishedDisks(vmStatus) } } +// finishedDisks returns a number of the disks that have completed the disk transfer +// This can reduce the migration time as VMs with one large disks and many small disks won't halt the scheduler +func (r *Scheduler) finishedDisks(vmStatus *plan.VMStatus) int { + var resp = 0 + for _, step := range vmStatus.Pipeline { + if step.Name == "DiskTransfer" { + for _, task := range step.Tasks { + if task.Phase == "Completed" { + resp += 1 + } + } + } + } + return resp +} + // Return a map of all the VMs that could be scheduled // based on the available host capacities. func (r *Scheduler) schedulable() (schedulable map[string][]*pendingVM) {