This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 5df15a7aa62 KVM/s390x Support:  Add support for KVM on s390x 
architecture (#10038)
5df15a7aa62 is described below

commit 5df15a7aa62a2fe0caa95fa2e05710205b26e3b1
Author: niyamsw <[email protected]>
AuthorDate: Wed Jan 29 22:04:16 2025 +0530

    KVM/s390x Support:  Add support for KVM on s390x architecture (#10038)
    
    Signed-off-by: Niyam Siwach <[email protected]>
    Signed-off-by: Himanshu Mishra <[email protected]>
---
 agent/conf/agent.properties                        |  2 +-
 .../cloud/agent/properties/AgentProperties.java    |  2 +-
 .../kvm/resource/LibvirtComputingResource.java     | 46 ++++++++++++++++------
 .../hypervisor/kvm/resource/LibvirtVMDef.java      |  8 ++--
 .../apache/cloudstack/utils/linux/KVMHostInfo.java |  7 ++++
 .../kvm/resource/LibvirtComputingResourceTest.java |  4 +-
 .../com/cloud/hypervisor/HypervisorGuruBase.java   |  2 +
 7 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index 515614fff16..eb2fbe3aed9 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -209,7 +209,7 @@ hypervisor.type=kvm
 # the management server would send.
 # In case of arm64 (aarch64), this will change the machine type to 'virt' and
 # adds a SCSI and a USB controller in the domain xml.
-# Possible values: x86_64 | aarch64
+# Possible values: x86_64 | aarch64 | s390x
 # If null (default), defaults to the VM's OS architecture
 #guest.cpu.arch=
 
diff --git 
a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java 
b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
index 52679811f7c..f66232b86e5 100644
--- a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
+++ b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
@@ -383,7 +383,7 @@ public class AgentProperties{
     /**
      * This param will set the CPU architecture for the domain to override 
what the management server would send.<br>
      * In case of arm64 (aarch64), this will change the machine type to 'virt' 
and add a SCSI and a USB controller in the domain XML.<br>
-     * Possible values: x86_64 | aarch64 <br>
+     * Possible values: x86_64 | aarch64 | s390x <br>
      * Data type: String.<br>
      * Default value: <code>null</code> (will set use the architecture of the 
VM's OS).
      */
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 47edd2eff18..2f57ad6ffb0 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -18,6 +18,7 @@ package com.cloud.hypervisor.kvm.resource;
 
 import static com.cloud.host.Host.HOST_INSTANCE_CONVERSION;
 import static com.cloud.host.Host.HOST_VOLUME_ENCRYPTION;
+import static org.apache.cloudstack.utils.linux.KVMHostInfo.isHostS390x;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -244,11 +245,16 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
     private static final String LEGACY = "legacy";
     private static final String SECURE = "secure";
 
+    /**
+     * Machine type for s390x architecture
+     */
+    private static final String S390X_VIRTIO_DEVICE = "s390-ccw-virtio";
+
     /**
      * Machine type.
      */
-    private static final String PC = "pc";
-    private static final String VIRT = "virt";
+    private static final String PC = isHostS390x() ? S390X_VIRTIO_DEVICE : 
"pc";
+    private static final String VIRT = isHostS390x() ? S390X_VIRTIO_DEVICE : 
"virt";
 
     /**
      * Possible devices to add to VM.
@@ -305,6 +311,10 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
      * Constant that defines ARM64 (aarch64) guest architectures.
      */
     private static final String AARCH64 = "aarch64";
+    /**
+     * Constant that defines IBM Z Arch (s390x) guest architectures.
+     */
+    private static final String S390X = "s390x";
 
     public static final String RESIZE_NOTIFY_ONLY = "NOTIFYONLY";
     public static final String BASEPATH = "/usr/share/cloudstack-common/vms/";
@@ -1796,7 +1806,8 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
             "^dummy",
             "^lo",
             "^p\\d+p\\d+",
-            "^vni"
+            "^vni",
+            "^enc"
     };
 
     /**
@@ -2642,12 +2653,15 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         }
 
         devices.addDevice(createChannelDef(vmTO));
-        devices.addDevice(createWatchDogDef());
+        if (!isGuestS390x()) {
+            devices.addDevice(createWatchDogDef());
+        }
         devices.addDevice(createVideoDef(vmTO));
         devices.addDevice(createConsoleDef());
         devices.addDevice(createGraphicDef(vmTO));
-        devices.addDevice(createTabletInputDef());
-
+        if (!isGuestS390x()) {
+            devices.addDevice(createTabletInputDef());
+        }
         if (isGuestAarch64()) {
             createArm64UsbDef(devices);
         }
@@ -2765,7 +2779,9 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         FeaturesDef features = new FeaturesDef();
         features.addFeatures(PAE);
         features.addFeatures(APIC);
-        features.addFeatures(ACPI);
+        if (!isHostS390x()) {
+            features.addFeatures(ACPI);
+        }
         if (isUefiEnabled && isSecureBoot) {
             features.addFeatures(SMM);
         }
@@ -2857,6 +2873,10 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         return AARCH64.equals(guestCpuArch);
     }
 
+    private boolean isGuestS390x() {
+        return S390X.equals(guestCpuArch);
+    }
+
     /**
      * Creates a guest definition from a VM specification.
      */
@@ -2867,7 +2887,7 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         guest.setManufacturer(vmTO.getMetadataManufacturer());
         guest.setProduct(vmTO.getMetadataProductName());
         guest.setGuestArch(guestCpuArch != null ? guestCpuArch : 
vmTO.getArch());
-        guest.setMachineType(isGuestAarch64() ? VIRT : PC);
+        guest.setMachineType((isGuestAarch64() || isGuestS390x()) ? VIRT : PC);
         guest.setBootType(GuestDef.BootType.BIOS);
         if (MapUtils.isNotEmpty(customParams)) {
             if (customParams.containsKey(GuestDef.BootType.UEFI.toString())) {
@@ -2881,7 +2901,9 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
             
guest.setIothreads(customParams.containsKey(VmDetailConstants.IOTHREADS));
         }
         guest.setUuid(uuid);
-        guest.setBootOrder(GuestDef.BootOrder.CDROM);
+        if(!isGuestS390x()) {
+            guest.setBootOrder(GuestDef.BootOrder.CDROM);
+        }
         guest.setBootOrder(GuestDef.BootOrder.HARDISK);
         return guest;
     }
@@ -3122,7 +3144,7 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
                 final DiskDef.DiskType diskType = getDiskType(physicalDisk);
                 disk.defISODisk(volPath, devId, isUefiEnabled, diskType);
 
-                if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
+                if (guestCpuArch != null && (guestCpuArch.equals("aarch64") || 
guestCpuArch.equals("s390x"))) {
                     disk.setBusType(DiskDef.DiskBus.SCSI);
                 }
             } else {
@@ -3220,7 +3242,7 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
         if (vmSpec.getType() != VirtualMachine.Type.User) {
             final DiskDef iso = new DiskDef();
             iso.defISODisk(sysvmISOPath, DiskDef.DiskType.FILE);
-            if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
+            if (guestCpuArch != null && (guestCpuArch.equals("aarch64") || 
guestCpuArch.equals("s390x"))) {
                 iso.setBusType(DiskDef.DiskBus.SCSI);
             }
             vm.getDevices().addDevice(iso);
@@ -4294,7 +4316,7 @@ public class LibvirtComputingResource extends 
ServerResourceBase implements Serv
             return DiskDef.DiskBus.VIRTIO;
         } else if (isUefiEnabled && 
StringUtils.startsWithAny(platformEmulator, "Windows", "Other")) {
             return DiskDef.DiskBus.SATA;
-        } else if (guestCpuArch != null && guestCpuArch.equals("aarch64")) {
+        } else if (guestCpuArch != null && (guestCpuArch.equals("aarch64") || 
guestCpuArch.equals("s390x"))) {
             return DiskDef.DiskBus.SCSI;
         } else {
             return DiskDef.DiskBus.IDE;
diff --git 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
index 39373ab6e3b..82617696954 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
@@ -248,7 +248,9 @@ public class LibvirtVMDef {
                         guestDef.append("<boot dev='" + bo + "'/>\n");
                     }
                 }
-                guestDef.append("<smbios mode='sysinfo'/>\n");
+                if (!(_arch != null && _arch.equals("s390x"))) {
+                    guestDef.append("<smbios mode='sysinfo'/>\n");
+                }
                 guestDef.append("</os>\n");
                 if (iothreads) {
                     guestDef.append(String.format("<iothreads>%s</iothreads>", 
NUMBER_OF_IOTHREADS));
@@ -580,7 +582,7 @@ public class LibvirtVMDef {
                 }
             }
 
-            if (_emulator != null && _emulator.endsWith("aarch64")) {
+            if (_emulator != null && (_emulator.endsWith("aarch64") || 
_emulator.endsWith("s390x"))) {
                 devicesBuilder.append("<controller type='pci' 
model='pcie-root'/>\n");
                 for (int i = 0; i < 32; i++) {
                   devicesBuilder.append("<controller type='pci' 
model='pcie-root-port'/>\n");
@@ -1652,7 +1654,7 @@ public class LibvirtVMDef {
             if (_scriptPath != null) {
                 netBuilder.append("<script path='" + _scriptPath + "'/>\n");
             }
-            if (_pxeDisable) {
+            if (_pxeDisable && !"s390x".equals(System.getProperty("os.arch"))) 
{
                 netBuilder.append("<rom bar='off' file=''/>");
             }
             if (_virtualPortType != null) {
diff --git 
a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
 
b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
index c0b416410cb..00a9e4a8883 100644
--- 
a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
+++ 
b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
@@ -111,6 +111,10 @@ public class KVMHostInfo {
         return cpuArch;
     }
 
+    public static boolean isHostS390x() {
+       return "s390x".equals(System.getProperty("os.arch"));
+    }
+
     protected static long getCpuSpeed(final String cpabilities, final NodeInfo 
nodeInfo) {
         long speed = 0L;
         speed = getCpuSpeedFromCommandLscpu();
@@ -137,6 +141,9 @@ public class KVMHostInfo {
         try {
             LOGGER.info("Fetching CPU speed from command \"lscpu\".");
             String command = "lscpu | grep -i 'Model name' | head -n 1 | egrep 
-o '[[:digit:]].[[:digit:]]+GHz' | sed 's/GHz//g'";
+            if(isHostS390x()) {
+                command = "lscpu | grep 'CPU dynamic MHz' | cut -d ':' -f 2 | 
tr -d ' ' | awk '{printf \"%.1f\\n\", $1 / 1000}'";
+            }
             String result = Script.runSimpleBashScript(command);
             long speed = (long) (Float.parseFloat(result) * 1000);
             LOGGER.info(String.format("Command [%s] resulted in the value [%s] 
for CPU speed.", command, speed));
diff --git 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
index 7faebb01b6b..fb5e85f8647 100644
--- 
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ 
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@ -401,7 +401,7 @@ public class LibvirtComputingResourceTest {
         VirtualMachineTO to = createDefaultVM(false);
         LibvirtVMDef vm = new LibvirtVMDef();
         GuestDef guestDef = 
libvirtComputingResourceSpy.createGuestFromSpec(to, vm, to.getUuid(), null);
-        verifySysInfo(guestDef, "smbios", to.getUuid(), "pc");
+        verifySysInfo(guestDef, "smbios", to.getUuid(), 
"s390x".equals(System.getProperty("os.arch")) ? "s390-ccw-virtio" : "pc");
         Assert.assertEquals(GuestDef.BootType.BIOS, guestDef.getBootType());
         Assert.assertNull(guestDef.getBootMode());
     }
@@ -829,7 +829,7 @@ public class LibvirtComputingResourceTest {
     }
 
     private void verifyOsType(Document domainDoc) {
-        assertXpath(domainDoc, "/domain/os/type/@machine", "pc");
+        assertXpath(domainDoc, "/domain/os/type/@machine", 
"s390x".equals(System.getProperty("os.arch")) ? "s390-ccw-virtio" : "pc");
         assertXpath(domainDoc, "/domain/os/type/text()", "hvm");
     }
 
diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java 
b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
index c510502f5f9..7554c1f9704 100644
--- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -309,6 +309,8 @@ public abstract class HypervisorGuruBase extends 
AdapterBase implements Hypervis
 
         if (vmProfile.getTemplate().getBits() == 32) {
             to.setArch("i686");
+        } else if("s390x".equals(System.getProperty("os.arch"))) {
+            to.setArch("s390x");
         } else {
             to.setArch("x86_64");
         }

Reply via email to