Report correct error when O_DIRECT is not supported (#9545)

fixes #9537
master
Harshavardhana 5 years ago committed by GitHub
parent 0674c0075e
commit 2dc46cb153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      cmd/config/errors.go
  2. 6
      cmd/fs-v1.go
  3. 5
      cmd/posix-errors.go
  4. 13
      cmd/posix.go
  5. 10
      cmd/server-main.go
  6. 5
      cmd/storage-errors.go
  7. 8
      cmd/storage-rest-server.go

@ -169,6 +169,12 @@ Example 1:
$ minio server /data/minio/`,
)
ErrUnsupportedBackend = newErrFn(
"Unable to write to the backend",
"Please ensure your disk supports O_DIRECT",
"",
)
ErrUnableToWriteInBackend = newErrFn(
"Unable to write to the backend",
"Please ensure MinIO binary has write permissions for the backend",

@ -131,8 +131,12 @@ func NewFSObjectLayer(fsPath string) (ObjectLayer, error) {
var err error
if fsPath, err = getValidPath(fsPath); err != nil {
if err == errMinDiskSize {
return nil, err
return nil, config.ErrUnableToWriteInBackend(err).Hint(err.Error())
} else if err == errUnsupportedDisk {
hint := fmt.Sprintf("'%s' does not support O_DIRECT flags, refusing to use", fsPath)
return nil, config.ErrUnsupportedBackend(err).Hint(hint)
}
// Show a descriptive error with a hint about how to fix it.
var username string
if u, err := user.Current(); err == nil {

@ -38,6 +38,11 @@ func isSysErrNoSpace(err error) bool {
return errors.Is(err, syscall.ENOSPC)
}
// Invalid argument, unsupported flags such as O_DIRECT
func isSysErrInvalidArg(err error) bool {
return errors.Is(err, syscall.EINVAL)
}
// Input/output error
func isSysErrIO(err error) bool {
return errors.Is(err, syscall.EIO)

@ -177,13 +177,20 @@ func getValidPath(path string) (string, error) {
// check if backend is writable.
var rnd [8]byte
_, _ = rand.Read(rnd[:])
fn := pathJoin(path, ".writable-check-"+hex.EncodeToString(rnd[:])+".tmp")
file, err := disk.OpenFileDirectIO(fn, os.O_CREATE, 0600)
defer os.Remove(fn)
// open file in direct I/O and use default umask, this also verifies
// if direct i/o failed.
file, err := disk.OpenFileDirectIO(fn, os.O_CREATE|os.O_EXCL, 0666)
if err != nil {
if isSysErrInvalidArg(err) {
return path, errUnsupportedDisk
}
return path, err
}
file.Close()
os.Remove(fn)
return path, nil
}
@ -1279,6 +1286,8 @@ func (s *posix) CreateFile(volume, path string, fileSize int64, r io.Reader) (er
return errFileAccessDenied
case isSysErrIO(err):
return errFaultyDisk
case isSysErrInvalidArg(err):
return errUnsupportedDisk
default:
return err
}

@ -215,7 +215,11 @@ func initSafeMode() (err error) {
logger.Info("Waiting for all MinIO sub-systems to be initialized.. trying to acquire lock")
continue
}
logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired")
// These messages only meant primarily for distributed setup, so only log during distributed setup.
if globalIsDistXL {
logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired")
}
// Migrate all backend configs to encrypted backend configs, optionally
// handles rotating keys for encryption, if there is any retriable failure
@ -225,6 +229,10 @@ func initSafeMode() (err error) {
// if all sub-systems initialized successfully return right away
if err = initAllSubsystems(newObject); err == nil {
// All successful return.
if globalIsDistXL {
// These messages only meant primarily for distributed setup, so only log during distributed setup.
logger.Info("All MinIO sub-systems initialized successfully")
}
return nil
}
}

@ -25,6 +25,9 @@ var errCorruptedFormat = StorageErr("corrupted backend format, please join https
// errUnformattedDisk - unformatted disk found.
var errUnformattedDisk = StorageErr("unformatted disk found")
// errUnsupporteDisk - when disk does not support O_DIRECT flag.
var errUnsupportedDisk = StorageErr("disk does not support O_DIRECT")
// errDiskFull - cannot create volume or files when disk is full.
var errDiskFull = StorageErr("disk path full")
@ -81,7 +84,7 @@ var errBitrotHashAlgoInvalid = StorageErr("bit-rot hash algorithm is invalid")
var errCrossDeviceLink = StorageErr("Rename across devices not allowed, please fix your backend configuration")
// errMinDiskSize - cannot create volume or files when disk size is less than threshold.
var errMinDiskSize = StorageErr("The disk size is less than the minimum threshold")
var errMinDiskSize = StorageErr("The disk size is less than 900MiB threshold")
// errLessData - returned when less data available than what was requested.
var errLessData = StorageErr("less data available than what was requested")

@ -738,6 +738,12 @@ func registerStorageRESTHandlers(router *mux.Router, endpointZones EndpointZones
}
storage, err := newPosix(endpoint.Path)
if err != nil {
if err == errMinDiskSize {
logger.Fatal(config.ErrUnableToWriteInBackend(err).Hint(err.Error()), "Unable to initialize backend")
} else if err == errUnsupportedDisk {
hint := fmt.Sprintf("'%s' does not support O_DIRECT flags, refusing to use", endpoint.Path)
logger.Fatal(config.ErrUnsupportedBackend(err).Hint(hint), "Unable to initialize backend")
}
// Show a descriptive error with a hint about how to fix it.
var username string
if u, err := user.Current(); err == nil {
@ -747,7 +753,7 @@ func registerStorageRESTHandlers(router *mux.Router, endpointZones EndpointZones
}
hint := fmt.Sprintf("Run the following command to add the convenient permissions: `sudo chown %s %s && sudo chmod u+rxw %s`",
username, endpoint.Path, endpoint.Path)
logger.Fatal(config.ErrUnableToWriteInBackend(err).Msg(err.Error()).Hint(hint),
logger.Fatal(config.ErrUnableToWriteInBackend(err).Hint(hint),
"Unable to initialize posix backend")
}

Loading…
Cancel
Save