Download this file
| 1 | package host |
| 2 | |
| 3 | import "errors" |
| 4 | |
| 5 | // generationCensusRefusal is a refusal of root's kernel generation census |
| 6 | // (productionGenerationKernelCensus). Recovery with no journal open defers |
| 7 | // a settlement this refused (settleWithoutJournal), and only this: an image |
| 8 | // that does not verify, malformed state and a failed durable write keep |
| 9 | // their own errors and still fail. |
| 10 | type generationCensusRefusal struct{ err error } |
| 11 | |
| 12 | func (r *generationCensusRefusal) Error() string { return "generation census: " + r.err.Error() } |
| 13 | |
| 14 | func (r *generationCensusRefusal) Unwrap() error { return r.err } |
| 15 | |
| 16 | // onlyCensusRefusal reports whether every error err carries is a |
| 17 | // generationCensusRefusal: a wrapped refusal is, a join with any other |
| 18 | // error (a durable write that failed beside it) is not. |
| 19 | func onlyCensusRefusal(err error) bool { |
| 20 | switch e := err.(type) { |
| 21 | case nil: |
| 22 | return false |
| 23 | case *generationCensusRefusal: |
| 24 | return true |
| 25 | case interface{ Unwrap() []error }: |
| 26 | found := false |
| 27 | for _, inner := range e.Unwrap() { |
| 28 | if inner == nil { |
| 29 | continue |
| 30 | } |
| 31 | if !onlyCensusRefusal(inner) { |
| 32 | return false |
| 33 | } |
| 34 | found = true |
| 35 | } |
| 36 | return found |
| 37 | } |
| 38 | if inner := errors.Unwrap(err); inner != nil { |
| 39 | return onlyCensusRefusal(inner) |
| 40 | } |
| 41 | return false |
| 42 | } |
| 43 | |