Skip to content

Commit d4046b6

Browse files
authored
Automated cherry pick of #23725: feat(baremetal-agent): Linux PCIE disk support mdadm soft raid (#23930)
* feat(baremetal-agent): Linux PCIE disk support mdadm soft raid * fix(baremeta-agent): soft raid support intel imsm * fix: update baremetal-agent base
1 parent 55ab19d commit d4046b6

File tree

16 files changed

+609
-44
lines changed

16 files changed

+609
-44
lines changed

build/docker/Dockerfile.baremetal-agent

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.9-20231219.0
1+
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.9-20251215.0
22

33
LABEL maintainer="Zexi Li <[email protected]>"
44

build/docker/Dockerfile.baremetal-base

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#RUN yum install -y https://iso.yunion.cn/vm-images/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
22
#RUN yum install -y http://192.168.23.50:8083/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
3-
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunionos:v4.0.0-20251110.1 as yunionos
3+
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunionos:v4.0.0-20251201.0 as yunionos
44

55
FROM centos:8 as grub-stage
66

build/docker/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ WEBCONSOLE_BASE_VERSION_3-22-2 = 3.22.2-1
4040
webconsole-base:
4141
$(DOCKER_BUILDX)/webconsole-base:$(WEBCONSOLE_BASE_VERSION_3-22-2) -f ./Dockerfile.webconsole-base .
4242

43-
BAREMETAL_BASE_VERSION = v0.3.9-20231219.1
43+
BAREMETAL_BASE_VERSION = v0.3.9-20251112.1
4444

4545
FEDORA_RISCV64_VERSION = 42
4646
fedora-riscv64-base:

pkg/apis/compute/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ type BaremetalDiskConfig struct {
325325
RA *bool `json:"ra,omitempty"`
326326
WT *bool `json:"wt,omitempty"`
327327
Direct *bool `json:"direct,omitempty"`
328+
SoftRaidIdx *int `json:"soft_raid_idx"`
328329
}
329330

