Skip to content

Commit

Permalink
fix migrate with multi local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
wanyaoqi committed May 29, 2020
1 parent 4362927 commit 4d404e0
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 111 deletions.
4 changes: 0 additions & 4 deletions pkg/compute/models/guestdisks.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,11 @@ func (self *SGuestdisk) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
desc.Add(jsonutils.NewString(storagecacheimg.Path), "image_path")
}
}
storage := disk.GetStorage()
// XXX ???
if host.HostType == api.HOST_TYPE_HYPERVISOR {
desc.Add(jsonutils.NewString(disk.StorageId), "storage_id")
localpath := disk.GetPathAtHost(host)
if len(localpath) == 0 {
desc.Add(jsonutils.JSONTrue, "migrating")
target := host.GetLeastUsedStorage(storage.StorageType)
desc.Add(jsonutils.NewString(target.Id), "target_storage_id")
disk.SetStatus(nil, api.DISK_START_MIGRATE, "migration")
} else {
desc.Add(jsonutils.NewString(localpath), "path")
Expand Down
33 changes: 19 additions & 14 deletions pkg/compute/tasks/guest_live_migrate_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ func (self *GuestMigrateTask) SaveScheduleResult(ctx context.Context, obj ISched
isLocalStorage := utils.IsInStringArray(disk.GetStorage().StorageType,
api.STORAGE_LOCAL_TYPES)
if isLocalStorage {
targetStorages := jsonutils.NewArray()
for i := 0; i < len(disks); i++ {
var targetStroage string
if len(target.Disks[i].StorageIds) == 0 {
targetStroage = targetHost.GetLeastUsedStorage(disk.GetStorage().StorageType).Id
} else {
targetStroage = target.Disks[i].StorageIds[0]
}
targetStorages.Add(jsonutils.NewString(targetStroage))
}
body.Set("target_storages", targetStorages)
body.Set("is_local_storage", jsonutils.JSONTrue)
} else {
body.Set("is_local_storage", jsonutils.JSONFalse)
Expand Down Expand Up @@ -309,19 +320,14 @@ func (self *GuestMigrateTask) localStorageMigrateConf(ctx context.Context,
self.TaskFailed(ctx, guest, "Get disksDesc error")
return nil, true
}
targetStorageId, _ := disksDesc[0].GetString("target_storage_id")
if len(targetStorageId) == 0 {
self.TaskFailed(ctx, guest, "Get targetStorageId error")
return nil, true
targetStorages, _ := self.Params.GetArray("target_storages")
for i := 0; i < len(disks); i++ {
diskDesc := disksDesc[i].(*jsonutils.JSONDict)
diskDesc.Set("target_storage_id", targetStorages[i])
}

targetStorage := targetHost.GetHoststorageOfId(targetStorageId)
sourceStorage := sourceHost.GetHoststorageOfId(disks[0].GetDisk().StorageId)
if sourceStorage.MountPoint != targetStorage.MountPoint {
// rebase disks backing file
body.Set("rebase_disks", jsonutils.JSONTrue)
}
body.Set("desc", targetDesc)
body.Set("rebase_disks", jsonutils.JSONTrue)
body.Set("is_local_storage", jsonutils.JSONTrue)
return body, false
}
Expand Down Expand Up @@ -363,20 +369,19 @@ func (self *GuestLiveMigrateTask) OnStartDestCompleteFailed(ctx context.Context,
func (self *GuestMigrateTask) setGuest(ctx context.Context, guest *models.SGuest) error {
targetHostId, _ := self.Params.GetString("target_host_id")
if jsonutils.QueryBoolean(self.Params, "is_local_storage", false) {
targetHost := models.HostManager.FetchHostById(targetHostId)
targetStorage := targetHost.GetLeastUsedStorage(api.STORAGE_LOCAL)
targetStorages, _ := self.Params.GetArray("target_storages")
guestDisks := guest.GetDisks()
for i := 0; i < len(guestDisks); i++ {
disk := guestDisks[i].GetDisk()
db.Update(disk, func() error {
disk.Status = api.DISK_READY
disk.StorageId = targetStorage.Id
disk.StorageId, _ = targetStorages[i].GetString()
return nil
})
snapshots := models.SnapshotManager.GetDiskSnapshots(disk.Id)
for _, snapshot := range snapshots {
db.Update(&snapshot, func() error {
snapshot.StorageId = targetStorage.Id
snapshot.StorageId, _ = targetStorages[i].GetString()
return nil
})
}
Expand Down
14 changes: 10 additions & 4 deletions pkg/hostman/guestman/guesthandlers/guesthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,17 @@ func guestDestPrepareMigrate(ctx context.Context, sid string, body jsonutils.JSO
if err != nil {
return nil, httperrors.NewInputParameterError("Get desc disks error")
} else {
targetStorageId, _ := disks[0].GetString("target_storage_id")
if len(targetStorageId) == 0 {
return nil, httperrors.NewMissingParameterError("target_storage_id")
targetStorageIds := []string{}
for i := 0; i < len(disks); i++ {
targetStorageId, _ := disks[i].GetString("target_storage_id")
if len(targetStorageId) == 0 {
return nil, httperrors.NewMissingParameterError("target_storage_id")
}
targetStorageIds = append(targetStorageIds, targetStorageId)
// params.TargetStorageId = targetStorageId
params.TargetStorageIds = targetStorageIds
}
params.TargetStorageId = targetStorageId

}
params.RebaseDisks = jsonutils.QueryBoolean(body, "rebase_disks", false)
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/hostman/guestman/guesthelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ type SSrcPrepareMigrate struct {
}

type SDestPrepareMigrate struct {
Sid string
ServerUrl string
QemuVersion string
SnapshotsUri string
DisksUri string
TargetStorageId string
LiveMigrate bool
RebaseDisks bool
Sid string
ServerUrl string
QemuVersion string
SnapshotsUri string
DisksUri string
// TargetStorageId string
TargetStorageIds []string
LiveMigrate bool
RebaseDisks bool

Desc jsonutils.JSONObject
DisksBackingFile jsonutils.JSONObject
Expand Down
28 changes: 16 additions & 12 deletions pkg/hostman/guestman/guestman.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,23 +598,27 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
return nil, err
}

if len(migParams.TargetStorageId) > 0 {
iStorage := storageman.GetManager().GetStorage(migParams.TargetStorageId)
if iStorage == nil {
return nil, fmt.Errorf("Target storage %s not found", migParams.TargetStorageId)
}
disks, _ := migParams.Desc.GetArray("disks")
if len(migParams.TargetStorageIds) > 0 {
for i := 0; i < len(migParams.TargetStorageIds); i++ {
iStorage := storageman.GetManager().GetStorage(migParams.TargetStorageIds[i])
if iStorage == nil {
return nil, fmt.Errorf("Target storage %s not found", migParams.TargetStorageIds[i])
}

err := iStorage.DestinationPrepareMigrate(
ctx, migParams.LiveMigrate, migParams.DisksUri, migParams.SnapshotsUri,
migParams.Desc, migParams.DisksBackingFile, migParams.SrcSnapshots, migParams.RebaseDisks)
if err != nil {
return nil, fmt.Errorf("dest prepare migrate failed %s", err)
err := iStorage.DestinationPrepareMigrate(
ctx, migParams.LiveMigrate, migParams.DisksUri, migParams.SnapshotsUri,
migParams.DisksBackingFile, migParams.SrcSnapshots, migParams.RebaseDisks, disks[i],
)
if err != nil {
return nil, fmt.Errorf("dest prepare migrate failed %s", err)
}
}

if err = guest.SaveDesc(migParams.Desc); err != nil {
if err := guest.SaveDesc(migParams.Desc); err != nil {
log.Errorln(err)
return nil, err
}

}

if migParams.LiveMigrate {
Expand Down
4 changes: 2 additions & 2 deletions pkg/hostman/storageman/storage_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ type IStorage interface {
GetImgsaveBackupPath() string

DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error
disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool, diskDesc jsonutils.JSONObject) error

Accessible() error
}
Expand Down Expand Up @@ -312,7 +312,7 @@ func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, c

func (s *SBaseStorage) DestinationPrepareMigrate(
ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool,
disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool, diskinfo jsonutils.JSONObject,
) error {
return nil
}
Expand Down
131 changes: 64 additions & 67 deletions pkg/hostman/storageman/storage_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,86 +342,83 @@ func (s *SLocalStorage) DeleteSnapshots(ctx context.Context, params interface{})

func (s *SLocalStorage) DestinationPrepareMigrate(
ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error {
disks, _ := desc.GetArray("disks")
for i, diskinfo := range disks {
var (
diskId, _ = diskinfo.GetString("disk_id")
snapshots, _ = srcSnapshots.GetArray(diskId)
disk = s.CreateDisk(diskId)
)

if disk == nil {
return fmt.Errorf(
"Storage %s create disk %s failed", s.GetId(), diskId)
}
disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool, diskinfo jsonutils.JSONObject) error {
var (
diskId, _ = diskinfo.GetString("disk_id")
snapshots, _ = srcSnapshots.GetArray(diskId)
disk = s.CreateDisk(diskId)
)

templateId, _ := diskinfo.GetString("template_id")
// prepare disk snapshot dir
if len(snapshots) > 0 && !fileutils2.Exists(disk.GetSnapshotDir()) {
_, err := procutils.NewCommand("mkdir", "-p", disk.GetSnapshotDir()).Output()
if err != nil {
return err
}
}
if disk == nil {
return fmt.Errorf(
"Storage %s create disk %s failed", s.GetId(), diskId)
}

// create snapshots form remote url
var (
diskStorageId, _ = diskinfo.GetString("storage_id")
baseImagePath string
)
for i, snapshotId := range snapshots {
snapId, _ := snapshotId.GetString()
snapshotUrl := fmt.Sprintf("%s/%s/%s/%s",
snapshotsUri, diskStorageId, diskId, snapId)
snapshotPath := path.Join(disk.GetSnapshotDir(), snapId)
log.Infof("Disk %s snapshot %s url: %s", diskId, snapId, snapshotUrl)
if err := s.CreateSnapshotFormUrl(ctx, snapshotUrl, diskId, snapshotPath); err != nil {
return errors.Wrap(err, "create from snapshot url failed")
}
baseImagePath = snapshotPath
if i == 0 && len(templateId) > 0 {
templatePath := path.Join(storageManager.LocalStorageImagecacheManager.GetPath(), templateId)
if err := doRebaseDisk(snapshotPath, templatePath); err != nil {
return err
}
} else if rebaseDisks {
if err := doRebaseDisk(snapshotPath, baseImagePath); err != nil {
return err
}
}
templateId, _ := diskinfo.GetString("template_id")
// prepare disk snapshot dir
if len(snapshots) > 0 && !fileutils2.Exists(disk.GetSnapshotDir()) {
_, err := procutils.NewCommand("mkdir", "-p", disk.GetSnapshotDir()).Output()
if err != nil {
return err
}
}

if liveMigrate {
// create local disk
backingFile, _ := disksBackingFile.GetString(diskId)
size, _ := diskinfo.Int("size")
_, err := disk.CreateRaw(ctx, int(size), "qcow2", "", false, "", backingFile)
if err != nil {
log.Errorln(err)
return err
}
} else {
// download disk form remote url
diskUrl := fmt.Sprintf("%s/%s/%s", disksUri, diskStorageId, diskId)
if err := disk.CreateFromUrl(ctx, diskUrl, 0); err != nil {
log.Errorln(err)
return err
}
// create snapshots form remote url
var (
diskStorageId, _ = diskinfo.GetString("storage_id")
baseImagePath string
)
for i, snapshotId := range snapshots {
snapId, _ := snapshotId.GetString()
snapshotUrl := fmt.Sprintf("%s/%s/%s/%s",
snapshotsUri, diskStorageId, diskId, snapId)
snapshotPath := path.Join(disk.GetSnapshotDir(), snapId)
log.Infof("Disk %s snapshot %s url: %s", diskId, snapId, snapshotUrl)
if err := s.CreateSnapshotFormUrl(ctx, snapshotUrl, diskId, snapshotPath); err != nil {
return errors.Wrap(err, "create from snapshot url failed")
}
if rebaseDisks && len(templateId) > 0 && len(baseImagePath) == 0 {
if i == 0 && len(templateId) > 0 {
templatePath := path.Join(storageManager.LocalStorageImagecacheManager.GetPath(), templateId)
if err := doRebaseDisk(disk.GetPath(), templatePath); err != nil {
if err := doRebaseDisk(snapshotPath, templatePath); err != nil {
return err
}
} else if rebaseDisks && len(baseImagePath) > 0 {
if err := doRebaseDisk(disk.GetPath(), baseImagePath); err != nil {
if err := doRebaseDisk(snapshotPath, baseImagePath); err != nil {
return err
}
}
diskDesc, _ := disks[i].(*jsonutils.JSONDict)
diskDesc.Set("path", jsonutils.NewString(disk.GetPath()))
baseImagePath = snapshotPath
}

if liveMigrate {
// create local disk
backingFile, _ := disksBackingFile.GetString(diskId)
size, _ := diskinfo.Int("size")
_, err := disk.CreateRaw(ctx, int(size), "qcow2", "", false, "", backingFile)
if err != nil {
log.Errorln(err)
return err
}
} else {
// download disk form remote url
diskUrl := fmt.Sprintf("%s/%s/%s", disksUri, diskStorageId, diskId)
if err := disk.CreateFromUrl(ctx, diskUrl, 0); err != nil {
log.Errorln(err)
return err
}
}
if rebaseDisks && len(templateId) > 0 && len(baseImagePath) == 0 {
templatePath := path.Join(storageManager.LocalStorageImagecacheManager.GetPath(), templateId)
if err := doRebaseDisk(disk.GetPath(), templatePath); err != nil {
return err
}
} else if rebaseDisks && len(baseImagePath) > 0 {
if err := doRebaseDisk(disk.GetPath(), baseImagePath); err != nil {
return err
}
}
diskDesc, _ := diskinfo.(*jsonutils.JSONDict)
diskDesc.Set("path", jsonutils.NewString(disk.GetPath()))
return nil
}

Expand Down

0 comments on commit 4d404e0

Please sign in to comment.