Skip to content

Commit

Permalink
Merge pull request autotest#5670 from smitterl/virsh_setmem
Browse files Browse the repository at this point in the history
virsh_setmem: skip dmidecode on s390x
  • Loading branch information
dzhengfy authored Jun 20, 2024
2 parents 509ff38 + 7c72d8d commit 58e8163
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 76 deletions.
1 change: 1 addition & 0 deletions libvirt/tests/cfg/memory/virsh_setmem.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
reset_vm_memory = "yes"
s390-virtio:
reset_vm_memory = "no"
use_dmidecode = "no"
vm_attrs = {'memory': 4, 'memory_unit': 'GiB', 'current_mem': 4, 'current_mem_unit': 'GiB'}
variants:
- valid_options:
Expand Down
195 changes: 119 additions & 76 deletions libvirt/tests/src/memory/virsh_setmem.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

# Using as lower capital is not the best way to do, but this is just a
# workaround to avoid changing the entire file.
logging = log.getLogger('avocado.' + __name__)
logging = log.getLogger("avocado." + __name__)


def manipulate_domain(test, vm_name, action, recover=False):
Expand All @@ -30,23 +30,27 @@ def manipulate_domain(test, vm_name, action, recover=False):
if not recover:
if action == "save":
save_option = ""
result = virsh.save(vm_name, save_file, save_option,
ignore_status=True, debug=True)
result = virsh.save(
vm_name, save_file, save_option, ignore_status=True, debug=True
)
libvirt.check_exit_status(result)
elif action == "managedsave":
managedsave_option = ""
result = virsh.managedsave(vm_name, managedsave_option,
ignore_status=True, debug=True)
result = virsh.managedsave(
vm_name, managedsave_option, ignore_status=True, debug=True
)
libvirt.check_exit_status(result)
elif action == "s3":
suspend_target = "mem"
result = virsh.dompmsuspend(vm_name, suspend_target,
ignore_status=True, debug=True)
result = virsh.dompmsuspend(
vm_name, suspend_target, ignore_status=True, debug=True
)
libvirt.check_exit_status(result)
elif action == "s4":
suspend_target = "disk"
result = virsh.dompmsuspend(vm_name, suspend_target,
ignore_status=True, debug=True)
result = virsh.dompmsuspend(
vm_name, suspend_target, ignore_status=True, debug=True
)
libvirt.check_exit_status(result)
# Wait domain state change: 'in shutdown' -> 'shut off'
utils_misc.wait_for(lambda: virsh.is_dead(vm_name), 5)
Expand Down Expand Up @@ -90,8 +94,7 @@ def get_vm_usable_mem(session):
"""
cmd = "cat /proc/meminfo"
proc_mem = session.cmd_output(cmd)
total_usable_mem = re.search(r'MemTotal:\s+(\d+)\s+[kK]B',
proc_mem).group(1)
total_usable_mem = re.search(r"MemTotal:\s+(\d+)\s+[kK]B", proc_mem).group(1)
return int(total_usable_mem)

def vm_unusable_mem(session):
Expand All @@ -101,18 +104,18 @@ def vm_unusable_mem(session):
# Get total physical memory from dmidecode
cmd = "dmidecode -t 17"
dmi_mem = session.cmd_output(cmd)
dmi_mem_size = re.findall(r'Size:\s(\d+\s+[K|M|G]B)', dmi_mem)
dmi_mem_size = re.findall(r"Size:\s(\d+\s+[K|M|G]B)", dmi_mem)
if not dmi_mem_size:
test.fail("Cannot get memory size info inside VM.")
total_physical_mem = 0
for size_info in dmi_mem_size:
mem_size = int(size_info.split()[0].strip())
mem_unit = size_info.split()[1].strip()
if mem_unit.lower() == 'kb':
if mem_unit.lower() == "kb":
total_physical_mem += mem_size
elif mem_unit.lower() == 'mb':
elif mem_unit.lower() == "mb":
total_physical_mem += mem_size * 1024
elif mem_unit.lower() == 'gb':
elif mem_unit.lower() == "gb":
total_physical_mem += mem_size * 1048576
return total_physical_mem - get_vm_usable_mem(session)

Expand Down Expand Up @@ -176,6 +179,7 @@ def cal_deviation(actual, expected):
"""
Calculate deviation of actual result and expected result
"""
logging.debug(f"(actual, expected) = ({actual}, {expected})")
numerator = float(actual)
denominator = float(expected)
if numerator > denominator:
Expand All @@ -187,39 +191,49 @@ def is_old_libvirt():
"""
Check if libvirt is old version
"""
regex = r'\s+\[--size\]\s+'
return bool(not virsh.has_command_help_match('setmem', regex))

def print_debug_stats(original_inside_mem, original_outside_mem,
test_inside_mem, test_outside_mem,
expected_outside_mem, expected_inside_mem,
delta_percentage, unusable_mem):
regex = r"\s+\[--size\]\s+"
return bool(not virsh.has_command_help_match("setmem", regex))

def print_debug_stats(
original_inside_mem,
original_outside_mem,
test_inside_mem,
test_outside_mem,
expected_outside_mem,
expected_inside_mem,
delta_percentage,
unusable_mem,
):
"""
Print debug message for test
"""
# Calculate deviation
inside_deviation = cal_deviation(test_inside_mem, expected_inside_mem)
outside_deviation = cal_deviation(test_outside_mem, expected_outside_mem)
dbgmsg = ("Unusable memory of VM : %d KiB\n"
"Original inside memory : %d KiB\n"
"Expected inside memory : %d KiB\n"
"Actual inside memory : %d KiB\n"
"Inside memory deviation : %0.2f%%\n"
"Original outside memory : %d KiB\n"
"Expected outside memory : %d KiB\n"
"Actual outside memory : %d KiB\n"
"Outside memory deviation: %0.2f%%\n"
"Acceptable deviation : %0.2f%%" % (
unusable_mem,
original_inside_mem,
expected_inside_mem,
test_inside_mem,
inside_deviation,
original_outside_mem,
expected_outside_mem,
test_outside_mem,
outside_deviation,
delta_percentage))
dbgmsg = (
"Unusable memory of VM : %d KiB\n"
"Original inside memory : %d KiB\n"
"Expected inside memory : %d KiB\n"
"Actual inside memory : %d KiB\n"
"Inside memory deviation : %0.2f%%\n"
"Original outside memory : %d KiB\n"
"Expected outside memory : %d KiB\n"
"Actual outside memory : %d KiB\n"
"Outside memory deviation: %0.2f%%\n"
"Acceptable deviation : %0.2f%%"
% (
unusable_mem,
original_inside_mem,
expected_inside_mem,
test_inside_mem,
inside_deviation,
original_outside_mem,
expected_outside_mem,
test_outside_mem,
outside_deviation,
delta_percentage,
)
)
for dbgline in dbgmsg.splitlines():
logging.debug(dbgline)

Expand All @@ -239,9 +253,11 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
vm_name = params.get("main_vm", "avocado-vt-vm1")
paused_after_start_vm = "yes" == params.get("paused_after_start_vm", "no")
manipulate_dom_before_setmem = "yes" == params.get(
"manipulate_dom_before_setmem", "no")
"manipulate_dom_before_setmem", "no"
)
manipulate_dom_after_setmem = "yes" == params.get(
"manipulate_dom_after_setmem", "no")
"manipulate_dom_after_setmem", "no"
)
manipulate_action = params.get("manipulate_action", "")
readonly = "yes" == params.get("setmem_readonly", "no")
expect_msg = params.get("setmem_err_msg")
Expand All @@ -250,6 +266,7 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
expect_xml_line = params.get("expect_xml_line")
expect_qemu_line = params.get("expect_qemu_line")
reset_vm_memory = "yes" == params.get("reset_vm_memory", "no")
use_dmidecode = "yes" == params.get("use_dmidecode", "yes")

vm = env.get_vm(vm_name)
# Back up domain XML
Expand All @@ -258,28 +275,34 @@ def print_debug_stats(original_inside_mem, original_outside_mem,

# filter out reset vm memory on s390x
if reset_vm_memory:
vm_attrs = eval(params.get('vm_attrs'))
memory_size = vm_attrs['memory']
memory_unit = vm_attrs['memory_unit']
vm_attrs = eval(params.get("vm_attrs"))
memory_size = vm_attrs["memory"]
memory_unit = vm_attrs["memory_unit"]
guest_memory = memory_base.convert_data_size(
str(memory_size) + memory_unit, dest_unit='KiB')
str(memory_size) + memory_unit, dest_unit="KiB"
)
host_free_mem = utils_memory.freememtotal()
logging.debug("The allocation memory for guest is %sKiB,"
" the total free memory of host is %sKiB.",
guest_memory, host_free_mem)
logging.debug(
"The allocation memory for guest is %sKiB,"
" the total free memory of host is %sKiB.",
guest_memory,
host_free_mem,
)
if host_free_mem < guest_memory:
test.cancel("There is not enough memory for guest.")

vmxml.setup_attrs(**vm_attrs)
vmxml.sync()

if with_packed and not libvirt_version.version_compare(6, 3, 0):
test.cancel("The virtio packed attribute is not supported in"
" current libvirt version.")
test.cancel(
"The virtio packed attribute is not supported in"
" current libvirt version."
)

vmosxml = vmxml.os
need_mkswap = False
if manipulate_action in ['s3', 's4']:
if manipulate_action in ["s3", "s4"]:
vm.destroy()
BIOS_BIN = "/usr/share/seabios/bios.bin"
if os.path.isfile(BIOS_BIN):
Expand All @@ -299,8 +322,8 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
memballoon_model = params.get("memballoon_model", "")
if memballoon_model:
vm.destroy()
vmxml.del_device('memballoon', by_tag=True)
memballoon_xml = vmxml.get_device_class('memballoon')()
vmxml.del_device("memballoon", by_tag=True)
memballoon_xml = vmxml.get_device_class("memballoon")()
memballoon_xml.model = memballoon_model
if with_packed:
memballoon_xml.driver = {"packed": driver_packed}
Expand All @@ -323,8 +346,9 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
cmd = "rmmod virtio_balloon"
s_rmmod, o_rmmod = session.cmd_status_output(cmd)
if s_rmmod != 0:
logging.error("Fail to remove module virtio_balloon in guest:\n%s",
o_rmmod)
logging.error(
"Fail to remove module virtio_balloon in guest:\n%s", o_rmmod
)
session.close()
# Get original data
domid = vm.get_id()
Expand All @@ -333,11 +357,15 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
if not vm.is_alive():
vm.start()
session = vm.wait_for_login()
if session.cmd_status('dmidecode') and not utils_package.package_install("dmidecode", session):
# if fail to install dmidecode then use memory size in vm xml
unusable_mem = int(vmxml.memory) - get_vm_usable_mem(session)
else:
if use_dmidecode:
# try make dmidecode available if not present
use_dmidecode &= 0 == session.cmd_status(
"dmidecode"
) or utils_package.package_install("dmidecode", session)
if use_dmidecode:
unusable_mem = vm_unusable_mem(session)
else:
unusable_mem = int(vmxml.memory) - get_vm_usable_mem(session)
original_outside_mem = vm.get_used_mem()
original_inside_mem = get_vm_usable_mem(session)
session.close()
Expand All @@ -356,10 +384,14 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
use_kilobytes = False

# Argument pattern is complex, build with dargs
dargs = {'flagstr': flags,
'use_kilobytes': use_kilobytes,
'uri': uri, 'ignore_status': True, "debug": True,
'readonly': readonly}
dargs = {
"flagstr": flags,
"use_kilobytes": use_kilobytes,
"uri": uri,
"ignore_status": True,
"debug": True,
"readonly": readonly,
}
dargs.update(make_domref(domarg, vm_ref, domid, vm_name, domuuid))
dargs.update(make_sizeref(sizearg, mem_ref, original_outside_mem))

Expand All @@ -378,15 +410,14 @@ def print_debug_stats(original_inside_mem, original_outside_mem,
memory_change = True
if manipulate_dom_before_setmem:
manipulate_domain(test, vm_name, manipulate_action)
if manipulate_action in ['save', 'managedsave', 's4']:
if manipulate_action in ["save", "managedsave", "s4"]:
memory_change = False

result = virsh.setmem(**dargs)
status = result.exit_status

if status is 0:
logging.info(
"Waiting %d seconds for VM memory to settle", quiesce_delay)
logging.info("Waiting %d seconds for VM memory to settle", quiesce_delay)
# It takes time for kernel to settle on new memory
# and current clean pages is not predictable. Therefore,
# extremely difficult to determine quiescence, so
Expand Down Expand Up @@ -448,11 +479,17 @@ def get_vm_mem():
# Don't care about memory comparison on error test
def verify_outside_result():
_, test_outside_mem = get_vm_mem()
return (cal_deviation(test_outside_mem, expected_outside_mem) <= delta_percentage)
return (
cal_deviation(test_outside_mem, expected_outside_mem)
<= delta_percentage
)

def verify_inside_result():
test_inside_mem, _ = get_vm_mem()
return (cal_deviation(test_inside_mem, expected_inside_mem) <= delta_percentage)
return (
cal_deviation(test_inside_mem, expected_inside_mem)
<= delta_percentage
)

msg = "test conditions not met: "
error_flag = 0
Expand All @@ -467,10 +504,16 @@ def verify_inside_result():
msg += "Inside memory deviated. "

test_inside_mem, test_outside_mem = get_vm_mem()
print_debug_stats(original_inside_mem, original_outside_mem,
test_inside_mem, test_outside_mem,
expected_outside_mem, expected_inside_mem,
delta_percentage, unusable_mem)
print_debug_stats(
original_inside_mem,
original_outside_mem,
test_inside_mem,
test_outside_mem,
expected_outside_mem,
expected_inside_mem,
delta_percentage,
unusable_mem,
)
if error_flag:
test.fail(msg)
elif not status_error and old_libvirt_fail:
Expand All @@ -484,7 +527,7 @@ def verify_inside_result():
if status is 0:
test.fail("Error test did not result in an error")
if expect_msg:
libvirt.check_result(result, expect_msg.split(';'))
libvirt.check_result(result, expect_msg.split(";"))
finally:
if need_mkswap:
vm.cleanup_swap()
Expand Down

0 comments on commit 58e8163

Please sign in to comment.