admin/heal: Fix deep healing to heal objects under more conditions (#8321)

- Heal if the part.1 is truncated from its original size
- Heal if the part.1 fails while being verified in between
- Heal if the part.1 fails while being at a certain offset

Other cleanups include make sure to flush the HTTP responses
properly from storage-rest-server, avoid using 'defer' to
improve call latency. 'defer' incurs latency avoid them
in our hot-paths such as storage-rest handlers.

Fixes #8319
This commit is contained in:
Harshavardhana
2019-10-01 13:12:15 -07:00
committed by kannappanr
parent 61927d228c
commit ff5bf51952
14 changed files with 133 additions and 112 deletions

View File

@@ -22,13 +22,11 @@ import (
"crypto/tls"
"encoding/gob"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"net/url"
"path"
"strconv"
"strings"
"github.com/minio/minio/cmd/http"
"github.com/minio/minio/cmd/rest"
@@ -61,12 +59,10 @@ func toStorageErr(err error) error {
}
switch err.Error() {
case io.EOF.Error():
return io.EOF
case io.ErrUnexpectedEOF.Error():
return io.ErrUnexpectedEOF
case errFileUnexpectedSize.Error():
return errFileUnexpectedSize
case errFaultyDisk.Error():
return errFaultyDisk
case errFileCorrupt.Error():
return errFileCorrupt
case errUnexpected.Error():
return errUnexpected
case errDiskFull.Error():
@@ -99,15 +95,10 @@ func toStorageErr(err error) error {
return errRPCAPIVersionUnsupported
case errServerTimeMismatch.Error():
return errServerTimeMismatch
}
if strings.Contains(err.Error(), "Bitrot verification mismatch") {
var expected string
var received string
fmt.Sscanf(err.Error(), "Bitrot verification mismatch - expected %s received %s", &expected, &received)
// Go's Sscanf %s scans "," that comes after the expected hash, hence remove it. Providing "," in the format string does not help.
expected = strings.TrimSuffix(expected, ",")
bitrotErr := HashMismatchError{expected, received}
return bitrotErr
case io.EOF.Error():
return io.EOF
case io.ErrUnexpectedEOF.Error():
return io.ErrUnexpectedEOF
}
return err
}
@@ -461,8 +452,7 @@ func (client *storageRESTClient) VerifyFile(volume, path string, size int64, alg
}
}
verifyResp := &VerifyFileResp{}
err = gob.NewDecoder(reader).Decode(verifyResp)
if err != nil {
if err = gob.NewDecoder(reader).Decode(verifyResp); err != nil {
return err
}
return toStorageErr(verifyResp.Err)