XL: Implement ignore errors. (#2136)

Each metadata ops have a list of errors which can be
ignored, this is essentially needed when

  - disks are not found
  - disks are found but cannot be accessed (permission denied)
  - disks are there but fresh disks were added

This is needed since we don't have healing code in place where
it would have healed the fresh disks added.

Fixes #2072
This commit is contained in:
Harshavardhana
2016-07-07 22:10:27 -07:00
committed by Anand Babu (AB) Periasamy
parent 4c21d6d09d
commit ca1b1921c4
8 changed files with 122 additions and 76 deletions
+29 -21
View File
@@ -21,6 +21,15 @@ import (
"strings"
)
// list of all errors that can be ignored in tree walk operation.
var walkResultIgnoredErrs = []error{
errFileNotFound,
errVolumeNotFound,
errDiskNotFound,
errDiskAccessDenied,
errFaultyDisk,
}
// Tree walk result carries results of tree walking.
type treeWalkResult struct {
entry string
@@ -48,32 +57,31 @@ func listDirFactory(isLeaf func(string, string) bool, disks ...StorageAPI) listD
continue
}
entries, err = disk.ListDir(bucket, prefixDir)
if err != nil {
// For any reason disk was deleted or goes offline, continue
// and list from other disks if possible.
if err == errDiskNotFound || err == errFaultyDisk {
continue
if err == nil {
// Skip the entries which do not match the prefixEntry.
for i, entry := range entries {
if !strings.HasPrefix(entry, prefixEntry) {
entries[i] = ""
continue
}
if isLeaf(bucket, pathJoin(prefixDir, entry)) {
entries[i] = strings.TrimSuffix(entry, slashSeparator)
}
}
break
}
// Skip the entries which do not match the prefixEntry.
for i, entry := range entries {
if !strings.HasPrefix(entry, prefixEntry) {
entries[i] = ""
continue
}
if isLeaf(bucket, pathJoin(prefixDir, entry)) {
entries[i] = strings.TrimSuffix(entry, slashSeparator)
sort.Strings(entries)
// Skip the empty strings
for len(entries) > 0 && entries[0] == "" {
entries = entries[1:]
}
return entries, nil
}
sort.Strings(entries)
// Skip the empty strings
for len(entries) > 0 && entries[0] == "" {
entries = entries[1:]
// For any reason disk was deleted or goes offline, continue
// and list from other disks if possible.
if isErrIgnored(err, walkResultIgnoredErrs) {
continue
}
return entries, nil
break
}
// Return error at the end.
return nil, err
}