@@ -21,6 +21,7 @@ import (
2121 "crypto/sha256"
2222 "encoding/json"
2323 "fmt"
24+ "strconv"
2425 "sync"
2526 "time"
2627
@@ -39,7 +40,6 @@ const (
3940 // Kubernetes labels
4041 labelAppName = "app.kubernetes.io/name"
4142 labelComponent = "app.kubernetes.io/component"
42- labelVolumeID = "rclone.csi.veloxpack.io/volume-id"
4343 labelValueAppName = "csi-driver-rclone"
4444 labelValueComp = "mount-state"
4545
@@ -54,9 +54,7 @@ const (
5454 keyMountParams = "mountParams"
5555 keyMountOptions = "mountOptions"
5656 keyReadOnly = "readonly"
57-
58- // Default namespace
59- defaultNamespace = "default"
57+ keyPid = "pid"
6058)
6159
6260// MountState represents the complete state needed to remount a volume.
@@ -77,6 +75,9 @@ type MountState struct {
7775 MountParams map [string ]string `json:"mountParams"`
7876 MountOptions []string `json:"mountOptions"`
7977 ReadOnly bool `json:"readonly"`
78+
79+ // Daemon process ID (for remount cleanup)
80+ MountDaemonPID int `json:"pid,omitempty"`
8081}
8182
8283// Validate checks if the MountState contains required fields.
@@ -105,7 +106,7 @@ type MountStateManager struct {
105106// It initializes the Kubernetes client and sets up the secret interface.
106107func NewMountStateManager (namespace string ) (* MountStateManager , error ) {
107108 if namespace == "" {
108- namespace = defaultNamespace
109+ namespace = "default"
109110 }
110111
111112 clientset , err := getK8sClient ()
@@ -128,35 +129,6 @@ func (sm *MountStateManager) makeSecretName(volumeID string) string {
128129 return secretNamePrefix + hash
129130}
130131
131- // GetState retrieves the complete mount state for a specific volume.
132- // Returns nil without error if no state exists for the volume.
133- func (sm * MountStateManager ) GetState (ctx context.Context , volumeID , targetPath string ) (* MountState , error ) {
134- if volumeID == "" {
135- return nil , fmt .Errorf ("volumeID is required" )
136- }
137-
138- sm .mu .RLock ()
139- defer sm .mu .RUnlock ()
140-
141- secretName := sm .makeSecretName (volumeID )
142- secret , err := sm .secrets .Get (ctx , secretName , metav1.GetOptions {})
143- if err != nil {
144- if errors .IsNotFound (err ) {
145- klog .V (4 ).Infof ("No state found for volume %s" , volumeID )
146- return nil , nil
147- }
148- return nil , fmt .Errorf ("failed to get state secret %s: %w" , secretName , err )
149- }
150-
151- state , err := sm .deserializeSecret (secret )
152- if err != nil {
153- return nil , fmt .Errorf ("failed to deserialize secret %s: %w" , secretName , err )
154- }
155-
156- klog .V (4 ).Infof ("Retrieved state for volume %s from secret %s" , volumeID , secretName )
157- return state , nil
158- }
159-
160132// deserializeSecret converts a Kubernetes Secret into a MountState struct.
161133func (sm * MountStateManager ) deserializeSecret (secret * v1.Secret ) (* MountState , error ) {
162134 state := & MountState {
@@ -198,6 +170,16 @@ func (sm *MountStateManager) deserializeSecret(secret *v1.Secret) (*MountState,
198170 state .MountOptions = make ([]string , 0 )
199171 }
200172
173+ // Parse PID if present
174+ if pidStr := byteToString (secret .Data [keyPid ]); pidStr != "" {
175+ if pid , err := strconv .Atoi (pidStr ); err != nil {
176+ klog .Warningf ("Failed to parse PID '%s': %v" , pidStr , err )
177+ state .MountDaemonPID = 0
178+ } else {
179+ state .MountDaemonPID = pid
180+ }
181+ }
182+
201183 return state , nil
202184}
203185
@@ -264,7 +246,6 @@ func (sm *MountStateManager) buildSecret(state *MountState) (*v1.Secret, error)
264246 Labels : map [string ]string {
265247 labelAppName : labelValueAppName ,
266248 labelComponent : labelValueComp ,
267- labelVolumeID : state .VolumeID ,
268249 },
269250 },
270251 Type : v1 .SecretTypeOpaque ,
@@ -282,6 +263,11 @@ func (sm *MountStateManager) buildSecret(state *MountState) (*v1.Secret, error)
282263 },
283264 }
284265
266+ // Add PID if set
267+ if state .MountDaemonPID > 0 {
268+ secret .StringData [keyPid ] = fmt .Sprintf ("%d" , state .MountDaemonPID )
269+ }
270+
285271 return secret , nil
286272}
287273
@@ -338,31 +324,6 @@ func (sm *MountStateManager) LoadState(ctx context.Context) ([]*MountState, erro
338324 return states , nil
339325}
340326
341- // CleanupStaleStates removes mount state secrets older than the specified duration.
342- // Useful for cleaning up orphaned secrets from failed mounts.
343- func (sm * MountStateManager ) CleanupStaleStates (ctx context.Context , olderThan time.Duration ) (int , error ) {
344- states , err := sm .LoadState (ctx )
345- if err != nil {
346- return 0 , fmt .Errorf ("failed to load states: %w" , err )
347- }
348-
349- cutoff := time .Now ().Add (- olderThan )
350- deleted := 0
351-
352- for _ , state := range states {
353- if state .Timestamp .Before (cutoff ) {
354- if err := sm .DeleteState (ctx , state .VolumeID , state .TargetPath ); err != nil {
355- klog .Warningf ("Failed to delete stale state for volume %s: %v" , state .VolumeID , err )
356- continue
357- }
358- deleted ++
359- klog .V (4 ).Infof ("Deleted stale state for volume %s (age: %v)" , state .VolumeID , time .Since (state .Timestamp ))
360- }
361- }
362-
363- return deleted , nil
364- }
365-
366327func byteToString (value []byte ) string {
367328 return string (value )
368329}
0 commit comments