Merge pull request #3567 from renzhengeek/renzhen/devmapper
devmapper: activate dm device if snap device marked as activated
This commit is contained in:
commit
95301fee3a
@ -73,23 +73,41 @@ func NewPoolDevice(ctx context.Context, config *Config) (*PoolDevice, error) {
|
|||||||
return poolDevice, nil
|
return poolDevice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensureDeviceStates marks devices with incomplete states (after crash) as 'Faulty'
|
// ensureDeviceStates updates devices to their real state:
|
||||||
|
// - marks devices with incomplete states (after crash) as 'Faulty'
|
||||||
|
// - activates devices if they are marked as 'Activated' but the dm
|
||||||
|
// device is not active, which can happen to a stopped container
|
||||||
|
// after a reboot
|
||||||
func (p *PoolDevice) ensureDeviceStates(ctx context.Context) error {
|
func (p *PoolDevice) ensureDeviceStates(ctx context.Context) error {
|
||||||
var devices []*DeviceInfo
|
var faultyDevices []*DeviceInfo
|
||||||
|
var activatedDevices []*DeviceInfo
|
||||||
|
|
||||||
if err := p.metadata.WalkDevices(ctx, func(info *DeviceInfo) error {
|
if err := p.metadata.WalkDevices(ctx, func(info *DeviceInfo) error {
|
||||||
switch info.State {
|
switch info.State {
|
||||||
case Activated, Suspended, Resumed, Deactivated, Removed, Faulty:
|
case Suspended, Resumed, Deactivated, Removed, Faulty:
|
||||||
return nil
|
case Activated:
|
||||||
|
activatedDevices = append(activatedDevices, info)
|
||||||
|
default:
|
||||||
|
faultyDevices = append(faultyDevices, info)
|
||||||
}
|
}
|
||||||
devices = append(devices, info)
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "failed to query devices from metastore")
|
return errors.Wrap(err, "failed to query devices from metastore")
|
||||||
}
|
}
|
||||||
|
|
||||||
var result *multierror.Error
|
var result *multierror.Error
|
||||||
for _, dev := range devices {
|
for _, dev := range activatedDevices {
|
||||||
|
if p.IsActivated(dev.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.G(ctx).Warnf("devmapper device %q marked as %q but not active, activating it", dev.Name, dev.State)
|
||||||
|
if err := p.activateDevice(ctx, dev); err != nil {
|
||||||
|
result = multierror.Append(result, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dev := range faultyDevices {
|
||||||
log.G(ctx).
|
log.G(ctx).
|
||||||
WithField("dev_id", dev.DeviceID).
|
WithField("dev_id", dev.DeviceID).
|
||||||
WithField("parent", dev.ParentName).
|
WithField("parent", dev.ParentName).
|
||||||
@ -350,7 +368,7 @@ func (p *PoolDevice) DeactivateDevice(ctx context.Context, deviceName string, de
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsActivated returns true if thin-device is activated and not suspended
|
// IsActivated returns true if thin-device is activated
|
||||||
func (p *PoolDevice) IsActivated(deviceName string) bool {
|
func (p *PoolDevice) IsActivated(deviceName string) bool {
|
||||||
infos, err := dmsetup.Info(deviceName)
|
infos, err := dmsetup.Info(deviceName)
|
||||||
if err != nil || len(infos) != 1 {
|
if err != nil || len(infos) != 1 {
|
||||||
@ -358,11 +376,11 @@ func (p *PoolDevice) IsActivated(deviceName string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if devInfo := infos[0]; devInfo.Suspended {
|
if devInfo := infos[0]; devInfo.TableLive {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLoaded returns true if thin-device is visible for dmsetup
|
// IsLoaded returns true if thin-device is visible for dmsetup
|
||||||
|
@ -161,7 +161,9 @@ func TestPoolDeviceMarkFaulty(t *testing.T) {
|
|||||||
err := store.AddDevice(testCtx, &DeviceInfo{Name: "1", State: Unknown})
|
err := store.AddDevice(testCtx, &DeviceInfo{Name: "1", State: Unknown})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
err = store.AddDevice(testCtx, &DeviceInfo{Name: "2", State: Activated})
|
// Note: do not use 'Activated' here because pool.ensureDeviceStates() will
|
||||||
|
// try to activate the real dm device, which will fail on a faked device.
|
||||||
|
err = store.AddDevice(testCtx, &DeviceInfo{Name: "2", State: Deactivated})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
pool := &PoolDevice{metadata: store}
|
pool := &PoolDevice{metadata: store}
|
||||||
@ -177,7 +179,7 @@ func TestPoolDeviceMarkFaulty(t *testing.T) {
|
|||||||
assert.Equal(t, Faulty, info.State)
|
assert.Equal(t, Faulty, info.State)
|
||||||
assert.Equal(t, "1", info.Name)
|
assert.Equal(t, "1", info.Name)
|
||||||
case 2:
|
case 2:
|
||||||
assert.Equal(t, Activated, info.State)
|
assert.Equal(t, Deactivated, info.State)
|
||||||
assert.Equal(t, "2", info.Name)
|
assert.Equal(t, "2", info.Name)
|
||||||
default:
|
default:
|
||||||
t.Error("unexpected walk call")
|
t.Error("unexpected walk call")
|
||||||
|
Loading…
Reference in New Issue
Block a user