From 7a684d347f165c61faa8ae968786d6cb81af0f65 Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Wed, 30 Dec 2020 15:45:45 +0800 Subject: [PATCH] fix(region): server start check host memory is enough --- pkg/compute/models/guest_actions.go | 10 ++++++++++ pkg/compute/models/hosts.go | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index accf2d0c6b..226c3e2e68 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -806,6 +806,16 @@ func (self *SGuest) AllowPerformStart(ctx context.Context, func (self *SGuest) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { if utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_START_FAILED, api.VM_SAVE_DISK_FAILED, api.VM_SUSPEND}) { + if !self.guestDisksStorageTypeIsShared() { + host := self.GetHost() + guestsMem, err := host.GetNotReadyGuestsMemorySize() + if err != nil { + return nil, err + } + if float32(guestsMem+self.VmemSize) > host.GetVirtualMemorySize() { + return nil, httperrors.NewInsufficientResourceError("host virtual memory not enough") + } + } if self.isAllDisksReady() { var kwargs *jsonutils.JSONDict if data != nil { diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 751c275ebf..ea901a4fd1 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -1497,6 +1497,23 @@ func (self *SHost) GetRunningGuestCount() (int, error) { return q.CountWithError() } +func (self *SHost) GetNotReadyGuestsMemorySize() (int, error) { + guests := GuestManager.Query().SubQuery() + q := guests.Query(sqlchemy.COUNT("guest_count"), + sqlchemy.SUM("guest_vcpu_count", guests.Field("vcpu_count")), + sqlchemy.SUM("guest_vmem_size", guests.Field("vmem_size"))) + cond := sqlchemy.OR(sqlchemy.Equals(q.Field("host_id"), self.Id), + sqlchemy.Equals(q.Field("backup_host_id"), self.Id)) + q = q.Filter(cond) + q = q.NotEquals("status", api.VM_READY) + stat := SHostGuestResourceUsage{} + err := q.First(&stat) + if err != nil { + return -1, err + } + return stat.GuestVmemSize, nil +} + func (self *SHost) GetRunningGuestMemorySize() int { res := self.getGuestsResource(api.VM_RUNNING) if res != nil {