reject mixed drive situations with drives on root disks (#11057)

till now we used to match the inode number of the root
drive and the drive path minio would use, if they match
we knew that its a root disk.

this may not be true in all situations such as running
inside a container environment where the container might
be mounted from a different partition altogether, root
disk detection might fail.
This commit is contained in:
Harshavardhana 2020-12-09 00:27:02 -08:00 committed by GitHub
parent 54d243cd98
commit d8c1f93de6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 69 deletions

View File

@ -240,7 +240,7 @@ func newXLStorage(ep Endpoint) (*xlStorage, error) {
return nil, err
}
rootDisk, err := disk.IsRootDisk(path)
rootDisk, err := disk.IsRootDisk(path, "/")
if err != nil {
return nil, err
}

View File

@ -30,3 +30,21 @@ type Info struct {
Ffree uint64
FSType string
}
// SameDisk reports whether di1 and di2 describe the same disk.
func SameDisk(di1, di2 Info) bool {
if di1.Total != di2.Total {
// disk total size different
return false
}
if di1.Files != di2.Files {
// disk total inodes different
return false
}
// returns true only if Used, Free and number of free
// inodes are same, then its the same disk.
return di1.Used == di2.Used && di1.Free == di2.Free &&
di1.Ffree == di2.Ffree
}

View File

@ -1,7 +1,5 @@
// +build windows
/*
* MinIO Cloud Storage, (C) 2019 MinIO, Inc.
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,8 +17,21 @@
package disk
import "runtime"
// IsRootDisk returns if diskPath belongs to root-disk, i.e the disk mounted at "/"
func IsRootDisk(diskPath string) (bool, error) {
// On windows a disk can never be mounted on a subpath.
return false, nil
func IsRootDisk(diskPath string, rootDisk string) (bool, error) {
if runtime.GOOS == "windows" {
// On windows this function is not implemented.
return false, nil
}
info, err := GetInfo(diskPath)
if err != nil {
return false, err
}
rootInfo, err := GetInfo(rootDisk)
if err != nil {
return false, err
}
return SameDisk(info, rootInfo), nil
}

View File

@ -1,62 +0,0 @@
// +build !windows
/*
* MinIO Cloud Storage, (C) 2019 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package disk
import (
"os"
"syscall"
)
// IsRootDisk returns if diskPath belongs to root-disk, i.e the disk mounted at "/"
func IsRootDisk(diskPath string) (bool, error) {
rootDisk := false
diskInfo, err := os.Stat(diskPath)
if err != nil {
return false, err
}
rootHostsInfo, err := os.Stat("/etc/hosts")
if err != nil {
return false, err
}
rootInfo, err := os.Stat("/")
if err != nil {
return false, err
}
diskStat, diskStatOK := diskInfo.Sys().(*syscall.Stat_t)
rootHostsStat, rootHostsStatOK := rootHostsInfo.Sys().(*syscall.Stat_t)
rootStat, rootStatOK := rootInfo.Sys().(*syscall.Stat_t)
if diskStatOK && rootHostsStatOK {
if diskStat.Dev == rootHostsStat.Dev {
// Indicate if the disk path is on root disk. This is used to indicate the healing
// process not to format the drive and end up healing it.
rootDisk = true
}
}
if !rootDisk {
if diskStatOK && rootStatOK {
if diskStat.Dev == rootStat.Dev {
// Indicate if the disk path is on root disk. This is used to indicate the healing
// process not to format the drive and end up healing it.
rootDisk = true
}
}
}
return rootDisk, nil
}