@@ -118,35 +118,59 @@ func (p *PoolDevice) CreateThinDevice(ctx context.Context, deviceName string, vi
118118 State : Unknown ,
119119 }
120120
121- // Save initial device metadata and allocate new device ID from store
122- if err := p .metadata .AddDevice (ctx , info ); err != nil {
123- return errors .Wrapf (err , "failed to save initial metadata for new thin device %q" , deviceName )
124- }
121+ var (
122+ metaErr error
123+ devErr error
124+ activeErr error
125+ )
125126
126127 defer func () {
127- if retErr == nil {
128+ // We've created a devmapper device, but failed to activate it, try rollback everything
129+ if activeErr != nil {
130+ // Delete the device first.
131+ delErr := p .deleteDevice (ctx , info )
132+ if delErr != nil {
133+ // Failed to rollback, mark the device as faulty and keep metadata in order to
134+ // preserve the faulty device ID
135+ retErr = multierror .Append (retErr , delErr , p .metadata .MarkFaulty (ctx , info ))
136+ return
137+ }
138+
139+ // The devmapper device has been successfully deleted, deallocate device ID
140+ if err := p .RemoveDevice (ctx , info .Name ); err != nil {
141+ retErr = multierror .Append (retErr , err )
142+ return
143+ }
144+
128145 return
129146 }
130147
131- // Rollback metadata
132- retErr = multierror .Append (retErr , p .metadata .RemoveDevice (ctx , info .Name ))
148+ // We're unable to create the devmapper device, most likely something wrong with the deviceID
149+ if devErr != nil {
150+ retErr = multierror .Append (retErr , p .metadata .MarkFaulty (ctx , info ))
151+ return
152+ }
133153 }()
134154
135- // Create thin device
136- if err := p .createDevice (ctx , info ); err != nil {
137- return err
155+ // Save initial device metadata and allocate new device ID from store
156+ metaErr = p .metadata .AddDevice (ctx , info )
157+ if metaErr != nil {
158+ return metaErr
138159 }
139160
140- defer func () {
141- if retErr == nil {
142- return
143- }
161+ // Create thin device
162+ devErr = p .createDevice (ctx , info )
163+ if devErr != nil {
164+ return devErr
165+ }
144166
145- // Rollback creation
146- retErr = multierror .Append (retErr , p .deleteDevice (ctx , info ))
147- }()
167+ // Activate thin device
168+ activeErr = p .activateDevice (ctx , info )
169+ if activeErr != nil {
170+ return activeErr
171+ }
148172
149- return p . activateDevice ( ctx , info )
173+ return nil
150174}
151175
152176// createDevice creates thin device
@@ -185,36 +209,59 @@ func (p *PoolDevice) CreateSnapshotDevice(ctx context.Context, deviceName string
185209 State : Unknown ,
186210 }
187211
188- // Save snapshot metadata and allocate new device ID
189- if err := p .metadata .AddDevice (ctx , snapInfo ); err != nil {
190- return errors .Wrapf (err , "failed to save initial metadata for snapshot %q" , snapshotName )
191- }
212+ var (
213+ metaErr error
214+ devErr error
215+ activeErr error
216+ )
192217
193218 defer func () {
194- if retErr == nil {
219+ // We've created a devmapper device, but failed to activate it, try rollback everything
220+ if activeErr != nil {
221+ // Delete the device first.
222+ delErr := p .deleteDevice (ctx , snapInfo )
223+ if delErr != nil {
224+ // Failed to rollback, mark the device as faulty and keep metadata in order to
225+ // preserve the faulty device ID
226+ retErr = multierror .Append (retErr , delErr , p .metadata .MarkFaulty (ctx , snapInfo ))
227+ return
228+ }
229+
230+ // The devmapper device has been successfully deleted, deallocate device ID
231+ if err := p .RemoveDevice (ctx , snapInfo .Name ); err != nil {
232+ retErr = multierror .Append (retErr , err )
233+ return
234+ }
235+
195236 return
196237 }
197238
198- // Rollback metadata
199- retErr = multierror .Append (retErr , p .metadata .RemoveDevice (ctx , snapInfo .Name ))
239+ // We're unable to create the devmapper device, most likely something wrong with the deviceID
240+ if devErr != nil {
241+ retErr = multierror .Append (retErr , p .metadata .MarkFaulty (ctx , snapInfo ))
242+ return
243+ }
200244 }()
201245
202- // Create thin device snapshot
203- if err := p .createSnapshot (ctx , baseInfo , snapInfo ); err != nil {
204- return err
246+ // Save snapshot metadata and allocate new device ID
247+ metaErr = p .metadata .AddDevice (ctx , snapInfo )
248+ if metaErr != nil {
249+ return metaErr
205250 }
206251
207- defer func () {
208- if retErr == nil {
209- return
210- }
252+ // Create thin device snapshot
253+ devErr = p .createSnapshot (ctx , baseInfo , snapInfo )
254+ if devErr != nil {
255+ return devErr
256+ }
211257
212- // Rollback snapshot creation
213- retErr = multierror .Append (retErr , p .deleteDevice (ctx , snapInfo ))
214- }()
258+ // Activate the snapshot device
259+ activeErr = p .activateDevice (ctx , snapInfo )
260+ if activeErr != nil {
261+ return activeErr
262+ }
215263
216- // Activate snapshot device
217- return p .activateDevice (ctx , snapInfo )
264+ return nil
218265}
219266
220267func (p * PoolDevice ) createSnapshot (ctx context.Context , baseInfo , snapInfo * DeviceInfo ) error {
0 commit comments