From cddadf9f0391cc9ade515f37a336a75b68bb6947 Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Thu, 21 Nov 2019 20:41:45 +0800 Subject: [PATCH] instance snapshot bugfix --- pkg/compute/models/guests.go | 12 +++++++---- pkg/compute/models/instance_snapshots.go | 4 +++- pkg/compute/tasks/guest_start_task.go | 4 +++- .../tasks/instance_snapshot_create_task.go | 18 ++++++----------- pkg/hostman/guestman/guestman.go | 3 +++ pkg/hostman/guestman/qemu-kvm.go | 16 +++++++++++++++ pkg/hostman/hostinfo/hostinfohelper.go | 2 ++ pkg/hostman/storageman/disk_local.go | 20 +++++++++++++++++++ 8 files changed, 61 insertions(+), 18 deletions(-) diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index a6780d0ef1..3e02222068 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -1124,10 +1124,14 @@ func (manager *SGuestManager) validateCreateData( return nil, httperrors.NewInputParameterError("invalid duration %s", input.Duration) } - if input.BillingType == billing_api.BILLING_TYPE_POSTPAID && !GetDriver(hypervisor).IsSupportPostpaidExpire() { - return nil, httperrors.NewBadRequestError("guest %s unsupport postpaid expire", hypervisor) - } else if !GetDriver(hypervisor).IsSupportedBillingCycle(billingCycle) { - return nil, httperrors.NewInputParameterError("unsupported duration %s", input.Duration) + if input.BillingType == billing_api.BILLING_TYPE_POSTPAID { + if !GetDriver(hypervisor).IsSupportPostpaidExpire() { + return nil, httperrors.NewBadRequestError("guest %s unsupport postpaid expire", hypervisor) + } + } else { + if !GetDriver(hypervisor).IsSupportedBillingCycle(billingCycle) { + return nil, httperrors.NewInputParameterError("unsupported duration %s", input.Duration) + } } if len(input.BillingType) == 0 { diff --git a/pkg/compute/models/instance_snapshots.go b/pkg/compute/models/instance_snapshots.go index 429efba2d0..7fbb08ef66 100644 --- a/pkg/compute/models/instance_snapshots.go +++ b/pkg/compute/models/instance_snapshots.go @@ -57,6 +57,7 @@ type SInstanceSnapshot struct { RefCount int `default:"0" list:"user"` SecGroups jsonutils.JSONObject `nullable:"true" list:"user"` KeypairId string `width:"36" charset:"ascii" nullable:"true" list:"user"` + OsType string `width:"36" charset:"ascii" nullable:"true" list:"user"` } type SInstanceSnapshotManager struct { @@ -208,7 +209,7 @@ func (manager *SInstanceSnapshotManager) CreateInstanceSnapshot( } instanceSnapshot.SecGroups = jsonutils.Marshal(secIds) } - + instanceSnapshot.OsType = guest.OsType instanceSnapshot.ServerMetadata = serverMetadata err := manager.TableSpec().Insert(instanceSnapshot) if err != nil { @@ -254,6 +255,7 @@ func (self *SInstanceSnapshot) ToInstanceCreateInput( } sourceInput.Secgroups = inputSecgs } + sourceInput.OsType = self.OsType // sourceInput.Networks = serverConfig.Networks return sourceInput, nil } diff --git a/pkg/compute/tasks/guest_start_task.go b/pkg/compute/tasks/guest_start_task.go index 61744fdc13..906807021a 100644 --- a/pkg/compute/tasks/guest_start_task.go +++ b/pkg/compute/tasks/guest_start_task.go @@ -133,7 +133,9 @@ func (self *GuestStartTask) OnStartComplete(ctx context.Context, obj db.IStandal guest := obj.(*models.SGuest) db.OpsLog.LogEvent(guest, db.ACT_START, guest.GetShortDesc(ctx), self.UserCred) self.SetStage("OnGuestSyncstatusAfterStart", nil) - guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId()) + if guest.Hypervisor != api.HYPERVISOR_KVM { + guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId()) + } // self.taskComplete(ctx, guest) } diff --git a/pkg/compute/tasks/instance_snapshot_create_task.go b/pkg/compute/tasks/instance_snapshot_create_task.go index 83b4ded1f6..8dd96872d3 100644 --- a/pkg/compute/tasks/instance_snapshot_create_task.go +++ b/pkg/compute/tasks/instance_snapshot_create_task.go @@ -125,6 +125,12 @@ func (self *InstanceSnapshotCreateTask) GuestDiskCreateSnapshot( return } + err = models.InstanceSnapshotJointManager.CreateJoint(isp.Id, snapshot.Id, int8(diskIndex)) + if err != nil { + self.taskFail(ctx, isp, guest, err.Error()) + return + } + params := jsonutils.NewDict() params.Set("disk_index", jsonutils.NewInt(int64(diskIndex))) params.Set(strconv.Itoa(diskIndex), jsonutils.NewString(snapshot.Id)) @@ -147,18 +153,6 @@ func (self *InstanceSnapshotCreateTask) OnDiskSnapshot( return } - snapshotId, err := self.Params.GetString(strconv.Itoa(int(diskIndex))) - if err != nil { - self.taskFail(ctx, isp, guest, err.Error()) - return - } - - err = models.InstanceSnapshotJointManager.CreateJoint(isp.Id, snapshotId, int8(diskIndex)) - if err != nil { - self.taskFail(ctx, isp, guest, err.Error()) - return - } - self.GuestDiskCreateSnapshot(ctx, isp, guest, int(diskIndex+1)) } diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index 0efa84951f..baf4a1ba9e 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -452,6 +452,9 @@ func (m *SGuestManager) GetStatus(sid string) string { } } if guest.IsRunning() { + if guest.BlockJobsCount() > 0 { + return GUEST_BLOCK_STREAM + } return GUEST_RUNNING } else if guest.IsSuspend() { return GUEST_SUSPEND diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 54673f9bf4..a93bd422fd 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -666,6 +666,22 @@ func (s *SKVMGuestInstance) MirrorJobStatus() MirrorJob { } } +func (s *SKVMGuestInstance) BlockJobsCount() int { + res := make(chan *jsonutils.JSONArray) + s.Monitor.GetBlockJobs(func(jobs *jsonutils.JSONArray) { + res <- jobs + }) + select { + case <-time.After(time.Second * 3): + return -1 + case v := <-res: + if v != nil && v.Length() > 0 { + return v.Length() + } + } + return 0 +} + func (s *SKVMGuestInstance) CleanStartupTask() { log.Infof("Clean startup task ...") if s.startupTask != nil { diff --git a/pkg/hostman/hostinfo/hostinfohelper.go b/pkg/hostman/hostinfo/hostinfohelper.go index b504bf71a6..bb6a0332e9 100644 --- a/pkg/hostman/hostinfo/hostinfohelper.go +++ b/pkg/hostman/hostinfo/hostinfohelper.go @@ -294,6 +294,8 @@ func NewNIC(desc string) (*SNIC, error) { log.Infof("IP %s/%s/%s", nic.Ip, nic.Bridge, nic.Inter) // 这是干啥呢 ??? if len(nic.Ip) > 0 { + // waiting for interface assign ip + // in case nic bonding is too slow var max, wait = 30, 0 for wait < max { inf := netutils2.NewNetInterfaceWithExpectIp(nic.Inter, nic.Ip) diff --git a/pkg/hostman/storageman/disk_local.go b/pkg/hostman/storageman/disk_local.go index 127e1b14f4..4dfb4d707a 100644 --- a/pkg/hostman/storageman/disk_local.go +++ b/pkg/hostman/storageman/disk_local.go @@ -17,8 +17,10 @@ package storageman import ( "context" "fmt" + "io/ioutil" "os" "path" + "strings" "github.com/pkg/errors" @@ -95,6 +97,15 @@ func (d *SLocalDisk) UmountFuseImage() { mntPath := path.Join(d.Storage.GetFuseMountPath(), d.Id) procutils.NewCommand("umount", mntPath).Run() procutils.NewCommand("rm", "-rf", mntPath).Run() + tmpPath := d.Storage.GetFuseTmpPath() + tmpFiles, err := ioutil.ReadDir(tmpPath) + if err != nil { + for _, f := range tmpFiles { + if strings.HasPrefix(f.Name(), d.Id) { + procutils.NewCommand("rm", "-f", path.Join(tmpPath, f.Name())) + } + } + } } func (d *SLocalDisk) Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) { @@ -317,6 +328,15 @@ func (d *SLocalDisk) PostCreateFromImageFuse() { if _, err := procutils.NewCommand("rm", "-rf", mntPath).Run(); err != nil { log.Errorln(err) } + tmpPath := d.Storage.GetFuseTmpPath() + tmpFiles, err := ioutil.ReadDir(tmpPath) + if err != nil { + for _, f := range tmpFiles { + if strings.HasPrefix(f.Name(), d.Id) { + procutils.NewCommand("rm", "-f", path.Join(tmpPath, f.Name())) + } + } + } } func (d *SLocalDisk) CreateSnapshot(snapshotId string) error {