Change-Id: I4a6fcad56c3e97995440262a3bdc0930408eaf68 Signed-off-by: Pawel Kaminski <pawelx.kaminski@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/703 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
1020 lines
43 KiB
Python
1020 lines
43 KiB
Python
import io
|
|
import math
|
|
import time
|
|
import sys
|
|
import random
|
|
import signal
|
|
import subprocess
|
|
import pprint
|
|
import socket
|
|
import threading
|
|
import os
|
|
|
|
from errno import ESRCH
|
|
from os import kill, path, unlink, path, listdir, remove
|
|
from rpc_commands_lib import Commands_Rpc
|
|
from time import sleep
|
|
from uuid import uuid4
|
|
|
|
|
|
MEGABYTE = 1024 * 1024
|
|
|
|
|
|
current_fio_pid = -1
|
|
|
|
# ## Objective
|
|
# The purpose of these tests is to verify the possibility of using lvol configuration in SPDK.
|
|
#
|
|
# ## Methodology
|
|
# Configuration in test is to be done using example stub application.
|
|
# All management is done using RPC calls, including logical volumes management.
|
|
# All tests are performed using malloc backends.
|
|
# One exception to malloc backends are tests for logical volume
|
|
# tasting - these require persistent merory like NVMe backend.
|
|
#
|
|
# Tests will be executed as scenarios - sets of smaller test step
|
|
# in which return codes from RPC calls is validated.
|
|
# Some configuration calls may also be validated by use of
|
|
# "get_*" RPC calls, which provide additional information for verifying
|
|
# results.
|
|
#
|
|
# Tests with thin provisioned lvol bdevs, snapshots and clones are using nbd devices.
|
|
# Before writing/reading to lvol bdev, bdev is installed with rpc nbd_start_disk.
|
|
# After finishing writing/reading, rpc nbd_stop_disk is used.
|
|
|
|
|
|
def is_process_alive(pid):
|
|
try:
|
|
os.kill(pid, 0)
|
|
except Exception as e:
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
def get_fio_cmd(nbd_disk, offset, size, rw, pattern, extra_params=""):
|
|
fio_template = "fio --name=fio_test --filename=%(file)s --offset=%(offset)s --size=%(size)s"\
|
|
" --rw=%(rw)s --direct=1 %(extra_params)s %(pattern)s"
|
|
pattern_template = ""
|
|
if pattern:
|
|
pattern_template = "--do_verify=1 --verify=pattern --verify_pattern=%s"\
|
|
" --verify_state_save=0" % pattern
|
|
fio_cmd = fio_template % {"file": nbd_disk, "offset": offset, "size": size,
|
|
"rw": rw, "pattern": pattern_template,
|
|
"extra_params": extra_params}
|
|
|
|
return fio_cmd
|
|
|
|
|
|
def run_fio(fio_cmd, expected_ret_value):
|
|
global current_fio_pid
|
|
try:
|
|
proc = subprocess.Popen([fio_cmd], shell=True)
|
|
current_fio_pid = proc.pid
|
|
proc.wait()
|
|
rv = proc.returncode
|
|
except Exception as e:
|
|
print("ERROR: Fio test ended with unexpected exception.")
|
|
rv = 1
|
|
if expected_ret_value == rv:
|
|
return 0
|
|
|
|
if rv == 0:
|
|
print("ERROR: Fio test ended with unexpected success")
|
|
else:
|
|
print("ERROR: Fio test ended with unexpected failure")
|
|
return 1
|
|
|
|
|
|
class FioThread(threading.Thread):
|
|
def __init__(self, nbd_disk, offset, size, rw, pattern, expected_ret_value,
|
|
extra_params=""):
|
|
super(FioThread, self).__init__()
|
|
self.fio_cmd = get_fio_cmd(nbd_disk, offset, size, rw, pattern,
|
|
extra_params=extra_params)
|
|
self.rv = 1
|
|
self.expected_ret_value = expected_ret_value
|
|
|
|
def run(self):
|
|
print("INFO: Starting fio")
|
|
self.rv = run_fio(self.fio_cmd, self.expected_ret_value)
|
|
print("INFO: Fio test finished")
|
|
|
|
|
|
def test_counter():
|
|
'''
|
|
:return: the number of tests
|
|
'''
|
|
return ['test_case' in i for i in dir(TestCases)].count(True)
|
|
|
|
|
|
def case_message(func):
|
|
def inner(*args, **kwargs):
|
|
test_name = {
|
|
# bdev_lvol_delete_lvstore - positive tests
|
|
254: 'destroy_after_bdev_lvol_resize_positive',
|
|
255: 'delete_lvol_store_persistent_positive',
|
|
551: 'delete_lvol_bdev',
|
|
552: 'bdev_lvol_delete_lvstore_with_clones',
|
|
553: 'unregister_lvol_bdev',
|
|
602: 'bdev_lvol_create_lvstore_with_all_clear_methods',
|
|
# Provisioning
|
|
651: 'thin_provisioning_read_empty_bdev',
|
|
652: 'thin_provisioning_data_integrity_test',
|
|
653: 'thin_provisioning_resize',
|
|
654: 'thin_overprovisioning',
|
|
655: 'thin_provisioning_filling_disks_less_than_lvs_size',
|
|
# logical volume clear_method test
|
|
850: 'clear_method_none',
|
|
851: 'clear_method_unmap',
|
|
}
|
|
num = int(func.__name__.strip('test_case')[:])
|
|
print("************************************")
|
|
print("START TEST CASE {name}".format(name=test_name[num]))
|
|
print("************************************")
|
|
fail_count = func(*args, **kwargs)
|
|
print("************************************")
|
|
if not fail_count:
|
|
print("END TEST CASE {name} PASS".format(name=test_name[num]))
|
|
else:
|
|
print("END TEST CASE {name} FAIL".format(name=test_name[num]))
|
|
print("************************************")
|
|
return fail_count
|
|
return inner
|
|
|
|
|
|
class TestCases(object):
|
|
|
|
def __init__(self, rpc_py, total_size, block_size, base_dir_path, app_path):
|
|
self.c = Commands_Rpc(rpc_py)
|
|
self.total_size = total_size
|
|
self.block_size = block_size
|
|
self.cluster_size = None
|
|
self.path = base_dir_path
|
|
self.app_path = app_path
|
|
self.lvs_name = "lvs_test"
|
|
self.lbd_name = "lbd_test"
|
|
self.vhost_config_path = path.join(path.dirname(sys.argv[0]), 'vhost.conf')
|
|
|
|
def _gen_lvs_uuid(self):
|
|
return str(uuid4())
|
|
|
|
def _gen_lvb_uuid(self):
|
|
return "_".join([str(uuid4()), str(random.randrange(9999999999))])
|
|
|
|
def compare_two_disks(self, disk1, disk2, expected_ret_value):
|
|
cmp_cmd = "cmp %s %s" % (disk1, disk2)
|
|
try:
|
|
process = subprocess.check_output(cmp_cmd, stderr=subprocess.STDOUT, shell=True)
|
|
rv = 0
|
|
except subprocess.CalledProcessError as ex:
|
|
rv = 1
|
|
except Exception as e:
|
|
print("ERROR: Cmp ended with unexpected exception.")
|
|
rv = 1
|
|
|
|
if expected_ret_value == rv:
|
|
return 0
|
|
elif rv == 0:
|
|
print("ERROR: Cmp ended with unexpected success")
|
|
else:
|
|
print("ERROR: Cmp ended with unexpected failure")
|
|
|
|
return 1
|
|
|
|
def run_fio_test(self, nbd_disk, offset, size, rw, pattern, expected_ret_value=0):
|
|
fio_cmd = get_fio_cmd(nbd_disk, offset, size, rw, pattern)
|
|
return run_fio(fio_cmd, expected_ret_value)
|
|
|
|
def _stop_vhost(self, pid_path):
|
|
with io.open(pid_path, 'r') as vhost_pid:
|
|
pid = int(vhost_pid.readline())
|
|
if pid:
|
|
try:
|
|
kill(pid, signal.SIGTERM)
|
|
for count in range(30):
|
|
sleep(1)
|
|
kill(pid, 0)
|
|
except OSError as err:
|
|
if err.errno == ESRCH:
|
|
pass
|
|
else:
|
|
return 1
|
|
else:
|
|
return 1
|
|
else:
|
|
return 1
|
|
return 0
|
|
|
|
def _start_vhost(self, vhost_path, pid_path):
|
|
subprocess.call("{app} -f "
|
|
"{pid} &".format(app=vhost_path,
|
|
pid=pid_path), shell=True)
|
|
for timeo in range(10):
|
|
if timeo == 9:
|
|
print("ERROR: Timeout on waiting for app start")
|
|
return 1
|
|
if not path.exists(pid_path):
|
|
print("Info: Waiting for PID file...")
|
|
sleep(1)
|
|
continue
|
|
else:
|
|
break
|
|
|
|
# Wait for RPC to open
|
|
sock = socket.socket(socket.AF_UNIX)
|
|
for timeo in range(30):
|
|
if timeo == 29:
|
|
print("ERROR: Timeout on waiting for RPC start")
|
|
return 1
|
|
try:
|
|
sock.connect("/var/tmp/spdk.sock")
|
|
break
|
|
except socket.error as e:
|
|
print("Info: Waiting for RPC Unix socket...")
|
|
sleep(1)
|
|
continue
|
|
else:
|
|
sock.close()
|
|
break
|
|
|
|
with io.open(pid_path, 'r') as vhost_pid:
|
|
pid = int(vhost_pid.readline())
|
|
if not pid:
|
|
return 1
|
|
return 0
|
|
|
|
def get_lvs_size(self, lvs_name="lvs_test"):
|
|
lvs = self.c.bdev_lvol_get_lvstores(lvs_name)[0]
|
|
return int(int(lvs['free_clusters'] * lvs['cluster_size']) / MEGABYTE)
|
|
|
|
def get_lvs_divided_size(self, split_num, lvs_name="lvs_test"):
|
|
# Actual size of lvol bdevs on creation is rounded up to multiple of cluster size.
|
|
# In order to avoid over provisioning, this function returns
|
|
# lvol store size in MB divided by split_num - rounded down to multiple of cluster size."
|
|
lvs = self.c.bdev_lvol_get_lvstores(lvs_name)[0]
|
|
return int(int(lvs['free_clusters'] / split_num) * lvs['cluster_size'] / MEGABYTE)
|
|
|
|
def get_lvs_cluster_size(self, lvs_name="lvs_test"):
|
|
lvs = self.c.bdev_lvol_get_lvstores(lvs_name)[0]
|
|
return int(int(lvs['cluster_size']) / MEGABYTE)
|
|
|
|
@case_message
|
|
def test_case254(self):
|
|
"""
|
|
destroy_resize_logical_volume_positive
|
|
|
|
Positive test for destroying a logical_volume after resizing.
|
|
Call bdev_lvol_delete_lvstore with correct logical_volumes name.
|
|
"""
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store on create malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name)
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
size = self.get_lvs_divided_size(4)
|
|
# bdev_lvol_create on correct lvs_uuid and size is
|
|
# equal to one quarter of size malloc bdev
|
|
uuid_bdev = self.c.bdev_lvol_create(uuid_store,
|
|
self.lbd_name,
|
|
size)
|
|
# check size of the lvol bdev
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, size)
|
|
sz = size + 4
|
|
# Resize_lvol_bdev on correct lvs_uuid and size is
|
|
# equal to one quarter of size malloc bdev plus 4 MB
|
|
self.c.bdev_lvol_resize(uuid_bdev, sz)
|
|
# check size of the lvol bdev by command RPC : bdev_get_bdevs
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, sz)
|
|
# Resize_lvol_bdev on correct lvs_uuid and size is
|
|
# equal half of size malloc bdev
|
|
sz = size * 2
|
|
self.c.bdev_lvol_resize(uuid_bdev, sz)
|
|
# check size of the lvol bdev by command RPC : bdev_get_bdevs
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, sz)
|
|
# Resize_lvol_bdev on correct lvs_uuid and size is
|
|
# equal to three quarters of size malloc bdev
|
|
sz = size * 3
|
|
self.c.bdev_lvol_resize(uuid_bdev, sz)
|
|
# check size of the lvol bdev by command RPC : bdev_get_bdevs
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, sz)
|
|
# Resize_lvol_bdev on correct lvs_uuid and size is
|
|
# equal to size if malloc bdev minus 4 MB
|
|
sz = (size * 4) - 4
|
|
self.c.bdev_lvol_resize(uuid_bdev, sz)
|
|
# check size of the lvol bdev by command RPC : bdev_get_bdevs
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, sz)
|
|
# Resize_lvol_bdev on the correct lvs_uuid and size is equal 0 MiB
|
|
sz = 0
|
|
self.c.bdev_lvol_resize(uuid_bdev, sz)
|
|
# check size of the lvol bdev by command RPC : bdev_get_bdevs
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, sz)
|
|
|
|
# Destroy lvol store
|
|
self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
if self.c.check_bdev_lvol_get_lvstores("", "", "") == 1:
|
|
fail_count += 1
|
|
self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - lvol bdev should change size after resize operations
|
|
# - calls successful, return code = 0
|
|
# - no other operation fails
|
|
# - bdev_lvol_get_lvstores: response should be of no value after destroyed lvol store
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case255(self):
|
|
"""
|
|
delete_lvol_store_persistent_positive
|
|
|
|
Positive test for removing lvol store persistently
|
|
"""
|
|
base_path = path.dirname(sys.argv[0])
|
|
base_name = "aio_bdev0"
|
|
aio_bdev0 = path.join(base_path, "aio_bdev_0")
|
|
# Construct aio bdev
|
|
self.c.bdev_aio_create(aio_bdev0, base_name, 4096)
|
|
# Create lvol store on created aio bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
# Destroy lvol store
|
|
if self.c.bdev_lvol_delete_lvstore(self.lvs_name) != 0:
|
|
fail_count += 1
|
|
|
|
# Delete aio bdev
|
|
self.c.bdev_aio_delete(base_name)
|
|
# Create aio bdev on the same file
|
|
self.c.bdev_aio_create(aio_bdev0, base_name, 4096)
|
|
# Wait 1 second to allow time for lvolstore tasting
|
|
sleep(1)
|
|
|
|
# check if destroyed lvol store does not exist on aio bdev
|
|
ret_value = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
if ret_value == 0:
|
|
fail_count += 1
|
|
self.c.bdev_aio_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - bdev_lvol_get_lvstores should not report any existsing lvol stores in configuration
|
|
# after deleting and adding NVMe bdev
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case551(self):
|
|
"""
|
|
bdev_lvol_delete_ordering
|
|
|
|
Test for destroying lvol bdevs in particular order.
|
|
Check destroying wrong one is not possible and returns error.
|
|
"""
|
|
|
|
fail_count = 0
|
|
snapshot_name = "snapshot"
|
|
clone_name = "clone"
|
|
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct_lvol_store on correct, exisitng malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name,
|
|
self.cluster_size)
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores()
|
|
size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
|
|
|
|
# Construct thin provisioned lvol bdev
|
|
uuid_bdev0 = self.c.bdev_lvol_create(uuid_store,
|
|
self.lbd_name, size, thin=True)
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
|
|
|
|
# Create snapshot of thin provisioned lvol bdev
|
|
fail_count += self.c.bdev_lvol_snapshot(lvol_bdev['name'], snapshot_name)
|
|
snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
|
|
|
|
# Create clone of snapshot and check if it ends with success
|
|
fail_count += self.c.bdev_lvol_clone(self.lvs_name + "/" + snapshot_name, clone_name)
|
|
clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
|
|
|
|
# Try to destroy snapshot with clones and check if it fails
|
|
ret_value = self.c.bdev_lvol_delete(snapshot_bdev['name'])
|
|
if ret_value == 0:
|
|
print("ERROR: Delete snapshot should fail but didn't")
|
|
fail_count += 1
|
|
|
|
# Destroy clone and then snapshot
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev['name'])
|
|
fail_count += self.c.bdev_lvol_delete(clone_bdev['name'])
|
|
fail_count += self.c.bdev_lvol_delete(snapshot_bdev['name'])
|
|
|
|
# Destroy lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
|
|
# Check response bdev_lvol_get_lvstores command
|
|
if self.c.check_bdev_lvol_get_lvstores("", "", "") == 1:
|
|
fail_count += 1
|
|
|
|
# Delete malloc bdev
|
|
self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - bdev_lvol_get_lvstores: response should be of no value after destroyed lvol store
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case552(self):
|
|
"""
|
|
bdev_lvol_delete_lvstore_with_clones
|
|
|
|
Test for destroying lvol store with clones present,
|
|
without removing them first.
|
|
"""
|
|
|
|
fail_count = 0
|
|
snapshot_name = "snapshot"
|
|
snapshot_name2 = "snapshot2"
|
|
clone_name = "clone"
|
|
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct_lvol_store on correct, exisitng malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name,
|
|
self.cluster_size)
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores()
|
|
size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
|
|
|
|
# Create lvol bdev, snapshot it, then clone it and then snapshot the clone
|
|
uuid_bdev0 = self.c.bdev_lvol_create(uuid_store, self.lbd_name, size, thin=True)
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
|
|
|
|
fail_count += self.c.bdev_lvol_snapshot(lvol_bdev['name'], snapshot_name)
|
|
snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
|
|
|
|
fail_count += self.c.bdev_lvol_clone(self.lvs_name + "/" + snapshot_name, clone_name)
|
|
clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
|
|
|
|
fail_count += self.c.bdev_lvol_snapshot(clone_bdev['name'], snapshot_name2)
|
|
snapshot_bdev2 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name2)
|
|
|
|
# Try to destroy snapshot with 2 clones and check if it fails
|
|
ret_value = self.c.bdev_lvol_delete(snapshot_bdev['name'])
|
|
if ret_value == 0:
|
|
print("ERROR: Delete snapshot should fail but didn't")
|
|
fail_count += 1
|
|
|
|
# Destroy lvol store without deleting lvol bdevs
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
|
|
# Check response bdev_lvol_get_lvstores command
|
|
if self.c.check_bdev_lvol_get_lvstores("", "", "") == 1:
|
|
fail_count += 1
|
|
|
|
# Delete malloc bdev
|
|
self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - bdev_lvol_get_lvstores: response should be of no value after destroyed lvol store
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case553(self):
|
|
"""
|
|
unregister_lvol_bdev
|
|
|
|
Test for unregistering the lvol bdevs.
|
|
Removing malloc bdev under an lvol store triggers unregister of
|
|
all lvol bdevs. Verify it with clones present.
|
|
"""
|
|
|
|
fail_count = 0
|
|
snapshot_name = "snapshot"
|
|
snapshot_name2 = "snapshot2"
|
|
clone_name = "clone"
|
|
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct_lvol_store on correct, exisitng malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name,
|
|
self.cluster_size)
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores()
|
|
size = int(int(lvs[0]['free_clusters'] * lvs[0]['cluster_size']) / 4 / MEGABYTE)
|
|
|
|
# Create lvol bdev, snapshot it, then clone it and then snapshot the clone
|
|
uuid_bdev0 = self.c.bdev_lvol_create(uuid_store, self.lbd_name, size, thin=True)
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev0)
|
|
|
|
fail_count += self.c.bdev_lvol_snapshot(lvol_bdev['name'], snapshot_name)
|
|
snapshot_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name)
|
|
|
|
fail_count += self.c.bdev_lvol_clone(self.lvs_name + "/" + snapshot_name, clone_name)
|
|
clone_bdev = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + clone_name)
|
|
|
|
fail_count += self.c.bdev_lvol_snapshot(clone_bdev['name'], snapshot_name2)
|
|
snapshot_bdev2 = self.c.get_lvol_bdev_with_name(self.lvs_name + "/" + snapshot_name2)
|
|
|
|
# Delete malloc bdev
|
|
self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Check response bdev_lvol_get_lvstores command
|
|
if self.c.check_bdev_lvol_get_lvstores("", "", "") == 1:
|
|
fail_count += 1
|
|
|
|
# Expected result:
|
|
# - bdev_lvol_get_lvstores: response should be of no value after destroyed lvol store
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case602(self):
|
|
"""
|
|
bdev_lvol_create_lvstore_with_all_clear_methods
|
|
|
|
Call bdev_lvol_create_lvstore with all options for clear methods.
|
|
"""
|
|
fail_count = 0
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store with clear method 'none'
|
|
lvol_uuid = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name, clear_method="none")
|
|
fail_count += self.c.check_bdev_lvol_get_lvstores(base_name, lvol_uuid)
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store with clear method 'unmap'
|
|
lvol_uuid = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name, clear_method="unmap")
|
|
fail_count += self.c.check_bdev_lvol_get_lvstores(base_name, lvol_uuid)
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store with clear method 'write_zeroes'
|
|
lvol_uuid = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name, clear_method="write_zeroes")
|
|
fail_count += self.c.check_bdev_lvol_get_lvstores(base_name, lvol_uuid)
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - construct lvol store return code != 0
|
|
# - Error code response printed to stdout
|
|
return fail_count
|
|
|
|
def test_case651(self):
|
|
"""
|
|
thin_provisioning_read_empty_bdev
|
|
|
|
Check if we can create thin provisioned bdev on empty lvol store
|
|
and check if we can read from this device and it returns zeroes.
|
|
"""
|
|
# create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# construct lvol store on malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
free_clusters_start = int(lvs['free_clusters'])
|
|
lbd_name0 = self.lbd_name + str("0")
|
|
lbd_name1 = self.lbd_name + str("1")
|
|
# calculate bdev size in megabytes
|
|
bdev_size = self.get_lvs_size()
|
|
# create thick provisioned lvol bvdev with size equal to lvol store
|
|
bdev_name0 = self.c.bdev_lvol_create(uuid_store, lbd_name0,
|
|
bdev_size, thin=False)
|
|
# create thin provisioned lvol bdev with the same size
|
|
bdev_name1 = self.c.bdev_lvol_create(uuid_store, lbd_name1,
|
|
bdev_size, thin=True)
|
|
lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
|
|
lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
|
|
nbd_name0 = "/dev/nbd0"
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev0['name'], nbd_name0)
|
|
nbd_name1 = "/dev/nbd1"
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev1['name'], nbd_name1)
|
|
|
|
size = bdev_size * MEGABYTE
|
|
# fill the whole thick provisioned lvol bdev
|
|
fail_count += self.run_fio_test(nbd_name0, 0, size, "write", False)
|
|
|
|
size = bdev_size * MEGABYTE
|
|
# perform read operations on thin provisioned lvol bdev
|
|
# and check if they return zeroes
|
|
fail_count += self.run_fio_test(nbd_name1, 0, size, "read", "0x00")
|
|
|
|
fail_count += self.c.nbd_stop_disk(nbd_name0)
|
|
fail_count += self.c.nbd_stop_disk(nbd_name1)
|
|
# destroy thin provisioned lvol bdev
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev0['name'])
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev1['name'])
|
|
# destroy lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
# destroy malloc bdev
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case652(self):
|
|
"""
|
|
thin_provisioning_data_integrity_test
|
|
|
|
Check if data written to thin provisioned lvol bdev
|
|
were properly written (fio test with verification).
|
|
"""
|
|
# create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# construct lvol store on malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
free_clusters_start = int(lvs['free_clusters'])
|
|
bdev_size = self.get_lvs_size()
|
|
# construct thin provisioned lvol bdev with size equal to lvol store
|
|
bdev_name = self.c.bdev_lvol_create(uuid_store, self.lbd_name,
|
|
bdev_size, thin=True)
|
|
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(bdev_name)
|
|
nbd_name = "/dev/nbd0"
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev['name'], nbd_name)
|
|
size = bdev_size * MEGABYTE
|
|
# on the whole lvol bdev perform write operation with verification
|
|
fail_count += self.run_fio_test(nbd_name, 0, size, "write", "0xcc")
|
|
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
# destroy thin provisioned lvol bdev
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev['name'])
|
|
# destroy lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
# destroy malloc bdev
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - verification ends with success
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case653(self):
|
|
"""
|
|
thin_provisioning_resize
|
|
|
|
Check thin provisioned bdev resize.
|
|
"""
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store on malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
# Construct thin provisioned lvol bdevs on created lvol store
|
|
# with size equal to 50% of lvol store
|
|
size = self.get_lvs_divided_size(2)
|
|
uuid_bdev = self.c.bdev_lvol_create(uuid_store,
|
|
self.lbd_name, size, thin=True)
|
|
fail_count += self.c.check_bdev_get_bdevs_methods(uuid_bdev, size)
|
|
# Fill all free space of lvol bdev with data
|
|
nbd_name = "/dev/nbd0"
|
|
fail_count += self.c.nbd_start_disk(uuid_bdev, nbd_name)
|
|
fail_count += self.run_fio_test(nbd_name, 0, size*MEGABYTE, "write", "0xcc", 0)
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
# Save number of free clusters for lvs
|
|
lvs = self.c.bdev_lvol_get_lvstores()[0]
|
|
free_clusters_start = int(lvs['free_clusters'])
|
|
# Resize bdev to full size of lvs
|
|
full_size = int(lvs['total_data_clusters'] * lvs['cluster_size'] / MEGABYTE)
|
|
fail_count += self.c.bdev_lvol_resize(uuid_bdev, full_size)
|
|
# Check if bdev size changed (total_data_clusters*cluster_size
|
|
# equals to num_blocks*block_size)
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(uuid_bdev)
|
|
lbd_size = int(lvol_bdev['num_blocks'] * lvol_bdev['block_size'] / MEGABYTE)
|
|
if full_size != lbd_size:
|
|
fail_count += 1
|
|
# Check if free_clusters on lvs remain unaffected
|
|
lvs = self.c.bdev_lvol_get_lvstores()[0]
|
|
free_clusters_resize = int(lvs['free_clusters'])
|
|
if free_clusters_start != free_clusters_resize:
|
|
fail_count += 1
|
|
# Perform write operation with verification
|
|
# to newly created free space of lvol bdev
|
|
nbd_name = "/dev/nbd0"
|
|
fail_count += self.c.nbd_start_disk(uuid_bdev, nbd_name)
|
|
fail_count += self.run_fio_test(nbd_name, int(lbd_size * MEGABYTE / 2),
|
|
int(lbd_size * MEGABYTE / 2), "write", "0xcc", 0)
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
# Check if free clusters on lvs equals to zero
|
|
lvs = self.c.bdev_lvol_get_lvstores()[0]
|
|
if int(lvs['free_clusters']) != 0:
|
|
fail_count += 1
|
|
# Resize bdev to 25% of lvs and check if it ended with success
|
|
size = self.get_lvs_divided_size(4)
|
|
fail_count += self.c.bdev_lvol_resize(uuid_bdev, size)
|
|
# Check free clusters on lvs
|
|
lvs = self.c.bdev_lvol_get_lvstores()[0]
|
|
free_clusters_resize2 = int(lvs['free_clusters'])
|
|
free_clusters_expected = int((full_size - size) * MEGABYTE / lvs['cluster_size'])
|
|
if free_clusters_expected != free_clusters_resize2:
|
|
fail_count += 1
|
|
|
|
self.c.bdev_lvol_delete(uuid_bdev)
|
|
self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case654(self):
|
|
"""
|
|
thin_overprovisioning
|
|
|
|
Create two thin provisioned lvol bdevs with max size
|
|
and check if writting more than total size of lvol store
|
|
will cause failures.
|
|
"""
|
|
# create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# construct lvol store on malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
free_clusters_start = int(lvs['free_clusters'])
|
|
lbd_name0 = self.lbd_name + str("0")
|
|
lbd_name1 = self.lbd_name + str("1")
|
|
bdev_size = self.get_lvs_size()
|
|
# construct two thin provisioned lvol bdevs on created lvol store
|
|
# with size equals to free lvs size
|
|
bdev_name0 = self.c.bdev_lvol_create(uuid_store, lbd_name0,
|
|
bdev_size, thin=True)
|
|
bdev_name1 = self.c.bdev_lvol_create(uuid_store, lbd_name1,
|
|
bdev_size, thin=True)
|
|
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
free_clusters_create_lvol = int(lvs['free_clusters'])
|
|
if free_clusters_start != free_clusters_create_lvol:
|
|
fail_count += 1
|
|
lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
|
|
lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
|
|
|
|
nbd_name0 = "/dev/nbd0"
|
|
nbd_name1 = "/dev/nbd1"
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev0['name'], nbd_name0)
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev1['name'], nbd_name1)
|
|
|
|
size = "75%"
|
|
# fill first bdev to 75% of its space with specific pattern
|
|
fail_count += self.run_fio_test(nbd_name0, 0, size, "write", "0xcc")
|
|
|
|
size = "75%"
|
|
# fill second bdev up to 75% of its space
|
|
# check that error message occured while filling second bdev with data
|
|
fail_count += self.run_fio_test(nbd_name1, 0, size, "write", "0xee",
|
|
expected_ret_value=1)
|
|
|
|
size = "75%"
|
|
# check if data on first disk stayed unchanged
|
|
fail_count += self.run_fio_test(nbd_name0, 0, size, "read", "0xcc")
|
|
|
|
size = "25%"
|
|
offset = "75%"
|
|
fail_count += self.run_fio_test(nbd_name0, offset, size, "read", "0x00")
|
|
|
|
fail_count += self.c.nbd_stop_disk(nbd_name0)
|
|
fail_count += self.c.nbd_stop_disk(nbd_name1)
|
|
# destroy thin provisioned lvol bdev
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev0['name'])
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev1['name'])
|
|
# destroy lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
# destroy malloc bdev
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case655(self):
|
|
"""
|
|
thin_provisioning_filling_disks_less_than_lvs_size
|
|
|
|
Check if writing to two thin provisioned lvol bdevs
|
|
less than total size of lvol store will end with success
|
|
"""
|
|
# create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# construct lvol store on malloc bdev
|
|
uuid_store = self.c.bdev_lvol_create_lvstore(base_name, self.lvs_name)
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, uuid_store,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
free_clusters_start = int(lvs['free_clusters'])
|
|
lbd_name0 = self.lbd_name + str("0")
|
|
lbd_name1 = self.lbd_name + str("1")
|
|
lvs_size = self.get_lvs_size()
|
|
bdev_size = int(lvs_size * 0.7)
|
|
# construct two thin provisioned lvol bdevs on created lvol store
|
|
# with size equal to 70% of lvs size
|
|
bdev_name0 = self.c.bdev_lvol_create(uuid_store, lbd_name0,
|
|
bdev_size, thin=True)
|
|
bdev_name1 = self.c.bdev_lvol_create(uuid_store, lbd_name1,
|
|
bdev_size, thin=True)
|
|
|
|
lvol_bdev0 = self.c.get_lvol_bdev_with_name(bdev_name0)
|
|
lvol_bdev1 = self.c.get_lvol_bdev_with_name(bdev_name1)
|
|
# check if bdevs are available and size of every disk is equal to 70% of lvs size
|
|
nbd_name0 = "/dev/nbd0"
|
|
nbd_name1 = "/dev/nbd1"
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev0['name'], nbd_name0)
|
|
fail_count += self.c.nbd_start_disk(lvol_bdev1['name'], nbd_name1)
|
|
size = int(int(lvol_bdev0['num_blocks']) * int(lvol_bdev0['block_size']) * 0.7)
|
|
# fill first disk with 70% of its size
|
|
# check if operation didn't fail
|
|
fail_count += self.run_fio_test(nbd_name0, 0, size, "write", "0xcc")
|
|
size = int(int(lvol_bdev1['num_blocks']) * int(lvol_bdev1['block_size']) * 0.7)
|
|
# fill second disk also with 70% of its size
|
|
# check if operation didn't fail
|
|
fail_count += self.run_fio_test(nbd_name1, 0, size, "write", "0xee")
|
|
|
|
fail_count += self.c.nbd_stop_disk(nbd_name0)
|
|
fail_count += self.c.nbd_stop_disk(nbd_name1)
|
|
# destroy thin provisioned lvol bdevs
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev0['name'])
|
|
fail_count += self.c.bdev_lvol_delete(lvol_bdev1['name'])
|
|
# destroy lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(uuid_store)
|
|
# destroy malloc bdev
|
|
fail_count += self.c.bdev_malloc_delete(base_name)
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case850(self):
|
|
""""
|
|
Clear_method
|
|
|
|
Test for clear_method equals to none
|
|
"""
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
# Construct lvol store on created malloc bddev
|
|
lvs_uuid = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name)
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, lvs_uuid,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
# Construct lvol bdev on lvol store
|
|
lbd_size = int(lvs['cluster_size'] / MEGABYTE)
|
|
bdev_uuid = self.c.bdev_lvol_create(lvs_uuid,
|
|
self.lbd_name,
|
|
lbd_size,
|
|
clear_method='none')
|
|
lvol_bdev = self.c.get_lvol_bdev_with_name(bdev_uuid)
|
|
|
|
nbd_name = "/dev/nbd0"
|
|
fail_count += self.c.nbd_start_disk(bdev_uuid, nbd_name)
|
|
# Write pattern to lvol bdev starting from offset 0.
|
|
fail_count += self.run_fio_test(nbd_name, 0, lvs['cluster_size'],
|
|
"write", "0xdd")
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
|
|
# Delete lvol bdev
|
|
fail_count += self.c.bdev_lvol_delete(bdev_uuid)
|
|
|
|
# Delete lvol store. We need to do this so that we can attach the underlying malloc
|
|
# bdev to nbd to examine its contents.
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(lvs_uuid)
|
|
|
|
fail_count += self.c.nbd_start_disk(base_name, nbd_name)
|
|
metadata_pages = 1 + lvs['total_data_clusters'] + (math.ceil(5 + math.ceil(lvs['total_data_clusters'] / 8) / 4096)) * 3
|
|
last_metadata_lba = int(metadata_pages * 4096 / self.block_size)
|
|
offset_metadata_end = int(last_metadata_lba * self.block_size)
|
|
last_cluster_of_metadata = math.ceil(metadata_pages / lvs['cluster_size'] / 4096)
|
|
offset = last_cluster_of_metadata * lvs['cluster_size']
|
|
size_metadata_end = offset - offset_metadata_end
|
|
|
|
# Check if data on area between end of metadata
|
|
# and first cluster of lvol bdev remained unchaged
|
|
fail_count += self.run_fio_test("/dev/nbd0", offset_metadata_end,
|
|
size_metadata_end, "read", "0x00")
|
|
# Check if data on first lvol bdevs remains unchanged.
|
|
fail_count += self.run_fio_test("/dev/nbd0", offset, lvs['cluster_size'], "read", "0xdd")
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
|
|
self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - get_bdevs: no change
|
|
# - no other operation fails
|
|
return fail_count
|
|
|
|
@case_message
|
|
def test_case851(self):
|
|
""""
|
|
Clear_method
|
|
|
|
Test lvol bdev with clear_method equals to unmap
|
|
"""
|
|
# Create malloc bdev
|
|
base_name = self.c.bdev_malloc_create(self.total_size,
|
|
self.block_size)
|
|
|
|
nbd_name = "/dev/nbd0"
|
|
fail_count = self.c.nbd_start_disk(base_name, nbd_name)
|
|
|
|
# Write data to malloc bdev starting from offset 0.
|
|
fail_count += self.run_fio_test(nbd_name, 0, self.total_size * MEGABYTE,
|
|
"write", "0xdd")
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
|
|
# Construct lvol store on created malloc bddev
|
|
lvs_uuid = self.c.bdev_lvol_create_lvstore(base_name,
|
|
self.lvs_name,
|
|
clear_method='none')
|
|
# Check correct uuid values in response bdev_lvol_get_lvstores command
|
|
fail_count = self.c.check_bdev_lvol_get_lvstores(base_name, lvs_uuid,
|
|
self.cluster_size)
|
|
lvs = self.c.bdev_lvol_get_lvstores(self.lvs_name)[0]
|
|
|
|
# Construct lvol bdev on lvol store
|
|
lbd_size = int(lvs['cluster_size'] / MEGABYTE)
|
|
bdev_uuid = self.c.bdev_lvol_create(lvs_uuid,
|
|
self.lbd_name,
|
|
lbd_size,
|
|
clear_method='unmap')
|
|
# Check that data on lvol bdev remains unchanged
|
|
fail_count += self.c.nbd_start_disk(bdev_uuid, nbd_name)
|
|
fail_count += self.run_fio_test(nbd_name, 0, lvs['cluster_size'],
|
|
"read", "0xdd")
|
|
fail_count += self.c.nbd_stop_disk(nbd_name)
|
|
|
|
# Delete lvol bdev
|
|
fail_count += self.c.bdev_lvol_delete(bdev_uuid)
|
|
|
|
# Delete lvol store
|
|
fail_count += self.c.bdev_lvol_delete_lvstore(lvs_uuid)
|
|
|
|
fail_count += self.c.nbd_start_disk(base_name, nbd_name)
|
|
metadata_pages = 1 + lvs['total_data_clusters'] + \
|
|
(math.ceil(5 + math.ceil(lvs['total_data_clusters'] / 8) / 4096)) * 3
|
|
last_metadata_lba = int(metadata_pages * 4096 / self.block_size)
|
|
offset_metadata_end = int(last_metadata_lba * self.block_size)
|
|
last_cluster_of_metadata = math.ceil(metadata_pages / lvs['cluster_size'] / 4096)
|
|
offset = last_cluster_of_metadata * lvs['cluster_size']
|
|
size_metadata_end = offset - offset_metadata_end
|
|
|
|
# Check if data on area between end of metadata
|
|
# and first cluster of lvol bdev remained unchaged
|
|
fail_count += self.run_fio_test("/dev/nbd0", offset_metadata_end,
|
|
size_metadata_end, "read", "0xdd")
|
|
# Check if data on lvol bdev was zeroed.
|
|
# Malloc bdev should zero any data that is unmapped.
|
|
fail_count += self.run_fio_test("/dev/nbd0", offset, lvs['cluster_size'], "read", "0x00")
|
|
|
|
self.c.bdev_malloc_delete(base_name)
|
|
|
|
# Expected result:
|
|
# - calls successful, return code = 0
|
|
# - get_bdevs: no change
|
|
# - no other operation fails
|
|
return fail_count
|