From d9137720aba000fcf2fb77d513d99c33372e3a0e Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Mon, 14 Dec 2020 18:53:35 +0800 Subject: [PATCH] fix(region,host): fix hot remove nic - region: check is hot remove nic enable - host: del qemu device after del netdev --- pkg/compute/guestdrivers/base.go | 4 ++++ pkg/compute/guestdrivers/kvm.go | 7 +++++++ pkg/compute/models/guest_actions.go | 3 +++ pkg/compute/models/guestdrivers.go | 1 + pkg/hostman/guestman/guesttasks.go | 15 ++++++++++++++- pkg/hostman/guestman/qemu-kvm.go | 2 ++ pkg/hostman/guestman/qemu-kvmhelper.go | 1 + 7 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkg/compute/guestdrivers/base.go b/pkg/compute/guestdrivers/base.go index a5c8327410..41ed88c43b 100644 --- a/pkg/compute/guestdrivers/base.go +++ b/pkg/compute/guestdrivers/base.go @@ -409,3 +409,7 @@ func (self *SBaseGuestDriver) RequestRemoteUpdate(ctx context.Context, guest *mo func (self *SBaseGuestDriver) ValidateRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, input *api.ServerRebuildRootInput) (*api.ServerRebuildRootInput, error) { return input, nil } + +func (self *SBaseGuestDriver) ValidateDetachNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest) error { + return nil +} diff --git a/pkg/compute/guestdrivers/kvm.go b/pkg/compute/guestdrivers/kvm.go index 54c3617741..2d05c8075f 100644 --- a/pkg/compute/guestdrivers/kvm.go +++ b/pkg/compute/guestdrivers/kvm.go @@ -654,3 +654,10 @@ func (self *SKVMGuestDriver) CheckLiveMigrate(guest *models.SGuest, userCred mcc } return nil } + +func (self *SKVMGuestDriver) ValidateDetachNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest) error { + if guest.Status == api.VM_RUNNING && guest.GetMetadata("hot_remove_nic", nil) != "enable" { + return httperrors.NewBadRequestError("Guest %s can't hot remove nic", guest.GetName()) + } + return nil +} diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 63cbb40ffe..437794b336 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2131,6 +2131,9 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient. if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING}) { return nil, httperrors.NewInvalidStatusError("Cannot detach network in status %s", self.Status) } + if err := self.GetDriver().ValidateDetachNetwork(ctx, userCred, self); err != nil { + return nil, err + } var ( reserve = jsonutils.QueryBoolean(data, "reserve", false) netStr, _ = data.GetString("net_id") diff --git a/pkg/compute/models/guestdrivers.go b/pkg/compute/models/guestdrivers.go index f772b5b200..bb7d5e8214 100644 --- a/pkg/compute/models/guestdrivers.go +++ b/pkg/compute/models/guestdrivers.go @@ -146,6 +146,7 @@ type IGuestDriver interface { IsRebuildRootSupportChangeUEFI() bool ValidateRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, input *api.ServerRebuildRootInput) (*api.ServerRebuildRootInput, error) + ValidateDetachNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest) error IsSupportdDcryptPasswordFromSecretKey() bool diff --git a/pkg/hostman/guestman/guesttasks.go b/pkg/hostman/guestman/guesttasks.go index 4a303cdb65..422b680c77 100644 --- a/pkg/hostman/guestman/guesttasks.go +++ b/pkg/hostman/guestman/guesttasks.go @@ -385,7 +385,20 @@ func (n *SGuestNetworkSyncTask) onNetdevDel(nic jsonutils.JSONObject) { log.Errorf("script down nic failed %s", output) n.errors = append(n.errors, err) } - n.syncNetworkConf() + n.delNicDevice(nic) +} + +func (n *SGuestNetworkSyncTask) delNicDevice(nic jsonutils.JSONObject) { + callback := func(res string) { + if len(res) > 0 { + log.Errorf("network device del failed %s", res) + n.errors = append(n.errors, fmt.Errorf("network device del failed %s", res)) + } else { + n.syncNetworkConf() + } + } + ifname, _ := nic.GetString("ifname") + n.guest.Monitor.DeviceDel(fmt.Sprintf("netdev-%s", ifname), callback) } func (n *SGuestNetworkSyncTask) addNic(nic jsonutils.JSONObject) { diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 90494a37cd..a762b434e0 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -404,6 +404,7 @@ func (s *SKVMGuestInstance) onImportGuestMonitorConnected(ctx context.Context) { s.QemuVersion = version meta := jsonutils.NewDict() meta.Set("hotplug_cpu_mem", jsonutils.NewString("disable")) + meta.Set("hot_remove_nic", jsonutils.NewString("disable")) meta.Set("__qemu_version", jsonutils.NewString(s.GetQemuVersionStr())) s.SyncMetadata(meta) s.SyncStatus() @@ -1327,6 +1328,7 @@ func (s *SKVMGuestInstance) OnResumeSyncMetadataInfo() { meta.Set("__qemu_version", jsonutils.NewString(s.GetQemuVersionStr())) meta.Set("__vnc_port", jsonutils.NewInt(int64(s.GetVncPort()))) meta.Set("hotplug_cpu_mem", jsonutils.NewString("enable")) + meta.Set("hot_remove_nic", jsonutils.NewString("enable")) if len(s.VncPassword) > 0 { meta.Set("__vnc_password", jsonutils.NewString(s.VncPassword)) } diff --git a/pkg/hostman/guestman/qemu-kvmhelper.go b/pkg/hostman/guestman/qemu-kvmhelper.go index 1c2d43031f..a264630f3f 100644 --- a/pkg/hostman/guestman/qemu-kvmhelper.go +++ b/pkg/hostman/guestman/qemu-kvmhelper.go @@ -285,6 +285,7 @@ func (s *SKVMGuestInstance) getVnicDesc(nic jsonutils.JSONObject) string { bw, _ := nic.Int("bw") cmd := fmt.Sprintf(" -device %s", s.getNicDeviceModel(driver)) + cmd += fmt.Sprintf(",id=netdev-%s", ifname) cmd += fmt.Sprintf(",netdev=%s", ifname) cmd += fmt.Sprintf(",mac=%s", mac)