Skip to content

[WIP] feat(region,host): loongarch support #21775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: release/3.11
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/climc/shell/image/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,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|loongarch64"`
OsLang string `help:"OS Language" choices:"zh_CN|en_US"`
Preference int64 `help:"Disk preferences"`
Notes string `help:"Notes about the image"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/compute/guest_const.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,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"
Expand Down
15 changes: 10 additions & 5 deletions pkg/apis/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,12 @@ const (
OS_ARCH_X86 = "x86"
OS_ARCH_ARM = "arm"

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_I386 = "i386"
OS_ARCH_X86_32 = "x86_32"
OS_ARCH_X86_64 = "x86_64"
OS_ARCH_AARCH32 = "aarch32"
OS_ARCH_AARCH64 = "aarch64"
OS_ARCH_LOONGARCH64 = "loongarch64"
)

var (
Expand All @@ -143,6 +144,10 @@ func IsARM(osArch string) bool {
return utils.IsInStringArray(osArch, ARCH_ARM)
}

func IsLoongarch64(osArch string) bool {
return osArch == OS_ARCH_LOONGARCH64
}

func IsIllegalSearchDomain(domain string) bool {
switch domain {
case "cloud.onecloud.io":
Expand Down
6 changes: 6 additions & 0 deletions pkg/cloudcommon/db/archs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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_LOONGARCH64 {
conditions = append(conditions, sqlchemy.OR(
sqlchemy.Startswith(q.Field(fieldKey), arch),
sqlchemy.Equals(q.Field(fieldKey), apis.OS_ARCH_LOONGARCH64),
))
} else {
conditions = append(conditions, sqlchemy.Startswith(q.Field(fieldKey), arch))
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/cloudcommon/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ type BaseOptions struct {

DefaultProcessTimeoutSeconds int `default:"60" help:"request process timeout, default is 60 seconds"`

EnableSsl bool `help:"Enable https"`
SslCaCerts string `help:"ssl certificate ca root file, separating ca and cert file is not encouraged" alias:"ca-file"`
SslCertfile string `help:"ssl certification file, normally combines all the certificates in the chain" alias:"cert-file"`
SslKeyfile string `help:"ssl certification private key file" alias:"key-file"`
EnableEtcdEndpointPuller bool `help:"Enable etcd endpoint puller" default:"true"`
EnableSsl bool `help:"Enable https"`
SslCaCerts string `help:"ssl certificate ca root file, separating ca and cert file is not encouraged" alias:"ca-file"`
SslCertfile string `help:"ssl certification file, normally combines all the certificates in the chain" alias:"cert-file"`
SslKeyfile string `help:"ssl certification private key file" alias:"key-file"`

NotifyAdminUsers []string `default:"sysadmin" help:"System administrator user ID or name to notify system events, if domain is not default, specify domain as prefix ending with double backslash, e.g. domain\\\\user"`
NotifyAdminGroups []string `help:"System administrator group ID or name to notify system events, if domain is not default, specify domain as prefix ending with double backslash, e.g. domain\\\\group"`
Expand Down
6 changes: 3 additions & 3 deletions pkg/compute/guestdrivers/kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -966,8 +966,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.IsLoongarch64(osArch) {
candidate = []string{api.VM_MACHINE_TYPE_VIRT}
} else {
candidate = []string{api.VM_MACHINE_TYPE_PC, api.VM_MACHINE_TYPE_Q35}
}
Expand Down Expand Up @@ -1248,7 +1248,7 @@ 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) {
if apis.IsARM(guest.OsArch) || apis.IsLoongarch64(guest.OsArch) {
return confs, errors.Wrap(errors.ErrInvalidStatus, "cpu architecture is arm")
}
return confs, nil
Expand Down
2 changes: 2 additions & 0 deletions pkg/compute/models/disks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,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_LOONGARCH64:
q = q.Equals("cpu_architecture", apis.OS_ARCH_LOONGARCH64)
}
}
host := SHost{}
Expand Down
4 changes: 2 additions & 2 deletions pkg/compute/models/guest_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,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.IsLoongarch64(self.OsArch) {
if osArch := self.GetMetadata(ctx, "os_arch", nil); len(osArch) == 0 {
host, _ := self.GetHost()
input.OsArch = host.CpuArchitecture
Expand Down Expand Up @@ -260,7 +260,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.IsLoongarch64(self.OsArch) {
var osArch string
if osArch = self.GetMetadata(ctx, "os_arch", nil); len(osArch) == 0 {
host, _ := self.GetHost()
Expand Down
7 changes: 5 additions & 2 deletions pkg/compute/models/guests.go
Original file line number Diff line number Diff line change
Expand Up @@ -1657,16 +1657,19 @@ 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 arch == apis.OS_ARCH_LOONGARCH64 {
input.OsArch = apis.OS_ARCH_LOONGARCH64
}

var imgSupportUEFI *bool
if desc, ok := imgProperties[imageapi.IMAGE_UEFI_SUPPORT]; ok {
support := desc == "true"
imgSupportUEFI = &support
}
if input.OsArch == apis.OS_ARCH_AARCH64 {
if input.OsArch == apis.OS_ARCH_AARCH64 || input.OsArch == apis.OS_ARCH_LOONGARCH64 {
// arm image supports UEFI by default
support := true
imgSupportUEFI = &support
Expand Down
8 changes: 8 additions & 0 deletions pkg/hostman/guestfs/fsdriver/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ func (l *sLinuxRootFs) DeployQgaService(rootFs IDiskPartition) error {
// qemu-ga has been installed
return nil
}
if !fileutils2.Exists(QGA_BINARY_PATH) {
return nil
}
output, err := procutils.NewCommand("cp", "-f",
QGA_BINARY_PATH, path.Join(rootFs.GetMountPath(), qemuGuestAgentPath)).Output()
if err != nil {
Expand Down Expand Up @@ -546,6 +549,8 @@ func (l *sLinuxRootFs) GetArch(rootFs IDiskPartition) string {
return apis.OS_ARCH_AARCH64
case elf.EM_ARM:
return apis.OS_ARCH_AARCH32
case elf.EM_LOONGARCH:
return apis.OS_ARCH_LOONGARCH64
}
}
}
Expand Down Expand Up @@ -768,6 +773,9 @@ func (l *sLinuxRootFs) IsCloudinitInstall() bool {
}

func (d *sLinuxRootFs) DeployTelegraf(config string) (bool, error) {
if !fileutils2.Exists(TELEGRAF_BINARY_PATH) {
return false, nil
}
var (
part = d.GetPartition()
modeRwxOwner = syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IXUSR
Expand Down
6 changes: 6 additions & 0 deletions pkg/hostman/guestfs/fsdriver/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,9 @@ func (l *SWindowsRootFs) IsResizeFsPartitionSupport() bool {
}

func (w *SWindowsRootFs) DeployQgaService(part IDiskPartition) error {
if !fileutils2.Exists(QGA_WIN_MSI_INSTALLER_PATH) {
return nil
}
if err := w.rootFs.Mkdir(WIN_QGA_PATH, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {
return errors.Wrap(err, "mkdir qemu-ga path")
}
Expand All @@ -604,6 +607,9 @@ func (w *SWindowsRootFs) DeployQgaBlackList(part IDiskPartition) error {
}

func (w *SWindowsRootFs) DeployTelegraf(config string) (bool, error) {
if !fileutils2.Exists(WIN_TELEGRAF_BINARY_PATH) {
return false, nil
}
if err := w.rootFs.Mkdir(WIN_TELEGRAF_PATH, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {
return false, errors.Wrap(err, "mkdir telegraf path")
}
Expand Down
7 changes: 5 additions & 2 deletions pkg/hostman/guestman/arch/arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ package arch
import "yunion.io/x/onecloud/pkg/hostman/guestman/desc"

const (
Arch_x86_64 string = "x86_64"
Arch_aarch64 string = "aarch64"
Arch_x86_64 string = "x86_64"
Arch_aarch64 string = "aarch64"
Arch_loongarch64 string = "loongarch64"
)

type Arch interface {
Expand Down Expand Up @@ -50,6 +51,8 @@ func NewArch(arch string) Arch {
return &X86{}
case Arch_aarch64:
return &ARM{}
case Arch_loongarch64:
return &LOONGARCH64{}
}
return nil
}
Expand Down
86 changes: 86 additions & 0 deletions pkg/hostman/guestman/arch/loongarch64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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 (
"fmt"

"yunion.io/x/onecloud/pkg/hostman/guestman/desc"
)

const (
LOONGARCH64_MAX_CPUS = 8
LOONGARCH64_SOCKETS = 1
LOONGARCH64_CORES = 8
LOONGARCH64_THREADS = 1

LOONGARCH64_MEM_DEFAULT_SLOTS = 4
LOONGARCH64_MAX_MEM_MB = 262144
)

type LOONGARCH64 struct {
archBase
}

// -device scsi-cd,drive=cd0,share-rw=true
// if=none,file=%s,id=cd0,media=cdrom
func (*LOONGARCH64) 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 (*LOONGARCH64) GenerateFloppyDesc(osName string, floppy *desc.SGuestFloppy) {

}

func (*LOONGARCH64) GenerateMachineDesc(accel string) *desc.SGuestMachine {
return &desc.SGuestMachine{
Accel: accel,
}
}

func (*LOONGARCH64) GenerateMemDesc() *desc.SGuestMem {
return &desc.SGuestMem{
Slots: LOONGARCH64_MEM_DEFAULT_SLOTS,
MaxMem: LOONGARCH64_MAX_MEM_MB,
}
}

func (*LOONGARCH64) GenerateCpuDesc(cpus uint, cpuMax uint, s KVMGuestInstance) (*desc.SGuestCpu, error) {
var accel, cpuType string
if s.IsKvmSupport() {
accel = "kvm"

// * 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,
Model: cpuType,
Accel: accel,
}, nil
}
2 changes: 1 addition & 1 deletion pkg/hostman/guestman/guestman.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func NewGuestManager(host hostutils.IHost, serversPath string, workerCnt int) (*
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] = arch.ARM_MAX_CPUS
if len(machineCaps) == 0 {
return
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/hostman/guestman/qemu-kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,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.IsLoongarch64() {
qemuArch = arch.Arch_loongarch64
}
return &SKVMGuestInstance{
SKVMInstanceRuntime: SKVMInstanceRuntime{
Expand Down
17 changes: 11 additions & 6 deletions pkg/hostman/guestman/qemu-kvmhelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,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 {
Expand Down Expand Up @@ -378,6 +378,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.IsLoongarch64() {
input.QemuArch = qemu.Arch_loongarch64
} else {
input.QemuArch = qemu.Arch_x86_64
}
Expand Down Expand Up @@ -445,7 +447,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
* cmd += "fi\n"
*/
cmd += "QEMU_CMD=$DEFAULT_QEMU_CMD\n"
if s.IsKvmSupport() && !options.HostOptions.DisableKVM {
if s.IsKvmSupport() && !options.HostOptions.DisableKVM && !s.manager.host.IsLoongarch64() {
cmd += "QEMU_CMD_KVM_ARG=-enable-kvm\n"
} else if utils.IsInStringArray(s.manager.host.GetCpuArchitecture(), apis.ARCH_X86) {
// -no-kvm仅x86适用,且将在qemu 5.2之后移除
Expand Down Expand Up @@ -503,7 +505,7 @@ function nic_mtu() {
}

// inject usb devices
if input.QemuArch == qemu.Arch_aarch64 {
if input.QemuArch == qemu.Arch_aarch64 || input.QemuArch == qemu.Arch_loongarch64 {
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),
Expand Down Expand Up @@ -1047,9 +1049,12 @@ func (s *SKVMGuestInstance) fixGuestMachineType() {
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
}
s.Desc.Bios = qemu.BIOS_UEFI
} else if s.manager.host.IsLoongarch64() {
s.Desc.Machine = api.VM_MACHINE_TYPE_VIRT
s.Desc.Bios = qemu.BIOS_UEFI
}
}

Expand Down Expand Up @@ -1082,7 +1087,7 @@ func (s *SKVMGuestInstance) initIsaSerialDesc() {
}

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
Expand Down
Loading
Loading