github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/qrm-plugins/io/handlers/iocost/utils.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package iocost 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "os" 23 "path/filepath" 24 "strings" 25 26 "github.com/kubewharf/katalyst-core/pkg/util/general" 27 ) 28 29 func getDevicesIdToModel(deviceNames []string) (map[string]DevModel, error) { 30 devsIDToModel := make(map[string]DevModel, len(deviceNames)) 31 for _, devName := range deviceNames { 32 _, err := os.Stat(fmt.Sprintf("/sys/block/%s/device", devName)) 33 if os.IsNotExist(err) { 34 continue 35 } 36 37 devIDFile := fmt.Sprintf("/sys/block/%s/dev", devName) 38 devIDBytes, err := ioutil.ReadFile(devIDFile) 39 if err != nil { 40 general.Errorf("failed to ReadFile %s, err %v", devIDFile, err) 41 continue 42 } 43 devID := strings.TrimSpace(string(devIDBytes)) 44 45 modelBytes, err := ioutil.ReadFile(fmt.Sprintf("/sys/block/%s/device/model", devName)) 46 if err != nil { 47 if strings.HasPrefix(devName, "vd") { 48 devsIDToModel[devID] = DevModelVirtualdisk 49 } 50 continue 51 } 52 53 model := strings.TrimSpace(string(modelBytes)) 54 if strings.HasPrefix(strings.ToLower(model), "qemu") { 55 devsIDToModel[devID] = DevModelVirtualdisk 56 } else { 57 devsIDToModel[devID] = DevModel(model) 58 } 59 } 60 61 return devsIDToModel, nil 62 } 63 64 func getAllDeviceNames() ([]string, error) { 65 files, err := ioutil.ReadDir("/sys/block") 66 if err != nil { 67 return nil, err 68 } 69 70 allDeviceNames := make([]string, 0, len(files)) 71 for _, fi := range files { 72 allDeviceNames = append(allDeviceNames, fi.Name()) 73 } 74 75 return allDeviceNames, nil 76 } 77 78 func getDeviceNameFromID(targetDevID string) (string, bool, error) { 79 allDeviceNames, err := getAllDeviceNames() 80 if err != nil { 81 return "", false, err 82 } 83 84 for _, devName := range allDeviceNames { 85 _, err := os.Stat(fmt.Sprintf("/sys/block/%s/device", devName)) 86 if os.IsNotExist(err) { 87 continue 88 } 89 90 devIDFile := fmt.Sprintf("/sys/block/%s/dev", devName) 91 devIDBytes, err := ioutil.ReadFile(devIDFile) 92 if err != nil { 93 general.Errorf("failed to ReadFile %s, err %v", devIDFile, err) 94 continue 95 } 96 devID := strings.TrimSpace(string(devIDBytes)) 97 98 if devID == targetDevID { 99 return devName, true, nil 100 } 101 } 102 103 return "", false, nil 104 } 105 106 func getDeviceType(deviceName, rotationalFilePath string) (DeviceType, error) { 107 /* Check if the device name starts with "sd" 108 * sd means scsi devices. 109 * Currently, only HDD/SSD could be scsi device. 110 */ 111 // Step1, the device should be scsi device. 112 if !strings.HasPrefix(deviceName, "sd") { 113 return Unknown, fmt.Errorf("not scsi disk") 114 } 115 116 // Step2, if it is scsi device, then check rotational 117 // if rotational = 1, then HDD, else SSD. 118 cleanedRotationalFilePath := filepath.Clean(rotationalFilePath) 119 contents, err := ioutil.ReadFile(cleanedRotationalFilePath) 120 if err != nil { 121 if os.IsNotExist(err) { 122 return Unknown, nil 123 } 124 return Unknown, err 125 } 126 127 rotational := strings.TrimSpace(string(contents)) 128 switch rotational { 129 case "1": 130 return HDD, nil 131 case "0": 132 return SSD, nil 133 default: 134 return Unknown, fmt.Errorf("unknown rotational status") 135 } 136 }