mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(host): lvm guest reload disk before delete snapshot (#23053)
This commit is contained in:
@@ -2155,6 +2155,8 @@ type SGuestSnapshotDeleteTask struct {
|
||||
encryptInfo apis.SEncryptInfo
|
||||
|
||||
tmpPath string
|
||||
|
||||
delSnapshotPathAfterReload func() error
|
||||
}
|
||||
|
||||
func NewGuestSnapshotDeleteTask(
|
||||
@@ -2176,10 +2178,12 @@ func (s *SGuestSnapshotDeleteTask) Start(totalDeleteSnapshotCount, deletedSnapsh
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.doDiskConvert(); err != nil {
|
||||
cb, err := s.disk.ConvertSnapshotRelyOnReloadDisk(s.convertSnapshot, s.encryptInfo)
|
||||
if err != nil {
|
||||
s.taskFailed(err.Error())
|
||||
return
|
||||
}
|
||||
s.delSnapshotPathAfterReload = cb
|
||||
s.fetchDisksInfo(s.doReloadDisk)
|
||||
}
|
||||
|
||||
@@ -2205,15 +2209,17 @@ func (s *SGuestSnapshotDeleteTask) onStreamDiskComplete() {
|
||||
hostutils.TaskComplete(s.ctx, body)
|
||||
}
|
||||
|
||||
func (s *SGuestSnapshotDeleteTask) doDiskConvert() error {
|
||||
return s.disk.ConvertSnapshot(s.convertSnapshot, s.encryptInfo)
|
||||
}
|
||||
|
||||
func (s *SGuestSnapshotDeleteTask) doReloadDisk(device string) {
|
||||
s.SGuestReloadDiskTask.doReloadDisk(device, s.onReloadBlkdevSucc)
|
||||
}
|
||||
|
||||
func (s *SGuestSnapshotDeleteTask) onReloadBlkdevSucc(err string) {
|
||||
if s.delSnapshotPathAfterReload != nil {
|
||||
if e := s.delSnapshotPathAfterReload(); e != nil {
|
||||
log.Errorf("failed do delSnapshotPathAfterReload: %s", e)
|
||||
}
|
||||
}
|
||||
|
||||
var callback = s.onResumeSucc
|
||||
if len(err) > 0 {
|
||||
callback = func(string) {
|
||||
|
||||
@@ -77,7 +77,7 @@ type IDisk interface {
|
||||
DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error
|
||||
DeployGuestFs(diskInfo *deployapi.DiskInfo, guestDesc *desc.SGuestDesc,
|
||||
deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error)
|
||||
ConvertSnapshot(convertSnapshotId string, encryptInfo apis.SEncryptInfo) error
|
||||
ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error)
|
||||
|
||||
// GetBackupDir() string
|
||||
DiskBackup(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
@@ -147,8 +147,8 @@ func (d *SBaseDisk) CreateSnapshot(snapshotId string, encryptKey string, encForm
|
||||
return errors.Errorf("unsupported operation")
|
||||
}
|
||||
|
||||
func (d *SBaseDisk) ConvertSnapshot(convertSnapshotId string, encryptInfo apis.SEncryptInfo) error {
|
||||
return errors.Errorf("unsupported operation")
|
||||
func (d *SBaseDisk) ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
return nil, errors.Errorf("unsupported operation")
|
||||
}
|
||||
|
||||
func (d *SBaseDisk) DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error {
|
||||
|
||||
@@ -511,13 +511,13 @@ func (d *SLocalDisk) CreateSnapshot(snapshotId string, encryptKey string, encFor
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SLocalDisk) ConvertSnapshot(convertSnapshotId string, encryptInfo apis.SEncryptInfo) error {
|
||||
func (d *SLocalDisk) ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
snapshotDir := d.GetSnapshotDir()
|
||||
snapshotPath := path.Join(snapshotDir, convertSnapshotId)
|
||||
img, err := qemuimg.NewQemuImage(snapshotPath)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
convertedDisk := snapshotPath + ".tmp"
|
||||
if err = img.Convert2Qcow2To(convertedDisk, false, "", "", ""); err != nil {
|
||||
@@ -525,13 +525,13 @@ func (d *SLocalDisk) ConvertSnapshot(convertSnapshotId string, encryptInfo apis.
|
||||
if fileutils2.Exists(convertedDisk) {
|
||||
os.Remove(convertedDisk)
|
||||
}
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if output, err := procutils.NewCommand("mv", "-f", convertedDisk, snapshotPath).Output(); err != nil {
|
||||
log.Errorf("mv %s to %s failed: %s, %s", convertedDisk, snapshotPath, err, output)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (d *SLocalDisk) DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error {
|
||||
|
||||
@@ -613,6 +613,11 @@ func (d *SLVMDisk) ConvertSnapshot(convertSnapshot string, encryptInfo apis.SEnc
|
||||
return ConvertLVMDisk(d.Storage.GetPath(), convertSnapshotName, encryptInfo)
|
||||
}
|
||||
|
||||
func (d *SLVMDisk) ConvertSnapshotRelyOnReloadDisk(convertSnapshot string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
convertSnapshotName := d.GetSnapshotName(convertSnapshot)
|
||||
return ConvertLVMDiskNeedReload(d.Storage.GetPath(), convertSnapshotName, encryptInfo)
|
||||
}
|
||||
|
||||
func (d *SLVMDisk) DoDeleteSnapshot(snapshotId string) error {
|
||||
snapshotPath := d.GetSnapshotPath(snapshotId)
|
||||
return lvmutils.LvRemove(snapshotPath)
|
||||
|
||||
@@ -256,8 +256,8 @@ func (d *SRBDDisk) CreateSnapshot(snapshotId string, encryptKey string, encForma
|
||||
return storage.createSnapshot(d.Id, snapshotId)
|
||||
}
|
||||
|
||||
func (d *SRBDDisk) ConvertSnapshot(convertSnapshotId string, encryptInfo apis.SEncryptInfo) error {
|
||||
return nil
|
||||
func (d *SRBDDisk) ConvertSnapshotRelyOnReloadDisk(convertSnapshotId string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (d *SRBDDisk) DeleteSnapshot(snapshotId, convertSnapshot string, blockStream bool, encryptInfo apis.SEncryptInfo) error {
|
||||
|
||||
@@ -653,23 +653,27 @@ func (d *SLVMStorage) GetDisksPath() ([]string, error) {
|
||||
return disksPath, nil
|
||||
}
|
||||
|
||||
func ConvertLVMDisk(vgName, lvName string, encryptInfo apis.SEncryptInfo) error {
|
||||
func ConvertLVMDiskNeedReload(vgName, lvName string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
return convertLVMDisk(vgName, lvName, encryptInfo)
|
||||
}
|
||||
|
||||
func convertLVMDisk(vgName, lvName string, encryptInfo apis.SEncryptInfo) (func() error, error) {
|
||||
diskPath := path.Join("/dev", vgName, lvName)
|
||||
qemuImg, err := qemuimg.NewQemuImage(diskPath)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
lvSize, err := lvmutils.GetLvSize(diskPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tmpVolume := lvName + "-convert.tmp"
|
||||
tmpVolumePath := path.Join("/dev", vgName, tmpVolume)
|
||||
// create /dev/vg/disk-convert.tmp
|
||||
if err := lvmutils.LvCreate(vgName, tmpVolume, lvSize); err != nil {
|
||||
return errors.Wrap(err, "delete snapshot LvCreate")
|
||||
return nil, errors.Wrap(err, "delete snapshot LvCreate")
|
||||
}
|
||||
srcInfo := qemuimg.SImageInfo{
|
||||
Path: diskPath,
|
||||
@@ -692,25 +696,41 @@ func ConvertLVMDisk(vgName, lvName string, encryptInfo apis.SEncryptInfo) error
|
||||
}
|
||||
// convert /dev/vg/disk to /dev/vg/disk-convert.tmp
|
||||
if err = qemuimg.Convert(srcInfo, destInfo, false, nil); err != nil {
|
||||
lvmutils.LvRemove(tmpVolumePath)
|
||||
return errors.Wrap(err, "failed convert tmp disk")
|
||||
if e := lvmutils.LvRemove(tmpVolumePath); e != nil {
|
||||
log.Errorf("failed remote lvm convert tmp volume %s", tmpVolumePath)
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed convert tmp disk")
|
||||
}
|
||||
tmpVolume2 := lvName + "-convert.tmp2"
|
||||
tmpVolume2Path := path.Join("/dev", vgName, tmpVolume2)
|
||||
// rename /dev/vg/disk to /dev/vg/disk-convert.tmp2
|
||||
err = lvmutils.LvRename(vgName, diskPath, tmpVolume2)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed rename disk to tmp")
|
||||
return nil, errors.Wrap(err, "failed rename disk to tmp")
|
||||
}
|
||||
// rename /dev/vg/disk-convert.tmp to /dev/vg/disk
|
||||
err = lvmutils.LvRename(vgName, tmpVolume, diskPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed rename tmp to disk")
|
||||
return nil, errors.Wrap(err, "failed rename tmp to disk")
|
||||
}
|
||||
// delete /dev/vg/disk-convert.tmp2
|
||||
err = lvmutils.LvRemove(tmpVolume2Path)
|
||||
return func() error {
|
||||
// delete /dev/vg/disk-convert.tmp2
|
||||
e1 := lvmutils.LvRemove(tmpVolume2Path)
|
||||
if e1 != nil {
|
||||
return errors.Wrap(err, "failed remove tmp disk")
|
||||
}
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConvertLVMDisk(vgName, lvName string, encryptInfo apis.SEncryptInfo) error {
|
||||
delTmpVolume2Disk, err := convertLVMDisk(vgName, lvName, encryptInfo)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed remove tmp disk")
|
||||
return err
|
||||
}
|
||||
err = delTmpVolume2Disk()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user