commit
a9cc801922
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@ -298,7 +298,6 @@ jobs:
|
|||||||
- name: Tests
|
- name: Tests
|
||||||
env:
|
env:
|
||||||
GOPROXY: direct
|
GOPROXY: direct
|
||||||
SKIPTESTS: github.com/containerd/containerd/snapshots/devmapper
|
|
||||||
run: |
|
run: |
|
||||||
make test
|
make test
|
||||||
sudo -E PATH=$PATH GOPATH=$GOPATH GOPROXY=$GOPROXY make root-test
|
sudo -E PATH=$PATH GOPATH=$GOPATH GOPROXY=$GOPROXY make root-test
|
||||||
|
@ -75,6 +75,33 @@ func NewPoolDevice(ctx context.Context, config *Config) (*PoolDevice, error) {
|
|||||||
return poolDevice, nil
|
return poolDevice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func retry(ctx context.Context, f func() error) error {
|
||||||
|
var (
|
||||||
|
maxRetries = 100
|
||||||
|
retryDelay = 100 * time.Millisecond
|
||||||
|
retryErr error
|
||||||
|
)
|
||||||
|
|
||||||
|
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||||
|
retryErr = f()
|
||||||
|
if retryErr == nil {
|
||||||
|
return nil
|
||||||
|
} else if retryErr != unix.EBUSY {
|
||||||
|
return retryErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't spam logs
|
||||||
|
if attempt%10 == 0 {
|
||||||
|
log.G(ctx).WithError(retryErr).Warnf("retrying... (%d of %d)", attempt, maxRetries)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Devmapper device is busy, give it a bit of time and retry removal
|
||||||
|
time.Sleep(retryDelay)
|
||||||
|
}
|
||||||
|
|
||||||
|
return retryErr
|
||||||
|
}
|
||||||
|
|
||||||
// ensureDeviceStates updates devices to their real state:
|
// ensureDeviceStates updates devices to their real state:
|
||||||
// - marks devices with incomplete states (after crash) as 'Faulty'
|
// - marks devices with incomplete states (after crash) as 'Faulty'
|
||||||
// - activates devices if they are marked as 'Activated' but the dm
|
// - activates devices if they are marked as 'Activated' but the dm
|
||||||
@ -393,30 +420,13 @@ func (p *PoolDevice) DeactivateDevice(ctx context.Context, deviceName string, de
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := p.transition(ctx, deviceName, Deactivating, Deactivated, func() error {
|
if err := p.transition(ctx, deviceName, Deactivating, Deactivated, func() error {
|
||||||
var (
|
return retry(ctx, func() error {
|
||||||
maxRetries = 100
|
if err := dmsetup.RemoveDevice(deviceName, opts...); err != nil {
|
||||||
retryDelay = 100 * time.Millisecond
|
return errors.Wrap(err, "failed to deactivate device")
|
||||||
retryErr error
|
|
||||||
)
|
|
||||||
|
|
||||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
|
||||||
retryErr = dmsetup.RemoveDevice(deviceName, opts...)
|
|
||||||
if retryErr == nil {
|
|
||||||
return nil
|
|
||||||
} else if retryErr != unix.EBUSY {
|
|
||||||
return retryErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't spam logs
|
return nil
|
||||||
if attempt%10 == 0 {
|
})
|
||||||
log.G(ctx).WithError(retryErr).Warnf("failed to deactivate device, retrying... (%d of %d)", attempt, maxRetries)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Devmapper device is busy, give it a bit of time and retry removal
|
|
||||||
time.Sleep(retryDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryErr
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrapf(err, "failed to deactivate device %q", deviceName)
|
return errors.Wrapf(err, "failed to deactivate device %q", deviceName)
|
||||||
}
|
}
|
||||||
@ -493,14 +503,15 @@ func (p *PoolDevice) RemoveDevice(ctx context.Context, deviceName string) error
|
|||||||
|
|
||||||
func (p *PoolDevice) deleteDevice(ctx context.Context, info *DeviceInfo) error {
|
func (p *PoolDevice) deleteDevice(ctx context.Context, info *DeviceInfo) error {
|
||||||
if err := p.transition(ctx, info.Name, Removing, Removed, func() error {
|
if err := p.transition(ctx, info.Name, Removing, Removed, func() error {
|
||||||
// Send 'delete' message to thin-pool
|
return retry(ctx, func() error {
|
||||||
e := dmsetup.DeleteDevice(p.poolName, info.DeviceID)
|
// Send 'delete' message to thin-pool
|
||||||
|
e := dmsetup.DeleteDevice(p.poolName, info.DeviceID)
|
||||||
// Ignores the error if the device has been deleted already.
|
// Ignores the error if the device has been deleted already.
|
||||||
if e != nil && !errors.Is(e, unix.ENODATA) {
|
if e != nil && !errors.Is(e, unix.ENODATA) {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
})
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrapf(err, "failed to delete device %q (dev id: %d)", info.Name, info.DeviceID)
|
return errors.Wrapf(err, "failed to delete device %q (dev id: %d)", info.Name, info.DeviceID)
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ func (s *Snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.pool.DeactivateDevice(ctx, deviceName, false, false)
|
return s.pool.DeactivateDevice(ctx, deviceName, true, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user