Skip to content

Commit

Permalink
fix(host): reconnect disk when loop device already mounted or mount p…
Browse files Browse the repository at this point in the history
…oint busy
  • Loading branch information
zexi committed Jan 13, 2025
1 parent 4bdb85c commit ead0594
Showing 1 changed file with 57 additions and 10 deletions.
67 changes: 57 additions & 10 deletions pkg/hostman/container/volume_mount/disk/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"fmt"
"path/filepath"
"strings"

"yunion.io/x/log"
"yunion.io/x/pkg/errors"
Expand Down Expand Up @@ -153,29 +154,75 @@ func (d disk) newPostOverlay() iDiskPostOverlay {
return newDiskPostOverlay(d)
}

func (d disk) Mount(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount) error {
iDisk, gd, err := d.getPodDisk(pod, vm)
if err != nil {
return errors.Wrap(err, "get pod disk interface")
}
func (d disk) connectDisk(iDisk storageman.IDisk) (string, bool, error) {
drv, err := iDisk.GetContainerStorageDriver()
if err != nil {
return errors.Wrap(err, "get disk storage driver")
return "", false, errors.Wrap(err, "get disk storage driver")
}
devPath, isConnected, err := drv.CheckConnect(iDisk.GetPath())
if err != nil {
return errors.Wrapf(err, "CheckConnect %s", iDisk.GetPath())
return "", false, errors.Wrapf(err, "CheckConnect %s", iDisk.GetPath())
}
if !isConnected {
devPath, err = drv.ConnectDisk(iDisk.GetPath())
if err != nil {
return errors.Wrapf(err, "ConnectDisk %s", iDisk.GetPath())
return "", false, errors.Wrapf(err, "ConnectDisk %s", iDisk.GetPath())
}
}
mntPoint := pod.GetDiskMountPoint(iDisk)
if err := container_storage.Mount(devPath, mntPoint, gd.Fs); err != nil {
return devPath, isConnected, nil
}

func (d disk) mountDisk(devPath string, mntPoint string, fs string) error {
if err := container_storage.Mount(devPath, mntPoint, fs); err != nil {
return errors.Wrapf(err, "mount %s to %s", devPath, mntPoint)
}
return nil
}

func (d disk) connectDiskAndMount(drv container_storage.IContainerStorage, pod volume_mount.IPodInfo, iDisk storageman.IDisk, fs string) (string, error) {
devPath, isConnected, err := d.connectDisk(iDisk)
if err != nil {
return "", errors.Wrap(err, "connect disk")
}
mntPoint := pod.GetDiskMountPoint(iDisk)
mountErrs := []error{}
if err := d.mountDisk(devPath, mntPoint, fs); err != nil {
mountErrs = append(mountErrs, err)
if isConnected && strings.Contains(err.Error(), fmt.Sprintf("%s already mounted or mount point busy.", devPath)) {
// disconnect disk and mount agin
if err := drv.DisconnectDisk(iDisk.GetPath(), mntPoint); err != nil {
mountErrs = append(mountErrs, errors.Wrapf(err, "disconnect disk cause of mount point busy"))
return mntPoint, errors.NewAggregate(mountErrs)
}
devPath, _, err = d.connectDisk(iDisk)
if err != nil {
return mntPoint, errors.Wrap(err, "connect disk after disconnect")
}
if err := d.mountDisk(devPath, mntPoint, fs); err != nil {
mountErrs = append(mountErrs, errors.Wrapf(err, "mount disk after reconnect"))
return mntPoint, errors.NewAggregate(mountErrs)
}
return mntPoint, nil
}
return mntPoint, errors.Wrapf(err, "mount %s to %s", devPath, mntPoint)
}
return mntPoint, nil
}

func (d disk) Mount(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount) error {
iDisk, gd, err := d.getPodDisk(pod, vm)
if err != nil {
return errors.Wrap(err, "get pod disk interface")
}
drv, err := iDisk.GetContainerStorageDriver()
if err != nil {
return errors.Wrap(err, "get disk storage driver")
}
mntPoint, err := d.connectDiskAndMount(drv, pod, iDisk, gd.Fs)
if err != nil {
return errors.Wrap(err, "connect disk and mount disk")
}

vmDisk := vm.Disk
if vmDisk.SubDirectory != "" {
subDir := filepath.Join(mntPoint, vmDisk.SubDirectory)
Expand Down

0 comments on commit ead0594

Please sign in to comment.