From c005337eedfce32cfcbe03b519af4792c8845e71 Mon Sep 17 00:00:00 2001 From: wanyaoqi <18528551+wanyaoqi@users.noreply.github.com> Date: Sun, 1 Feb 2026 20:27:12 +0800 Subject: [PATCH] Automated cherry pick of #24126: feat(region,host): riscv64 cpu arch support (#24174) * feat(region,host): riscv64 cpu arch support * fix(region,host): compatible riscv64 * fix(host): add qemu v10.0.7 support --- build/docker/Dockerfile.host-deployer | 2 +- cmd/climc/shell/image/images.go | 2 +- pkg/apis/compute/guest_const.go | 2 +- pkg/apis/const.go | 18 +++- pkg/cloudcommon/db/archs.go | 6 ++ pkg/compute/guestdrivers/kvm.go | 8 +- pkg/compute/models/disks.go | 2 + pkg/compute/models/guest_actions.go | 4 +- pkg/compute/models/guests.go | 7 +- pkg/compute/models/hosts.go | 4 + pkg/compute/models/server_skus.go | 7 ++ pkg/hostman/diskutils/qemu_kvm/driver.go | 94 ++++++++++++++++++- pkg/hostman/guestfs/fsdriver/linux.go | 5 + pkg/hostman/guestman/arch/arch.go | 30 +++++- pkg/hostman/guestman/arch/arm.go | 22 +---- pkg/hostman/guestman/arch/riscv.go | 75 +++++++++++++++ pkg/hostman/guestman/guestman.go | 16 +++- pkg/hostman/guestman/pci.go | 8 +- pkg/hostman/guestman/qemu-kvm.go | 6 +- pkg/hostman/guestman/qemu-kvmhelper.go | 22 +++-- pkg/hostman/guestman/qemu/generate.go | 6 +- pkg/hostman/guestman/qemu/qemu.go | 30 ++++++ pkg/hostman/guestman/qemu/v10_0_3.go | 27 ++++++ pkg/hostman/guestman/qemu/v10_0_7.go | 71 ++++++++++++++ pkg/hostman/guestman/qemu/v2_12_1.go | 20 +++- .../hostdeployer/deployserver/options.go | 2 +- pkg/hostman/hostinfo/hostinfo.go | 6 +- pkg/hostman/hostutils/hostutils.go | 1 + pkg/hostman/options/options.go | 2 +- pkg/mcclient/options/base.go | 2 +- .../predicates/guest/cpu_predicate.go | 7 +- pkg/scheduler/cache/candidate/base.go | 4 + pkg/scheduler/core/types.go | 1 + pkg/scheduler/test/mock/core.go | 4 + pkg/util/qemutils/qemutils.go | 2 +- 35 files changed, 459 insertions(+), 66 deletions(-) create mode 100644 pkg/hostman/guestman/arch/riscv.go create mode 100644 pkg/hostman/guestman/qemu/v10_0_3.go create mode 100644 pkg/hostman/guestman/qemu/v10_0_7.go diff --git a/build/docker/Dockerfile.host-deployer b/build/docker/Dockerfile.host-deployer index ffe236a05f..c16d0522f4 100644 --- a/build/docker/Dockerfile.host-deployer +++ b/build/docker/Dockerfile.host-deployer @@ -1,4 +1,4 @@ -FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.5.3 +FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.5.5 LABEL maintainer="Yaoqi Wan wanyaoqi@yunionyun.com" diff --git a/cmd/climc/shell/image/images.go b/cmd/climc/shell/image/images.go index d0299b9442..4c227eddbc 100644 --- a/cmd/climc/shell/image/images.go +++ b/cmd/climc/shell/image/images.go @@ -54,7 +54,7 @@ type ImageOptionalOptions struct { OsDist string `help:"Distribution name of OS" metavar:"OS_DISTRIBUTION"` OsVersion string `help:"Version of OS"` OsCodename string `help:"Codename of OS"` - OsArch string `help:"Os hardware architecture" choices:"x86|x86_64|aarch32|aarch64"` + OsArch string `help:"Os hardware architecture" choices:"x86|x86_64|aarch32|aarch64|riscv32|riscv64"` OsLang string `help:"OS Language" choices:"zh_CN|en_US"` Preference int64 `help:"Disk preferences"` Notes string `help:"Notes about the image"` diff --git a/pkg/apis/compute/guest_const.go b/pkg/apis/compute/guest_const.go index 262a74d01d..f2bd9f5273 100644 --- a/pkg/apis/compute/guest_const.go +++ b/pkg/apis/compute/guest_const.go @@ -259,7 +259,7 @@ const ( VM_MACHINE_TYPE_PC = "pc" VM_MACHINE_TYPE_Q35 = "q35" - VM_MACHINE_TYPE_ARM_VIRT = "virt" + VM_MACHINE_TYPE_VIRT = "virt" VM_VDI_PROTOCOL_VNC = "vnc" VM_VDI_PROTOCOL_SPICE = "spice" diff --git a/pkg/apis/const.go b/pkg/apis/const.go index eadee6a780..18fdef3f5b 100644 --- a/pkg/apis/const.go +++ b/pkg/apis/const.go @@ -151,14 +151,16 @@ const ( const ( OS_ARCH_ALL = "all" - OS_ARCH_X86 = "x86" - OS_ARCH_ARM = "arm" + OS_ARCH_X86 = "x86" + OS_ARCH_ARM = "arm" + OS_ARCH_RISCV = "riscv" OS_ARCH_I386 = "i386" OS_ARCH_X86_32 = "x86_32" OS_ARCH_X86_64 = "x86_64" OS_ARCH_AARCH32 = "aarch32" OS_ARCH_AARCH64 = "aarch64" + OS_ARCH_RISCV32 = "riscv32" OS_ARCH_RISCV64 = "riscv64" ) @@ -174,6 +176,11 @@ var ( OS_ARCH_AARCH32, OS_ARCH_AARCH64, } + ARCH_RISCV = []string{ + OS_ARCH_RISCV, + OS_ARCH_RISCV32, + OS_ARCH_RISCV64, + } ) func IsARM(osArch string) bool { @@ -184,6 +191,10 @@ func IsX86(osArch string) bool { return utils.IsInStringArray(osArch, ARCH_X86) } +func IsRISCV(osArch string) bool { + return utils.IsInStringArray(osArch, ARCH_RISCV) +} + func IsIllegalSearchDomain(domain string) bool { switch domain { case "cloud.onecloud.io": @@ -202,5 +213,8 @@ func IsSameArch(arch1, arch2 string) bool { if IsX86(arch1) && IsX86(arch2) { return true } + if IsRISCV(arch1) && IsRISCV(arch2) { + return true + } return false } diff --git a/pkg/cloudcommon/db/archs.go b/pkg/cloudcommon/db/archs.go index 12b187ebbb..965679f271 100644 --- a/pkg/cloudcommon/db/archs.go +++ b/pkg/cloudcommon/db/archs.go @@ -62,6 +62,12 @@ func ListQueryByArchitecture(q *sqlchemy.SQuery, fieldKey string, archs []string sqlchemy.Equals(q.Field(fieldKey), apis.OS_ARCH_AARCH32), sqlchemy.Equals(q.Field(fieldKey), apis.OS_ARCH_AARCH64), )) + } else if arch == apis.OS_ARCH_RISCV { + conditions = append(conditions, sqlchemy.OR( + sqlchemy.Startswith(q.Field(fieldKey), arch), + sqlchemy.Equals(q.Field(fieldKey), apis.OS_ARCH_RISCV32), + sqlchemy.Equals(q.Field(fieldKey), apis.OS_ARCH_RISCV64), + )) } else { conditions = append(conditions, sqlchemy.Startswith(q.Field(fieldKey), arch)) } diff --git a/pkg/compute/guestdrivers/kvm.go b/pkg/compute/guestdrivers/kvm.go index 0fc891f9a4..2206f7daf5 100644 --- a/pkg/compute/guestdrivers/kvm.go +++ b/pkg/compute/guestdrivers/kvm.go @@ -1005,8 +1005,8 @@ func (self *SKVMGuestDriver) validateVGA(ovdi, ovga string, nvdi, nvga *string) func (self *SKVMGuestDriver) validateMachineType(machine string, osArch string) error { var candidate []string - if apis.IsARM(osArch) { - candidate = []string{api.VM_MACHINE_TYPE_ARM_VIRT} + if apis.IsARM(osArch) || apis.IsRISCV(osArch) { + candidate = []string{api.VM_MACHINE_TYPE_VIRT} } else { candidate = []string{api.VM_MACHINE_TYPE_PC, api.VM_MACHINE_TYPE_Q35} } @@ -1311,8 +1311,8 @@ func (kvm *SKVMGuestDriver) ValidateGuestHotChangeConfigInput(ctx context.Contex if guest.GetMetadata(ctx, api.VM_METADATA_HOTPLUG_CPU_MEM, nil) != "enable" { return confs, errors.Wrap(errors.ErrInvalidStatus, "host plug cpu memory is disabled") } - if apis.IsARM(guest.OsArch) { - return confs, errors.Wrap(errors.ErrInvalidStatus, "cpu architecture is arm") + if apis.IsARM(guest.OsArch) || apis.IsRISCV(guest.OsArch) { + return confs, errors.Wrapf(errors.ErrInvalidStatus, "cpu architecture is %s", guest.OsArch) } return confs, nil } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 758279db2a..364f44faf1 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -1627,6 +1627,8 @@ func (self *SDisk) GetMasterHost(storage *SStorage) (*SHost, error) { q = q.In("cpu_architecture", apis.ARCH_X86) case apis.OS_ARCH_ARM: q = q.In("cpu_architecture", apis.ARCH_ARM) + case apis.OS_ARCH_RISCV: + q = q.In("cpu_architecture", apis.ARCH_RISCV) } } host := SHost{} diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index c0492703be..55206c018b 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -207,7 +207,7 @@ func (self *SGuest) PerformSaveImage(ctx context.Context, userCred mcclient.Toke input.OsType = "Linux" } input.OsArch = self.OsArch - if apis.IsARM(self.OsArch) { + if apis.IsARM(self.OsArch) || apis.IsRISCV(self.OsArch) { if osArch := self.GetMetadata(ctx, "os_arch", nil); len(osArch) == 0 { host, _ := self.GetHost() input.OsArch = host.CpuArchitecture @@ -293,7 +293,7 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient } kwargs.Properties["os_type"] = osType - if apis.IsARM(self.OsArch) { + if apis.IsARM(self.OsArch) || apis.IsRISCV(self.OsArch) { var osArch string if osArch = self.GetMetadata(ctx, "os_arch", nil); len(osArch) == 0 { host, _ := self.GetHost() diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 31c153e516..0a397568f5 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -1805,8 +1805,11 @@ func (manager *SGuestManager) validateCreateData( } } - if arch := imgProperties["os_arch"]; strings.Contains(arch, "aarch") || strings.Contains(arch, "arm") { + arch := imgProperties["os_arch"] + if strings.Contains(arch, "aarch") || strings.Contains(arch, "arm") { input.OsArch = apis.OS_ARCH_AARCH64 + } else if strings.Contains(arch, "riscv") { + input.OsArch = apis.OS_ARCH_RISCV64 } // enable tpm on windows 11 image @@ -1837,7 +1840,7 @@ func (manager *SGuestManager) validateCreateData( imgSupportBIOS = &supportBIOS } - if input.OsArch == apis.OS_ARCH_AARCH64 { + if apis.IsARM(input.OsArch) || apis.IsRISCV(input.OsArch) { // arm image supports UEFI by default support := true imgSupportUEFI = &support diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 202cfe2521..b05470b97e 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -985,6 +985,10 @@ func (hh *SHost) IsArmHost() bool { return hh.CpuArchitecture == apis.OS_ARCH_AARCH64 } +func (hh *SHost) IsRISCVHost() bool { + return hh.CpuArchitecture == apis.OS_ARCH_RISCV64 +} + func (hh *SHost) GetZone() (*SZone, error) { zone, err := ZoneManager.FetchById(hh.ZoneId) if err != nil { diff --git a/pkg/compute/models/server_skus.go b/pkg/compute/models/server_skus.go index 9dc9d3bcf6..9e4f7c7ad2 100644 --- a/pkg/compute/models/server_skus.go +++ b/pkg/compute/models/server_skus.go @@ -781,6 +781,13 @@ func (manager *SServerSkuManager) ListItemFilter( sqlchemy.Equals(q.Field("cpu_arch"), apis.OS_ARCH_AARCH64), sqlchemy.IsNullOrEmpty(q.Field("cpu_arch")), )) + } else if arch == apis.OS_ARCH_RISCV { + conditions = append(conditions, sqlchemy.OR( + sqlchemy.Startswith(q.Field("cpu_arch"), arch), + sqlchemy.Equals(q.Field("cpu_arch"), apis.OS_ARCH_RISCV32), + sqlchemy.Equals(q.Field("cpu_arch"), apis.OS_ARCH_RISCV64), + sqlchemy.IsNullOrEmpty(q.Field("cpu_arch")), + )) } else { conditions = append(conditions, sqlchemy.Startswith(q.Field("cpu_arch"), arch)) } diff --git a/pkg/hostman/diskutils/qemu_kvm/driver.go b/pkg/hostman/diskutils/qemu_kvm/driver.go index da872b8151..e199125517 100644 --- a/pkg/hostman/diskutils/qemu_kvm/driver.go +++ b/pkg/hostman/diskutils/qemu_kvm/driver.go @@ -47,10 +47,14 @@ var ( QEMU_KVM_PATH = "/usr/libexec/qemu-kvm" OS_ARCH_AARCH64 = "aarch64" - ARM_INITRD_PATH = "/yunionos/aarch64/initramfs" - ARM_KERNEL_PATH = "/yunionos/aarch64/kernel" - X86_INITRD_PATH = "/yunionos/x86_64/initramfs" - X86_KERNEL_PATH = "/yunionos/x86_64/kernel" + OS_ARCH_RISCV64 = "riscv64" + + ARM_INITRD_PATH = "/yunionos/aarch64/initramfs" + ARM_KERNEL_PATH = "/yunionos/aarch64/kernel" + X86_INITRD_PATH = "/yunionos/x86_64/initramfs" + X86_KERNEL_PATH = "/yunionos/x86_64/kernel" + RISCV_INITRD_PATH = "/yunionos/riscv64/initramfs" + RISCV_KERNEL_PATH = "/yunionos/riscv64/kernel" RUN_ON_HOST_ROOT_PATH = "/opt/cloud/host-deployer" @@ -102,6 +106,14 @@ func (m *QemuDeployManager) GetARMInitrdPath() string { } } +func (m *QemuDeployManager) GetRISCVInitrdPath() string { + if m.runOnHost() { + return path.Join(RUN_ON_HOST_ROOT_PATH, RISCV_INITRD_PATH) + } else { + return RISCV_INITRD_PATH + } +} + func (m *QemuDeployManager) GetX86KernelPath() string { if m.runOnHost() { return path.Join(RUN_ON_HOST_ROOT_PATH, X86_KERNEL_PATH) @@ -118,6 +130,14 @@ func (m *QemuDeployManager) GetARMKernelPath() string { } } +func (m *QemuDeployManager) GetRISCVKernelPath() string { + if m.runOnHost() { + return path.Join(RUN_ON_HOST_ROOT_PATH, RISCV_KERNEL_PATH) + } else { + return RISCV_KERNEL_PATH + } +} + func (m *QemuDeployManager) Acquire() { log.Infof("acquire QemuDeployManager") m.c <- struct{}{} @@ -202,6 +222,8 @@ func InitQemuDeployManager( if cpuArch == OS_ARCH_AARCH64 { qemutils.UseAarch64() + } else if cpuArch == OS_ARCH_RISCV64 { + qemutils.UseRiscv64() } var qemuCmd string @@ -598,6 +620,7 @@ func (d *QemuBaseDriver) CleanGuest() { if d.pidPath != "" && fileutils2.Exists(d.pidPath) { pid, _ := fileutils2.FileGetContents(d.pidPath) + pid = strings.TrimSpace(pid) if len(pid) > 0 { out, err := procutils.NewCommand("kill", pid).Output() log.Infof("kill process %s %v", out, err) @@ -674,7 +697,9 @@ func (d *QemuBaseDriver) startCmds( } cmd += diskDrive - cmd += __("-device scsi-hd,drive=drive_%d,bus=scsi.0,id=drive_%d,serial=%s", i, i, strings.ReplaceAll(diskIds[i], "-", "")) + serialId := strings.ReplaceAll(diskIds[i], "-", "") + deviceId := serialId[:20] + cmd += __("-device scsi-hd,drive=drive_%d,bus=scsi.0,id=drive_%d,serial=%s,device_id=%s", i, i, serialId, deviceId) } cmd += __("-drive id=cd0,if=none,media=cdrom,file=%s", DEPLOY_ISO) cmd += cdromDeviceOpts @@ -801,6 +826,63 @@ func (d *QemuARMDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, return nil } +type QemuRISCVDriver struct { + QemuBaseDriver +} + +func (d *QemuRISCVDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string) error { + uuid := stringutils.UUID4() + socketPath := fmt.Sprintf("/opt/cloud/host-deployer/hmp_%s.socket", uuid) + d.pidPath = fmt.Sprintf("/opt/cloud/host-deployer/%s.pid", uuid) + + machineOpts := __("-M virt") + cdromDeviceOpts := __("-device scsi-cd,drive=cd0,share-rw=true") + fwOpts := "" + cmd := d.startCmds( + sshPort, + ncpu, + memSizeMB, + imageInfo, + disksPath, + diskIds, + machineOpts, + cdromDeviceOpts, + fwOpts, + socketPath, + manager.GetRISCVInitrdPath(), + manager.GetRISCVKernelPath(), + ) + + log.Infof("start guest %s", cmd) + out, err := manager.startQemu(cmd) + if err != nil { + log.Errorf("failed start guest %s: %s", out, err) + return errors.Wrapf(err, "failed start guest %s", out) + } + + var c = make(chan error) + onMonitorConnected := func() { + log.Infof("monitor connected") + c <- nil + } + onMonitorDisConnect := func(e error) { + log.Errorf("monitor disconnect %s", e) + } + onMonitorConnectFailed := func(e error) { + log.Errorf("monitor connect failed %s", e) + c <- e + } + m := monitor.NewHmpMonitor("", "", onMonitorDisConnect, onMonitorConnectFailed, onMonitorConnected) + if err = m.ConnectWithSocket(socketPath); err != nil { + return errors.Wrapf(err, "connect socket %s failed", socketPath) + } + if err = <-c; err != nil { + return errors.Wrap(err, "monitor connect failed") + } + d.hmp = m + return nil +} + type IQemuArchDriver interface { StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string) error CleanGuest() @@ -809,6 +891,8 @@ type IQemuArchDriver interface { func NewCpuArchDriver(cpuArch string) IQemuArchDriver { if cpuArch == OS_ARCH_AARCH64 { return &QemuARMDriver{} + } else if cpuArch == OS_ARCH_RISCV64 { + return &QemuRISCVDriver{} } return &QemuX86Driver{} diff --git a/pkg/hostman/guestfs/fsdriver/linux.go b/pkg/hostman/guestfs/fsdriver/linux.go index 081f2d5250..489d44dd92 100644 --- a/pkg/hostman/guestfs/fsdriver/linux.go +++ b/pkg/hostman/guestfs/fsdriver/linux.go @@ -578,6 +578,11 @@ func (l *sLinuxRootFs) GetArch(rootFs IDiskPartition) string { return apis.OS_ARCH_AARCH64 case elf.EM_ARM: return apis.OS_ARCH_AARCH32 + case elf.EM_RISCV: + if elfHeader.Class == elf.ELFCLASS32 { + return apis.OS_ARCH_RISCV32 + } + return apis.OS_ARCH_RISCV64 } } } diff --git a/pkg/hostman/guestman/arch/arch.go b/pkg/hostman/guestman/arch/arch.go index 8916f0bb35..2bb7aabda8 100644 --- a/pkg/hostman/guestman/arch/arch.go +++ b/pkg/hostman/guestman/arch/arch.go @@ -14,11 +14,16 @@ package arch -import "yunion.io/x/onecloud/pkg/hostman/guestman/desc" +import ( + "fmt" + + "yunion.io/x/onecloud/pkg/hostman/guestman/desc" +) const ( Arch_x86_64 string = "x86_64" Arch_aarch64 string = "aarch64" + Arch_riscv64 string = "riscv64" ) type Arch interface { @@ -50,6 +55,8 @@ func NewArch(arch string) Arch { return &X86{} case Arch_aarch64: return &ARM{} + case Arch_riscv64: + return &RISCV{} } return nil } @@ -87,3 +94,24 @@ func (*archBase) GeneratePvpanicDesc() *desc.SGuestPvpanic { func (*archBase) GenerateIsaSerialDesc() *desc.SGuestIsaSerial { return nil } + +type otherArchBase struct { +} + +// -device scsi-cd,drive=cd0,share-rw=true +// if=none,file=%s,id=cd0,media=cdrom +func (*otherArchBase) GenerateCdromDesc(osName string, cdrom *desc.SGuestCdrom) { + id := fmt.Sprintf("scsi%d-cd0", cdrom.Ordinal) + scsiDev := desc.NewScsiDevice("", "scsi-cd", id) + scsiDev.Options = map[string]string{"share-rw": "true"} + driveOptions := map[string]string{ + "if": "none", + "media": "cdrom", + } + cdrom.Scsi = scsiDev + cdrom.DriveOptions = driveOptions + cdrom.Id = id +} + +func (*otherArchBase) GenerateFloppyDesc(osName string, floppy *desc.SGuestFloppy) { +} diff --git a/pkg/hostman/guestman/arch/arm.go b/pkg/hostman/guestman/arch/arm.go index de984f1279..4b37012f04 100644 --- a/pkg/hostman/guestman/arch/arm.go +++ b/pkg/hostman/guestman/arch/arm.go @@ -15,8 +15,6 @@ package arch import ( - "fmt" - "yunion.io/x/onecloud/pkg/hostman/guestman/desc" "yunion.io/x/onecloud/pkg/hostman/options" ) @@ -34,25 +32,7 @@ var ARM_MAX_MEM_MB uint = 262144 type ARM struct { archBase -} - -// -device scsi-cd,drive=cd0,share-rw=true -// if=none,file=%s,id=cd0,media=cdrom -func (*ARM) GenerateCdromDesc(osName string, cdrom *desc.SGuestCdrom) { - id := fmt.Sprintf("scsi%d-cd0", cdrom.Ordinal) - scsiDev := desc.NewScsiDevice("", "scsi-cd", id) - scsiDev.Options = map[string]string{"share-rw": "true"} - driveOptions := map[string]string{ - "if": "none", - "media": "cdrom", - } - cdrom.Scsi = scsiDev - cdrom.DriveOptions = driveOptions - cdrom.Id = id -} - -func (*ARM) GenerateFloppyDesc(osName string, floppy *desc.SGuestFloppy) { - + otherArchBase } func (*ARM) GenerateMachineDesc(accel string) *desc.SGuestMachine { diff --git a/pkg/hostman/guestman/arch/riscv.go b/pkg/hostman/guestman/arch/riscv.go new file mode 100644 index 0000000000..8620b672ed --- /dev/null +++ b/pkg/hostman/guestman/arch/riscv.go @@ -0,0 +1,75 @@ +// 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 arch + +import ( + "yunion.io/x/onecloud/pkg/hostman/guestman/desc" + "yunion.io/x/onecloud/pkg/hostman/options" +) + +const ( + RISCV_MAX_CPUS = 128 + RISCV_SOCKETS = 1 + RISCV_THREADS = 1 + + RISCV_MEM_DEFAULT_SLOTS = 4 +) + +var RISCV_MAX_MEM_MB uint = 262144 + +type RISCV struct { + archBase + otherArchBase +} + +func (*RISCV) GenerateMachineDesc(accel string) *desc.SGuestMachine { + return &desc.SGuestMachine{ + Accel: accel, + } +} + +func (*RISCV) GenerateMemDesc() *desc.SGuestMem { + return &desc.SGuestMem{ + Slots: RISCV_MEM_DEFAULT_SLOTS, + MaxMem: RISCV_MAX_MEM_MB, + } +} + +func (*RISCV) GenerateCpuDesc(cpus uint, cpuMax uint, s KVMGuestInstance) (*desc.SGuestCpu, error) { + var hostCPUPassthrough = options.HostOptions.HostCpuPassthrough + var accel, cpuType string + if s.IsKvmSupport() { + accel = "kvm" + if hostCPUPassthrough { + cpuType = "host" + } else { + // * under KVM, -cpu max is the same as -cpu host + // * under TCG, -cpu max means "emulate with as many features as possible" + cpuType = "max" + } + } else { + accel = "tcg" + cpuType = "max" + } + return &desc.SGuestCpu{ + Cpus: cpus, + Sockets: RISCV_SOCKETS, + Cores: cpuMax / RISCV_SOCKETS / RISCV_THREADS, + Threads: RISCV_THREADS, + MaxCpus: cpuMax, + Model: cpuType, + Accel: accel, + }, nil +} diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index 88fc9308d6..9be4d800ec 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -210,10 +210,19 @@ func (m *SGuestManager) startContainerSyncLoop() { } } +func (m *SGuestManager) getMachineVirtMaxCpus() uint { + if m.host.IsAarch64() { + return arch.ARM_MAX_CPUS + } else if m.host.IsRiscv64() { + return arch.RISCV_MAX_CPUS + } + return 0 +} + func (m *SGuestManager) InitQemuMaxCpus(machineCaps []monitor.MachineInfo, kvmMaxCpus uint) { m.qemuMachineCpuMax[compute.VM_MACHINE_TYPE_PC] = arch.X86_MAX_CPUS m.qemuMachineCpuMax[compute.VM_MACHINE_TYPE_Q35] = arch.X86_MAX_CPUS - m.qemuMachineCpuMax[compute.VM_MACHINE_TYPE_ARM_VIRT] = arch.ARM_MAX_CPUS + m.qemuMachineCpuMax[compute.VM_MACHINE_TYPE_VIRT] = m.getMachineVirtMaxCpus() if len(machineCaps) == 0 { return } @@ -259,6 +268,11 @@ func (m *SGuestManager) InitQemuMaxMems(maxMems uint) { arch.ARM_MAX_MEM_MB = maxMems } } + if m.host.IsRiscv64() { + if maxMems > arch.RISCV_MAX_MEM_MB { + arch.RISCV_MAX_MEM_MB = maxMems + } + } } func (m *SGuestManager) InitPythonPath() error { diff --git a/pkg/hostman/guestman/pci.go b/pkg/hostman/guestman/pci.go index 66ac7e0ea0..111ee905f1 100644 --- a/pkg/hostman/guestman/pci.go +++ b/pkg/hostman/guestman/pci.go @@ -456,11 +456,11 @@ func (s *SKVMGuestInstance) initGuestDisks(pciRoot, pciBridge *desc.PCIControlle func (s *SKVMGuestInstance) fixDiskDriver() (bool, bool, bool) { var virtioScsi, pvScsi, sataDisk = false, false, false - isArm := s.manager.host.IsAarch64() + isX86 := s.manager.host.IsX8664() osname := s.GetOsName() for i := 0; i < len(s.Desc.Disks); i++ { - if isArm && (s.Desc.Disks[i].Driver == DISK_DRIVER_IDE || + if !isX86 && (s.Desc.Disks[i].Driver == DISK_DRIVER_IDE || s.Desc.Disks[i].Driver == DISK_DRIVER_SATA) { s.Desc.Disks[i].Driver = DISK_DRIVER_SCSI } else if osname == OS_NAME_MACOS { @@ -485,10 +485,10 @@ func (s *SKVMGuestInstance) initVirtioSerial(pciRoot *desc.PCIController) { } func (s *SKVMGuestInstance) initGuestVga(pciRoot *desc.PCIController) { - var isAarch64 = s.manager.host.IsAarch64() + var isNotX86 = !s.manager.host.IsX8664() if s.gpusHasVga() { s.Desc.Vga = "none" - } else if isAarch64 { + } else if isNotX86 { s.Desc.Vga = "virtio-gpu" } else if s.Desc.Vga == "" { s.Desc.Vga = "std" diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 3343e80be6..0937418a26 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -121,6 +121,8 @@ func NewKVMGuestInstance(id string, manager *SGuestManager) *SKVMGuestInstance { qemuArch := arch.Arch_x86_64 if manager.host.IsAarch64() { qemuArch = arch.Arch_aarch64 + } else if manager.host.IsRiscv64() { + qemuArch = arch.Arch_riscv64 } return &SKVMGuestInstance{ SKVMInstanceRuntime: SKVMInstanceRuntime{ @@ -626,6 +628,8 @@ func (s *SKVMGuestInstance) isSelfCmdline(cmdline, uuid string) bool { func (s *SKVMGuestInstance) GetRescueDirPath() string { if s.manager.host.IsAarch64() { return path.Join("/opt/cloud/host-deployer/yunionos/aarch64") + } else if s.manager.host.IsRiscv64() { + return path.Join("/opt/cloud/host-deployer/yunionos/riscv64") } else { return path.Join("/opt/cloud/host-deployer/yunionos/x86_64") } @@ -1366,7 +1370,7 @@ func (s *SKVMGuestInstance) syncStatusUnsync(reason string) { func (s *SKVMGuestInstance) collectGuestDescription() error { var cpuList []monitor.HotpluggableCPU var err error - if !s.manager.host.IsAarch64() { + if s.manager.host.IsX8664() { cpuList, err = s.getHotpluggableCPUList() if err != nil { return errors.Wrap(err, "get hotpluggable cpus") diff --git a/pkg/hostman/guestman/qemu-kvmhelper.go b/pkg/hostman/guestman/qemu-kvmhelper.go index 4bd4f86a8d..30c60c7f56 100644 --- a/pkg/hostman/guestman/qemu-kvmhelper.go +++ b/pkg/hostman/guestman/qemu-kvmhelper.go @@ -262,12 +262,12 @@ func (s *SKVMGuestInstance) isQ35() bool { } func (s *SKVMGuestInstance) isVirt() bool { - return s.getMachine() == api.VM_MACHINE_TYPE_ARM_VIRT + return s.getMachine() == api.VM_MACHINE_TYPE_VIRT } func (s *SKVMGuestInstance) isPcie() bool { return utils.IsInStringArray(s.getMachine(), - []string{api.VM_MACHINE_TYPE_Q35, api.VM_MACHINE_TYPE_ARM_VIRT}) + []string{api.VM_MACHINE_TYPE_Q35, api.VM_MACHINE_TYPE_VIRT}) } func (s *SKVMGuestInstance) GetVdiProtocol() string { @@ -393,6 +393,8 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin // inject qemu arch if s.manager.host.IsAarch64() { input.QemuArch = qemu.Arch_aarch64 + } else if s.manager.host.IsRiscv64() { + input.QemuArch = qemu.Arch_riscv64 } else { input.QemuArch = qemu.Arch_x86_64 } @@ -541,7 +543,7 @@ function start_swtpm() { } // inject usb devices - if input.QemuArch == qemu.Arch_aarch64 { + if !input.QemuArch.IsX86() { input.Devices = append(input.Devices, fmt.Sprintf("usb-tablet,id=input0,bus=%s.0,port=1", s.Desc.Usb.Id), fmt.Sprintf("usb-kbd,id=input1,bus=%s.0,port=2", s.Desc.Usb.Id), @@ -1112,12 +1114,14 @@ func (s *SKVMGuestInstance) fixGuestMachineType() { s.Desc.Machine = api.VM_MACHINE_TYPE_Q35 s.Desc.Bios = qemu.BIOS_UEFI } - if s.manager.host.IsAarch64() { + if !s.manager.host.IsX8664() { if utils.IsInStringArray(s.Desc.Machine, []string{ "", api.VM_MACHINE_TYPE_PC, api.VM_MACHINE_TYPE_Q35, }) { - s.Desc.Machine = api.VM_MACHINE_TYPE_ARM_VIRT + s.Desc.Machine = api.VM_MACHINE_TYPE_VIRT } + } + if s.manager.host.IsAarch64() || s.manager.host.IsRiscv64() { s.Desc.Bios = qemu.BIOS_UEFI } } @@ -1164,7 +1168,7 @@ func (s *SKVMGuestInstance) initTpmDesc() { } func (s *SKVMGuestInstance) getVfioDeviceHotPlugPciControllerType() *desc.PCI_CONTROLLER_TYPE { - if s.Desc.Machine == api.VM_MACHINE_TYPE_Q35 || s.Desc.Machine == api.VM_MACHINE_TYPE_ARM_VIRT { + if s.Desc.Machine == api.VM_MACHINE_TYPE_Q35 || s.Desc.Machine == api.VM_MACHINE_TYPE_VIRT { _, _, found := s.findUnusedSlotForController(desc.CONTROLLER_TYPE_PCIE_ROOT_PORT, 0) if found { var contType desc.PCI_CONTROLLER_TYPE = desc.CONTROLLER_TYPE_PCIE_ROOT_PORT @@ -1208,12 +1212,12 @@ func (s *SKVMGuestInstance) getDiskBootOrderType(driver string) uefi.OvmfDeviceP case qemu.DISK_DRIVER_SCSI, qemu.DISK_DRIVER_PVSCSI: return uefi.DEVICE_TYPE_SCSI case qemu.DISK_DRIVER_IDE: - if s.manager.host.IsAarch64() { + if !s.manager.host.IsX8664() { return uefi.DEVICE_TYPE_SCSI } return uefi.DEVICE_TYPE_IDE case qemu.DISK_DRIVER_SATA: - if s.manager.host.IsAarch64() { + if !s.manager.host.IsX8664() { return uefi.DEVICE_TYPE_SCSI } return uefi.DEVICE_TYPE_SATA @@ -1222,7 +1226,7 @@ func (s *SKVMGuestInstance) getDiskBootOrderType(driver string) uefi.OvmfDeviceP } func (s *SKVMGuestInstance) getCdromBootOrder() uefi.OvmfDevicePathType { - if s.manager.host.IsAarch64() { + if !s.manager.host.IsX8664() { return uefi.DEVICE_TYPE_SCSI_CDROM } return uefi.DEVICE_TYPE_CDROM diff --git a/pkg/hostman/guestman/qemu/generate.go b/pkg/hostman/guestman/qemu/generate.go index bcdc4378dc..dba51a2312 100644 --- a/pkg/hostman/guestman/qemu/generate.go +++ b/pkg/hostman/guestman/qemu/generate.go @@ -350,7 +350,9 @@ func getDiskDeviceOption(optDrv QemuOptions, disk *desc.SGuestDisk, osName strin var opt = "" opt += GetDiskDeviceModel(diskDriver) if osName != OS_NAME_VMWARE { - opt += fmt.Sprintf(",serial=%s", strings.ReplaceAll(disk.DiskId, "-", "")) + serial := strings.ReplaceAll(disk.DiskId, "-", "") + opt += fmt.Sprintf(",serial=%s", serial) + opt += optDrv.ScsiDeviceId(serial) } opt += fmt.Sprintf(",drive=drive_%d", diskIndex) if diskDriver == DISK_DRIVER_VIRTIO { @@ -846,7 +848,7 @@ func GenerateStartOptions( opts = append(opts, nicOpts...) if !input.GuestDesc.LightMode { - if input.QemuArch == Arch_aarch64 { + if !input.QemuArch.IsX86() { if input.GuestDesc.Usb != nil { opts = append(opts, generatePCIDeviceOption(input.GuestDesc.Usb.PCIDevice)) for _, device := range input.Devices { diff --git a/pkg/hostman/guestman/qemu/qemu.go b/pkg/hostman/guestman/qemu/qemu.go index cd4db794d9..1cec8f083c 100644 --- a/pkg/hostman/guestman/qemu/qemu.go +++ b/pkg/hostman/guestman/qemu/qemu.go @@ -35,6 +35,8 @@ const ( Version_4_0_1 Version = "4.0.1" Version_2_12_1 Version = "2.12.1" Version_9_0_1 Version = "9.0.1" + Version_10_0_3 Version = "10.0.3" + Version_10_0_7 Version = "10.0.7" ) type Arch string @@ -42,8 +44,13 @@ type Arch string const ( Arch_x86_64 Arch = "x86_64" Arch_aarch64 Arch = "aarch64" + Arch_riscv64 Arch = "riscv64" ) +func (a Arch) IsX86() bool { + return a == Arch_x86_64 +} + const ( OS_NAME_LINUX = "Linux" OS_NAME_WINDOWS = "Windows" @@ -110,6 +117,7 @@ type QemuOptions interface { VNC(port uint, usePasswd bool) string Initrd(initrdPath string) string Kernel(kernelPath string) string + ScsiDeviceId(serial string) string } var ( @@ -218,6 +226,10 @@ func (o baseOptions) Nodefconfig() string { return "-nodefconfig" } +func (o baseOptions) ScsiDeviceId(serial string) string { + return fmt.Sprintf(",device_id=%s", serial[:20]) +} + /* @subsection -no-kvm-pit-reinjection (since 1.3.0) @@ -407,3 +419,21 @@ func (o baseOptions_aarch64) Global() string { func (o baseOptions_aarch64) NoHpet() (bool, string) { return false, "" } + +type baseOptions_riscv64 struct { + *baseOptions +} + +func newBaseOptions_riscv64() *baseOptions_riscv64 { + return &baseOptions_riscv64{ + baseOptions: newBaseOptions(Arch_riscv64), + } +} + +func (o baseOptions_riscv64) Global() string { + return "" +} + +func (o baseOptions_riscv64) NoHpet() (bool, string) { + return false, "" +} diff --git a/pkg/hostman/guestman/qemu/v10_0_3.go b/pkg/hostman/guestman/qemu/v10_0_3.go new file mode 100644 index 0000000000..1ca5cfe439 --- /dev/null +++ b/pkg/hostman/guestman/qemu/v10_0_3.go @@ -0,0 +1,27 @@ +package qemu + +func init() { + RegisterCmd( + newCmd_10_0_3_riscv64(), + ) +} + +type opt_1003_riscv64 struct { + *baseOptions_riscv64 + *baseOptions_ge_310 +} + +func newCmd_10_0_3_riscv64() QemuCommand { + return newBaseCommand( + Version_10_0_3, + Arch_riscv64, + newOpt_10_0_3_riscv64(), + ) +} + +func newOpt_10_0_3_riscv64() QemuOptions { + return &opt_1003_riscv64{ + baseOptions_riscv64: newBaseOptions_riscv64(), + baseOptions_ge_310: newBaseOptionsGE310(), + } +} diff --git a/pkg/hostman/guestman/qemu/v10_0_7.go b/pkg/hostman/guestman/qemu/v10_0_7.go new file mode 100644 index 0000000000..3c7bd60c8e --- /dev/null +++ b/pkg/hostman/guestman/qemu/v10_0_7.go @@ -0,0 +1,71 @@ +package qemu + +func init() { + RegisterCmd( + newCmd_10_0_7_x86_64(), + newCmd_10_0_7_aarch64(), + newCmd_10_0_7_riscv64(), + ) +} + +type opt_1007_x86_64 struct { + *baseOptions_x86_64 + *baseOptions_ge_310 + *baseOptions_ge_800_x86_64 +} + +func newOpt_10_0_7_x86_64() QemuOptions { + return &opt_1007_x86_64{ + baseOptions_x86_64: newBaseOptions_x86_64(), + baseOptions_ge_800_x86_64: newBaseOptionsGE800_x86_64(), + baseOptions_ge_310: newBaseOptionsGE310(), + } +} + +func newCmd_10_0_7_x86_64() QemuCommand { + return newBaseCommand( + Version_10_0_7, + Arch_x86_64, + newOpt_10_0_7_x86_64(), + ) +} + +type opt_1007_aarch64 struct { + *baseOptions_aarch64 + *baseOptions_ge_310 +} + +func newCmd_10_0_7_aarch64() QemuCommand { + return newBaseCommand( + Version_10_0_7, + Arch_aarch64, + newOpt_10_0_7_aarch64(), + ) +} + +func newOpt_10_0_7_aarch64() QemuOptions { + return &opt_1007_aarch64{ + baseOptions_aarch64: newBaseOptions_aarch64(), + baseOptions_ge_310: newBaseOptionsGE310(), + } +} + +type opt_1007_riscv64 struct { + *baseOptions_riscv64 + *baseOptions_ge_310 +} + +func newCmd_10_0_7_riscv64() QemuCommand { + return newBaseCommand( + Version_10_0_7, + Arch_riscv64, + newOpt_10_0_7_riscv64(), + ) +} + +func newOpt_10_0_7_riscv64() QemuOptions { + return &opt_1007_riscv64{ + baseOptions_riscv64: newBaseOptions_riscv64(), + baseOptions_ge_310: newBaseOptionsGE310(), + } +} diff --git a/pkg/hostman/guestman/qemu/v2_12_1.go b/pkg/hostman/guestman/qemu/v2_12_1.go index 6549443f5c..3db6db23f6 100644 --- a/pkg/hostman/guestman/qemu/v2_12_1.go +++ b/pkg/hostman/guestman/qemu/v2_12_1.go @@ -33,16 +33,34 @@ type opt_2121_x86_64 struct { *baseOptions_x86_64 } +func (o opt_2121_x86_64) ScsiDeviceId(serial string) string { + return "" +} + func newOpt_2_12_1_x86_64() QemuOptions { return &opt_2121_x86_64{ baseOptions_x86_64: newBaseOptions_x86_64(), } } +type opt_2121_aarch64 struct { + *baseOptions_aarch64 +} + +func (o opt_2121_aarch64) ScsiDeviceId(serial string) string { + return "" +} + +func newOpt_2_12_1_aarch64() QemuOptions { + return &opt_2121_aarch64{ + baseOptions_aarch64: newBaseOptions_aarch64(), + } +} + func newCmd_2_12_1_aarch64() QemuCommand { return newBaseCommand( Version_2_12_1, Arch_aarch64, - newBaseOptions_aarch64(), + newOpt_2_12_1_aarch64(), ) } diff --git a/pkg/hostman/hostdeployer/deployserver/options.go b/pkg/hostman/hostdeployer/deployserver/options.go index ac55019df1..0a656e9a47 100644 --- a/pkg/hostman/hostdeployer/deployserver/options.go +++ b/pkg/hostman/hostdeployer/deployserver/options.go @@ -38,7 +38,7 @@ type SDeployOptions struct { HugepagesOption string `help:"Hugepages option: disable|native|transparent" default:"transparent"` HugepageSizeMb int `help:"hugepage size mb default 1G" default:"1024"` // DefaultQemuVersion string `help:"Default qemu version" default:"4.2.0"` - DeployGuestMemSizeMb int `help:"Deploy guest mem size mb" default:"320"` + DeployGuestMemSizeMb int `help:"Deploy guest mem size mb" default:"512"` ListenInterface string `help:"Master address of host server"` Networks []string `help:"Network interface information"` diff --git a/pkg/hostman/hostinfo/hostinfo.go b/pkg/hostman/hostinfo/hostinfo.go index 60cb23cd03..11fd882d95 100644 --- a/pkg/hostman/hostinfo/hostinfo.go +++ b/pkg/hostman/hostinfo/hostinfo.go @@ -2722,7 +2722,7 @@ func (h *SHostInfo) IsAarch64() bool { return h.GetCpuArchitecture() == apis.OS_ARCH_AARCH64 } -func (h *SHostInfo) IsRiscV() bool { +func (h *SHostInfo) IsRiscv64() bool { return h.GetCpuArchitecture() == apis.OS_ARCH_RISCV64 } @@ -2848,8 +2848,8 @@ func NewHostInfo() (*SHostInfo, error) { if res.IsAarch64() { qemutils.UseAarch64() - } else if res.IsRiscV() { - qemutils.UseRiscV() + } else if res.IsRiscv64() { + qemutils.UseRiscv64() } else if !res.IsX8664() { return nil, fmt.Errorf("unsupport cpu architecture %s", cpu.CpuArchitecture) } diff --git a/pkg/hostman/hostutils/hostutils.go b/pkg/hostman/hostutils/hostutils.go index be89d0ee92..8c5354562b 100644 --- a/pkg/hostman/hostutils/hostutils.go +++ b/pkg/hostman/hostutils/hostutils.go @@ -73,6 +73,7 @@ type IHost interface { GetKernelVersion() string IsAarch64() bool IsX8664() bool + IsRiscv64() bool GetHostTopology() *hostapi.HostTopology GetReservedCpusInfo() (*cpuset.CPUSet, *cpuset.CPUSet) GetReservedMemMb() int diff --git a/pkg/hostman/options/options.go b/pkg/hostman/options/options.go index b57760019c..1de16348ca 100644 --- a/pkg/hostman/options/options.go +++ b/pkg/hostman/options/options.go @@ -39,7 +39,7 @@ type SHostBaseOptions struct { LiveMigrateCpuThrottleInitial int64 `default:"60" help:"live migrate auto convert cpu throttle initial"` LiveMigrateCpuThrottleIncrement int64 `default:"20" help:"live migrate auto convert cpu throttle increment"` - DefaultQemuVersion string `help:"Default qemu version" default:"4.2.0"` + DefaultQemuVersion string `help:"Default qemu version" default:"10.0.7"` NoHpet bool `help:"Disable qemu hpet timer" default:"true"` CdromCount int `help:"cdrom count" default:"1"` diff --git a/pkg/mcclient/options/base.go b/pkg/mcclient/options/base.go index 578f581eaa..c05c80297d 100644 --- a/pkg/mcclient/options/base.go +++ b/pkg/mcclient/options/base.go @@ -443,7 +443,7 @@ func (o *ScopedResourceListOptions) Params() (*jsonutils.JSONDict, error) { } type MultiArchListOptions struct { - OsArch string `help:"Filter resource by arch" choices:"i386|x86|x86_32|x86_64|arm|aarch32|aarch64"` + OsArch string `help:"Filter resource by arch" choices:"i386|x86|x86_32|x86_64|arm|aarch32|aarch64|riscv|riscv32|riscv64"` } func (o *MultiArchListOptions) Params() (*jsonutils.JSONDict, error) { diff --git a/pkg/scheduler/algorithm/predicates/guest/cpu_predicate.go b/pkg/scheduler/algorithm/predicates/guest/cpu_predicate.go index 885d1c77b2..54050c6ada 100644 --- a/pkg/scheduler/algorithm/predicates/guest/cpu_predicate.go +++ b/pkg/scheduler/algorithm/predicates/guest/cpu_predicate.go @@ -61,15 +61,20 @@ func (f *CPUPredicate) Execute(ctx context.Context, u *core.Unit, c core.Candida archMatch := true isArmHost := getter.IsArmHost() + isRiscvHost := getter.IsRISCVHost() if d.Hypervisor != compute.HYPERVISOR_POD { if apis.IsARM(d.OsArch) { // process arm64 host if !isArmHost { archMatch = false } + } else if apis.IsRISCV(d.OsArch) { + if !isRiscvHost { + archMatch = false + } } else { // process x86_64 host - if isArmHost { + if isArmHost || isRiscvHost { archMatch = false } } diff --git a/pkg/scheduler/cache/candidate/base.go b/pkg/scheduler/cache/candidate/base.go index f38d1be207..c4e35726d3 100644 --- a/pkg/scheduler/cache/candidate/base.go +++ b/pkg/scheduler/cache/candidate/base.go @@ -93,6 +93,10 @@ func (b baseHostGetter) IsArmHost() bool { return b.h.IsArmHost() } +func (b baseHostGetter) IsRISCVHost() bool { + return b.h.IsRISCVHost() +} + func (b baseHostGetter) CPUArch() string { return b.h.CpuArchitecture } diff --git a/pkg/scheduler/core/types.go b/pkg/scheduler/core/types.go index 834980e9b8..202ed968e3 100644 --- a/pkg/scheduler/core/types.go +++ b/pkg/scheduler/core/types.go @@ -90,6 +90,7 @@ type CandidatePropertyGetter interface { CPUArch() string IsArmHost() bool + IsRISCVHost() bool RunningCPUCount() int64 TotalCPUCount(useRsvd bool) int64 FreeCPUCount(useRsvd bool) int64 diff --git a/pkg/scheduler/test/mock/core.go b/pkg/scheduler/test/mock/core.go index 38f9a27a22..f15599f450 100644 --- a/pkg/scheduler/test/mock/core.go +++ b/pkg/scheduler/test/mock/core.go @@ -314,6 +314,10 @@ func (m *MockCandidatePropertyGetter) IsArmHost() bool { return false } +func (m *MockCandidatePropertyGetter) IsRISCVHost() bool { + return false +} + func (m *MockCandidatePropertyGetter) CPUArch() string { return "" } diff --git a/pkg/util/qemutils/qemutils.go b/pkg/util/qemutils/qemutils.go index 70f022ea6c..7d12e63a0a 100644 --- a/pkg/util/qemutils/qemutils.go +++ b/pkg/util/qemutils/qemutils.go @@ -39,7 +39,7 @@ func UseAarch64() { qemuSystemCmd = "qemu-system-aarch64" } -func UseRiscV() { +func UseRiscv64() { qemuSystemCmd = "qemu-system-riscv64" }