Skip to content

Commit 0c4e766

Browse files
authored
publish v1.0.5 and fix rclone mount hang issue (#270)
* Use cmd.Start() and Wait() for commands execution Signed-off-by: Mayank Sachan <[email protected]> * publish v1.0.5 and fix rclone mount hang issue Signed-off-by: Mayank Sachan <[email protected]> --------- Signed-off-by: Mayank Sachan <[email protected]>
1 parent 654bcf8 commit 0c4e766

File tree

4 files changed

+86
-36
lines changed

4 files changed

+86
-36
lines changed

.github/workflows/release.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717

1818
env:
1919
IS_LATEST_RELEASE: 'true'
20-
APP_VERSION: 1.0.4
20+
APP_VERSION: 1.0.5
2121

2222
steps:
2323
- name: Checkout Code
@@ -63,15 +63,11 @@ jobs:
6363
/home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.deb.tar.gz.sha256
6464
/home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.rpm.tar.gz
6565
/home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.rpm.tar.gz.sha256
66-
tag_name: v1.0.4
67-
name: v1.0.4
66+
tag_name: v1.0.5
67+
name: v1.0.5
6868
body: |
6969
## 🚀 What’s New
70-
- Enable --vfs-cache-mode flag for rclone mount to support random write
71-
- Update golang dependencies
72-
- Fetch IAM Endpoint Dynamically
73-
- Add TLS cipher suites in the mount options
74-
- Fix issue with s3fs mount randomly taking time using IAM credentials on Private VPC clusters
70+
- Fix for rclone mount hang issue
7571
prerelease: ${{ env.IS_LATEST_RELEASE != 'true' }}
7672

7773
- name: Perform CodeQL Analysis

cos-csi-mounter/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
NAME := cos-csi-mounter
2-
APP_VERSION := 1.0.4
2+
APP_VERSION := 1.0.5
33
BUILD_DIR := $(NAME)-$(APP_VERSION)
44
BIN_DIR := bin
55

cos-csi-mounter/server/rclone.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type RCloneArgs struct {
2020
DirectIO string `json:"direct-io,omitempty"`
2121
GID string `json:"gid,omitempty"`
2222
LogFile string `json:"log-file,omitempty"`
23+
LogLevel string `json:"log-level,omitempty"`
2324
NoModificationTime string `json:"no-modtime,omitempty"`
2425
PollInterval string `json:"poll-interval,omitempty"`
2526
ReadOnly string `json:"read-only,omitempty"`

pkg/mounter/utils/mounter_utils.go

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package utils
55

66
import (
7+
"context"
78
"errors"
89
"fmt"
910
"os"
@@ -19,7 +20,7 @@ import (
1920
)
2021

2122
var unmount = syscall.Unmount
22-
var command = exec.Command
23+
var commandWithCtx = exec.CommandContext
2324

2425
var ErrTimeoutWaitProcess = errors.New("timeout waiting for process to end")
2526

@@ -33,28 +34,70 @@ type MounterOptsUtils struct {
3334

3435
func (su *MounterOptsUtils) FuseMount(path string, comm string, args []string) error {
3536
klog.Info("-FuseMount-")
36-
klog.Infof("FuseMount params:\n\tpath: <%s>\n\tcommand: <%s>\n\targs: <%v>", path, comm, args)
37-
out, err := command(comm, args...).CombinedOutput()
38-
if err != nil {
39-
klog.Warningf("FuseMount: mount command failed: mounter=%s, args=%v, error=%v, output=%s", comm, args, err, string(out))
40-
klog.Infof("FuseMount: checking if path already exists and is a mountpoint: path=%s", path)
41-
if mounted, err1 := isMountpoint(path); err1 == nil && mounted { // check if bucket already got mounted
42-
klog.Infof("bucket is already mounted using '%s' mounter", comm)
43-
return nil
37+
klog.Infof("FuseMount: params:\n\tpath: <%s>\n\tcommand: <%s>\n\targs: <%v>", path, comm, args)
38+
39+
ctx, cancel := context.WithCancel(context.Background())
40+
var mounted bool
41+
defer func() {
42+
if !mounted {
43+
cancel()
4444
}
45-
klog.Errorf("FuseMount: path is not mountpoint, mount failed: path=%s", path)
46-
return fmt.Errorf("'%s' mount failed: <%v>", comm, string(out))
45+
}()
46+
47+
cmd := commandWithCtx(ctx, comm, args...)
48+
err := cmd.Start()
49+
if err != nil {
50+
klog.Errorf("FuseMount: command start failed: mounter=%s, args=%v, error=%v", comm, args, err)
51+
return fmt.Errorf("FuseMount: '%s' command start failed: %v", comm, err)
4752
}
48-
klog.Infof("mount command succeeded: mounter=%s, output=%s", comm, string(out))
49-
if err := waitForMount(path, 10*time.Second); err != nil {
50-
return err
53+
klog.Infof("FuseMount: command 'start' succeeded for '%s' mounter", comm)
54+
55+
waitCh := make(chan error, 1)
56+
mountCh := make(chan error, 1)
57+
58+
go func() {
59+
klog.Infof("FuseMount: cmd.Wait() goroutine start for mounter=%s, path=%v", comm, path)
60+
waitCh <- cmd.Wait()
61+
klog.Infof("FuseMount: cmd.Wait() goroutine end for mounter=%s, path=%v", comm, path)
62+
}()
63+
64+
go func() {
65+
klog.Infof("FuseMount: waitForMount() goroutine start for mounter=%s, path=%v", comm, path)
66+
mountCh <- waitForMount(ctx, path, 2*time.Second, 30*time.Second) // kubelet retries NodePublishVolume after 120 seconds
67+
klog.Infof("FuseMount: waitForMount() goroutine end for mounter=%s, path=%v", comm, path)
68+
}()
69+
70+
select {
71+
case err := <-waitCh:
72+
if err != nil {
73+
klog.Warningf("FuseMount: command 'wait' failed: mounter=%s, args=%v, error=%v", comm, args, err)
74+
klog.Infof("FuseMount: checking if path already exists and is a mountpoint: path=%s", path)
75+
if isMount, err1 := isMountpoint(path); err1 == nil && isMount { // check if bucket already got mounted
76+
klog.Infof("bucket is already mounted using '%s' mounter", comm)
77+
mounted = true
78+
return nil
79+
}
80+
return fmt.Errorf("'%s' mount failed: %v", comm, err)
81+
}
82+
klog.Infof("FuseMount: command 'wait' succeeded for '%s' mounter", comm)
83+
if err := <-mountCh; err != nil {
84+
return err
85+
}
86+
87+
case err := <-mountCh:
88+
if err != nil {
89+
klog.Errorf("FuseMount: path is not mountpoint. Mount failed: mounter=%s, path=%s", comm, path)
90+
return fmt.Errorf("'%s' mount failed: %v", comm, err)
91+
}
5192
}
93+
5294
klog.Infof("bucket mounted successfully using '%s' mounter", comm)
95+
mounted = true
5396
return nil
5497
}
5598

5699
func (su *MounterOptsUtils) FuseUnmount(path string) error {
57-
klog.Info("-fuseUnmount-")
100+
klog.Info("-FuseUnmount-")
58101
// check if mountpoint exists
59102
isMount, checkMountErr := isMountpoint(path)
60103
if isMount || checkMountErr != nil {
@@ -127,23 +170,33 @@ func isMountpoint(pathname string) (bool, error) {
127170
return false, nil
128171
}
129172

130-
func waitForMount(path string, timeout time.Duration) error {
173+
func waitForMount(ctx context.Context, path string, initialDelay, timeout time.Duration) error {
174+
if initialDelay > 0 {
175+
time.Sleep(initialDelay)
176+
}
131177
var elapsed time.Duration
132178
attempt := 1
133179
for {
134-
isMount, err := k8sMountUtils.New("").IsMountPoint(path)
135-
if err == nil && isMount {
136-
klog.Infof("Path is a mountpoint: pathname: %s", path)
137-
return nil
138-
}
180+
select {
181+
case <-ctx.Done():
182+
err := ctx.Err()
183+
klog.Infof("waitForMount: context is done, error: %v", err)
184+
return err
185+
default:
186+
isMount, err := k8sMountUtils.New("").IsMountPoint(path)
187+
if err == nil && isMount {
188+
klog.Infof("Path is a mountpoint: pathname: %s", path)
189+
return nil
190+
}
139191

140-
klog.Infof("Mountpoint check in progress: attempt=%d, path=%s, isMount=%v, err=%v", attempt, path, isMount, err)
141-
time.Sleep(constants.Interval)
142-
elapsed += constants.Interval
143-
if elapsed >= timeout {
144-
return fmt.Errorf("timeout waiting for mount. Last check response: isMount=%v, err=%v", isMount, err)
192+
klog.Infof("Mountpoint check in progress: attempt=%d, path=%s, isMount=%v, err=%v, timeout=%v", attempt, path, isMount, err, timeout)
193+
time.Sleep(constants.Interval)
194+
elapsed += constants.Interval
195+
if elapsed >= timeout {
196+
return fmt.Errorf("timeout waiting for mount. Last check response: isMount=%v, err=%v, timeout=%v", isMount, err, constants.Timeout)
197+
}
198+
attempt++
145199
}
146-
attempt++
147200
}
148201
}
149202

0 commit comments

Comments
 (0)