mirror of
https://github.com/minio/minio.git
synced 2025-11-22 02:35:30 -05:00
Detect underlying disk mount/unmount (#8408)
This commit is contained in:
committed by
kannappanr
parent
8aaaa46be9
commit
980bf78b4d
144
cmd/posix.go
144
cmd/posix.go
@@ -35,6 +35,7 @@ import (
|
||||
"bytes"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/klauspost/readahead"
|
||||
"github.com/minio/minio/cmd/logger"
|
||||
"github.com/minio/minio/pkg/disk"
|
||||
@@ -71,15 +72,18 @@ type posix struct {
|
||||
totalUsed uint64 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
ioErrCount int32 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
|
||||
diskPath string
|
||||
pool sync.Pool
|
||||
connected bool
|
||||
diskPath string
|
||||
pool sync.Pool
|
||||
|
||||
diskMount bool // indicates if the path is an actual mount.
|
||||
|
||||
diskFileInfo os.FileInfo
|
||||
diskID string
|
||||
|
||||
formatFileInfo os.FileInfo
|
||||
// Disk usage metrics
|
||||
stopUsageCh chan struct{}
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// checkPathLength - returns error if given path name length more than 255
|
||||
@@ -182,22 +186,20 @@ func newPosix(path string) (*posix, error) {
|
||||
if path, err = getValidPath(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fi, err := os.Stat(path)
|
||||
_, err = os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := &posix{
|
||||
connected: true,
|
||||
diskPath: path,
|
||||
diskPath: path,
|
||||
pool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
b := directio.AlignedBlock(readBlockSize)
|
||||
return &b
|
||||
},
|
||||
},
|
||||
stopUsageCh: make(chan struct{}),
|
||||
diskFileInfo: fi,
|
||||
diskMount: mountinfo.IsLikelyMountPoint(path),
|
||||
stopUsageCh: make(chan struct{}),
|
||||
diskMount: mountinfo.IsLikelyMountPoint(path),
|
||||
}
|
||||
|
||||
if !p.diskMount {
|
||||
@@ -298,12 +300,11 @@ func (s *posix) LastError() error {
|
||||
|
||||
func (s *posix) Close() error {
|
||||
close(s.stopUsageCh)
|
||||
s.connected = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *posix) IsOnline() bool {
|
||||
return s.connected
|
||||
return true
|
||||
}
|
||||
|
||||
// DiskInfo is an extended type which returns current
|
||||
@@ -329,10 +330,6 @@ func (s *posix) DiskInfo() (info DiskInfo, err error) {
|
||||
return info, errFaultyDisk
|
||||
}
|
||||
|
||||
if err := s.checkDiskFound(); err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
di, err := getDiskInfo(s.diskPath)
|
||||
if err != nil {
|
||||
return info, err
|
||||
@@ -370,30 +367,37 @@ func (s *posix) getVolDir(volume string) (string, error) {
|
||||
return volumeDir, nil
|
||||
}
|
||||
|
||||
// checkDiskFound - validates if disk is available,
|
||||
// returns errDiskNotFound if not found.
|
||||
func (s *posix) checkDiskFound() (err error) {
|
||||
if !s.IsOnline() {
|
||||
return errDiskNotFound
|
||||
}
|
||||
fi, err := os.Stat(s.diskPath)
|
||||
func (s *posix) getDiskID() (string, error) {
|
||||
s.RLock()
|
||||
diskID := s.diskID
|
||||
s.RUnlock()
|
||||
|
||||
formatFile := pathJoin(s.diskPath, minioMetaBucket, formatConfigFile)
|
||||
fi, err := os.Stat(formatFile)
|
||||
if err != nil {
|
||||
switch {
|
||||
case os.IsNotExist(err):
|
||||
return errDiskNotFound
|
||||
case isSysErrTooLong(err):
|
||||
return errFileNameTooLong
|
||||
case isSysErrIO(err):
|
||||
return errFaultyDisk
|
||||
default:
|
||||
return err
|
||||
}
|
||||
// If the disk is still not initialized.
|
||||
return "", err
|
||||
}
|
||||
if !os.SameFile(s.diskFileInfo, fi) {
|
||||
s.connected = false
|
||||
return errDiskNotFound
|
||||
|
||||
if xioutil.SameFile(fi, s.formatFileInfo) {
|
||||
// If the file has not changed, just return the cached diskID information.
|
||||
return diskID, nil
|
||||
}
|
||||
return nil
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
b, err := ioutil.ReadFile(formatFile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
format := &formatXLV3{}
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
if err = json.Unmarshal(b, &format); err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.diskID = format.XL.This
|
||||
s.formatFileInfo = fi
|
||||
return s.diskID, nil
|
||||
}
|
||||
|
||||
// diskUsage returns du information for the posix path, in a continuous routine.
|
||||
@@ -478,6 +482,12 @@ func (s *posix) diskUsage(doneCh chan struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Make a volume entry.
|
||||
func (s *posix) SetDiskID(id string) {
|
||||
// NO-OP for posix as it is handled either by posixDiskIDCheck{} for local disks or
|
||||
// storage rest server for remote disks.
|
||||
}
|
||||
|
||||
// Make a volume entry.
|
||||
func (s *posix) MakeVol(volume string) (err error) {
|
||||
defer func() {
|
||||
@@ -490,10 +500,6 @@ func (s *posix) MakeVol(volume string) (err error) {
|
||||
return errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isValidVolname(volume) {
|
||||
return errInvalidArgument
|
||||
}
|
||||
@@ -533,10 +539,6 @@ func (s *posix) ListVols() (volsInfo []VolInfo, err error) {
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
volsInfo, err = listVols(s.diskPath)
|
||||
if err != nil {
|
||||
if isSysErrIO(err) {
|
||||
@@ -602,10 +604,6 @@ func (s *posix) StatVol(volume string) (volInfo VolInfo, err error) {
|
||||
return VolInfo{}, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return VolInfo{}, err
|
||||
}
|
||||
|
||||
// Verify if volume is valid and it exists.
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
@@ -643,10 +641,6 @@ func (s *posix) DeleteVol(volume string) (err error) {
|
||||
return errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Verify if volume is valid and it exists.
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
@@ -685,10 +679,6 @@ func (s *posix) Walk(volume, dirPath, marker string, recursive bool, leafFile st
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify if volume is valid and it exists.
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
@@ -762,10 +752,6 @@ func (s *posix) ListDir(volume, dirPath string, count int, leafFile string) (ent
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify if volume is valid and it exists.
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
@@ -818,10 +804,6 @@ func (s *posix) ReadAll(volume, path string) (buf []byte, err error) {
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -895,10 +877,6 @@ func (s *posix) ReadFile(volume, path string, offset int64, buffer []byte, verif
|
||||
return 0, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -996,10 +974,6 @@ func (s *posix) openFile(volume, path string, mode int) (f *os.File, err error)
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1071,10 +1045,6 @@ func (s *posix) ReadFileStream(volume, path string, offset, length int64) (io.Re
|
||||
return nil, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1161,10 +1131,6 @@ func (s *posix) CreateFile(volume, path string, fileSize int64, r io.Reader) (er
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1312,10 +1278,6 @@ func (s *posix) StatFile(volume, path string) (file FileInfo, err error) {
|
||||
return FileInfo{}, errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return FileInfo{}, err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return FileInfo{}, err
|
||||
@@ -1412,10 +1374,6 @@ func (s *posix) DeleteFile(volume, path string) (err error) {
|
||||
return errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1465,10 +1423,6 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
|
||||
return errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srcVolumeDir, err := s.getVolDir(srcVolume)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1561,10 +1515,6 @@ func (s *posix) VerifyFile(volume, path string, fileSize int64, algo BitrotAlgor
|
||||
return errFaultyDisk
|
||||
}
|
||||
|
||||
if err = s.checkDiskFound(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user