From 82af0be1aaac3dd7916329ca04c89743e022249d Mon Sep 17 00:00:00 2001 From: Krishna Srinivas <634494+krishnasrinivas@users.noreply.github.com> Date: Wed, 23 Jan 2019 15:29:29 -0800 Subject: [PATCH] Healing process should not heal root disk (#7089) --- cmd/posix.go | 22 ++++++++++++++-------- cmd/xl-sets.go | 12 ++++++++++++ pkg/disk/root-disk-unix.go | 31 +++++++++++++++++++++++++++++++ pkg/disk/root-disk-windows.go | 9 +++++++++ 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 pkg/disk/root-disk-unix.go create mode 100644 pkg/disk/root-disk-windows.go diff --git a/cmd/posix.go b/cmd/posix.go index 7ca778d90..01b49b933 100644 --- a/cmd/posix.go +++ b/cmd/posix.go @@ -303,9 +303,10 @@ func (s *posix) IsOnline() bool { // DiskInfo is an extended type which returns current // disk usage per path. type DiskInfo struct { - Total uint64 - Free uint64 - Used uint64 + Total uint64 + Free uint64 + Used uint64 + RootDisk bool } // DiskInfo provides current information about disk space usage, @@ -319,12 +320,17 @@ func (s *posix) DiskInfo() (info DiskInfo, err error) { if !s.diskMount { used = atomic.LoadUint64(&s.totalUsed) } - return DiskInfo{ - Total: di.Total, - Free: di.Free, - Used: used, - }, nil + rootDisk, err := disk.IsRootDisk(s.diskPath) + if err != nil { + return info, err + } + return DiskInfo{ + Total: di.Total, + Free: di.Free, + Used: used, + RootDisk: rootDisk, + }, nil } // getVolDir - will convert incoming volume names to diff --git a/cmd/xl-sets.go b/cmd/xl-sets.go index dbeb6b254..2c9216236 100644 --- a/cmd/xl-sets.go +++ b/cmd/xl-sets.go @@ -1029,6 +1029,18 @@ func (s *xlSets) HealFormat(ctx context.Context, dryRun bool) (res madmin.HealRe } }(storageDisks) + for i, disk := range storageDisks { + info, err := disk.DiskInfo() + if err != nil { + storageDisks[i] = nil + } + if info.RootDisk { + // We should not heal on root disk. i.e in a situation where the minio-administrator has unmounted a + // defective drive we should not heal a path on the root disk. + storageDisks[i] = nil + } + } + formats, sErrs := loadFormatXLAll(storageDisks) if err = checkFormatXLValues(formats); err != nil { return madmin.HealResultItem{}, err diff --git a/pkg/disk/root-disk-unix.go b/pkg/disk/root-disk-unix.go new file mode 100644 index 000000000..be51f0df7 --- /dev/null +++ b/pkg/disk/root-disk-unix.go @@ -0,0 +1,31 @@ +// +build !windows + +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 + } + rootInfo, err := os.Stat("/") + if err != nil { + return false, err + } + diskStat, diskStatOK := diskInfo.Sys().(*syscall.Stat_t) + rootStat, rootStatOK := rootInfo.Sys().(*syscall.Stat_t) + 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 +} diff --git a/pkg/disk/root-disk-windows.go b/pkg/disk/root-disk-windows.go new file mode 100644 index 000000000..b19034f3b --- /dev/null +++ b/pkg/disk/root-disk-windows.go @@ -0,0 +1,9 @@ +// +build windows + +package disk + +// 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 +}