diff --git a/pkg/driver/node.go b/pkg/driver/node.go index 46dd519e61..b11251eb71 100644 --- a/pkg/driver/node.go +++ b/pkg/driver/node.go @@ -143,12 +143,7 @@ func (d *nodeService) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol fsType = defaultFsType } - var mountOptions []string - for _, f := range mountVolume.MountFlags { - if !hasMountOption(mountOptions, f) { - mountOptions = append(mountOptions, f) - } - } + mountOptions := collectMountOptions(fsType, mountVolume.MountFlags) if ok := d.inFlight.Insert(volumeID); !ok { return nil, status.Errorf(codes.Aborted, VolumeOperationAlreadyExists, volumeID) @@ -624,6 +619,8 @@ func (d *nodeService) nodePublishVolumeForFileSystem(req *csi.NodePublishVolumeR fsType = defaultFsType } + mountOptions = collectMountOptions(fsType, mountOptions) + klog.V(4).Infof("NodePublishVolume: mounting %s at %s with option %s as fstype %s", source, target, mountOptions, fsType) if err := d.mounter.Mount(source, target, fsType, mountOptions); err != nil { if removeErr := os.Remove(target); removeErr != nil { @@ -659,3 +656,24 @@ func hasMountOption(options []string, opt string) bool { } return false } + +// collectMountOptions returns array of mount options from +// VolumeCapability_MountVolume and special mount options for +// given filesystem. +func collectMountOptions(fsType string, mntFlags []string) []string { + var options []string + for _, opt := range mntFlags { + if !hasMountOption(options, opt) { + options = append(options, opt) + } + } + + // By default, xfs does not allow mounting of two volumes with the same filesystem uuid. + // Force ignore this uuid to be able to mount volume + its clone / restored snapshot on the same node. + if fsType == FSTypeXfs { + if !hasMountOption(options, "nouuid") { + options = append(options, "nouuid") + } + } + return options +} diff --git a/pkg/driver/node_test.go b/pkg/driver/node_test.go index f1e16ea8c6..c19157d764 100644 --- a/pkg/driver/node_test.go +++ b/pkg/driver/node_test.go @@ -613,7 +613,7 @@ func TestNodePublishVolume(t *testing.T) { }, }, { - name: "success fstype", + name: "success fstype xfs", testFunc: func(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() @@ -628,7 +628,7 @@ func TestNodePublishVolume(t *testing.T) { } mockMounter.EXPECT().MakeDir(gomock.Eq(targetPath)).Return(nil) - mockMounter.EXPECT().Mount(gomock.Eq(stagingTargetPath), gomock.Eq(targetPath), gomock.Eq(FSTypeXfs), gomock.Eq([]string{"bind"})).Return(nil) + mockMounter.EXPECT().Mount(gomock.Eq(stagingTargetPath), gomock.Eq(targetPath), gomock.Eq(FSTypeXfs), gomock.Eq([]string{"bind", "nouuid"})).Return(nil) req := &csi.NodePublishVolumeRequest{ PublishContext: map[string]string{DevicePathKey: devicePath},