@@ -73,23 +73,41 @@ func NewPoolDevice(ctx context.Context, config *Config) (*PoolDevice, error) {
7373 return poolDevice , nil
7474}
7575
76- // ensureDeviceStates marks devices with incomplete states (after crash) as 'Faulty'
76+ // ensureDeviceStates updates devices to their real state:
77+ // - marks devices with incomplete states (after crash) as 'Faulty'
78+ // - activates devices if they are marked as 'Activated' but the dm
79+ // device is not active, which can happen to a stopped container
80+ // after a reboot
7781func (p * PoolDevice ) ensureDeviceStates (ctx context.Context ) error {
78- var devices []* DeviceInfo
82+ var faultyDevices []* DeviceInfo
83+ var activatedDevices []* DeviceInfo
7984
8085 if err := p .metadata .WalkDevices (ctx , func (info * DeviceInfo ) error {
8186 switch info .State {
82- case Activated , Suspended , Resumed , Deactivated , Removed , Faulty :
83- return nil
87+ case Suspended , Resumed , Deactivated , Removed , Faulty :
88+ case Activated :
89+ activatedDevices = append (activatedDevices , info )
90+ default :
91+ faultyDevices = append (faultyDevices , info )
8492 }
85- devices = append (devices , info )
8693 return nil
8794 }); err != nil {
8895 return errors .Wrap (err , "failed to query devices from metastore" )
8996 }
9097
9198 var result * multierror.Error
92- for _ , dev := range devices {
99+ for _ , dev := range activatedDevices {
100+ if p .IsActivated (dev .Name ) {
101+ continue
102+ }
103+
104+ log .G (ctx ).Warnf ("devmapper device %q marked as %q but not active, activating it" , dev .Name , dev .State )
105+ if err := p .activateDevice (ctx , dev ); err != nil {
106+ result = multierror .Append (result , err )
107+ }
108+ }
109+
110+ for _ , dev := range faultyDevices {
93111 log .G (ctx ).
94112 WithField ("dev_id" , dev .DeviceID ).
95113 WithField ("parent" , dev .ParentName ).
@@ -350,19 +368,19 @@ func (p *PoolDevice) DeactivateDevice(ctx context.Context, deviceName string, de
350368 return nil
351369}
352370
353- // IsActivated returns true if thin-device is activated and not suspended
371+ // IsActivated returns true if thin-device is activated
354372func (p * PoolDevice ) IsActivated (deviceName string ) bool {
355373 infos , err := dmsetup .Info (deviceName )
356374 if err != nil || len (infos ) != 1 {
357375 // Couldn't query device info, device not active
358376 return false
359377 }
360378
361- if devInfo := infos [0 ]; devInfo .Suspended {
362- return false
379+ if devInfo := infos [0 ]; devInfo .TableLive {
380+ return true
363381 }
364382
365- return true
383+ return false
366384}
367385
368386// IsLoaded returns true if thin-device is visible for dmsetup
0 commit comments