Merge pull request #15518 from wanyaoqi/automated-cherry-pick-of-#15509-upstream-release-3.10

Automated cherry pick of #15509: fix(region,host): fix some bugs of server disk change storage
This commit is contained in:
Zexi Li
2022-12-09 11:45:26 +08:00
committed by GitHub
6 changed files with 113 additions and 40 deletions
+5 -4
View File
@@ -842,10 +842,11 @@ type ServerChangeDiskStorageInput struct {
type ServerChangeDiskStorageInternalInput struct {
ServerChangeDiskStorageInput
StorageId string `json:"storage_id"`
TargetDiskId string `json:"target_disk_id"`
DiskFormat string `json:"disk_format"`
GuestRunning bool `josn:"guest_running"`
StorageId string `json:"storage_id"`
TargetDiskId string `json:"target_disk_id"`
DiskFormat string `json:"disk_format"`
GuestRunning bool `josn:"guest_running"`
TargetDiskDesc *GuestdiskJsonDesc `json:"target_disk_desc"`
}
type ServerSetExtraOptionInput struct {
+7 -3
View File
@@ -175,8 +175,12 @@ func (self *SGuestdisk) GetDisk() *SDisk {
func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api.GuestdiskJsonDesc {
disk := self.GetDisk()
return self.GetDiskJsonDescAtHost(ctx, host, disk)
}
func (self *SGuestdisk) GetDiskJsonDescAtHost(ctx context.Context, host *SHost, disk *SDisk) *api.GuestdiskJsonDesc {
desc := &api.GuestdiskJsonDesc{
DiskId: self.DiskId,
DiskId: disk.Id,
Driver: self.Driver,
CacheMode: self.CacheMode,
AioMode: self.AioMode,
@@ -185,9 +189,9 @@ func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api
Size: disk.DiskSize,
}
desc.TemplateId = disk.GetTemplateId()
storage, _ := disk.GetStorage()
desc.StorageType = storage.StorageType
if len(desc.TemplateId) > 0 {
storage, _ := disk.GetStorage()
desc.StorageType = storage.StorageType
storagecacheimg := StoragecachedimageManager.GetStoragecachedimage(storage.StoragecacheId, desc.TemplateId)
if storagecacheimg != nil {
desc.ImagePath = storagecacheimg.Path
@@ -118,6 +118,26 @@ func (t *GuestChangeDiskStorageTask) OnDiskLiveChangeStorageReady(
) {
if !jsonutils.QueryBoolean(data, "block_jobs_ready", false) {
log.Infof("OnDiskLiveChangeStorageReady block jobs not ready")
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
if err := data.Unmarshal(resp); err != nil {
t.TaskFailed(ctx, guest,
jsonutils.NewString(fmt.Sprintf("unmarshal OnDiskLiveChangeStorageReady resp failed %s", err)),
)
return
}
targetDisk, err := t.GetTargetDisk()
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get target disk %s", err)))
return
}
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
targetDisk.AccessPath = resp.TargetAccessPath
targetDisk.DiskFormat = resp.TargetFormat
return nil
}); err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
return
}
return
}
@@ -126,6 +146,22 @@ func (t *GuestChangeDiskStorageTask) OnDiskLiveChangeStorageReady(
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetInputParams error: %v", err)))
return
}
guestdisk := guest.GetGuestDisk(input.DiskId)
if guestdisk == nil {
t.TaskFailed(ctx, guest, jsonutils.NewString("failed get guest disk"))
return
}
host, err := guest.GetHost()
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get host %s", err)))
return
}
targetDisk, err := t.GetTargetDisk()
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed get target disk %s", err)))
return
}
input.TargetDiskDesc = guestdisk.GetDiskJsonDescAtHost(ctx, host, targetDisk)
t.SetStage("OnDiskChangeStorageComplete", nil)
// block job ready, start switch to target storage disk
@@ -157,29 +193,36 @@ func (t *GuestChangeDiskStorageTask) OnDiskChangeStorageComplete(ctx context.Con
return
}
// update target disk attributes by response
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
if err := data.Unmarshal(resp); err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Unmarshal response: %v", err)))
return
}
if len(resp.TargetFormat) == 0 {
resp.TargetFormat = srcDisk.DiskFormat
}
targetDisk, err := t.GetTargetDisk()
input, err := t.GetInputParams()
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetTargetDisk error: %v", err)))
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetInputParams error: %v", err)))
return
}
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
targetDisk.AccessPath = resp.TargetAccessPath
targetDisk.DiskFormat = resp.TargetFormat
return nil
}); err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
return
if !input.GuestRunning {
resp := new(hostapi.ServerCloneDiskFromStorageResponse)
err = data.Unmarshal(resp)
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Unmarshal response: %v", err)))
return
}
if len(resp.TargetFormat) == 0 {
resp.TargetFormat = srcDisk.DiskFormat
}
targetDisk, err := t.GetTargetDisk()
if err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("GetTargetDisk error: %v", err)))
return
}
if _, err := db.UpdateWithLock(ctx, targetDisk, func() error {
targetDisk.AccessPath = resp.TargetAccessPath
targetDisk.DiskFormat = resp.TargetFormat
return nil
}); err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("Update target disk attributes error: %v", err)))
return
}
}
guestSrcDisk := guest.GetGuestDisk(srcDisk.GetId())
@@ -248,9 +291,20 @@ func (t *GuestChangeDiskStorageTask) attachTargetDisk(ctx context.Context, guest
}
func (t *GuestChangeDiskStorageTask) OnTargetDiskAttachComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
t.SetStage("OnGuestSyncStatus", nil)
if err := guest.StartSyncstatus(ctx, t.UserCred, t.Id); err != nil {
t.TaskFailed(ctx, guest, jsonutils.NewString(err.Error()))
}
}
func (t *GuestChangeDiskStorageTask) OnGuestSyncStatus(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
t.TaskComplete(ctx, guest, nil)
}
func (t *GuestChangeDiskStorageTask) OnGuestSyncStatusFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
t.TaskFailed(ctx, guest, data)
}
func (t *GuestChangeDiskStorageTask) OnTargetDiskAttachCompleteFailed(ctx context.Context, guest *models.SGuest, err jsonutils.JSONObject) {
t.TaskFailed(ctx, guest, err)
}
@@ -389,7 +389,7 @@ func guestDestPrepareMigrateInternal(ctx context.Context, userCred mcclient.Toke
params.DisksBackingFile = disksBack
}
disks := guestDesc.Disks
if err != nil {
if disks == nil {
return httperrors.NewInputParameterError("Get desc disks error")
} else {
targetStorageIds := []string{}
@@ -666,12 +666,13 @@ func formatCloneDiskParams(sid string, body jsonutils.JSONObject) (*guestman.SSt
}
params := &guestman.SStorageCloneDisk{
ServerId: sid,
SourceStorage: srcStorage,
SourceDisk: srcDisk,
TargetStorage: targetStorage,
TargetDiskId: input.TargetDiskId,
DiskFormat: input.DiskFormat,
ServerId: sid,
SourceStorage: srcStorage,
SourceDisk: srcDisk,
TargetStorage: targetStorage,
TargetDiskId: input.TargetDiskId,
DiskFormat: input.DiskFormat,
TargetDiskDesc: input.TargetDiskDesc,
}
return params, nil
}
+7 -6
View File
@@ -1278,12 +1278,13 @@ func (m *SGuestManager) ExitGuestCleanup() {
}
type SStorageCloneDisk struct {
ServerId string
SourceStorage storageman.IStorage
SourceDisk storageman.IDisk
TargetStorage storageman.IStorage
TargetDiskId string
DiskFormat string
ServerId string
SourceStorage storageman.IStorage
SourceDisk storageman.IDisk
TargetStorage storageman.IStorage
TargetDiskId string
DiskFormat string
TargetDiskDesc *compute.GuestdiskJsonDesc
}
func (m *SGuestManager) StorageCloneDisk(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
+12
View File
@@ -2359,6 +2359,7 @@ func (t *SGuestStorageCloneDiskTask) Start(guestRunning bool) {
disks := t.Desc.Disks
for diskIndex = 0; diskIndex < len(disks); diskIndex++ {
if disks[diskIndex].DiskId == t.params.SourceDisk.GetId() {
diskIndex = int(disks[diskIndex].Index)
break
}
}
@@ -2444,6 +2445,7 @@ func NewGuestLiveChangeDiskTask(ctx context.Context, guest *SKVMGuestInstance, p
disks := guest.Desc.Disks
for diskIndex = 0; diskIndex < len(disks); diskIndex++ {
if disks[diskIndex].DiskId == params.SourceDisk.GetId() {
diskIndex = int(disks[diskIndex].Index)
break
}
}
@@ -2495,6 +2497,16 @@ func (t *SGuestLiveChangeDisk) onReopenImageSuccess(res string) {
hostutils.TaskFailed(t.ctx, fmt.Sprintf("reopen image failed: %s", res))
return
}
if t.params.TargetDiskDesc != nil {
for i := 0; i < len(t.Desc.Disks); i++ {
if t.Desc.Disks[i].Index == int8(t.diskIndex) {
log.Debugf("update guest disk %s desc", t.Desc.Disks[i].DiskId)
t.Desc.Disks[i].GuestdiskJsonDesc = *t.params.TargetDiskDesc
t.SaveLiveDesc(t.Desc)
break
}
}
}
resp := &hostapi.ServerCloneDiskFromStorageResponse{
TargetAccessPath: t.targetDisk.GetPath(),