@@ -61,10 +61,47 @@ func NewPoolDevice(ctx context.Context, config *Config) (*PoolDevice, error) {
6161 return nil , errors .Wrapf (err , "failed to query pool %q" , poolPath )
6262 }
6363
64- return & PoolDevice {
64+ poolDevice := & PoolDevice {
6565 poolName : config .PoolName ,
6666 metadata : poolMetaStore ,
67- }, nil
67+ }
68+
69+ if err := poolDevice .ensureDeviceStates (ctx ); err != nil {
70+ return nil , errors .Wrap (err , "failed to check devices state" )
71+ }
72+
73+ return poolDevice , nil
74+ }
75+
76+ // ensureDeviceStates marks devices with incomplete states (after crash) as 'Faulty'
77+ func (p * PoolDevice ) ensureDeviceStates (ctx context.Context ) error {
78+ var devices []* DeviceInfo
79+
80+ if err := p .metadata .WalkDevices (ctx , func (info * DeviceInfo ) error {
81+ switch info .State {
82+ case Activated , Suspended , Resumed , Deactivated , Removed , Faulty :
83+ return nil
84+ }
85+ devices = append (devices , info )
86+ return nil
87+ }); err != nil {
88+ return errors .Wrap (err , "failed to query devices from metastore" )
89+ }
90+
91+ var result * multierror.Error
92+ for _ , dev := range devices {
93+ log .G (ctx ).
94+ WithField ("dev_id" , dev .DeviceID ).
95+ WithField ("parent" , dev .ParentName ).
96+ WithField ("error" , dev .Error ).
97+ Warnf ("devmapper device %q has invalid state %q, marking as faulty" , dev .Name , dev .State )
98+
99+ if err := p .metadata .MarkFaulty (ctx , dev .Name ); err != nil {
100+ result = multierror .Append (result , err )
101+ }
102+ }
103+
104+ return multierror .Prefix (result .ErrorOrNil (), "devmapper:" )
68105}
69106
70107// transition invokes 'updateStateFn' callback to perform devmapper operation and reflects device state changes/errors in meta store.
0 commit comments