Commit 9437ec3a authored by Alain Takoudjou's avatar Alain Takoudjou

kvm: reduce number of options used for cpu/ram hotplug

parent 9c6f8f1f
......@@ -99,7 +99,7 @@ recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/instance-kvm.cfg.jinja2
mode = 644
md5sum = 152b052f4b418ab3138a3e109a3ec01e
md5sum = e3cc9ffe857da1078e321cab65173fb1
download-only = true
on-update = true
......@@ -108,7 +108,7 @@ recipe = hexagonit.recipe.download
ignore-existing = true
url = ${:_profile_base_location_}/instance-kvm-cluster.cfg.jinja2.in
mode = 644
md5sum = dd5c37d60f2ea3dc3a7af15718d4ac6c
md5sum = 26d931a0279d49eadb3881f440b623bc
download-only = true
on-update = true
......@@ -186,7 +186,7 @@ ignore-existing = true
url = ${:_profile_base_location_}/template/template-kvm-run.in
mode = 644
filename = template-kvm-run.in
md5sum = 7f34fbb05f0cfdb6753e008e47cacf30
md5sum = 122bf5e8c7a12bceef1bdd6d6b54f4d7
download-only = true
on-update = true
......@@ -196,7 +196,7 @@ ignore-existing = true
url = ${:_profile_base_location_}/template/kvm-controller-run.in
mode = 644
filename = kvm-controller-run.in
md5sum = 9ba27ec934e0e86ef88493356a40bed5
md5sum = 7e6c79232cc88c15ed21c112ff801b76
download-only = true
on-update = true
......
......@@ -189,36 +189,35 @@
"default": "started",
"enum": ["started", "stopped"]
},
"enable-device-hotplug": {
"title": "Enable device hotplug mode",
"description": "If yes, this will allow to Create devices like CPU and Memory in hotplug mode without restart the VM. Operatin System should be configured to Online new created devices.",
"type": "boolean",
"default": false
},
"ram-size": {
"title": "RAM size",
"description": "RAM size, in MB.",
"type": "integer",
"default": 1024,
"minimum": 128,
"multipleOf": 128
"minimum": 1024,
"multipleOf": 512
},
"hotplug-slot-size": {
"ram-max-size": {
"title": "Maximum RAM size, in MB",
"description": "Define the maximum size of the memory. The size is in MB and should be a multiple of 512.",
"type": "integer",
"default": 51200,
"minimum": 1024,
"multipleOf": 512
},
"ram-hotplug-slot-size": {
"title": "Size of Hotpluggable RAM slot, in MB",
"description": "Define the RAM size to plug on one hotpluggable slot in MB, understand the size of one RAM bar. The RAM hotplugged on each slot will always have the same RAM size.",
"type": "integer",
"default": 512,
"minimum": 128,
"multipleOf": 128
},
"max-ram-hotplug-size": {
"title": "Maximum hotpluggable RAM size, in MB",
"description": "Define the maximum size of hotpluggable memory. The size is in MB and should be a multiple of the defined hotpluggable slot size.",
"type": "integer",
"default": 0,
"minimum": 128,
"multipleOf": 128
},
"hotplugged-slot-amount": {
"title": "Hotplugged RAM slot amount",
"description": "Define the number of Memory slot to hotplug. Ex: if slot-hotplug-size=512 MB, then to hotplug 1G of RAM 2 slots will be used.",
"type": "integer",
"default": 0,
"minimum": 0
"minimum": 512,
"multipleOf": 512
},
"auto-ballooning": {
"title": "Enable qemu auto ballooning.",
......@@ -268,17 +267,13 @@
"type": "integer",
"minimum": 1
},
"max-cpu-hotplug-count": {
"title": "Maximum hotpluggable CPU amount",
"description": "Specifies the maximum number of hotpluggable CPUs.",
"type": "integer",
"default": 1
},
"cpu-hotplug-amount": {
"title": "hotpluggable CPU amount",
"description": "Specifies the number of CPUs to hotplug",
"cpu-max-count": {
"title": "Maximum CPU amount",
"description": "Specifies the maximum number of CPUs.",
"type": "integer",
"default": 0
"default": 24,
"minimum": 1,
"maximum": 64
},
"numa": {
"title": "Simulate a multi node NUMA system.",
......
......@@ -51,16 +51,15 @@ config-authorized-key = {{ dumps(slapparameter_dict.get('authorized-keys') | joi
config-nbd-port = {{ dumps(kvm_parameter_dict.get('nbd-port', 1024)) }}
config-nbd2-port = {{ dumps(kvm_parameter_dict.get('nbd-port2', 1024)) }}
config-ram-size = {{ dumps(kvm_parameter_dict.get('ram-size', 1024)) }}
config-max-ram-hotplug-size = {{ dumps(kvm_parameter_dict.get('max-ram-hotplug-size', 0)) }}
config-hotplug-slot-size = {{ dumps(kvm_parameter_dict.get('hotplug-slot-size', 512)) }}
config-hotplugged-slot-amount = {{ dumps(kvm_parameter_dict.get('hotplugged-slot-amount', 0)) }}
config-ram-max-size = {{ dumps(kvm_parameter_dict.get('ram-max-size', '50G')) }}
config-enable-device-hotplug = {{ dumps(kvm_parameter_dict.get('enable-device-hotplug', False)) }}
config-ram-hotplug-slot-size = {{ dumps(kvm_parameter_dict.get('ram-hotplug-slot-size', 512)) }}
config-disk-size = {{ dumps(kvm_parameter_dict.get('disk-size', 10)) }}
config-disk-type = {{ dumps(kvm_parameter_dict.get('disk-type', 'virtio')) }}
config-cpu-count = {{ dumps(kvm_parameter_dict.get('cpu-count', 1)) }}
config-max-cpu-hotplug-count = {{ dumps(kvm_parameter_dict.get('max-cpu-hotplug-count', 1)) }}
config-cpu-hotplug-amount = {{ dumps(kvm_parameter_dict.get('cpu-hotplug-amount', 0)) }}
config-cpu-max-count = {{ dumps(kvm_parameter_dict.get('cpu-max-count', 24)) }}
{{ setconfig('numa', kvm_parameter_dict.get('numa', '')) }}
{{ setconfig('cpu-options', kvm_parameter_dict.get('cpu-options', '')) }}
{{ setconfig('machine-options', kvm_parameter_dict.get('machine-options', '')) }}
{{ setconfig('nbd-host', kvm_parameter_dict.get('nbd-host', '')) }}
{{ setconfig('host2', kvm_parameter_dict.get('host2', '')) }}
......@@ -71,7 +70,7 @@ config-auto-ballooning = {{ dumps(kvm_parameter_dict.get('auto-ballooning', True
{{ setconfig('disk-cache', kvm_parameter_dict.get('disk-cache', '')) }}
{% set nat_rules_list = kvm_parameter_dict.get('nat-rules', []) -%}
{{ setconfig('nat-rules', ' '.join(nat_rules_list)) }}
{{ setconfig('nat-rules', nat_rules_list | join(' ')) }}
config-publish-nat-url = True
config-use-nat = {{ use_nat }}
config-use-tap = {{ dumps(kvm_parameter_dict.get('use-tap', True)) }}
......
......@@ -4,36 +4,35 @@
"title": "Input Parameters",
"properties": {
"enable-device-hotplug": {
"title": "Enable device hotplug mode",
"description": "If yes, this will allow to Create devices like CPU and Memory in hotplug mode without restart the VM. Operatin System should be configured to Online new created devices.",
"type": "boolean",
"default": false
},
"ram-size": {
"title": "RAM size",
"description": "RAM size, in MB.",
"type": "integer",
"default": 1024,
"minimum": 128,
"multipleOf": 128
"minimum": 1024,
"multipleOf": 512
},
"hotplug-slot-size": {
"ram-max-size": {
"title": "Maximum RAM size, in MB",
"description": "Define the maximum size of the memory. The size is in MB and should be a multiple of 512.",
"type": "integer",
"default": 51200,
"minimum": 1024,
"multipleOf": 512
},
"ram-hotplug-slot-size": {
"title": "Size of Hotpluggable RAM slot, in MB",
"description": "Define the RAM size to plug on one hotpluggable slot in MB, understand the size of one RAM bar. The RAM hotplugged on each slot will always have the same RAM size.",
"type": "integer",
"default": 512,
"minimum": 128,
"multipleOf": 128
},
"max-ram-hotplug-size": {
"title": "Maximum hotpluggable RAM size, in MB",
"description": "Define the maximum size of hotpluggable memory. The size is in MB and should be a multiple of the defined hotpluggable slot size.",
"type": "integer",
"default": 0,
"minimum": 128,
"multipleOf": 128
},
"hotplugged-slot-amount": {
"title": "Hotplugged RAM slot amount",
"description": "Define the number of Memory slot to hotplug. Ex: if slot-hotplug-size=512 MB, then to hotplug 1G of RAM 2 slots will be used.",
"type": "integer",
"default": 0,
"minimum": 0
"minimum": 512,
"multipleOf": 512
},
"auto-ballooning": {
"title": "Enable qemu auto ballooning.",
......@@ -77,6 +76,14 @@
"type": "integer",
"minimum": 1
},
"cpu-max-count": {
"title": "Maximum CPU amount",
"description": "Specifies the maximum number of CPUs.",
"type": "integer",
"default": 24,
"minimum": 1,
"maximum": 64
},
"max-cpu-hotplug-count": {
"title": "Maximum hotpluggable CPU amount",
"description": "Specifies the maximum number of hotpluggable CPUs.",
......
......@@ -5,6 +5,7 @@
{% set nat_restrict = slapparameter_dict.get('nat-restrict-mode', 'False').lower() -%}
{% set name = slapparameter_dict.get('name', 'localhost') -%}
{% set disable_ansible_promise = slapparameter_dict.get('disable-ansible-promise', 'True').lower() -%}
{% set enable_device_hotplug = slapparameter_dict.get('enable-device-hotplug', 'false').lower() -%}
{% set instance_type = slapparameter_dict.get('type', 'standalone') -%}
{% set nat_rule_list = slapparameter_dict.get('nat-rules', '22 80 443') -%}
{% set frontend_software_type = 'default' -%}
......@@ -65,11 +66,12 @@ bytes = 8
python-path = {{ python_eggs_executable }}
vnc-passwd = ${gen-passwd:passwd}
socket-path = ${directory:var}/qmp_socket
pid-file = ${directory:run}/pid_file
kvm-status-path = ${directory:var}/qemu-vm-is-ready
cpu-hotplug-amount = ${slap-parameter:cpu-hotplug-amount}
hotplugged-slot-amount = ${slap-parameter:hotplugged-slot-amount}
hotplug-slot-size = ${slap-parameter:hotplug-slot-size}
max-ram-hotplug-size = ${slap-parameter:max-ram-hotplug-size}
cpu-count = ${slap-parameter:cpu-count}
ram-hotplug-slot-size = ${slap-parameter:ram-hotplug-slot-size}
ram-size = ${slap-parameter:ram-size}
enable-device-hotplug = ${slap-parameter:enable-device-hotplug}
[kvm-parameter-dict]
python-path = {{ python_executable }}
......@@ -91,14 +93,16 @@ disk-size = ${slap-parameter:disk-size}
disk-type = ${slap-parameter:disk-type}
pid-file-path = ${directory:run}/pid_file
pid-file-path = ${kvm-controller-parameter-dict:pid-file}
socket-path = ${kvm-controller-parameter-dict:socket-path}
smp-count = ${slap-parameter:cpu-count}
max-smp-hotplug-count = ${slap-parameter:max-cpu-hotplug-count}
ram-size = ${slap-parameter:ram-size}
max-ram-hotplug-size = ${slap-parameter:max-ram-hotplug-size}
hotplug-slot-size = ${slap-parameter:hotplug-slot-size}
enable-device-hotplug = ${kvm-controller-parameter-dict:enable-device-hotplug}
smp-count = ${kvm-controller-parameter-dict:cpu-count}
smp-max-count = ${slap-parameter:cpu-max-count}
ram-size = ${kvm-controller-parameter-dict:ram-size}
ram-max-size = ${slap-parameter:ram-max-size}
init-ram-size = 1024
mac-address = ${create-mac:mac-address}
tap-mac-address = ${create-tap-mac:mac-address}
......@@ -555,16 +559,15 @@ nbd-host =
nbd2-port = 1024
nbd2-host =
enable-device-hotplug = False
ram-size = 1024
hotplug-slot-size = 512
max-ram-hotplug-size = 0
hotplugged-slot-amount = 0
ram-max-size = 50G
ram-hotplug-slot-size = 512
disk-size = 10
disk-type = virtio
cpu-count = 1
max-cpu-hotplug-count = 1
cpu-hotplug-amount = 0
cpu-max-count = 24
disk-cache = writeback
disk-aio = native
auto-ballooning = True
......
......@@ -6,47 +6,58 @@
import socket
import time
import os
from slapos.qemuqmpclient import QemuQMPWrapper
from slapos.qemuqmpclient import QemuQMPWrapper, getInitialQemuResourceDict
# XXX: to be factored with slapos.toolbox qemu qmp wrapper.
socket_path = '{{ parameter_dict.get("socket-path") }}'
pid_file = '{{ parameter_dict.get("pid-file") }}'
vnc_password = '{{ parameter_dict.get("vnc-passwd") }}'
status_path = '{{ parameter_dict.get("kvm-status-path") }}'
cpu_hotplug_amount = {{ parameter_dict.get("cpu-hotplug-amount", 0) }}
cpu_model = '{{ parameter_dict.get("cpu-model", '') }}'
max_ram_hotplug_size = {{ parameter_dict.get("max-ram-hotplug-size", 0) }}
ram_hotplug_amount = {{ parameter_dict.get("hotplugged-slot-amount", 0) }}
slot_hotplug_size = {{ parameter_dict.get("hotplug-slot-size", 512) }}
cpu_amount = {{ parameter_dict.get("cpu-count") }}
cpu_model = '{{ parameter_dict.get("cpu-model", "qemu64-x86_64-cpu") }}'
slot_hotplug_size = {{ parameter_dict.get("ram-hotplug-slot-size", 512) }}
ram_size = {{ parameter_dict.get("ram-size") }}
enable_device_hotplug = '{{ parameter_dict.get("enable-device-hotplug") }}'.lower()
def write(message):
with open(status_path, 'w') as status_file:
status_file.write(message)
def update():
try:
init_dict = getInitialQemuResourceDict(pid_file)
init_ram_size = int(init_dict['ram'].split('M')[0])
if cpu_amount < 1:
raise ValueError("CPU should be at least equal to 1.")
hotplug_ram = ram_size - init_ram_size
if hotplug_ram < 0:
raise ValueError("RAM size cannot be less than the initial value %s MB" % init_ram_size)
if os.path.exists(status_path):
os.unlink(status_path)
qemu_wrapper = QemuQMPWrapper(socket_path)
try:
qemu_wrapper.setVNCPassword(vnc_password)
cpu_option_dict = {
if enable_device_hotplug == 'true':
write("Qemu Controller is still running...")
qemu_wrapper.updateDevice({
'device': 'cpu',
'amount': cpu_hotplug_amount
}
if cpu_model:
cpu_option_dict['model'] = cpu_model
qemu_wrapper.updateDevice(cpu_option_dict)
if max_ram_hotplug_size > 0:
'amount': cpu_amount,
'model': cpu_model
})
qemu_wrapper.updateDevice({
'device': 'memory',
'mem': ram_hotplug_amount * slot_hotplug_size,
'mem': hotplug_ram,
'slot': slot_hotplug_size,
'nslot': max_ram_hotplug_size / slot_hotplug_size
'nslot': 128,
'canreboot': 1
})
except ValueError, e:
with open(status_path, 'w') as status_file:
status_file.write(str(e))
except Exception, e:
write(str(e))
raise
with open(status_path, 'w') as status_file:
status_file.write("")
write("")
if __name__ == "__main__":
update()
......@@ -39,12 +39,10 @@ tap_interface = '{{ parameter_dict.get("tap-interface") }}'
listen_ip = '{{ parameter_dict.get("ipv4") }}'
mac_address = '{{ parameter_dict.get("mac-address") }}'
tap_mac_address = '{{ parameter_dict.get("tap-mac-address") }}'
smp_count = {{ parameter_dict.get("smp-count") }}
max_smp_hotplug_count = {{ parameter_dict.get("max-smp-hotplug-count") }}
numa_list = '{{ parameter_dict.get("numa", "") }}'.split()
ram_size = {{ parameter_dict.get("ram-size") }}
max_ram_hotplug_size = {{ parameter_dict.get("max-ram-hotplug-size") }}
slot_hotplug_size = {{ parameter_dict.get("hotplug-slot-size") }}
ram_max_size = '{{ parameter_dict.get("ram-max-size") }}'
init_ram_size = {{ parameter_dict.get("init-ram-size") }}
pid_file_path = '{{ parameter_dict.get("pid-file-path") }}'
external_disk_number = {{ parameter_dict.get("external-disk-number") }}
external_disk_size = {{ parameter_dict.get("external-disk-size") }}
......@@ -71,9 +69,13 @@ disk_cache = disk_cache if disk_cache in ["none", "writeback", "unsafe",
disk_aio = '{{ parameter_dict.get("disk-aio") }}'.strip()
disk_aio = disk_aio if disk_aio in ["threads", "native"] and \
disk_cache == "directsync" else "threads"
smp_count = {{ parameter_dict.get("smp-count") }}
smp_max_count = {{ parameter_dict.get("smp-max-count") }}
machine_options = '{{ parameter_dict.get("machine-options", "") }}'.strip()
cpu_model = '{{ parameter_dict.get("cpu-model", "") }}'.strip()
enable_device_hotplug = '{{ parameter_dict.get("enable-device-hotplug") }}'.lower()
logfile = '{{ parameter_dict.get("log-file") }}'
if hasattr(ssl, '_create_unverified_context') and url_check_certificate == 'false':
......@@ -146,12 +148,6 @@ def getMapStorageList(disk_storage_dict, external_disk_number):
lf.write('%s' % external_disk_number)
return id_list, external_disk_number
def getMemHotplugDict(max_mem_size, slot_size):
if max_mem_size == 0:
return None
number = max_mem_size / slot_size
return {'maxmem': max_mem_size + ram_size, 'slots': number}
# Download existing hard drive if needed at first boot
if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
print('Downloading virtual hard drive...')
......@@ -263,18 +259,14 @@ if use_tap == 'true':
tap_interface, vhost),
'-device', 'virtio-net-pci,netdev=lan%s,mac=%s' % (number, tap_mac_address)]
if not max_smp_hotplug_count >= 0:
raise ValueError("Max CPU hotpluggable count is not a valid interger")
smp ='%s,maxcpus=%s' % (smp_count, smp_count + max_smp_hotplug_count)
mem_dict = getMemHotplugDict(max_ram_hotplug_size, slot_hotplug_size)
if mem_dict is not None:
ram_string = '%sM,slots=%s,maxmem=%sM' % (ram_size, mem_dict['slots'], mem_dict['maxmem'])
if enable_device_hotplug != 'true':
smp = '%s,maxcpus=%s' % (smp_count, smp_max_count)
ram = '%sM,slots=128,maxmem=%s' % (ram_size, ram_max_size)
else:
ram_string = '%s' % ram_size
smp = '1,maxcpus=%s' % smp_max_count
ram = '%sM,slots=128,maxmem=%s' % (init_ram_size, ram_max_size)
kvm_argument_list = [qemu_path,
'-enable-kvm', '-smp', smp, '-name', vm_name,
'-m', ram_string, '-vga', 'std',
'-enable-kvm', '-smp', smp, '-name', vm_name, '-m', ram, '-vga', 'std',
'-drive', 'file=%s,if=%s,cache=%s,aio=%s' % (disk_path, disk_type, disk_cache, disk_aio),
'-vnc', '%s:1,ipv4,password' % listen_ip,
'-boot', 'order=cd,menu=on',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment