Merge pull request #233 from gman0/fuse-unmount-wait

cephfs: wait for FUSE to exit after unmount
This commit is contained in:
Huamin Chen 2019-02-27 15:00:28 -05:00 committed by GitHub
commit d938944528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -17,11 +17,15 @@ limitations under the License.
package cephfs package cephfs
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"regexp"
"strconv"
"sync"
"k8s.io/klog"
) )
const ( const (
@ -31,6 +35,12 @@ const (
var ( var (
availableMounters []string availableMounters []string
// maps a mountpoint to PID of its FUSE daemon
fusePidMap = make(map[string]int)
fusePidMapMtx sync.Mutex
fusePidRx = regexp.MustCompile(`(?m)^ceph-fuse\[(.+)\]: starting fuse$`)
) )
// Load available ceph mounters installed on system into availableMounters // Load available ceph mounters installed on system into availableMounters
@ -116,10 +126,24 @@ func mountFuse(mountPoint string, cr *credentials, volOptions *volumeOptions, vo
return err return err
} }
if !bytes.Contains(stderr, []byte("starting fuse")) { // Parse the output:
// We need "starting fuse" meaning the mount is ok
// and PID of the ceph-fuse daemon for unmount
match := fusePidRx.FindSubmatch(stderr)
if len(match) != 2 {
return fmt.Errorf("ceph-fuse failed: %s", stderr) return fmt.Errorf("ceph-fuse failed: %s", stderr)
} }
pid, err := strconv.Atoi(string(match[1]))
if err != nil {
return fmt.Errorf("failed to parse FUSE daemon PID: %v", err)
}
fusePidMapMtx.Lock()
fusePidMap[mountPoint] = pid
fusePidMapMtx.Unlock()
return nil return nil
} }
@ -173,7 +197,29 @@ func bindMount(from, to string, readOnly bool) error {
} }
func unmountVolume(mountPoint string) error { func unmountVolume(mountPoint string) error {
return execCommandErr("umount", mountPoint) if err := execCommandErr("umount", mountPoint); err != nil {
return err
}
fusePidMapMtx.Lock()
pid, ok := fusePidMap[mountPoint]
if ok {
delete(fusePidMap, mountPoint)
}
fusePidMapMtx.Unlock()
if ok {
p, err := os.FindProcess(pid)
if err != nil {
klog.Warningf("failed to find process %d: %v", pid, err)
} else {
if _, err = p.Wait(); err != nil {
klog.Warningf("%d is not a child process: %v", pid, err)
}
}
}
return nil
} }
func createMountPoint(root string) error { func createMountPoint(root string) error {