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:
parent
1d63c5ad97
commit
ab97f12d02
|
@ -1,2 +1 @@
|
|||
kvm_intel_options: ''
|
||||
kvm_amd_options: ''
|
||||
nested: true
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue