Skip to content

Commit a222b07

Browse files
authored
Add check if filesystem exists before re-formatting (#6)
* Add check if filesystem exists before re-formatting * Update to add retries in case If blkid fails * Variable scope issue
1 parent 9980664 commit a222b07

1 file changed

Lines changed: 63 additions & 2 deletions

File tree

pkg/driver/nodeserver.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66
"os/exec"
77
"strings"
8+
"time"
89

910
"github.com/container-storage-interface/spec/lib/go/csi"
1011
"google.golang.org/grpc/codes"
@@ -55,10 +56,70 @@ func (ns *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
5556

5657
func formateAndMakeFS(device string, fstype string) error {
5758
klog.Infof("formateAndMakeFS: called with args %s, %s", device, fstype)
59+
60+
// Wait for device to be ready and check if filesystem exists
61+
// This prevents race condition where device is attached but not yet accessible
62+
const maxRetries = 10
63+
const retryDelay = 500 * time.Millisecond
64+
65+
var existingFS string
66+
var deviceReady bool
67+
68+
for i := 0; i < maxRetries; i++ {
69+
// Check if device file exists
70+
if _, err := os.Stat(device); err != nil {
71+
if i < maxRetries-1 {
72+
klog.Infof("Device %s not ready (attempt %d/%d), waiting...", device, i+1, maxRetries)
73+
time.Sleep(retryDelay)
74+
continue
75+
}
76+
return fmt.Errorf("device %s not found after %d attempts: %v", device, maxRetries, err)
77+
}
78+
79+
// Try to read filesystem type with blkid
80+
blkidCmd := exec.Command("blkid", "-o", "value", "-s", "TYPE", device)
81+
output, err := blkidCmd.CombinedOutput()
82+
existingFS = strings.TrimSpace(string(output))
83+
84+
if err == nil {
85+
// blkid succeeded - filesystem exists
86+
deviceReady = true
87+
break
88+
}
89+
90+
// Check if error indicates device is not ready (vs no filesystem)
91+
exitErr, ok := err.(*exec.ExitError)
92+
if ok && exitErr.ExitCode() == 2 {
93+
// Exit code 2 means no filesystem found - device is ready but empty
94+
deviceReady = true
95+
break
96+
}
97+
98+
// Other errors might indicate device not ready
99+
if i < maxRetries-1 {
100+
klog.Infof("Device %s not ready for blkid (attempt %d/%d): %v, waiting...", device, i+1, maxRetries, err)
101+
time.Sleep(retryDelay)
102+
continue
103+
}
104+
105+
return fmt.Errorf("device %s not ready after %d attempts: %v", device, maxRetries, err)
106+
}
107+
108+
if !deviceReady {
109+
return fmt.Errorf("device %s did not become ready", device)
110+
}
111+
112+
if existingFS != "" {
113+
klog.Infof("Filesystem %s already exists on %s, skipping format", existingFS, device)
114+
return nil // Don't format if filesystem exists
115+
}
116+
117+
klog.Infof("No filesystem detected on %s, creating %s filesystem", device, fstype)
118+
119+
// Only format if no filesystem exists
58120
mkfsCmd := fmt.Sprintf("mkfs.%s", fstype)
59121

60-
_, err := exec.LookPath(mkfsCmd)
61-
if err != nil {
122+
if _, err := exec.LookPath(mkfsCmd); err != nil {
62123
return fmt.Errorf("unable to find the mkfs (%s) utiltiy errors is %s", mkfsCmd, err.Error())
63124
}
64125

0 commit comments

Comments
 (0)