diff --git a/pkg/cephfs/driver.go b/pkg/cephfs/driver.go index ece2c5ccb..785f62d04 100644 --- a/pkg/cephfs/driver.go +++ b/pkg/cephfs/driver.go @@ -46,14 +46,6 @@ var ( DefaultVolumeMounter string ) -func getVolumeMounterByProbing() string { - if execCommandAndValidate("ceph-fuse", "--version") == nil { - return volumeMounter_fuse - } else { - return volumeMounter_kernel - } -} - func NewCephFSDriver() *cephfsDriver { return &cephfsDriver{} } @@ -97,7 +89,12 @@ func (fs *cephfsDriver) Run(driverName, nodeId, endpoint, volumeMounter string) DefaultVolumeMounter = volumeMounter } } else { - DefaultVolumeMounter = getVolumeMounterByProbing() + availableMounters := getAvailableMounters() + if len(availableMounters) == 0 { + glog.Fatal("no ceph mounters found on system") + } + + DefaultVolumeMounter = availableMounters[0] } glog.Infof("cephfs: setting default volume mounter to %s", DefaultVolumeMounter) diff --git a/pkg/cephfs/nodeserver.go b/pkg/cephfs/nodeserver.go index f288a4390..2064634ab 100644 --- a/pkg/cephfs/nodeserver.go +++ b/pkg/cephfs/nodeserver.go @@ -134,9 +134,12 @@ func (ns *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol return nil, status.Error(codes.Internal, err.Error()) } - m := newMounter(volOptions) - glog.V(4).Infof("cephfs: mounting volume %s with %s", volId, m.name()) + m, err := newMounter(volOptions) + if err != nil { + glog.Errorf("failed to create mounter for volume %s: %v", volId, err) + } + glog.V(4).Infof("cephfs: mounting volume %s with %s", volId, m.name()) if err = m.mount(stagingTargetPath, cr, volOptions, volId); err != nil { glog.Errorf("failed to mount volume %s: %v", volId, err) return nil, status.Error(codes.Internal, err.Error()) diff --git a/pkg/cephfs/util.go b/pkg/cephfs/util.go index 161777a31..7007d3ce8 100644 --- a/pkg/cephfs/util.go +++ b/pkg/cephfs/util.go @@ -97,23 +97,6 @@ func storeCephCredentials(volId volumeID, cr *credentials) error { return nil } -func newMounter(volOptions *volumeOptions) volumeMounter { - mounter := volOptions.Mounter - - if mounter == "" { - mounter = DefaultVolumeMounter - } - - switch mounter { - case volumeMounter_fuse: - return &fuseMounter{} - case volumeMounter_kernel: - return &kernelMounter{} - } - - return nil -} - // // Controller service request validation // diff --git a/pkg/cephfs/volume.go b/pkg/cephfs/volume.go index 7c531055a..f28d14197 100644 --- a/pkg/cephfs/volume.go +++ b/pkg/cephfs/volume.go @@ -60,7 +60,12 @@ func createVolume(volOptions *volumeOptions, adminCr *credentials, volId volumeI // Access to cephfs's / is required volOptions.RootPath = "/" - if err := mountKernel(cephRoot, adminCr, volOptions, volId); err != nil { + m, err := newMounter(volOptions) + if err != nil { + return fmt.Errorf("failed to create mounter: %v", err) + } + + if err = m.mount(cephRoot, adminCr, volOptions, volId); err != nil { return fmt.Errorf("error mounting ceph root: %v", err) } @@ -91,22 +96,28 @@ func createVolume(volOptions *volumeOptions, adminCr *credentials, volId volumeI return nil } -func purgeVolume(volId volumeID, cr *credentials, volOptions *volumeOptions) error { - // Root path is not set for dynamically provisioned volumes - volOptions.RootPath = "/" - +func purgeVolume(volId volumeID, adminCr *credentials, volOptions *volumeOptions) error { var ( - root = getCephRootPath_local(volId) + cephRoot = getCephRootPath_local(volId) volRoot = getCephRootVolumePath_local(volId) volRootDeleting = volRoot + "-deleting" ) - if err := createMountPoint(root); err != nil { + if err := createMountPoint(cephRoot); err != nil { return err } - if err := mountKernel(root, cr, volOptions, volId); err != nil { - return err + // Root path is not set for dynamically provisioned volumes + // Access to cephfs's / is required + volOptions.RootPath = "/" + + m, err := newMounter(volOptions) + if err != nil { + return fmt.Errorf("failed to create mounter: %v", err) + } + + if err = m.mount(cephRoot, adminCr, volOptions, volId); err != nil { + return fmt.Errorf("error mounting ceph root: %v", err) } defer func() { diff --git a/pkg/cephfs/volumemounter.go b/pkg/cephfs/volumemounter.go index 7cb5263b6..3451bf154 100644 --- a/pkg/cephfs/volumemounter.go +++ b/pkg/cephfs/volumemounter.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "os" + "os/exec" ) const ( @@ -113,3 +114,63 @@ func unmountVolume(mountPoint string) error { func createMountPoint(root string) error { return os.MkdirAll(root, 0750) } + +func getAvailableMounters() []string { + var ms []string + + fuseMounterProbe := exec.Command("ceph-fuse", "--version") + kernelMounterProbe := exec.Command("mount.ceph") + + if fuseMounterProbe.Run() == nil { + ms = append(ms, volumeMounter_fuse) + } + + if kernelMounterProbe.Run() == nil { + ms = append(ms, volumeMounter_kernel) + } + + return ms +} + +func newMounter(volOptions *volumeOptions) (volumeMounter, error) { + // Get the mounter from the configuration + + wantMounter := volOptions.Mounter + + if wantMounter == "" { + wantMounter = DefaultVolumeMounter + } + + // Verify that it's available + + availableMounters := getAvailableMounters() + if len(availableMounters) == 0 { + return nil, fmt.Errorf("no ceph mounters found on system") + } + + var chosenMounter string + + for _, availMounter := range getAvailableMounters() { + if chosenMounter == "" { + if availMounter == wantMounter { + chosenMounter = wantMounter + } + } + } + + if chosenMounter == "" { + // Otherwise pick whatever is left + chosenMounter = availableMounters[0] + } + + // Create the mounter + + switch chosenMounter { + case volumeMounter_fuse: + return &fuseMounter{}, nil + case volumeMounter_kernel: + return &kernelMounter{}, nil + } + + return nil, fmt.Errorf("unknown mounter '%s'", chosenMounter) +}