diff --git a/docs/deploy-cephfs.md b/docs/deploy-cephfs.md index 2257cfa81..80e5fe7ca 100644 --- a/docs/deploy-cephfs.md +++ b/docs/deploy-cephfs.md @@ -78,6 +78,8 @@ is used to define in which namespace you want the configmaps to be stored | `fsName` | yes | CephFS filesystem name into which the volume shall be created | | `mounter` | no | Mount method to be used for this volume. Available options are `kernel` for Ceph kernel client and `fuse` for Ceph FUSE driver. Defaults to "default mounter". | | `pool` | no | Ceph pool into which volume data shall be stored | +| `kernelMountOptions` | no | Comma separated string of mount options accepted by cephfs kernel mounter, by default no options are passed. Check man mount.ceph for options. | +| `fuseMountOptions` | no | Comma separated string of mount options accepted by ceph-fuse mounter, by default no options are passed. | | `csi.storage.k8s.io/provisioner-secret-name`, `csi.storage.k8s.io/node-stage-secret-name` | for Kubernetes | Name of the Kubernetes Secret object containing Ceph client credentials. Both parameters should have the same value | | `csi.storage.k8s.io/provisioner-secret-namespace`, `csi.storage.k8s.io/node-stage-secret-namespace` | for Kubernetes | Namespaces of the above Secret objects | diff --git a/examples/cephfs/storageclass.yaml b/examples/cephfs/storageclass.yaml index edbfdbe78..30731b317 100644 --- a/examples/cephfs/storageclass.yaml +++ b/examples/cephfs/storageclass.yaml @@ -20,6 +20,14 @@ parameters: # (optional) Ceph pool into which volume data shall be stored # pool: cephfs_data + # (optional) Comma separated string of Ceph-fuse mount options. + # For eg: + # fuseMountOptions: debug + + # (optional) Comma separated string of Cephfs kernel mount options. + # Check man mount.ceph for mount options. For eg: + # kernelMountOptions: readdir_max_bytes=1048576,norbytes + # The secrets have to contain user and/or Ceph admin credentials. csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret csi.storage.k8s.io/provisioner-secret-namespace: default diff --git a/pkg/cephfs/volumemounter.go b/pkg/cephfs/volumemounter.go index 36d86bb67..a48331016 100644 --- a/pkg/cephfs/volumemounter.go +++ b/pkg/cephfs/volumemounter.go @@ -141,6 +141,9 @@ func mountFuse(ctx context.Context, mountPoint string, cr *util.Credentials, vol "-o", "nonempty", } + if volOptions.FuseMountOptions != "" { + args = append(args, ","+volOptions.FuseMountOptions) + } if volOptions.FsName != "" { args = append(args, "--client_mds_namespace="+volOptions.FsName) } @@ -197,6 +200,9 @@ func mountKernel(ctx context.Context, mountPoint string, cr *util.Credentials, v if volOptions.FsName != "" { optionsStr += fmt.Sprintf(",mds_namespace=%s", volOptions.FsName) } + if volOptions.KernelMountOptions != "" { + optionsStr += fmt.Sprintf(",%s", volOptions.KernelMountOptions) + } args = append(args, "-o", optionsStr) return execCommandErr(ctx, "mount", args[:]...) diff --git a/pkg/cephfs/volumeoptions.go b/pkg/cephfs/volumeoptions.go index 36d5fd072..504019745 100644 --- a/pkg/cephfs/volumeoptions.go +++ b/pkg/cephfs/volumeoptions.go @@ -27,17 +27,19 @@ import ( ) type volumeOptions struct { - RequestName string - Size int64 - ClusterID string - FsName string - FscID int64 - MetadataPool string - Monitors string `json:"monitors"` - Pool string `json:"pool"` - RootPath string `json:"rootPath"` - Mounter string `json:"mounter"` - ProvisionVolume bool `json:"provisionVolume"` + RequestName string + Size int64 + ClusterID string + FsName string + FscID int64 + MetadataPool string + Monitors string `json:"monitors"` + Pool string `json:"pool"` + RootPath string `json:"rootPath"` + Mounter string `json:"mounter"` + ProvisionVolume bool `json:"provisionVolume"` + KernelMountOptions string `json:"kernelMountOptions"` + FuseMountOptions string `json:"fuseMountOptions"` } func validateNonEmptyField(field, fieldName string) error { @@ -147,6 +149,14 @@ func newVolumeOptions(ctx context.Context, requestName string, size int64, volOp return nil, err } + if err = extractOptionalOption(&opts.KernelMountOptions, "kernelMountOptions", volOptions); err != nil { + return nil, err + } + + if err = extractOptionalOption(&opts.FuseMountOptions, "fuseMountOptions", volOptions); err != nil { + return nil, err + } + opts.RequestName = requestName opts.Size = size @@ -223,6 +233,14 @@ func newVolumeOptionsFromVolID(ctx context.Context, volID string, volOpt, secret return nil, nil, err } + if err = extractOptionalOption(&volOptions.KernelMountOptions, "kernelMountOptions", volOpt); err != nil { + return nil, nil, err + } + + if err = extractOptionalOption(&volOptions.FuseMountOptions, "fuseMountOptions", volOpt); err != nil { + return nil, nil, err + } + if err = extractMounter(&volOptions.Mounter, volOpt); err != nil { return nil, nil, err }