From d5292e37f286ba199eeaa042c70659b9148ebf53 Mon Sep 17 00:00:00 2001 From: wanyaoqi <18528551+wanyaoqi@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:45:54 +0800 Subject: [PATCH] Automated cherry pick of #18580: fix(host): sync guest machine type on live migrate (#18582) * fix(host): sync guest machine type on live migrate * fix(host): checkout real anonymous pci devs on ensure pci address --- pkg/hostman/guestman/desc/pci.go | 18 ++++++++++++++++++ pkg/hostman/guestman/guestman.go | 3 +++ pkg/hostman/guestman/pci.go | 16 ++++++++++++++++ pkg/hostman/guestman/qemu-kvm.go | 3 +++ pkg/hostman/guestman/qemu-kvmhelper.go | 4 ++++ 5 files changed, 44 insertions(+) diff --git a/pkg/hostman/guestman/desc/pci.go b/pkg/hostman/guestman/desc/pci.go index cc2404ed74..aa045a8603 100644 --- a/pkg/hostman/guestman/desc/pci.go +++ b/pkg/hostman/guestman/desc/pci.go @@ -213,6 +213,14 @@ func (b *SGuestPCIAddresses) ReleasePCIAddress(addr *PCIAddr) error { return bus.ReleaseSlotFunction(addr.Slot, addr.Function) } +func (b *SGuestPCIAddresses) IsAddrInUse(addr *PCIAddr) (error, bool) { + if int(addr.Bus+1) > len(b.Buses) { + return errors.Errorf("release pci address bus %02x out of range", addr.Bus), false + } + bus := b.Buses[addr.Bus] + return bus.IsSlotFunctionInUse(addr.Slot, addr.Function) +} + func (b *SGuestPCIAddressBus) EnsureSlotFunction(slot, function uint) error { if b.Slots == nil { b.Slots = make([]*SGuestPCIAddressSlot, 0, b.MaxSlot+1) @@ -244,6 +252,16 @@ func (b *SGuestPCIAddressBus) setSlotFunction(slot, function uint) { b.Slots[slot].Function |= 1 << function } +func (b *SGuestPCIAddressBus) IsSlotFunctionInUse(slot, function uint) (error, bool) { + if slot < b.MinSlot || slot > b.MaxSlot { + return errors.Errorf("slot %02x out of range %02x~%02x", slot, b.MinSlot, b.MaxSlot), false + } + if function >= 8 { + return errors.Errorf("function %x out of range 0~7", function), false + } + return nil, (b.Slots[slot].Function & (1 << function)) > 0 +} + func (b *SGuestPCIAddressBus) ReleaseSlotFunction(slot, function uint) error { if slot < b.MinSlot || slot > b.MaxSlot { return errors.Errorf("slot %02x out of range %02x~%02x", slot, b.MinSlot, b.MaxSlot) diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index e9dea8d853..732c29c286 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -1011,6 +1011,9 @@ func (m *SGuestManager) SrcPrepareMigrate(ctx context.Context, params interface{ ret.Set("migrate_certs", jsonutils.Marshal(certs)) } if migParams.LiveMigrate { + if guest.Desc.Machine == "" { + guest.Desc.Machine = guest.getMachine() + } if err = guest.syncVirtioDiskNumQueues(); err != nil { return nil, errors.Wrap(err, "syncVirtioDiskNumQueues") } diff --git a/pkg/hostman/guestman/pci.go b/pkg/hostman/guestman/pci.go index c17a376f8b..6a51fc3031 100644 --- a/pkg/hostman/guestman/pci.go +++ b/pkg/hostman/guestman/pci.go @@ -104,6 +104,7 @@ func (s *SKVMGuestInstance) loadGuestPciAddresses() error { if err != nil { return errors.Wrap(err, "init guest pci addresses") } + if err := s.initMachineDefaultAddresses(); err != nil { return errors.Wrap(err, "init machine default devices") } @@ -111,6 +112,9 @@ func (s *SKVMGuestInstance) loadGuestPciAddresses() error { if err != nil { return errors.Wrap(err, "load desc ensure pci address") } + if err = s.SaveLiveDesc(s.Desc); err != nil { + return errors.Wrap(err, "loadGuestPciAddresses save desc") + } return nil } @@ -707,12 +711,24 @@ func (s *SKVMGuestInstance) ensurePciAddresses() error { } } + anonymousPCIDevs := s.Desc.AnonymousPCIDevs[:0] for i := 0; i < len(s.Desc.AnonymousPCIDevs); i++ { + if s.isMachineDefaultAddress(s.Desc.AnonymousPCIDevs[i].PCIAddr) { + if _, inUse := s.pciAddrs.IsAddrInUse(s.Desc.AnonymousPCIDevs[i].PCIAddr); inUse { + log.Infof("guest %s anonymous dev addr %s in use", s.GetName(), s.Desc.AnonymousPCIDevs[i].String()) + continue + } + } err = s.ensureDevicePciAddress(s.Desc.AnonymousPCIDevs[i], -1, nil) if err != nil { return errors.Wrap(err, "ensure anonymous pci dev pci address") } + anonymousPCIDevs = append(anonymousPCIDevs, s.Desc.AnonymousPCIDevs[i]) } + if len(anonymousPCIDevs) == 0 { + anonymousPCIDevs = nil + } + s.Desc.AnonymousPCIDevs = anonymousPCIDevs return nil } diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 6421d79215..d7905861df 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -1126,6 +1126,9 @@ func (s *SKVMGuestInstance) collectGuestDescription() error { return errors.Wrap(err, "query mem devs") } + if s.Desc.Machine == "" { + s.Desc.Machine = s.getMachine() + } qtree := s.infoQtree() scsiNumQueues := s.getScsiNumQueues(qtree) for i := range s.Desc.Disks { diff --git a/pkg/hostman/guestman/qemu-kvmhelper.go b/pkg/hostman/guestman/qemu-kvmhelper.go index 4701124aeb..c4c468f1a6 100644 --- a/pkg/hostman/guestman/qemu-kvmhelper.go +++ b/pkg/hostman/guestman/qemu-kvmhelper.go @@ -962,6 +962,10 @@ func (s *SKVMGuestInstance) fixGuestMachineType() { } func (s *SKVMGuestInstance) initMachineDesc() { + if s.Desc.Machine == "" { + s.Desc.Machine = s.getMachine() + } + s.Desc.MachineDesc = s.archMan.GenerateMachineDesc(s.Desc.CpuDesc.Accel) if options.HostOptions.NoHpet { noHpet := true