Skip to content

Commit cc92a5e

Browse files
authored
fix(host): clean loop device before deleting (#22557)
1 parent c178cc8 commit cc92a5e

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

pkg/hostman/storageman/disk_local.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"yunion.io/x/log"
2828
"yunion.io/x/pkg/appctx"
2929
"yunion.io/x/pkg/errors"
30+
"yunion.io/x/pkg/util/qemuimgfmt"
3031
"yunion.io/x/pkg/utils"
3132

3233
"yunion.io/x/onecloud/pkg/apis"
@@ -40,6 +41,7 @@ import (
4041
"yunion.io/x/onecloud/pkg/httperrors"
4142
"yunion.io/x/onecloud/pkg/util/fileutils2"
4243
"yunion.io/x/onecloud/pkg/util/losetup"
44+
"yunion.io/x/onecloud/pkg/util/mountutils"
4345
"yunion.io/x/onecloud/pkg/util/netutils2"
4446
"yunion.io/x/onecloud/pkg/util/procutils"
4547
"yunion.io/x/onecloud/pkg/util/qemuimg"
@@ -127,6 +129,9 @@ func (d *SLocalDisk) UmountFuseImage() {
127129
func (d *SLocalDisk) Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
128130
p := params.(api.DiskDeleteInput)
129131
dpath := d.GetPath()
132+
if err := d.cleanLoopDevice(dpath); err != nil {
133+
return nil, errors.Wrapf(err, "clean loop device")
134+
}
130135
log.Infof("Delete guest disk %s", dpath)
131136
if err := d.Storage.DeleteDiskfile(dpath, p.SkipRecycle != nil && *p.SkipRecycle); err != nil {
132137
return nil, err
@@ -333,6 +338,47 @@ func (d *SLocalDisk) CreateFromUrl(ctx context.Context, url string, size int64,
333338
return nil
334339
}
335340

341+
func (d *SLocalDisk) cleanLoopDevice(diskPath string) error {
342+
diskFmt, _ := d.GetFormat()
343+
if diskFmt != string(qemuimgfmt.RAW) {
344+
return nil
345+
}
346+
devs, err := losetup.ListDevices()
347+
if err != nil {
348+
return errors.Wrap(err, "list devices fail")
349+
}
350+
dev := devs.GetDeviceByFile(diskPath)
351+
if dev == nil {
352+
return nil
353+
}
354+
drv, _ := d.GetContainerStorageDriver()
355+
if drv == nil {
356+
return nil
357+
}
358+
devPart := fmt.Sprintf("%sp1", dev.Name)
359+
cmd := fmt.Sprintf("mount | grep %s | awk '{print $3}'", devPart)
360+
out, err := procutils.NewRemoteCommandAsFarAsPossible("sh", "-c", cmd).Output()
361+
if err != nil {
362+
return errors.Wrapf(err, "exec cmd %s: %s", cmd, out)
363+
}
364+
mntPoints := strings.Split(string(out), "\n")
365+
lastMntPoint := ""
366+
for _, mntPoint := range mntPoints {
367+
if mntPoint == "" {
368+
continue
369+
}
370+
lastMntPoint = mntPoint
371+
if err := mountutils.Unmount(mntPoint, false); err != nil {
372+
return errors.Wrapf(err, "umount %s", mntPoint)
373+
}
374+
}
375+
376+
if err := drv.DisconnectDisk(diskPath, lastMntPoint); err != nil {
377+
return errors.Wrapf(err, "DisconnectDisk(%s)", diskPath)
378+
}
379+
return nil
380+
}
381+
336382
func (d *SLocalDisk) CreateRaw(ctx context.Context, sizeMB int, diskFormat string, fsFormat string, fsFeatures *api.DiskFsFeatures, encryptInfo *apis.SEncryptInfo, diskId string, back string) (jsonutils.JSONObject, error) {
337383
if fileutils2.Exists(d.GetPath()) {
338384
if err := os.Remove(d.GetPath()); err != nil {

0 commit comments

Comments
 (0)