aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrislusf <chris.lu@gmail.com>2025-12-06 12:36:34 -0800
committerChris Lu <chrislusf@users.noreply.github.com>2025-12-06 18:53:22 -0800
commit7f74627d1fc93b2ffe36a4193f9125bbeaf8cc0e (patch)
treedd631efcd2856cc8698baabafdb2cc53a4b95df6
parent66c6ba089d98d6a63c0c01feea48b0b423ecedea (diff)
downloadseaweedfs-csi-driver-7f74627d1fc93b2ffe36a4193f9125bbeaf8cc0e.tar.xz
seaweedfs-csi-driver-7f74627d1fc93b2ffe36a4193f9125bbeaf8cc0e.zip
fix: improve Unmount transactionality and add contextual logging
- Unmount now uses getMount first, only removes from state after all cleanup operations succeed (transactional behavior) - Add volume ID prefix to weed mount stdout/stderr logs for better debugging when multiple mounts are active
-rw-r--r--pkg/mountmanager/manager.go41
1 files changed, 35 insertions, 6 deletions
diff --git a/pkg/mountmanager/manager.go b/pkg/mountmanager/manager.go
index 161f795..493333a 100644
--- a/pkg/mountmanager/manager.go
+++ b/pkg/mountmanager/manager.go
@@ -1,8 +1,10 @@
package mountmanager
import (
+ "bufio"
"errors"
"fmt"
+ "io"
"os"
"os/exec"
"strings"
@@ -90,7 +92,8 @@ func (m *Manager) Unmount(req *UnmountRequest) (*UnmountResponse, error) {
lock.Lock()
defer lock.Unlock()
- entry := m.removeMount(req.VolumeID)
+ // Use getMount first to check if mounted, only remove from state after cleanup succeeds
+ entry := m.getMount(req.VolumeID)
if entry == nil {
glog.Infof("volume %s not mounted", req.VolumeID)
return &UnmountResponse{}, nil
@@ -111,6 +114,9 @@ func (m *Manager) Unmount(req *UnmountRequest) (*UnmountResponse, error) {
glog.Warningf("failed to remove cache dir %s for volume %s: %v", entry.cacheDir, req.VolumeID, err)
}
+ // Only remove from state after all cleanup operations succeeded
+ m.removeMount(req.VolumeID)
+
glog.Infof("stopped weed mount process for volume %s at %s", req.VolumeID, entry.targetPath)
return &UnmountResponse{}, nil
}
@@ -154,7 +160,7 @@ func (m *Manager) startMount(req *MountRequest) (*mountEntry, error) {
return nil, errors.New("mountArgs is required")
}
- process, err := startWeedMountProcess(m.weedBinary, args, targetPath)
+ process, err := startWeedMountProcess(m.weedBinary, args, targetPath, req.VolumeID)
if err != nil {
return nil, err
}
@@ -225,17 +231,29 @@ type weedMountProcess struct {
done chan struct{}
}
-func startWeedMountProcess(command string, args []string, target string) (*weedMountProcess, error) {
+func startWeedMountProcess(command string, args []string, target string, volumeID string) (*weedMountProcess, error) {
cmd := exec.Command(command, args...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- glog.V(0).Infof("Starting weed mount: %s %s", command, strings.Join(args, " "))
+ // Capture stdout/stderr and log with volume ID prefix for better debugging
+ stdoutPipe, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, fmt.Errorf("creating stdout pipe: %w", err)
+ }
+ stderrPipe, err := cmd.StderrPipe()
+ if err != nil {
+ return nil, fmt.Errorf("creating stderr pipe: %w", err)
+ }
+
+ glog.V(0).Infof("[%s] Starting weed mount: %s %s", volumeID, command, strings.Join(args, " "))
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("starting weed mount: %w", err)
}
+ // Forward stdout/stderr with volume ID prefix for better debugging
+ go forwardLogs(stdoutPipe, volumeID, "stdout")
+ go forwardLogs(stderrPipe, volumeID, "stderr")
+
process := &weedMountProcess{
cmd: cmd,
target: target,
@@ -308,3 +326,14 @@ func waitForMount(path string, timeout time.Duration) error {
}
}
}
+
+// forwardLogs reads from a pipe and logs each line with a volume ID prefix.
+func forwardLogs(pipe io.ReadCloser, volumeID string, stream string) {
+ scanner := bufio.NewScanner(pipe)
+ for scanner.Scan() {
+ glog.Infof("[%s] %s: %s", volumeID, stream, scanner.Text())
+ }
+ if err := scanner.Err(); err != nil {
+ glog.Warningf("[%s] error reading %s: %v", volumeID, stream, err)
+ }
+}