diff --git a/pkg/apis/compute/container.go b/pkg/apis/compute/container.go index 577e555b676..e2aa5dd4dc2 100644 --- a/pkg/apis/compute/container.go +++ b/pkg/apis/compute/container.go @@ -271,5 +271,6 @@ type ContainerVolumeMountAddPostOverlayInput struct { type ContainerVolumeMountRemovePostOverlayInput struct { Index int `json:"index"` PostOverlay []*apis.ContainerVolumeMountDiskPostOverlay `json:"post_overlay"` + UseLazy bool `json:"use_lazy"` ClearLayers bool `json:"clear_layers"` } diff --git a/pkg/hostman/container/storage/storage.go b/pkg/hostman/container/storage/storage.go index c6524734ff0..ccd99f22ca0 100644 --- a/pkg/hostman/container/storage/storage.go +++ b/pkg/hostman/container/storage/storage.go @@ -55,5 +55,5 @@ func Mount(devPath string, mountPoint string, fsType string) error { } func Unmount(devPath string) error { - return mountutils.Unmount(devPath) + return mountutils.Unmount(devPath, false) } diff --git a/pkg/hostman/container/volume_mount/disk/disk.go b/pkg/hostman/container/volume_mount/disk/disk.go index ddd14d85f2a..5eb6522d269 100644 --- a/pkg/hostman/container/volume_mount/disk/disk.go +++ b/pkg/hostman/container/volume_mount/disk/disk.go @@ -41,7 +41,7 @@ type IVolumeMountDisk interface { volume_mount.IUsageVolumeMount MountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay) error - UnmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, clearLayers bool) error + UnmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, clearLayers bool) error GetHostDiskRootPath(pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount) (string, error) @@ -237,7 +237,7 @@ func (d disk) Unmount(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.Conta return errors.Wrap(err, "get disk storage driver") } if len(vm.Disk.PostOverlay) != 0 { - if err := d.UnmountPostOverlays(pod, ctrId, vm, vm.Disk.PostOverlay, false); err != nil { + if err := d.UnmountPostOverlays(pod, ctrId, vm, vm.Disk.PostOverlay, false, false); err != nil { return errors.Wrap(err, "mount post overlay dirs") } } diff --git a/pkg/hostman/container/volume_mount/disk/post_overlay.go b/pkg/hostman/container/volume_mount/disk/post_overlay.go index ac0ebb7c3a7..ff1321d737d 100644 --- a/pkg/hostman/container/volume_mount/disk/post_overlay.go +++ b/pkg/hostman/container/volume_mount/disk/post_overlay.go @@ -35,8 +35,8 @@ func (d disk) MountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hos return d.newPostOverlay().mountPostOverlays(pod, ctrId, vm, ovs) } -func (d disk) UnmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, clearLayers bool) error { - return d.newPostOverlay().unmountPostOverlays(pod, ctrId, vm, ovs, clearLayers) +func (d disk) UnmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, clearLayers bool) error { + return d.newPostOverlay().unmountPostOverlays(pod, ctrId, vm, ovs, useLazy, clearLayers) } func (d disk) getPostOverlayRootPrefixDir(prefixDir string, pod volume_mount.IPodInfo, vm *hostapi.ContainerVolumeMount, ctrId string) (string, error) { @@ -61,7 +61,7 @@ func (d disk) GetPostOverlayRootUpperDir(pod volume_mount.IPodInfo, vm *hostapi. type iDiskPostOverlay interface { mountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay) error - unmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, clearLayers bool) error + unmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, clearLayers bool) error } type diskPostOverlay struct { @@ -83,9 +83,9 @@ func (d diskPostOverlay) mountPostOverlays(pod volume_mount.IPodInfo, ctrId stri return nil } -func (d diskPostOverlay) unmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, clearLayers bool) error { +func (d diskPostOverlay) unmountPostOverlays(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ovs []*apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, clearLayers bool) error { for _, ov := range ovs { - if err := d.unmountPostOverlay(pod, ctrId, vm, ov, clearLayers); err != nil { + if err := d.unmountPostOverlay(pod, ctrId, vm, ov, useLazy, clearLayers); err != nil { return errors.Wrapf(err, "unmount container %s post overlay dir: %#v", ctrId, ov) } } @@ -164,12 +164,12 @@ func (d diskPostOverlay) mountPostOverlay(pod volume_mount.IPodInfo, ctrId strin return mountutils.MountOverlay(ov.HostLowerDir, upperDir, workDir, mergedDir) } -func (d diskPostOverlay) unmountPostOverlay(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ov *apis.ContainerVolumeMountDiskPostOverlay, cleanLayers bool) error { +func (d diskPostOverlay) unmountPostOverlay(pod volume_mount.IPodInfo, ctrId string, vm *hostapi.ContainerVolumeMount, ov *apis.ContainerVolumeMountDiskPostOverlay, useLazy bool, cleanLayers bool) error { mergedDir, err := d.getPostOverlayMountpoint(pod, ctrId, vm, ov) if err != nil { return errors.Wrapf(err, "get post overlay mountpoint for container %s", ctrId) } - if err := mountutils.Unmount(mergedDir); err != nil { + if err := mountutils.Unmount(mergedDir, useLazy); err != nil { return errors.Wrapf(err, "unmount %s", mergedDir) } if cleanLayers { diff --git a/pkg/hostman/guestman/pod.go b/pkg/hostman/guestman/pod.go index a23c9775ecd..bfd63837c94 100644 --- a/pkg/hostman/guestman/pod.go +++ b/pkg/hostman/guestman/pod.go @@ -2216,7 +2216,7 @@ func (s *sPodGuestInstance) DoSnapshot(ctx context.Context, params *SDiskSnapsho for _, vol := range vols { // unbind mount for _, povPath := range povTmpBackRootDir { - if err := mountutils.Unmount(povPath); err != nil { + if err := mountutils.Unmount(povPath, false); err != nil { return errors.Wrapf(err, "umount bind point %s", povTmpBackRootDir) } } @@ -2224,7 +2224,7 @@ func (s *sPodGuestInstance) DoSnapshot(ctx context.Context, params *SDiskSnapsho if vol.Disk.StorageSizeFile != "" { targetBindMntPath = filepath.Join(tmpBackRootDir, vol.Disk.StorageSizeFile) } - if err := mountutils.Unmount(targetBindMntPath); err != nil { + if err := mountutils.Unmount(targetBindMntPath, false); err != nil { return errors.Wrapf(err, "umount bind point %s", targetBindMntPath) } } @@ -2473,5 +2473,5 @@ func (s *sPodGuestInstance) RemoveContainerVolumeMountPostOverlay(ctx context.Co if err := drv.Mount(s, ctrId, vol); err != nil { return errors.Wrapf(err, "mount volume %s, ctrId %s", jsonutils.Marshal(vol), ctrId) } - return diskDrv.UnmountPostOverlays(s, ctrId, vol, input.PostOverlay, input.ClearLayers) + return diskDrv.UnmountPostOverlays(s, ctrId, vol, input.PostOverlay, input.UseLazy, input.ClearLayers) } diff --git a/pkg/mcclient/options/compute/containers.go b/pkg/mcclient/options/compute/containers.go index 69b25a8f0da..e509ebdffac 100644 --- a/pkg/mcclient/options/compute/containers.go +++ b/pkg/mcclient/options/compute/containers.go @@ -481,6 +481,7 @@ func (o *ContainerAddVolumeMountPostOverlayOptions) Params() (jsonutils.JSONObje type ContainerRemoveVolumeMountPostOverlayOptions struct { ContainerAddVolumeMountPostOverlayOptions ClearLayers bool `help:"clear overlay upper and work layers"` + UseLazy bool `help:"use lazy umount"` } func (o *ContainerRemoveVolumeMountPostOverlayOptions) Params() (jsonutils.JSONObject, error) { @@ -491,5 +492,8 @@ func (o *ContainerRemoveVolumeMountPostOverlayOptions) Params() (jsonutils.JSONO if o.ClearLayers { params.(*jsonutils.JSONDict).Add(jsonutils.JSONTrue, "clear_layers") } + if o.UseLazy { + params.(*jsonutils.JSONDict).Add(jsonutils.JSONTrue, "use_lazy") + } return params, nil } diff --git a/pkg/util/losetup/ioctl/remove.go b/pkg/util/losetup/ioctl/remove.go index 08ce3a283a0..0fec7caebc6 100644 --- a/pkg/util/losetup/ioctl/remove.go +++ b/pkg/util/losetup/ioctl/remove.go @@ -83,7 +83,7 @@ func DetachAndRemoveDevice(devPath string) error { mntPoints := strings.Split(out, "\n") for _, mntPoint := range mntPoints { if mntPoint != "" { - if err := mountutils.Unmount(mntPoint); err != nil { + if err := mountutils.Unmount(mntPoint, false); err != nil { return errors.Wrapf(err, "umount %s of dev: %s, part: %s", mntPoint, dev.Name, part) } } diff --git a/pkg/util/losetup/losetup.go b/pkg/util/losetup/losetup.go index acb790caa90..0a271987438 100644 --- a/pkg/util/losetup/losetup.go +++ b/pkg/util/losetup/losetup.go @@ -286,7 +286,7 @@ func DetachDevice(devPath string) error { mntPoints := strings.Split(out, "\n") for _, mntPoint := range mntPoints { if mntPoint != "" { - if err := mountutils.Unmount(mntPoint); err != nil { + if err := mountutils.Unmount(mntPoint, false); err != nil { return errors.Wrapf(err, "umount %s of dev: %s, part: %s", mntPoint, dev.Name, part) } } diff --git a/pkg/util/mountutils/mount.go b/pkg/util/mountutils/mount.go index 1fed1d62157..a6fc40fe089 100644 --- a/pkg/util/mountutils/mount.go +++ b/pkg/util/mountutils/mount.go @@ -79,8 +79,8 @@ func MountBind(src, target string) error { }) } -func Unmount(mountPoint string) error { - err := unmount(mountPoint) +func Unmount(mountPoint string, useLazy bool) error { + err := unmount(mountPoint, useLazy) errs := []error{} if err != nil { errs = append(errs, errors.Wrap(err, "umount firstly")) @@ -90,7 +90,7 @@ func Unmount(mountPoint string) error { errs = append(errs, errors.Wrapf(err, "clean process use mountpoint: %s", mountPoint)) } // umount again - if err := unmount(mountPoint); err != nil { + if err := unmount(mountPoint, useLazy); err != nil { errs = append(errs, errors.Wrapf(err, "unmount %s after clean process using it", mountPoint)) return errors.NewAggregate(errs) } @@ -102,10 +102,14 @@ func Unmount(mountPoint string) error { return nil } -func unmount(mountPoint string) error { +func unmount(mountPoint string, useLazy bool) error { mountOut, err := procutils.NewRemoteCommandAsFarAsPossible("mountpoint", mountPoint).Output() if err == nil { - out, err := procutils.NewRemoteCommandAsFarAsPossible("umount", mountPoint).Output() + args := []string{mountPoint} + if useLazy { + args = append([]string{"-l"}, args...) + } + out, err := procutils.NewRemoteCommandAsFarAsPossible("umount", args...).Output() if err != nil { return errors.Wrapf(err, "umount %s failed %s", mountPoint, out) }