@@ -94,6 +94,126 @@ func syncDrive(drive *types.Drive, device device) (updated bool) {
9494 return
9595}
9696
97+ func verifyDrive (drive * types.Drive ) (updated bool ) {
98+ switch drive .Status .Status {
99+ case directpvtypes .DriveStatusReady , directpvtypes .DriveStatusLost , directpvtypes .DriveStatusError , directpvtypes .DriveStatusMoving :
100+ default :
101+ return false
102+ }
103+
104+ source := utils .AddDevPrefix (string (drive .GetDriveName ()))
105+ target := types .GetDriveMountDir (drive .Status .FSUUID )
106+ if err := xfs .Mount (source , target ); err != nil {
107+ drive .Status .Status = directpvtypes .DriveStatusError
108+ drive .SetMountErrorCondition (fmt .Sprintf ("unable to mount; %v" , err ))
109+ client .Eventf (drive , client .EventTypeWarning , client .EventReasonDriveMountError , "unable to mount the drive; %v" , err )
110+ klog .ErrorS (err , "unable to mount the drive" , "Source" , source , "Target" , target )
111+ return true
112+ }
113+
114+ client .Eventf (
115+ drive ,
116+ client .EventTypeNormal ,
117+ client .EventReasonDriveMounted ,
118+ "Drive mounted successfully to %s" , target ,
119+ )
120+
121+ if drive .Status .Status == directpvtypes .DriveStatusLost {
122+ updated = true
123+ drive .Status .Status = directpvtypes .DriveStatusReady
124+ }
125+
126+ latestErrorConditionType := drive .GetLatestErrorConditionType ()
127+ if drive .Status .Status == directpvtypes .DriveStatusError {
128+ switch latestErrorConditionType {
129+ case directpvtypes .DriveConditionTypeMountError , directpvtypes .DriveConditionTypeMultipleMatches , directpvtypes .DriveConditionTypeRelabelError :
130+ updated = true
131+ drive .Status .Status = directpvtypes .DriveStatusReady
132+ }
133+ }
134+
135+ if ! drive .Spec .Relabel {
136+ return updated
137+ }
138+
139+ err := os .Symlink ("." , types .GetVolumeRootDir (drive .Status .FSUUID ))
140+ if err != nil {
141+ switch {
142+ case errors .Is (err , os .ErrExist ):
143+ err = nil
144+ default :
145+ if latestErrorConditionType != directpvtypes .DriveConditionTypeIOError {
146+ drive .Status .Status = directpvtypes .DriveStatusError
147+ drive .SetRelabelErrorCondition (fmt .Sprintf ("unable to relabel; %v" , err ))
148+ }
149+
150+ client .Eventf (
151+ drive ,
152+ client .EventTypeWarning ,
153+ client .EventReasonDriveRelabelError ,
154+ "unable to relabel; %v" , err ,
155+ )
156+
157+ klog .ErrorS (
158+ err ,
159+ "unable to create symlink" ,
160+ "symlink" , types .GetVolumeRootDir (drive .Status .FSUUID ),
161+ "drive" , drive .Name ,
162+ )
163+ }
164+ }
165+
166+ if err == nil {
167+ drive .Spec .Relabel = false
168+ }
169+
170+ return true
171+ }
172+
173+ func updateDrive (ctx context.Context , driveName string , deviceMap map [string ][]device ) error {
174+ drive , err := client .DriveClient ().Get (ctx , driveName , metav1.GetOptions {})
175+ if err != nil {
176+ if apierrors .IsNotFound (err ) {
177+ return nil
178+ }
179+ return err
180+ }
181+ var updated bool
182+ devices := deviceMap [drive .Status .FSUUID ]
183+ switch len (devices ) {
184+ case 0 :
185+ // no match
186+ if drive .Status .Status != directpvtypes .DriveStatusLost {
187+ updated = true
188+ drive .Status .Status = directpvtypes .DriveStatusLost
189+ }
190+ case 1 :
191+ // device found
192+ updated = syncDrive (drive , devices [0 ])
193+ if verifyDrive (drive ) {
194+ updated = true
195+ }
196+ default :
197+ // more than one matching devices
198+ updated = true
199+ var deviceNames string
200+ for i := range devices {
201+ if deviceNames != "" {
202+ deviceNames += ", "
203+ }
204+ deviceNames += devices [i ].Name
205+ }
206+ drive .Status .Status = directpvtypes .DriveStatusError
207+ drive .SetMultipleMatchesErrorCondition (fmt .Sprintf ("multiple devices found by FSUUID; %v" , deviceNames ))
208+ client .Eventf (drive , client .EventTypeWarning , client .EventReasonDriveHasMultipleMatches , "unable to mount the drive due to %v" , err )
209+ klog .ErrorS (err , "multiple devices found by FSUUID" , "drive" , drive .GetDriveName (), "FSUUID" , drive .Status .FSUUID , "devices" , deviceNames )
210+ }
211+ if updated {
212+ _ , err = client .DriveClient ().Update (ctx , drive , metav1.UpdateOptions {TypeMeta : types .NewDriveTypeMeta ()})
213+ }
214+ return err
215+ }
216+
97217// Sync - matches and syncs the drive with locally probed device
98218func Sync (ctx context.Context , nodeID directpvtypes.NodeID ) error {
99219 deviceMap , err := probeDeviceMap ()
@@ -105,121 +225,7 @@ func Sync(ctx context.Context, nodeID directpvtypes.NodeID) error {
105225 return err
106226 }
107227 for i := range drives {
108- updateFunc := func () error {
109- drive , err := client .DriveClient ().Get (ctx , drives [i ].Name , metav1.GetOptions {})
110- if err != nil {
111- if apierrors .IsNotFound (err ) {
112- return nil
113- }
114- return err
115- }
116- var updated bool
117- devices := deviceMap [drive .Status .FSUUID ]
118- switch len (devices ) {
119- case 0 :
120- // no match
121- if drive .Status .Status != directpvtypes .DriveStatusLost {
122- updated = true
123- drive .Status .Status = directpvtypes .DriveStatusLost
124- }
125- case 1 :
126- // device found
127- if syncDrive (drive , devices [0 ]) {
128- updated = true
129- }
130-
131- // verify mount
132- switch drive .Status .Status {
133- case directpvtypes .DriveStatusReady , directpvtypes .DriveStatusLost , directpvtypes .DriveStatusError , directpvtypes .DriveStatusMoving :
134- source := utils .AddDevPrefix (string (drive .GetDriveName ()))
135- target := types .GetDriveMountDir (drive .Status .FSUUID )
136- if err = xfs .Mount (source , target ); err != nil {
137- updated = true
138- drive .Status .Status = directpvtypes .DriveStatusError
139- drive .SetMountErrorCondition (fmt .Sprintf ("unable to mount; %v" , err ))
140- // Events and logs
141- client .Eventf (drive , client .EventTypeWarning , client .EventReasonDriveMountError , "unable to mount the drive; %v" , err )
142- klog .ErrorS (err , "unable to mount the drive" , "Source" , source , "Target" , target )
143- } else {
144- client .Eventf (
145- drive ,
146- client .EventTypeNormal ,
147- client .EventReasonDriveMounted ,
148- "Drive mounted successfully to %s" , target ,
149- )
150-
151- if drive .Status .Status == directpvtypes .DriveStatusLost {
152- updated = true
153- drive .Status .Status = directpvtypes .DriveStatusReady
154- }
155-
156- latestErrorConditionType := drive .GetLatestErrorConditionType ()
157- if drive .Status .Status == directpvtypes .DriveStatusError {
158- switch latestErrorConditionType {
159- case directpvtypes .DriveConditionTypeMountError , directpvtypes .DriveConditionTypeMultipleMatches , directpvtypes .DriveConditionTypeRelabelError :
160- updated = true
161- drive .Status .Status = directpvtypes .DriveStatusReady
162- }
163- }
164-
165- if drive .Spec .Relabel {
166- updated = true
167-
168- if err = os .Symlink ("." , types .GetVolumeRootDir (drive .Status .FSUUID )); err != nil {
169- switch {
170- case errors .Is (err , os .ErrExist ):
171- err = nil
172- default :
173- if latestErrorConditionType != directpvtypes .DriveConditionTypeIOError {
174- drive .Status .Status = directpvtypes .DriveStatusError
175- drive .SetRelabelErrorCondition (fmt .Sprintf ("unable to relabel; %v" , err ))
176- }
177-
178- client .Eventf (
179- drive ,
180- client .EventTypeWarning ,
181- client .EventReasonDriveRelabelError ,
182- "unable to relabel; %v" , err ,
183- )
184-
185- klog .ErrorS (
186- err ,
187- "unable to create symlink" ,
188- "symlink" , types .GetVolumeRootDir (drive .Status .FSUUID ),
189- "drive" , drive .Name ,
190- )
191- }
192- }
193-
194- if err == nil {
195- drive .Spec .Relabel = false
196- }
197- }
198- }
199- }
200- default :
201- // more than one matching devices
202- updated = true
203- var deviceNames string
204- for i := range devices {
205- if deviceNames != "" {
206- deviceNames += ", "
207- }
208- deviceNames += devices [i ].Name
209- }
210- drive .Status .Status = directpvtypes .DriveStatusError
211- drive .SetMultipleMatchesErrorCondition (fmt .Sprintf ("multiple devices found by FSUUID; %v" , deviceNames ))
212- client .Eventf (drive , client .EventTypeWarning , client .EventReasonDriveHasMultipleMatches , "unable to mount the drive due to %v" , err )
213- klog .ErrorS (err , "multiple devices found by FSUUID" , "drive" , drive .GetDriveName (), "FSUUID" , drive .Status .FSUUID , "devices" , deviceNames )
214- }
215- if updated {
216- if _ , err := client .DriveClient ().Update (ctx , drive , metav1.UpdateOptions {TypeMeta : types .NewDriveTypeMeta ()}); err != nil {
217- return err
218- }
219- }
220- return nil
221- }
222- if err = retry .RetryOnConflict (retry .DefaultRetry , updateFunc ); err != nil {
228+ if err = retry .RetryOnConflict (retry .DefaultRetry , func () error { return updateDrive (ctx , drives [i ].Name , deviceMap ) }); err != nil {
223229 return err
224230 }
225231 }
0 commit comments