Skip to content

Commit 7efda48

Browse files
committed
devmapper: more precise way of checking if device is activated
Signed-off-by: Maksym Pavlenko <[email protected]>
1 parent 37cdedc commit 7efda48

2 files changed

Lines changed: 24 additions & 14 deletions

File tree

snapshots/devmapper/pool_device.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,8 @@ func (p *PoolDevice) CreateSnapshotDevice(ctx context.Context, deviceName string
188188
return errors.Wrapf(err, "failed to query device metadata for %q", deviceName)
189189
}
190190

191-
isActivated := baseInfo.State == Activated
192-
193191
// Suspend thin device if it was activated previously
192+
isActivated := p.IsActivated(baseInfo.Name)
194193
if isActivated {
195194
if err := p.transition(ctx, baseInfo.Name, Suspending, Suspended, func() error {
196195
return dmsetup.SuspendDevice(baseInfo.Name)
@@ -245,13 +244,8 @@ func (p *PoolDevice) CreateSnapshotDevice(ctx context.Context, deviceName string
245244

246245
// DeactivateDevice deactivates thin device
247246
func (p *PoolDevice) DeactivateDevice(ctx context.Context, deviceName string, deferred bool) error {
248-
devicePath := dmsetup.GetFullDevicePath(deviceName)
249-
if _, err := os.Stat(devicePath); err != nil {
250-
if os.IsNotExist(err) {
251-
return ErrNotFound
252-
}
253-
254-
return err
247+
if !p.IsActivated(deviceName) {
248+
return nil
255249
}
256250

257251
opts := []dmsetup.RemoveDeviceOpt{dmsetup.RemoveWithForce, dmsetup.RemoveWithRetries}
@@ -268,14 +262,29 @@ func (p *PoolDevice) DeactivateDevice(ctx context.Context, deviceName string, de
268262
return nil
269263
}
270264

265+
// IsActivated returns true if thin-device is activated and not suspended
266+
func (p *PoolDevice) IsActivated(deviceName string) bool {
267+
infos, err := dmsetup.Info(deviceName)
268+
if err != nil || len(infos) == 0 {
269+
// Couldn't query device info, device not active
270+
return false
271+
}
272+
273+
if devInfo := infos[0]; devInfo.Suspended {
274+
return false
275+
}
276+
277+
return true
278+
}
279+
271280
// RemoveDevice completely wipes out thin device from thin-pool and frees it's device ID
272281
func (p *PoolDevice) RemoveDevice(ctx context.Context, deviceName string) error {
273282
info, err := p.metadata.GetDevice(ctx, deviceName)
274283
if err != nil {
275284
return errors.Wrapf(err, "can't query metadata for device %q", deviceName)
276285
}
277286

278-
if err := p.DeactivateDevice(ctx, deviceName, true); err != nil && err != ErrNotFound {
287+
if err := p.DeactivateDevice(ctx, deviceName, true); err != nil {
279288
return err
280289
}
281290

@@ -305,7 +314,7 @@ func (p *PoolDevice) RemovePool(ctx context.Context) error {
305314

306315
// Deactivate devices if any
307316
for _, name := range deviceNames {
308-
if err := p.DeactivateDevice(ctx, name, true); err != nil && err != ErrNotFound {
317+
if err := p.DeactivateDevice(ctx, name, true); err != nil {
309318
result = multierror.Append(result, errors.Wrapf(err, "failed to remove %q", name))
310319
}
311320
}

snapshots/devmapper/pool_device_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,13 @@ func testDeactivateThinDevice(t *testing.T, pool *PoolDevice) {
191191
}
192192

193193
for _, deviceName := range deviceList {
194+
assert.Assert(t, pool.IsActivated(deviceName))
195+
194196
err := pool.DeactivateDevice(context.Background(), deviceName, false)
195197
assert.NilError(t, err, "failed to remove '%s'", deviceName)
196-
}
197198

198-
err := pool.DeactivateDevice(context.Background(), "not-existing-device", false)
199-
assert.Assert(t, err != nil, "should return an error if trying to remove not existing device")
199+
assert.Assert(t, !pool.IsActivated(deviceName))
200+
}
200201
}
201202

202203
func testRemoveThinDevice(t *testing.T, pool *PoolDevice) {

0 commit comments

Comments
 (0)