From 661b405ba613000986597f5270ef66b55e95382f Mon Sep 17 00:00:00 2001 From: "yingqi.ge" Date: Thu, 2 Dec 2021 15:28:22 +0800 Subject: [PATCH] UPSTREAM: 570: Fix snapshot recover disks mount: related: https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/issues/566 --- pkg/disk/nodeserver.go | 35 ++++++++++++++++++++++++++++------- pkg/disk/utils.go | 14 ++++++++++++-- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/pkg/disk/nodeserver.go b/pkg/disk/nodeserver.go index 06a95e55f..5cdb999bd 100644 --- a/pkg/disk/nodeserver.go +++ b/pkg/disk/nodeserver.go @@ -100,6 +100,8 @@ const ( FileSystemLoseCapacityPercent = "FILE_SYSTEM_LOSE_PERCENT" // NsenterCmd run command on host NsenterCmd = "/nsenter --mount=/proc/1/ns/mnt" + // NOUUID is xfs fs mount opts + NOUUID = "nouuid" ) // QueryResponse response struct for query server @@ -571,6 +573,7 @@ func (ns *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol if mnt.FsType != "" { fsType = mnt.FsType } + mountOptions := collectMountOptions(fsType, options) if err := ns.mounter.EnsureFolder(targetPath); err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -584,18 +587,18 @@ func (ns *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol // do format-mount or mount diskMounter := &k8smount.SafeFormatAndMount{Interface: ns.k8smounter, Exec: utilexec.New()} if len(mkfsOptions) > 0 && (fsType == "ext4" || fsType == "ext3") { - if err := formatAndMount(diskMounter, device, targetPath, fsType, mkfsOptions, options); err != nil { - log.Errorf("Mountdevice: FormatAndMount fail with mkfsOptions %s, %s, %s, %s, %s with error: %s", device, targetPath, fsType, mkfsOptions, options, err.Error()) + if err := formatAndMount(diskMounter, device, targetPath, fsType, mkfsOptions, mountOptions); err != nil { + log.Errorf("Mountdevice: FormatAndMount fail with mkfsOptions %s, %s, %s, %s, %s with error: %s", device, targetPath, fsType, mkfsOptions, mountOptions, err.Error()) return nil, status.Error(codes.Internal, err.Error()) } } else { - if err := diskMounter.FormatAndMount(device, targetPath, fsType, options); err != nil { + if err := diskMounter.FormatAndMount(device, targetPath, fsType, mountOptions); err != nil { log.Errorf("NodeStageVolume: Volume: %s, Device: %s, FormatAndMount error: %s", req.VolumeId, device, err.Error()) return nil, status.Error(codes.Internal, err.Error()) } } - log.Infof("NodeStageVolume: Mount Successful: volumeId: %s target %v, device: %s, mkfsOptions: %v, options: %v", req.VolumeId, targetPath, device, mkfsOptions, options) + log.Infof("NodeStageVolume: Mount Successful: volumeId: %s target %v, device: %s, mkfsOptions: %v, options: %v", req.VolumeId, targetPath, device, mkfsOptions, mountOptions) return &csi.NodeStageVolumeResponse{}, nil } @@ -835,6 +838,7 @@ func (ns *nodeServer) mountDeviceToGlobal(capability *csi.VolumeCapability, volu if mnt.FsType != "" { fsType = mnt.FsType } + mountOptions := collectMountOptions(fsType, options) if err := ns.mounter.EnsureFolder(sourcePath); err != nil { return status.Error(codes.Internal, err.Error()) } @@ -848,12 +852,12 @@ func (ns *nodeServer) mountDeviceToGlobal(capability *csi.VolumeCapability, volu // do format-mount or mount diskMounter := &k8smount.SafeFormatAndMount{Interface: ns.k8smounter, Exec: utilexec.New()} if len(mkfsOptions) > 0 && (fsType == "ext4" || fsType == "ext3") { - if err := formatAndMount(diskMounter, device, sourcePath, fsType, mkfsOptions, options); err != nil { - log.Errorf("mountDeviceToGlobal: FormatAndMount fail with mkfsOptions %s, %s, %s, %s, %s with error: %s", device, sourcePath, fsType, mkfsOptions, options, err.Error()) + if err := formatAndMount(diskMounter, device, sourcePath, fsType, mkfsOptions, mountOptions); err != nil { + log.Errorf("mountDeviceToGlobal: FormatAndMount fail with mkfsOptions %s, %s, %s, %s, %s with error: %s", device, sourcePath, fsType, mkfsOptions, mountOptions, err.Error()) return status.Error(codes.Internal, err.Error()) } } else { - if err := diskMounter.FormatAndMount(device, sourcePath, fsType, options); err != nil { + if err := diskMounter.FormatAndMount(device, sourcePath, fsType, mountOptions); err != nil { log.Errorf("mountDeviceToGlobal: Device: %s, FormatAndMount error: %s", device, err.Error()) return status.Error(codes.Internal, err.Error()) } @@ -890,3 +894,20 @@ func (ns *nodeServer) unmountDuplicateMountPoint(targetPath string) error { } return nil } + +// collectMountOptions returns array of mount options +func collectMountOptions(fsType string, mntFlags []string) (options []string) { + for _, opt := range mntFlags { + if !hasMountOption(options, opt) { + options = append(options, opt) + } + } + + if fsType == "xfs" { + if !hasMountOption(options, NOUUID) { + options = append(options, NOUUID) + } + } + return + +} diff --git a/pkg/disk/utils.go b/pkg/disk/utils.go index acb46e614..40f51cbde 100644 --- a/pkg/disk/utils.go +++ b/pkg/disk/utils.go @@ -952,8 +952,8 @@ func getDiskVolumeOptions(req *csi.CreateVolumeRequest) (*diskVolumeArgs, error) diskVolArgs.FsType = "ext4" } } - if diskVolArgs.FsType != "ext4" && diskVolArgs.FsType != "ext3" { - return nil, fmt.Errorf("illegal required parameter fsType, only support ext3, ext4, the input is: %s", diskVolArgs.FsType) + if diskVolArgs.FsType != "ext4" && diskVolArgs.FsType != "ext3" && diskVolArgs.FsType != "xfs" { + return nil, fmt.Errorf("illegal required parameter fsType, only support ext3, ext4 and xfs, the input is: %s", diskVolArgs.FsType) } // disk Type @@ -1259,3 +1259,13 @@ func intersect(slice1, slice2 []string) []string { } return nn } + +// hasMountOption return boolean value indicating whether the slice contains a mount option +func hasMountOption(options []string, opt string) bool { + for _, o := range options { + if o == opt { + return true + } + } + return false +}