Files
cloudpods/pkg/util/sysutils/storages.go

116 lines
2.7 KiB
Go

// Copyright 2019 Yunion
//
// 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 sysutils
import (
"io/ioutil"
"path/filepath"
"strconv"
"yunion.io/x/pkg/errors"
)
type SStorage struct {
Device string
Rotational bool
Size int64
ReadOnly bool
Removable bool
Partition bool
Scheduler string
}
const (
sysBlockDir = "/sys/class/block"
)
func DetectStorageType() (string, error) {
ss, err := DetectStorages()
if err != nil {
return "", errors.Wrap(err, "DetectStorages")
}
var hdd, ssd int
for _, s := range ss {
if s.Partition {
continue
}
if s.Removable {
continue
}
if s.Rotational {
hdd++
} else {
ssd++
}
}
if hdd > 0 && ssd > 0 {
return "hybrid", nil
} else if hdd > 0 {
return "hdd", nil
} else if ssd > 0 {
return "ssd", nil
} else {
return "", nil
}
}
func DetectStorages() ([]SStorage, error) {
files, err := ioutil.ReadDir(sysBlockDir)
if err != nil {
return nil, errors.Wrap(err, "ReadDir /sys/class/block")
}
ret := make([]SStorage, 0)
for _, f := range files {
s := detectStorage(filepath.Join(sysBlockDir, f.Name()), f.Name())
ret = append(ret, s)
}
return ret, nil
}
func detectStorage(path string, name string) SStorage {
s := SStorage{
Device: name,
}
sizeBytes, _ := ioutil.ReadFile(filepath.Join(path, "size"))
s.Size, _ = strconv.ParseInt(string(sizeBytes), 10, 64)
removableBytes, _ := ioutil.ReadFile(filepath.Join(path, "removable"))
if len(removableBytes) > 0 && removableBytes[0] == '0' {
s.Removable = false
} else {
s.Removable = true
}
roBytes, _ := ioutil.ReadFile(filepath.Join(path, "ro"))
if len(roBytes) > 0 && roBytes[0] == '0' {
s.ReadOnly = false
} else {
s.ReadOnly = true
}
partitionBytes, _ := ioutil.ReadFile(filepath.Join(path, "partition"))
if len(partitionBytes) > 0 && partitionBytes[0] == '1' {
s.Partition = true
} else {
s.Partition = false
}
rotationalBytes, _ := ioutil.ReadFile(filepath.Join(path, "queue/rotational"))
if len(rotationalBytes) > 0 && rotationalBytes[0] == '0' {
s.Rotational = false
} else {
s.Rotational = true
}
schedulerBytes, _ := ioutil.ReadFile(filepath.Join(path, "queue/scheduler"))
s.Scheduler = string(schedulerBytes)
return s
}