Skip to content

Commit 7505e73

Browse files
authored
[Linux] Update VHBA testing known issues (#711)
Signed-off-by: Qi Zhang <[email protected]>
1 parent 8e08606 commit 7505e73

18 files changed

+457
-306
lines changed

linux/network_device_ops/apply_new_network_config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
2525
- name: "Set fact of command for adding network connection with static IP addresss"
2626
ansible.builtin.set_fact:
27-
nmcli_connection_add_cmd: >-
27+
nmcli_connection_add_cmd: >-
2828
nmcli connection add type ethernet ifname {{ new_network_adapter }}
2929
con-name {{ new_network_adapter }} ipv4.method manual
3030
ipv4.addresses {{ new_nic_ipv4 }}/{{ new_nic_net_prefix }}
@@ -33,7 +33,7 @@
3333

3434
- name: "Set fact of command for adding network connection with DHCP IP addresss"
3535
ansible.builtin.set_fact:
36-
nmcli_connection_add_cmd: >-
36+
nmcli_connection_add_cmd: >-
3737
nmcli connection add type ethernet ifname {{ new_network_adapter }}
3838
con-name {{ new_network_adapter }} {{ nmcli_ipv6_method }}
3939
when: new_nic_ipv4_method == 'dhcp'

linux/network_device_ops/hot_add_network_adapter.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
vars:
3636
vm_wait_connection_timeout: 60
3737

38-
- name: "Get new messages in dmesg ring buffer"
38+
- name: "Collect dmesg after hot adding a new network adapter"
3939
include_tasks: ../utils/collect_dmesg.yml
4040
vars:
41-
dmesg_output_file_name: 'dmesg_after_nic_hotadd.log'
41+
dmesg_options: '-c'
42+
dmesg_output_file_name: 'dmesg_after_nic_hot_add.log'
43+
dmesg_check_call_trace: true
4244

4345
- name: "Set match string for newly added NIC in dmesg ring buffer"
4446
ansible.builtin.set_fact:

linux/network_device_ops/hot_remove_network_adapter.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
include_tasks: ../../common/vm_remove_network_adapter.yml
88
vars:
99
netadapter_mac_addr: "{{ new_network_adapter_mac_addr }}"
10-
vm_remove_adapter_ignore_errors: True
10+
vm_remove_adapter_ignore_errors: true
1111

1212
- name: "Network adapter hot-remove succeeded"
1313
ansible.builtin.debug:
@@ -30,7 +30,7 @@
3030
- known_issue
3131
when:
3232
- remove_adapter.module_stderr is defined
33-
- (remove_adapter.module_stderr |
33+
- (remove_adapter.module_stderr |
3434
regex_findall("The guest operating system did not respond to a hot-remove request for device '.*' in a timely manner.") | length > 0)
3535
- adapter_type == "pvrdma"
3636
- esxi_version is version('7.0.0', '>=')
@@ -47,6 +47,13 @@
4747
vars:
4848
vm_wait_connection_timeout: 60
4949

50+
- name: "Collect dmesg after hot removing the new network adapter"
51+
include_tasks: ../utils/collect_dmesg.yml
52+
vars:
53+
dmesg_options: '-c'
54+
dmesg_output_file_name: 'dmesg_after_nic_hot_remove.log'
55+
dmesg_check_call_trace: true
56+
5057
- name: "Get network adapter status after hot-remove"
5158
include_tasks: ../utils/get_network_adapters_status.yml
5259

linux/setup/linux_test_rescue.yml

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,20 @@
88
include_tasks: ../utils/collect_dmesg.yml
99
vars:
1010
dmesg_ignore_errors: true
11-
dmesg_output_file_name: "dmesg_at_test_failure.log"
11+
dmesg_output_file_name: "dmesg_at_{{ ansible_play_name }}_failure.log"
12+
dmesg_check_call_trace: true
1213

1314
- name: "No output file for dmesg"
1415
ansible.builtin.debug:
1516
msg: "There is no new messages in dmesg ring buffer or failed to get dmesg output"
1617
when: not dmesg_output_file_path
1718

18-
- name: "Detect errors in dmesg output"
19-
when: dmesg_output_file_path
20-
block:
21-
- name: "Extract errors from guest OS dmesg"
22-
include_tasks: ../../common/extract_errors_from_log.yml
23-
vars:
24-
extract_log_file_path: "{{ dmesg_output_file_path }}"
25-
26-
- name: "Display detected errors from guest OS dmesg"
27-
ansible.builtin.debug:
28-
msg: "{{ errors_in_log }}"
29-
tags:
30-
- fail_message
31-
when: errors_in_log | length > 0
19+
- name: "Display call trace stack detected in dmesg output"
20+
ansible.builtin.debug:
21+
msg: "{{ dmesg_call_trace_stack }}"
22+
tags:
23+
- fail_message
24+
when: dmesg_call_trace_stack | length > 0
3225

3326
- name: "Collect /var/log/messages at test case failure"
3427
include_tasks: ../utils/fetch_file.yml

linux/setup/test_setup.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,7 @@
9696
service_enabled: true
9797
service_state: "restarted"
9898
when: dns_servers_output.stdout.find("DNS Servers:") == -1
99+
100+
- name: "Initialize the fact of dmesg call trace stack"
101+
ansible.builtin.set_fact:
102+
dmesg_call_trace_stack: []

linux/utils/collect_dmesg.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88
# dmesg_output_file_name (optional): the file name for saving dmesg output in test case log folder
99
# dmesg_ignore_errors (optional): ignore errors when executing dmesg. Default is false.
1010
# dmesg_no_log (optional): true to hide output on console. Default is false.
11+
# dmesg_check_call_trace (optional): whether to check there is call trace or not in dmesg output.
12+
# Default value is false.
1113
# Return:
1214
# dmesg_output_file_path: the file path to save dmesg output at localhost
15+
# dmesg_call_trace_stack: all call traces found in current test case when
16+
# dmesg_check_call_trace is true.
1317
#
1418
- name: "Initialize facts of dmesg command result and output file path at localhost"
1519
ansible.builtin.set_fact:
@@ -50,6 +54,26 @@
5054
- save_dmesg_result.failed is defined
5155
- not save_dmesg_result.failed
5256

53-
- name: "Display the demst output file path"
57+
- name: "Display the dmesg output file path"
5458
ansible.builtin.debug:
5559
msg: "The output of dmesg is saved into {{ dmesg_output_file_path }}"
60+
61+
- name: "Check whether there is call trace in dmesg output"
62+
when: dmesg_check_call_trace | default(false)
63+
block:
64+
- name: "Extract errors from dmesg output in guest OS"
65+
include_tasks: ../../common/extract_errors_from_log.yml
66+
vars:
67+
extract_log_file_path: "{{ dmesg_output_file_path }}"
68+
69+
- name: "Update fact of call traces found in test case {{ ansible_play_name }}"
70+
ansible.builtin.set_fact:
71+
dmesg_call_trace_stack: >-
72+
{{
73+
dmesg_call_trace_stack |
74+
union(["Found call trace in "~ dmesg_output_file_name]) |
75+
union(errors_in_log)
76+
}}
77+
when:
78+
- errors_in_log | length > 0
79+
- errors_in_log is search('Call Trace')

linux/utils/freebsd_get_geom_list.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
ansible.builtin.shell: "sysctl -n kern.geom.confxml"
2525
delegate_to: "{{ vm_guest_ip }}"
2626
register: geom_in_xml_result
27+
no_log: true
2728

2829
- name: "Set fact of FreeBSD GEOM config info"
2930
ansible.builtin.set_fact:

linux/utils/get_device_list.yml

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,64 @@
99
# guest_device_list: A list of all guest devices or a list of guest devices with given type
1010
# and attributes of name, type, size in bytes and filesystem type
1111
#
12-
- name: "Initialize the fact of device list and command"
12+
- name: "Initialize the fact of device list in guest OS"
1313
ansible.builtin.set_fact:
1414
guest_device_list: []
15-
get_device_list_cmd: |-
16-
{%- if guest_os_family == 'FreeBSD' -%}lsblk -d | grep -i '^[a-z]' | grep -v SIZE | grep -v cd0
17-
{%- else -%}lsblk -o NAME,TYPE,SIZE,FSTYPE -b --nodeps
18-
{%- endif -%}
1915

20-
- name: "Update command to get device list with type of {{ guest_device_type }}"
21-
ansible.builtin.set_fact:
22-
get_device_list_cmd: "{{ get_device_list_cmd ~ ' | grep ' ~ guest_device_type }}"
23-
when:
24-
- guest_device_type is defined
25-
- guest_device_type
26-
- guest_os_family != "FreeBSD"
16+
- name: "Get device list on Linux"
17+
when: guest_os_ansible_system == 'linux'
18+
block:
19+
- name: "Get device list of type {{ guest_device_type }} on {{ vm_guest_os_distribution }}"
20+
ansible.builtin.shell: "lsblk -o NAME,TYPE,SIZE,FSTYPE -b --nodeps | grep -i {{ guest_device_type }}"
21+
delegate_to: "{{ vm_guest_ip }}"
22+
changed_when: false
23+
ignore_errors: true
24+
register: list_device_result
2725

28-
- name: "Get block device list"
29-
ansible.builtin.shell: "{{ get_device_list_cmd }}"
30-
delegate_to: "{{ vm_guest_ip }}"
31-
changed_when: false
32-
ignore_errors: true
33-
register: lsblk_result
26+
- name: "Set fact of {{ guest_device_type }} device list on {{ vm_guest_os_distribution }}"
27+
ansible.builtin.set_fact:
28+
guest_device_list: >
29+
{{
30+
guest_device_list | union([
31+
dict(['name', 'type', 'size', 'fstype'] |
32+
zip_longest(item.split(), fillvalue=''))
33+
])
34+
}}
35+
with_items: "{{ list_device_result.stdout_lines }}"
36+
when:
37+
- list_device_result is defined
38+
- list_device_result.stdout_lines is defined
39+
- list_device_result.stdout_lines | length > 0
3440

35-
- name: "Set the fact of block device list for {{ guest_os_ansible_distribution }}"
36-
ansible.builtin.set_fact:
37-
guest_device_list: >
38-
{{
39-
guest_device_list | union([
40-
dict(['name', 'type', 'size', 'fstype'] |
41-
zip_longest(item.split(), fillvalue=''))
42-
])
43-
}}
44-
with_items: "{{ lsblk_result.stdout_lines }}"
45-
when:
46-
- guest_os_family != 'FreeBSD'
47-
- lsblk_result is defined
48-
- lsblk_result.stdout_lines is defined
49-
- lsblk_result.stdout_lines | length > 0
41+
- name: "Get device list on FreeBSD"
42+
when: guest_os_ansible_system == 'freebsd'
43+
block:
44+
- name: "Get device list of type {{ guest_device_type }} on {{ vm_guest_os_distribution }}"
45+
include_tasks: freebsd_get_geom_list.yml
46+
vars:
47+
freebsd_geom_class: "DISK"
5048

51-
- name: "Set the fact of block device list for FreeBSD"
52-
ansible.builtin.set_fact:
53-
guest_device_list: >
54-
{{
55-
guest_device_list | union([
56-
dict(['name', 'size', 'model'] |
57-
zip_longest(item.split(None, maxsplit=2), fillvalue=''))
58-
])
59-
}}
60-
with_items: "{{ lsblk_result.stdout_lines }}"
61-
when:
62-
- guest_os_family == 'FreeBSD'
63-
- lsblk_result is defined
64-
- lsblk_result.stdout_lines is defined
65-
- lsblk_result.stdout_lines | length > 0
49+
- name: "Update fact of GEOM class list with {{ guest_device_type }} only"
50+
ansible.builtin.set_fact:
51+
freebsd_device_list: "{{ freebsd_geom_list | selectattr('name', 'match', 'cd\\d+') }}"
52+
when: guest_device_type | lower == 'rom'
53+
54+
- name: "Update fact of GEOM class list with {{ guest_device_type }} only"
55+
ansible.builtin.set_fact:
56+
freebsd_device_list: "{{ freebsd_geom_list | rejectattr('name', 'match', 'cd\\d+') }}"
57+
when: guest_device_type | lower != 'rom'
58+
59+
- name: "Set fact of {{ guest_device_type }} device list on {{ vm_guest_os_distribution }}"
60+
ansible.builtin.set_fact:
61+
guest_device_list: >
62+
{{
63+
guest_device_list |
64+
union([{'name': item.name,
65+
'size': item.provider.mediasize | default(0),
66+
'model': item.provider.config.descr | default('') }])
67+
}}
68+
with_items: "{{ freebsd_device_list }}"
69+
when: freebsd_device_list | length > 0
6670

6771
- name: "Print device list in guest OS"
6872
ansible.builtin.debug: var=guest_device_list
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2025 VMware, Inc.
2+
# SPDX-License-Identifier: BSD-2-Clause
3+
---
4+
# Get the boot disk controler type on Linux
5+
# Return:
6+
# guest_boot_disk_ctrl_type: The boot disk controller type
7+
#
8+
- name: "Initialze the fact of boot disk controller type in guest OS"
9+
ansible.builtin.set_fact:
10+
guest_boot_disk_ctrl_type: "{{ new_vm | ternary(boot_disk_controller, '') }}"
11+
12+
- name: "Get boot disk controller type on existing VM"
13+
when:
14+
- not new_vm
15+
- guest_os_ansible_system == 'linux'
16+
block:
17+
- name: "Get ansible facts of system devices in guest OS"
18+
include_tasks: ../../common/get_system_info.yml
19+
vars:
20+
filter:
21+
- 'ansible_mounts'
22+
- 'ansible_devices'
23+
24+
- name: "Get boot disk partitions in guest OS"
25+
ansible.builtin.set_fact:
26+
guest_boot_disk_partitions: >-
27+
{{
28+
guest_system_info.ansible_mounts |
29+
selectattr('device', 'match', '/dev/(sd|nvme)') |
30+
selectattr('mount', 'match', '/boot|^/$') |
31+
map(attribute='device') |
32+
map('replace', '/dev/', '')
33+
}}
34+
35+
- name: "Failed to find disk partitions for boot or root file system"
36+
ansible.builtin.fail:
37+
msg: "All disk partitions are {{ guest_system_info.ansible_mounts | selectattr('device', 'match', '/dev/(sd|nvme)') }}"
38+
when: guest_boot_disk_partitions | length == 0
39+
40+
- name: "Get boot disk controller in guest OS"
41+
ansible.builtin.set_fact:
42+
guest_boot_disk_controller: >-
43+
{{
44+
guest_system_info.ansible_devices.values() |
45+
selectattr('partitions', 'contains', guest_boot_disk_partitions[0]) |
46+
map(attribute='host') | first
47+
}}
48+
49+
- name: "Set fact of boot disk controller type in guest OS"
50+
ansible.builtin.set_fact:
51+
guest_boot_disk_ctrl_type: |-
52+
{%- if guest_boot_disk_controller is search('PVSCSI') -%}paravirtual
53+
{%- elif guest_boot_disk_controller is search('(Non-Volatile memory controller)|NVMe') -%}nvme
54+
{%- elif guest_boot_disk_controller is search('SATA') -%}sata
55+
{%- elif guest_boot_disk_controller is search('LSI.*SAS') -%}lsilogicsas
56+
{%- elif guest_boot_disk_controller is search('LSI.*SCSI') -%}lsilogic
57+
{%- elif guest_boot_disk_controller is search('IDE') -%}ide
58+
{%- endif -%}
59+
60+
- name: "Check boot disk controller type in guest OS"
61+
ansible.builtin.assert:
62+
that:
63+
- guest_boot_disk_ctrl_type
64+
fail_msg: "Failed to get boot disk controller type. The boot disk controller is {{ guest_boot_disk_controller }}"
65+
success_msg: "The boot disk controller type is {{ guest_boot_disk_ctrl_type }}"
66+
67+
- name: "Display the boot disk controller type in guest OS"
68+
ansible.builtin.debug: var=guest_boot_disk_ctrl_type
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copyright 2025 VMware, Inc.
2+
# SPDX-License-Identifier: BSD-2-Clause
3+
---
4+
# Get the new disk information in guest OS
5+
# Parameter:
6+
# current_guest_disk_list: A list of disks in guest OS
7+
#
8+
- name: "Initialize the fact of new disk info"
9+
ansible.builtin.set_fact:
10+
new_guest_disk_list: []
11+
new_guest_disk_info: ""
12+
13+
- name: "Set fact of new disk list in {{ vm_guest_os_distribution }} guest OS"
14+
ansible.builtin.set_fact:
15+
new_guest_disk_list: "{{ current_guest_disk_list | selectattr('size', 'equalto', new_disk_size_bytes | string) }}"
16+
17+
- name: "Set fact of the new disk info on {{ new_disk_ctrl_state }} {{ new_disk_ctrl_type }} controller"
18+
ansible.builtin.set_fact:
19+
new_guest_disk_info: "{{ new_guest_disk_list[0] }}"
20+
when: new_guest_disk_list | length == 1
21+
22+
- name: "Print the new disk info"
23+
ansible.builtin.debug: var=new_guest_disk_info
24+
25+
- name: "Failed to get the new disk on {{ new_disk_ctrl_state }} {{ new_disk_ctrl_type }} controller"
26+
ansible.builtin.assert:
27+
that:
28+
- new_guest_disk_info
29+
- new_guest_disk_info.name is defined
30+
- new_guest_disk_info.name
31+
fail_msg: "Not found the new disk from disk list {{ current_guest_disk_list }}"
32+
success_msg: "The new disk is {{ new_guest_disk_info }}"

0 commit comments

Comments
 (0)