330331
type RootDiskMatcherSizeMBRange struct {

pkg/apis/compute/baremetal_const.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ var (
6464
DISK_DRIVER_ADAPTECRAID,
6565
)
6666

67+
DISK_DRIVERS_SOFT_RAID = sets.NewString(
68+
DISK_DRIVER_LINUX,
69+
DISK_DRIVER_PCIE,
70+
)
71+
6772
DISK_DRIVERS = sets.NewString(
6873
DISK_DRIVER_LINUX,
6974
DISK_DRIVER_PCIE).Union(DISK_DRIVERS_RAID)

pkg/baremetal/manager.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ import (
5656
"yunion.io/x/onecloud/pkg/baremetal/utils/disktool"
5757
"yunion.io/x/onecloud/pkg/baremetal/utils/grub"
5858
"yunion.io/x/onecloud/pkg/baremetal/utils/ipmitool"
59+
raid2 "yunion.io/x/onecloud/pkg/baremetal/utils/raid"
5960
raiddrivers "yunion.io/x/onecloud/pkg/baremetal/utils/raid/drivers"
61+
"yunion.io/x/onecloud/pkg/baremetal/utils/raid/mdadm"
6062
"yunion.io/x/onecloud/pkg/baremetal/utils/uefi"
6163
"yunion.io/x/onecloud/pkg/cloudcommon/types"
6264
"yunion.io/x/onecloud/pkg/compute/baremetal"
@@ -2743,15 +2745,32 @@ func (s *SBaremetalServer) NewConfigedSSHPartitionTool(term *ssh.Client) (*diskt
27432745
return nil, fmt.Errorf("CalculateLayout: %v", err)
27442746
}
27452747

2748+
log.Errorf("NewConfigedSSHPartitionTool layouts: %s", jsonutils.Marshal(layouts))
27462749
diskConfs := baremetal.GroupLayoutResultsByDriverAdapter(layouts)
27472750
for _, dConf := range diskConfs {
27482751
driver := dConf.Driver
27492752
adapter := dConf.Adapter
2753+
isSoftRaid := baremetal.DISK_DRIVERS_SOFT_RAID.Has(driver)
2754+
27502755
raidDrv := raiddrivers.GetDriver(driver, term)
27512756
if raidDrv != nil {
27522757
if err := raidDrv.ParsePhyDevs(); err != nil {
27532758
return nil, fmt.Errorf("RaidDriver %s parse physical devices: %v", raidDrv.GetName(), err)
27542759
}
2760+
if isSoftRaid {
2761+
devs := make([]*baremetal.BaremetalStorage, 0)
2762+
for _, layout := range layouts {
2763+
if len(layout.Disks) > 0 && layout.Disks[0].Driver == driver && layout.Disks[0].Adapter == dConf.Adapter {
2764+
devs = append(devs, layout.Disks...)
2765+
}
2766+
}
2767+
2768+
log.Infof("SetDevicesForAdapter %v", jsonutils.Marshal(devs))
2769+
if mdadmDrver, ok := raidDrv.(raid2.IRaidDeviceSetter); ok {
2770+
mdadmDrver.SetDevicesForAdapter(dConf.Adapter, devs)
2771+
}
2772+
}
2773+
27552774
if err := raiddrivers.PostBuildRaid(raidDrv, adapter); err != nil {
27562775
return nil, fmt.Errorf("Build %s raid failed: %v", raidDrv.GetName(), err)
27572776
}
@@ -2803,11 +2822,27 @@ func (s *SBaremetalServer) DoDiskConfig(term *ssh.Client) (*disktool.SSHPartitio
28032822
for _, dConf := range diskConfs {
28042823
driver := dConf.Driver
28052824
adapter := dConf.Adapter
2825+
isSoftRaid := baremetal.DISK_DRIVERS_SOFT_RAID.Has(driver)
2826+
28062827
raidDrv := raiddrivers.GetDriver(driver, term)
28072828
if raidDrv != nil {
28082829
if err := raidDrv.ParsePhyDevs(); err != nil {
28092830
return nil, fmt.Errorf("RaidDriver %s parse physical devices: %v", raidDrv.GetName(), err)
28102831
}
2832+
if isSoftRaid {
2833+
devs := make([]*baremetal.BaremetalStorage, 0)
2834+
for _, layout := range layouts {
2835+
if len(layout.Disks) > 0 && layout.Disks[0].Driver == driver && layout.Disks[0].Adapter == dConf.Adapter {
2836+
devs = append(devs, layout.Disks...)
2837+
}
2838+
}
2839+
2840+
log.Infof("SetDevicesForAdapter %v", jsonutils.Marshal(devs))
2841+
if mdadmDriver, ok := raidDrv.(raid2.IRaidDeviceSetter); ok {
2842+
mdadmDriver.SetDevicesForAdapter(dConf.Adapter, devs)
2843+
}
2844+
}
2845+
28112846
if err := raiddrivers.BuildRaid(raidDrv, dConf.Configs, adapter); err != nil {
28122847
return nil, fmt.Errorf("Build %s raid failed: %v", raidDrv.GetName(), err)
28132848
}
@@ -2851,6 +2886,10 @@ func (s *SBaremetalServer) DoDiskUnconfig(term *ssh.Client) error {
28512886
}
28522887

28532888
func (s *SBaremetalServer) DoEraseDisk(term *ssh.Client) error {
2889+
// soft raid should stop mdadm first
2890+
if err := mdadm.CleanRaid(term); err != nil {
2891+
return err
2892+
}
28542893
cmd := "/lib/mos/partdestroy.sh"
28552894
_, err := term.Run(cmd)
28562895
return err
@@ -2911,6 +2950,7 @@ func (s *SBaremetalServer) DoPartitionDisk(tool *disktool.SSHPartitionTool, term
29112950
rootImageId := s.GetRootTemplateId()
29122951
diskOffset := 0
29132952
rootDisk := tool.GetRootDisk()
2953+
log.Infof("root disk name %s", rootDisk.GetDevName())
29142954
if len(rootImageId) > 0 {
29152955
rootDiskObj := disks[0]
29162956
rootSize, _ := rootDiskObj.Int("size")

pkg/baremetal/tasks/create.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ func (self *SBaremetalServerCreateTask) RemoveEFIOSEntry() bool {
5454
}
5555

5656
func (self *SBaremetalServerCreateTask) DoDeploys(ctx context.Context, term *ssh.Client) (jsonutils.JSONObject, error) {
57-
// Build raid
58-
tool, err := self.Baremetal.GetServer().DoDiskConfig(term)
59-
if err != nil {
57+
if err := self.Baremetal.GetServer().DoEraseDisk(term); err != nil {
6058
return nil, self.onError(ctx, term, err)
6159
}
6260
time.Sleep(2 * time.Second)
63-
if err := self.Baremetal.GetServer().DoEraseDisk(term); err != nil {
61+
// Build raid
62+
tool, err := self.Baremetal.GetServer().DoDiskConfig(term)
63+
if err != nil {
6464
return nil, self.onError(ctx, term, err)
6565
}
6666
time.Sleep(2 * time.Second)

pkg/baremetal/utils/disktool/disktool.go

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package disktool
1717
import (
1818
"fmt"
1919
"math"
20+
"strconv"
2021
"strings"
2122

2223
"yunion.io/x/jsonutils"
@@ -229,7 +230,7 @@ type DiskPartitions struct {
229230
partitions []*Partition
230231
}
231232

232-
func newDiskPartitions(driver string, adapter int, raidConfig string, sizeMB int64, blockSize int64, diskType string, tool *PartitionTool) *DiskPartitions {
233+
func newDiskPartitions(driver string, adapter int, raidConfig string, sizeMB int64, blockSize int64, diskType string, softRaidIdx *int, tool *PartitionTool) *DiskPartitions {
233234
ps := new(DiskPartitions)
234235
ps.driver = driver
235236
ps.adapter = adapter
@@ -239,9 +240,32 @@ func newDiskPartitions(driver string, adapter int, raidConfig string, sizeMB int
239240
ps.blockSize = blockSize
240241
ps.diskType = diskType
241242
ps.partitions = make([]*Partition, 0)
243+
244+
// soft raid, mdadm
245+
if softRaidIdx != nil {
246+
ps.GetMdadmInfo(softRaidIdx)
247+
}
242248
return ps
243249
}
244250

251+
func (ps *DiskPartitions) GetMdadmInfo(softRaidIdx *int) {
252+
devLinkName := fmt.Sprintf("/dev/md/md%d", *softRaidIdx)
253+
devLinkNickname := fmt.Sprintf("/dev/md/md%d_0", *softRaidIdx)
254+
cmd := fmt.Sprintf("readlink -f $(test -e %s && echo %s || echo %s)", devLinkName, devLinkName, devLinkNickname)
255+
out, err := ps.tool.Run(cmd)
256+
if err != nil || len(out) == 0 {
257+
log.Errorf("failed readlink of %s: %s", devLinkName, err)
258+
return
259+
}
260+
261+
ps.dev = strings.TrimSpace(out[0])
262+
ps.devName = ps.dev
263+
uuid, sectors := ps.tool.GetMdadmUuidAndSector(ps.dev)
264+
ps.pciPath = uuid
265+
ps.sectors = sectors
266+
ps.blockSize = 512
267+
}
268+
245269
func (p *DiskPartitions) IsRaidDriver() bool {
246270
return utils.IsInStringArray(p.driver, []string{
247271
baremetal.DISK_DRIVER_MEGARAID,
@@ -324,7 +348,7 @@ func (ps *DiskPartitions) IsReady() bool {
324348

325349
func (ps *DiskPartitions) GetDevName() string {
326350
devName := ps.devName
327-
if !ps.IsRaidDriver() || ps.raidConfig == baremetal.DISK_CONF_NONE {
351+
if ps.raidConfig == baremetal.DISK_CONF_NONE {
328352
return devName
329353
}
330354
raidDrv, err := raiddrivers.GetDriverWithInit(ps.driver, ps.tool.runner.Term())
@@ -690,12 +714,13 @@ func (tool *PartitionTool) parseLsDisk(lines []string, driver string) {
690714

691715
func (tool *PartitionTool) FetchDiskConfs(diskConfs []baremetal.DiskConfiguration) *PartitionTool {
692716
for _, d := range diskConfs {
693-
disk := newDiskPartitions(d.Driver, d.Adapter, d.RaidConfig, d.Size, d.Block, d.DiskType, tool)
717+
disk := newDiskPartitions(d.Driver, d.Adapter, d.RaidConfig, d.Size, d.Block, d.DiskType, d.SoftRaidIdx, tool)
694718
tool.disks = append(tool.disks, disk)
719+
isSoftRaid := d.RaidConfig != baremetal.DISK_CONF_NONE
695720
var key string
696-
if d.Driver == baremetal.DISK_DRIVER_LINUX {
721+
if d.Driver == baremetal.DISK_DRIVER_LINUX && !isSoftRaid {
697722
key = NONRAID_DRIVER
698-
} else if d.Driver == baremetal.DISK_DRIVER_PCIE {
723+
} else if d.Driver == baremetal.DISK_DRIVER_PCIE && !isSoftRaid {
699724
key = PCIE_DRIVER
700725
} else {
701726
key = RAID_DRVIER
@@ -768,7 +793,42 @@ func (tool *PartitionTool) IsAllDisksReady() bool {
768793
return true
769794
}
770795

796+
func (tool *PartitionTool) GetMdadmUuidAndSector(devPath string) (string, int64) {
797+
var uuid string
798+
var sectorsRet int64
799+
// get md uuid as pci path
800+
cmd := fmt.Sprintf("/sbin/mdadm --detail %s | grep UUID", devPath)
801+
output, err := tool.Run(cmd)
802+
if err == nil && len(output) > 0 {
803+
uuidSeg := output[0]
804+
segs := strings.SplitN(strings.TrimSpace(uuidSeg), ":", 2)
805+
if len(segs) == 2 {
806+
uuid = strings.TrimSpace(segs[1])
807+
}
808+
}
809+
810+
// get block size
811+
cmd = fmt.Sprintf("blockdev --getsz %s 2>/dev/null || echo 0", devPath)
812+
output, err = tool.Run(cmd)
813+
if err == nil && len(output) > 0 {
814+
if sectors, err := strconv.ParseInt(strings.TrimSpace(output[0]), 10, 64); err == nil {
815+
sectorsRet = sectors
816+
}
817+
}
818+
return uuid, sectorsRet
819+
}
820+
771821
func (tool *PartitionTool) RetrieveDiskInfo(rootMatcher *api.BaremetalRootDiskMatcher) error {
822+
for _, disk := range tool.disks {
823+
if baremetal.DISK_DRIVERS_SOFT_RAID.Has(disk.driver) && disk.raidConfig != baremetal.DISK_CONF_NONE {
824+
log.Infof("Soft raid mdadm set diskinfo dev %s", disk.dev)
825+
uuid, sectors := tool.GetMdadmUuidAndSector(disk.dev)
826+
disk.pciPath = uuid
827+
disk.sectors = sectors
828+
disk.blockSize = 512
829+
}
830+
}
831+
772832
for _, driver := range []string{RAID_DRVIER, NONRAID_DRIVER, PCIE_DRIVER} {
773833
cmd := fmt.Sprintf("/lib/mos/lsdisk --%s", driver)
774834
ret, err := tool.Run(cmd)

pkg/baremetal/utils/raid/drivers/drivers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
2626
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/adaptec"
2727
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/hpssactl"
28+
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/mdadm"
2829
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/megactl"
2930
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/mvcli"
3031
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/sas2iru"

pkg/baremetal/utils/raid/interface.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ type IRaidAdapter interface {
4545
PostBuildRaid() error
4646
}
4747

48+
type IRaidDeviceSetter interface {
49+
SetDevicesForAdapter(int, []*baremetal.BaremetalStorage)
50+
}
51+
4852
type IExecTerm interface {
4953
Run(cmds ...string) ([]string, error)
5054
RunWithInput(input io.Reader, cmds ...string) ([]string, error)

0 commit comments

Comments
 (0)