Better handling of KVM nested state changes

* add possiblity to disable nested virtualization
* remove all previous nested virtualization settings from modprobe.d
* only reload kvm module if the nested state is not matching the desired
* remove unused default options for the kernel modules

The previous solution could add extra module configurations if old ones
were present and required reloading the KVM module. Reload fails on
virthosts with active VMs. Also checked that nested=1 works on the intel
module on a recent (3.10) kernel (most online docs use nested=Y).

Change-Id: I491ff20240c7a87afea07b4dd6f83bad005de3be
This commit is contained in:
Attila Darazs 2016-11-21 16:55:14 +01:00
parent 1d63c5ad97
commit ab97f12d02
2 changed files with 55 additions and 69 deletions

View File

@ -1,2 +1 @@
kvm_intel_options: ''
kvm_amd_options: ''
nested: true

View File

@ -1,81 +1,68 @@
# Grab CPU flags from "/proc/cpuinfo" and put the result into the
# "cpu_flags_cmd" variable.
- name: Get cpu flags
command: |
awk -F: '/^flags/ {print $2; exit}' /proc/cpuinfo
- name: Set CPU vendor
set_fact:
cpu_vendor: "{{ 'intel' if 'Intel' in ansible_processor|join('') else
'amd' if 'AMD' in ansible_processor|join('') else 'unknown' }}"
- name: Get CPU flags
command: "awk -F: '/^flags/ {print $2; exit}' /proc/cpuinfo"
register: cpu_flags_cmd
changed_when: false
# Extract the flags into a list variable named "cpu_flags".
- name: Set cpu flags fact
- name: Check for nested support
set_fact:
cpu_flags: "{{ cpu_flags_cmd.stdout.split() }}"
cpu_nested_support: "{{ true if cpu_vendor == 'intel' and 'vmx' in cpu_flags_cmd.stdout.split() else
true if cpu_vendor == 'amd' and 'svm' in cpu_flags_cmd.stdout.split() else false }}"
- block:
- name: Unload kvm_intel module
- name: Disable nested if not supported
set_fact:
nested: "{{ false if not cpu_nested_support|bool else nested }}"
- name: Remove previous KVM modprobe configs
shell: find /etc/modprobe.d/ -type f -print0| xargs -0 sed -i '/^options kvm_intel/d;/^options kvm_amd/d'
become: true
changed_when: true
- name: Configure KVM module
copy:
dest: "/etc/modprobe.d/kvm.conf"
content: |
options kvm_{{ cpu_vendor }} nested={{ nested|bool|ternary('1', '0') }}
become: true
- name: Fetch current runtime nested setting
command: cat /sys/module/kvm_{{ cpu_vendor }}/parameters/nested
register: kvm_nested_info
changed_when: false
- name: Check if nested is enabled currently
set_fact:
cpu_nested_enabled: "{{ true if 'Y' in kvm_nested_info.stdout else
true if '1' in kvm_nested_info.stdout else false }}"
- when: nested|bool != cpu_nested_enabled|bool
block:
- name: Unload KVM module
modprobe:
name: "kvm_intel"
name: "kvm_{{ cpu_vendor }}"
state: "absent"
become: true
- name: Configure KVM module with Intel nested virtualization support
copy:
dest: "/etc/modprobe.d/kvm_intel.conf"
content: |
options kvm_intel nested=1
become: true
- name: Re-load kvm_intel module
- name: Reload KVM module
modprobe:
name: "kvm_intel"
name: "kvm_{{ cpu_vendor }}"
state: "present"
become: true
- name: Ensure nested virtualization is enabled
command: cat /sys/module/kvm_intel/parameters/nested
register: nested_virtualization
failed_when: ('FAILED' in nested_virtualization.stderr) or
('N' in nested_virtualization.stdout)
always:
- debug:
msg: >
/sys/module/kvm_intel/parameters/nested:
{{ nested_virtualization.stdout }}
when:
- "{{ 'Intel' in ansible_processor |join('') }}"
- "{{ 'vmx' in cpu_flags }}"
- name: Fetch current runtime nested setting
command: cat /sys/module/kvm_{{ cpu_vendor }}/parameters/nested
register: kvm_nested_info
changed_when: false
- block:
- name: Unload kvm_amd module
modprobe:
name: "kvm_amd"
state: "absent"
become: true
- name: Configure KVM module with AMD nested virtualization support
copy:
dest: "/etc/modprobe.d/kvm_amd.conf"
content: |
options kvm_amd nested=1
become: true
- name: Re-load kvm_amd module
modprobe:
name: "kvm_amd"
state: "present"
register: nested_virtualization
become: true
- name: Ensure nested virtualization is enabled
command: cat /sys/module/kvm_amd/parameters/nested
register: nested_virtualization
failed_when: ('FAILED' in nested_virtualization.stderr) or
('0' in nested_virtualization.stdout)
always:
- debug:
msg: >
/sys/module/kvm_amd/parameters/nested:
{{ nested_virtualization.stdout }}
when:
- "{{ 'AMD' in ansible_processor |join('') }}"
- "{{ 'svm' in cpu_flags }}"
- name: Check again if nested is enabled currently
set_fact:
cpu_nested_enabled: "{{ true if 'Y' in kvm_nested_info.stdout else
true if '1' in kvm_nested_info.stdout else false }}"
- name: Fail when the desired and actual state do not match
fail:
msg: "Cannot change the state of nested virtualization. Please shut down any running VMs."
when: nested|bool != cpu_nested_enabled|bool