mirror of https://github.com/k3s-io/k3s
Add `auto_unmount` mount option for glusterfs fuse mount.
libfuse has an auto_unmount option which, if enabled, ensures that the file system is unmounted at FUSE server termination by running a separate monitor process that performs the unmount when that occurs. (This feature would probably better be called "robust auto-unmount", as FUSE servers usually do try to unmount their file systems upon termination, it's just this mechanism is not crash resilient.) This change implements that option and behavior for glusterfs. This option will be only supported for clients with version >3.11. Signed-off-by: Humble Chirammal <hchiramm@redhat.com>pull/6/head
parent
ac62748480
commit
04bf95a5d1
|
@ -65,24 +65,26 @@ var _ volume.Provisioner = &glusterfsVolumeProvisioner{}
|
|||
var _ volume.Deleter = &glusterfsVolumeDeleter{}
|
||||
|
||||
const (
|
||||
glusterfsPluginName = "kubernetes.io/glusterfs"
|
||||
volPrefix = "vol_"
|
||||
dynamicEpSvcPrefix = "glusterfs-dynamic-"
|
||||
replicaCount = 3
|
||||
durabilityType = "replicate"
|
||||
secretKeyName = "key" // key name used in secret
|
||||
gciGlusterMountBinariesPath = "/sbin/mount.glusterfs"
|
||||
defaultGidMin = 2000
|
||||
defaultGidMax = math.MaxInt32
|
||||
glusterfsPluginName = "kubernetes.io/glusterfs"
|
||||
volPrefix = "vol_"
|
||||
dynamicEpSvcPrefix = "glusterfs-dynamic-"
|
||||
replicaCount = 3
|
||||
durabilityType = "replicate"
|
||||
secretKeyName = "key" // key name used in secret
|
||||
gciLinuxGlusterMountBinaryPath = "/sbin/mount.glusterfs"
|
||||
defaultGidMin = 2000
|
||||
defaultGidMax = math.MaxInt32
|
||||
// absoluteGidMin/Max are currently the same as the
|
||||
// default values, but they play a different role and
|
||||
// could take a different value. Only thing we need is:
|
||||
// absGidMin <= defGidMin <= defGidMax <= absGidMax
|
||||
absoluteGidMin = 2000
|
||||
absoluteGidMax = math.MaxInt32
|
||||
heketiAnn = "heketi-dynamic-provisioner"
|
||||
glusterTypeAnn = "gluster.org/type"
|
||||
glusterDescAnn = "Gluster: Dynamically provisioned PV"
|
||||
absoluteGidMin = 2000
|
||||
absoluteGidMax = math.MaxInt32
|
||||
heketiAnn = "heketi-dynamic-provisioner"
|
||||
glusterTypeAnn = "gluster.org/type"
|
||||
glusterDescAnn = "Gluster: Dynamically provisioned PV"
|
||||
linuxGlusterMountBinary = "mount.glusterfs"
|
||||
autoUnmountBinaryVer = "3.11"
|
||||
)
|
||||
|
||||
func (plugin *glusterfsPlugin) Init(host volume.VolumeHost) error {
|
||||
|
@ -290,8 +292,8 @@ func (b *glusterfsMounter) CanMount() error {
|
|||
exe := exec.New()
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
if _, err := exe.Command("/bin/ls", gciGlusterMountBinariesPath).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Required binary %s is missing", gciGlusterMountBinariesPath)
|
||||
if _, err := exe.Command("/bin/ls", gciLinuxGlusterMountBinaryPath).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Required binary %s is missing", gciLinuxGlusterMountBinaryPath)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -376,13 +378,58 @@ func (b *glusterfsMounter) setUpAtInternal(dir string) error {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
options = append(options, "backup-volfile-servers="+dstrings.Join(addrlist[:], ":"))
|
||||
|
||||
//fetch client version.
|
||||
mountBinaryVerStr := ""
|
||||
mountStr := ""
|
||||
|
||||
cmdOut, err := b.exe.Command(linuxGlusterMountBinary, "-V").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get binary %s version", linuxGlusterMountBinary)
|
||||
}
|
||||
//cmdOut will be filled as shown below.
|
||||
/*
|
||||
[root@]# mount.glusterfs -V
|
||||
glusterfs 3.10.1
|
||||
Repository revision: git://git.gluster.org/glusterfs.git
|
||||
Copyright (c) 2006-2016 Red Hat, Inc. <https://www.gluster.org/>
|
||||
GlusterFS comes with ABSOLUTELY NO WARRANTY.
|
||||
.........
|
||||
*/
|
||||
|
||||
parseStr := string(cmdOut)
|
||||
if parseStr != "" {
|
||||
|
||||
//Store the version line from parseStr
|
||||
mountStrSlice := dstrings.Split(parseStr, "\n")
|
||||
if len(mountStrSlice) > 0 {
|
||||
mountStr = mountStrSlice[0]
|
||||
}
|
||||
if mountStr != "" {
|
||||
|
||||
// Get the [binary, version] slice.
|
||||
mountBinaryVerSlice := dstrings.Split(mountStr, " ")
|
||||
if len(mountBinaryVerSlice) >= 2 {
|
||||
|
||||
// Get the 'version' string in mountBinaryVerStr
|
||||
mountBinaryVerStr = mountBinaryVerSlice[1]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mountOptions := volume.JoinMountOptions(b.mountOptions, options)
|
||||
|
||||
for i := len(mountOptions) - 1; i >= 0; i-- {
|
||||
if mountOptions[i] == "auto_unmount" && mountBinaryVerStr != "" && mountBinaryVerStr < autoUnmountBinaryVer {
|
||||
mountOptions = append(mountOptions[:i], mountOptions[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid mount storm, pick a host randomly.
|
||||
// Iterate all hosts until mount succeeds.
|
||||
for _, ip := range addrlist {
|
||||
mountOptions := volume.JoinMountOptions(b.mountOptions, options)
|
||||
errs = b.mounter.Mount(ip+":"+b.path, dir, "glusterfs", mountOptions)
|
||||
if errs == nil {
|
||||
glog.Infof("glusterfs: successfully mounted %s", dir)
|
||||
|
@ -819,6 +866,7 @@ func (p *glusterfsVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
|
|||
"kubernetes.io/createdby": heketiAnn,
|
||||
glusterTypeAnn: "file",
|
||||
"Description": glusterDescAnn,
|
||||
v1.MountOptionAnnotation: "auto_unmount",
|
||||
}
|
||||
|
||||
pv.Spec.Capacity = v1.ResourceList{
|
||||
|
|
Loading…
Reference in New Issue