fix(scheduler,baremetal): match RAID and PCIE storages in range (#20767)

The index of PCIE storages is not reindex when range is provided.
This commit is contained in:
Zexi Li
2024-07-09 11:11:55 +08:00
committed by GitHub
parent 36a8428f24
commit 9d90fb6a04
3 changed files with 312 additions and 14 deletions
+3 -2
View File
@@ -116,12 +116,13 @@ func buildRaid(driver raid.IRaidDriver, adapter raid.IRaidAdapter, confs []*api.
var selected []*baremetal.BaremetalStorage
var nonDisks []*baremetal.BaremetalStorage
var err error
left := devs
for _, conf := range confs {
selected, left = baremetal.RetrieveStorages(conf, left)
selected, left, err = baremetal.RetrieveStorages(conf, left)
if len(selected) == 0 {
return fmt.Errorf("No enough disks for config %#v", conf)
return errors.Wrapf(err, "no enough disks for config %#v", conf)
}
var err error
switch conf.Conf {
+34 -9
View File
@@ -45,7 +45,7 @@ func isDiskConfigStorageMatch(
confAdapter *int,
storage *BaremetalStorage,
selected []*BaremetalStorage,
) bool {
) (bool, error) {
isRotate := storage.Rotate
adapter := storage.Adapter
index := storage.Index
@@ -60,17 +60,26 @@ func isDiskConfigStorageMatch(
adapterIsEqual := (confAdapter == nil || *confAdapter == adapter) &&
(confDriver == nil || *confDriver == driver)
log.V(10).Debugf("Try storage: %#v, typeIsHybrid: %v, typeIsRotate: %v, typeIsSSD: %v, rangeIsNoneAndCountZero: %v, rangeIsNotNoneAndIndexInRange: %v, rangeIsNoneAndSmallThanCount: %v, adapterIsEqual: %v", *storage, typeIsHybrid, typeIsRotate, typeIsSSD, rangeIsNoneAndCountZero, rangeIsNotNoneAndIndexInRange, rangeIsNoneAndSmallThanCount, adapterIsEqual)
if (typeIsHybrid || typeIsRotate || typeIsSSD) &&
(rangeIsNoneAndCountZero || rangeIsNotNoneAndIndexInRange || rangeIsNoneAndSmallThanCount) &&
adapterIsEqual {
return true
return true, nil
}
return false
errs := []error{}
// aggregate errors
if !(typeIsHybrid || typeIsRotate || typeIsSSD) {
errs = append(errs, fmt.Errorf("check type: is_hybrid: %v, is_rotate: %v, is_ssd: %v, type: %s", typeIsHybrid, typeIsRotate, typeIsSSD, config.Type))
}
if !(rangeIsNoneAndCountZero || rangeIsNotNoneAndIndexInRange || rangeIsNoneAndSmallThanCount) {
errs = append(errs, fmt.Errorf("check range: is_none: %v, index_in_range: %v, small_than_count: %v, index: %d, range: %v", rangeIsNoneAndCountZero, rangeIsNotNoneAndIndexInRange, rangeIsNoneAndSmallThanCount, index, config.Range))
}
if adapterIsEqual {
errs = append(errs, fmt.Errorf("check adapter: is_equal: %v", adapterIsEqual))
}
return false, errors.NewAggregate(errs)
}
func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*BaremetalStorage) (selected, rest []*BaremetalStorage) {
func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*BaremetalStorage) (selected, rest []*BaremetalStorage, err error) {
var confDriver *string = nil
var confAdapter *int = nil
@@ -83,24 +92,36 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal
selected = make([]*BaremetalStorage, 0)
rest = make([]*BaremetalStorage, 0)
errs := []error{}
idx := 0
curAdapter := 0
adapterChange := false
curDriver := ""
driverChange := false
for _, storage := range storages {
if storage.Adapter != curAdapter {
adapterChange = true
curAdapter = storage.Adapter
}
if storage.Driver != curDriver {
driverChange = true
curDriver = storage.Driver
}
if adapterChange {
idx = 0
adapterChange = false
}
if driverChange {
idx = 0
driverChange = false
}
if storage.Index == 0 {
storage.Index = int64(idx)
}
if isDiskConfigStorageMatch(diskConfig, confDriver, confAdapter, storage, selected) {
if isMatched, mErr := isDiskConfigStorageMatch(diskConfig, confDriver, confAdapter, storage, selected); isMatched {
if confDriver == nil {
confDriver = &storage.Driver
}
@@ -110,6 +131,7 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal
selected = append(selected, storage)
} else {
rest = append(rest, storage)
errs = append(errs, mErr)
}
if confDriver == nil {
idx++
@@ -117,6 +139,9 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal
idx++
}
}
if len(errs) > 0 {
err = errors.NewAggregate(errs)
}
return
}
@@ -349,10 +374,10 @@ func CalculateLayout(confs []*api.BaremetalDiskConfig, storages []*BaremetalStor
noneConf, _ := ParseDiskConfig(DISK_CONF_NONE)
conf = &noneConf
}
selected, restStorges := RetrieveStorages(conf, storages)
selected, restStorges, rErr := RetrieveStorages(conf, storages)
storages = restStorges
if len(selected) == 0 {
err = fmt.Errorf("Not found matched storages by config: %#v", conf)
err = errors.Wrapf(rErr, "not found matched storages by config: %#v", conf)
return
}
resultErr := MeetConfig(conf, selected)
+275 -3
View File
@@ -476,6 +476,278 @@ func TestCalculateLayout(t *testing.T) {
}
}
func TestCalculateLayout2(t *testing.T) {
adapater0 := 0
confs := []*api.BaremetalDiskConfig{
{
Adapter: &adapater0,
Conf: DISK_CONF_RAID1,
Count: 2,
Driver: DISK_DRIVER_MEGARAID,
Range: []int64{12, 13},
Type: DISK_TYPE_ROTATE,
},
{
Adapter: &adapater0,
Conf: DISK_CONF_RAID10,
Count: 12,
Driver: DISK_DRIVER_MEGARAID,
Range: []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
Type: DISK_TYPE_ROTATE,
},
{
Adapter: &adapater0,
Conf: DISK_CONF_NONE,
Count: 1,
Driver: DISK_DRIVER_PCIE,
Range: []int64{0},
Type: DISK_TYPE_SSD,
},
}
storages := []*BaremetalStorage{}
storageJson := `[
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1A1JPM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 0,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AMGGM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 1,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AN53M",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 2,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1ATVBM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 3,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AR4VM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 4,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1ARYBM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 5,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AS36M",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 6,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1A1K6M",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 7,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AM98M",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 8,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1ATTLM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 9,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AR3DM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 10,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "HGST HUS728T8TAL5200 A9Y2VY1AN3DM",
"rotate": true,
"sector": 15626993664,
"size": 7630368,
"slot": 11,
"status": "unconfigured_good"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "TOSHIBA AL15SEB060N 310253K0A07BFYVH",
"rotate": true,
"sector": 1171062784,
"size": 571808,
"slot": 12,
"status": "online"
},
{
"adapter": 0,
"block": 512,
"driver": "MegaRaid",
"enclousure": 65,
"index": 0,
"max_strip_size": 0,
"min_strip_size": 0,
"model": "TOSHIBA AL15SEB060N 310253K0A0EDFYVH",
"rotate": true,
"sector": 1171062784,
"size": 571808,
"slot": 13,
"status": "online"
},
{
"adapter": 0,
"block": 512,
"dev": "nvme0n1",
"driver": "",
"enclousure": 0,
"index": 0,
"kernel": "unknown",
"max_strip_size": 0,
"min_strip_size": 0,
"module": "INSPUR-NS8600G2U640",
"pci_class": "unknown",
"rotate": false,
"sector": 12502446768,
"size": 6104710,
"slot": 0
}
]`
storageObj, err := jsonutils.ParseString(storageJson)
if err != nil {
t.Fatalf("parse json error: %v", err)
}
if err := storageObj.Unmarshal(&storages); err != nil {
t.Fatalf("unmarshal json to storages: %v", err)
}
layout, err := CalculateLayout(confs, storages)
if err != nil {
t.Fatalf("calculate layout: %v", err)
}
log.Infof("layout: %+v", layout)
}
func TestCheckDisksAllocable(t *testing.T) {
confs, err := NewBaremetalDiskConfigs(
"[0-1]:raid1:(100g,32g,):adapter0",
@@ -1211,12 +1483,12 @@ func TestRetrieveStorages(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotSelected, gotRest := RetrieveStorages(tt.args.diskConfig, tt.args.storages)
gotSelected, gotRest, err := RetrieveStorages(tt.args.diskConfig, tt.args.storages)
if !reflect.DeepEqual(gotSelected, tt.wantSelected) {
t.Errorf("RetrieveStorages() gotSelected = %v, want %v", gotSelected, tt.wantSelected)
t.Errorf("RetrieveStorages() gotSelected = %v, want %v, err: %s", gotSelected, tt.wantSelected, err)
}
if !reflect.DeepEqual(gotRest, tt.wantRest) {
t.Errorf("RetrieveStorages() gotRest = %v, want %v", gotRest, tt.wantRest)
t.Errorf("RetrieveStorages() gotRest = %v, want %v, err: %s", gotRest, tt.wantRest, err)
}
})
}