From 4888a609627a26b70c1409abbbaa178a97b34653 Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Fri, 11 Jan 2013 16:49:11 +0100
Subject: [PATCH] kvm: allow setting smp cores, threads, sockets

This was requested in Issue 322.
Note that maxcpus is not implemented yet, as it should be considered in
a cpu-hotplug global context.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/constants.py         |  9 +++++++++
 lib/hypervisor/hv_kvm.py | 21 +++++++++++++++++----
 man/gnt-instance.rst     | 15 +++++++++++++++
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/lib/constants.py b/lib/constants.py
index 759ab3e01..3b48426ae 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -827,6 +827,9 @@ HV_REBOOT_BEHAVIOR = "reboot_behavior"
 HV_CPU_TYPE = "cpu_type"
 HV_CPU_CAP = "cpu_cap"
 HV_CPU_WEIGHT = "cpu_weight"
+HV_CPU_CORES = "cpu_cores"
+HV_CPU_THREADS = "cpu_threads"
+HV_CPU_SOCKETS = "cpu_sockets"
 
 
 HVS_PARAMETER_TYPES = {
@@ -887,6 +890,9 @@ HVS_PARAMETER_TYPES = {
   HV_CPU_TYPE: VTYPE_STRING,
   HV_CPU_CAP: VTYPE_INT,
   HV_CPU_WEIGHT: VTYPE_INT,
+  HV_CPU_CORES: VTYPE_INT,
+  HV_CPU_THREADS: VTYPE_INT,
+  HV_CPU_SOCKETS: VTYPE_INT,
   }
 
 HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys())
@@ -1951,6 +1957,9 @@ HVC_DEFAULTS = {
     HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED,
     HV_CPU_MASK: CPU_PINNING_ALL,
     HV_CPU_TYPE: "",
+    HV_CPU_CORES: 0,
+    HV_CPU_THREADS: 0,
+    HV_CPU_SOCKETS: 0,
     },
   HT_FAKE: {},
   HT_CHROOT: {
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index e77d1c27d..8087d4988 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -532,6 +532,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
     constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
     constants.HV_CPU_TYPE: hv_base.NO_CHECK,
+    constants.HV_CPU_CORES: hv_base.NO_CHECK,
+    constants.HV_CPU_THREADS: hv_base.NO_CHECK,
+    constants.HV_CPU_SOCKETS: hv_base.NO_CHECK,
     }
 
   _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
@@ -617,7 +620,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       elif arg == "-m":
         memory = int(arg_list.pop(0))
       elif arg == "-smp":
-        vcpus = int(arg_list.pop(0))
+        vcpus = int(arg_list.pop(0).split(",")[0])
 
     if instance is None:
       raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
@@ -1000,8 +1003,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         done in L{_ExecuteKVMRuntime}
 
     """
-    # pylint: disable=R0914,R0915
+    # pylint: disable=R0912,R0914,R0915
     _, v_major, v_min, _ = self._GetKVMVersion()
+    hvp = instance.hvparams
 
     pidfile = self._InstancePidFile(instance.name)
     kvm = constants.KVM_PATH
@@ -1010,7 +1014,17 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     # used just by the vnc server, if enabled
     kvm_cmd.extend(["-name", instance.name])
     kvm_cmd.extend(["-m", instance.beparams[constants.BE_MAXMEM]])
-    kvm_cmd.extend(["-smp", instance.beparams[constants.BE_VCPUS]])
+
+    smp_list = ["%s" % instance.beparams[constants.BE_VCPUS]]
+    if hvp[constants.HV_CPU_CORES]:
+      smp_list.append("cores=%s" % hvp[constants.HV_CPU_CORES])
+    if hvp[constants.HV_CPU_THREADS]:
+      smp_list.append("threads=%s" % hvp[constants.HV_CPU_THREADS])
+    if hvp[constants.HV_CPU_SOCKETS]:
+      smp_list.append("sockets=%s" % hvp[constants.HV_CPU_SOCKETS])
+
+    kvm_cmd.extend(["-smp", ",".join(smp_list)])
+
     kvm_cmd.extend(["-pidfile", pidfile])
     kvm_cmd.extend(["-balloon", "virtio"])
     kvm_cmd.extend(["-daemonize"])
@@ -1020,7 +1034,6 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         constants.INSTANCE_REBOOT_EXIT:
       kvm_cmd.extend(["-no-reboot"])
 
-    hvp = instance.hvparams
     kernel_path = hvp[constants.HV_KERNEL_PATH]
     if kernel_path:
       boot_disk = boot_cdrom = boot_floppy = boot_network = False
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index f22ee5d2f..6e40d3771 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -634,6 +634,21 @@ reboot\_behavior
 
     It is set to ``reboot`` by default.
 
+cpu\_cores
+    Valid for the KVM hypervisor.
+
+    Number of emulated CPU cores.
+
+cpu\_threads
+    Valid for the KVM hypervisor.
+
+    Number of emulated CPU threads.
+
+cpu\_sockets
+    Valid for the KVM hypervisor.
+
+    Number of emulated CPU sockets.
+
 
 The ``-O (--os-parameters)`` option allows customisation of the OS
 parameters. The actual parameter names and values depends on the OS
-- 
GitLab