def set_copy_bin_file(self, format_type=0, source_range_entry_list=[[0, 0, 0, 0, 0]]):
""" 生成Copy的源起始的bin文件
Args:
format_type: int,copy format类型, 0/1
source_range_entry_list: List,copy的源起始entry列表,每个entry包含一个List:[slba、nlb、elbst_eilbrt、elbat、elbatm]
Returns:
out_file文件
"""
out_file = f'{str(time.time())}.bin'
count = len(source_range_entry_list)
if format_type == 0:
cmd = f'dd if=/dev/zero of={out_file} bs=1 count={count * 32} conv=notrunc'
stdout, stderr = self.linux_exec(cmd, get_pty=True)
assert f'{count * 32} bytes' in stdout, '命令下发失败'
for i in range(count):
modify_data = (source_range_entry_list[i][0] << 64) + (source_range_entry_list[i][1] << 128) + (source_range_entry_list[i][2] << 192) + (source_range_entry_list[i][3] << 224) + (source_range_entry_list[i][4] << 240)
start_byte = i * 32
self.set_dd_modify_file(start_byte=start_byte, file=out_file, modify_data=modify_data)
else:
cmd = f'dd if=/dev/zero of={out_file} bs=1 count={count * 40} conv=notrunc'
stdout, stderr = self.linux_exec(cmd, get_pty=True)
assert f'{count * 40} bytes' in stdout, '命令下发失败'
for i in range(count):
modify_data = (source_range_entry_list[i][0] << 64) + (source_range_entry_list[i][1] << 128) + (
source_range_entry_list[i][2] << 208) + (source_range_entry_list[i][3] << 288) + (
source_range_entry_list[i][4] << 304)
start_byte = i * 40
self.set_dd_modify_file(start_byte=start_byte, file=out_file, modify_data=modify_data)
return out_file
def set_copy(self, sn=None, dev=None, source_range_entry_list=[[0, 0, 0, 0, 0]], **kwargs):
""" nvme io-passthru命令下发copy
Args:
self :类对象
sn :盘片sn,字符串
dev :盘符,字符串
namespace_id :desired namespace, -n <NUM>
## datasize :data I/O length (bytes)
# ref_storage_tag :command dword 2 & dword3 & dword14 value,和PI相关,指定LBST和ILBRT,-2 <NUM>、-3 <NUM>、-8 <NUM>
sdlba :command dword 10 & dword11 value,64-bit addr of first block to access,-4 <NUM>、-5 <NUM>
range_count :int, number of ranges(NR), base 0, dword12.bit07:00 -6 <NUM>
descriptor_format :int, Descriptor Format, dword12.bit11:08, 0-Format0、 1-Format1、 all others-invalid -6 <NUM>
prinfor :int, PI Read, PI Action and Check field, dword12.bit15:12 -6 <NUM>
dirtype :int, Directive Type, dword12.bit23:20 -6 <NUM>
stcw :int, Storage Check Write, dword12.bit24 -6 <NUM>
prinfow :int, PI Write, PI Action and Check field, dword12.bit29:26 -6 <NUM>
fua :int, force unit access, force device to commit data before command completes, dword12.bit30 -6 <NUM>
lr :int, limited retry, limit media access attempts, dword12.bit31 -6 <NUM>
input_file :write/send file (default stdin), Copy Format0/1 Source Range Entrys, -i <FILE>
dirspec :directive specific, dword13.bit31:16 -7 <NUM>
# app_tag :command dword 15 bit15:00 value,和PI相关,指定LBAT,-9 <NUM>
# app_mask :command dword 15 bit31:16 value,和PI相关,指定LBATM,-9 <NUM>
timeout :timeout value, in milliseconds -t <NUM>
kwargs :不定参数,字典
Returns:
True布尔型
"""
namespace_id = kwargs.get('namespace_id')
sdlba = kwargs.get('sdlba')
range_count = kwargs.get('range_count')
descriptor_format = kwargs.get('descriptor_format')
limited_retry = kwargs.get('limited_retry')
force_access = kwargs.get('force_access')
prinfor = kwargs.get('prinfor')
dirtype = kwargs.get('dirtype')
dirspec = kwargs.get('dirspec')
# stcw = kwargs.get('stcw')
prinfow = kwargs.get('prinfow')
fua = kwargs.get('fua')
lr = kwargs.get('lr')
# app_mask = kwargs.get('app_mask')
# app_tag = kwargs.get('app_tag')
cmd_str = '-o 0x19 '
if namespace_id is not None:
cmd_str += f' -n {namespace_id}'
if sdlba is not None:
if len(hex(sdlba)[2:]) <= 8:
cmd_str += f' -4 {sdlba}'
else:
dword10 = int(hex(sdlba)[-8:], 16)
dword11 = sdlba >> 32
if dword10 == 0:
cmd_str += f' -5 {dword11}'
cmd_str += f' -4 {dword10} -5 {dword11}'
dword12 = 0
if range_count is not None:
dword12 += int(range_count)
if descriptor_format is not None:
dword12 += int(descriptor_format) << 8
if prinfor is not None:
dword12 += int(prinfor) << 12
if dirtype is not None:
dword12 += int(dirtype) << 20
# if stcw is not None:
# dword12 += int(stcw) << 24
if prinfow is not None:
dword12 += int(prinfow) << 26
if fua is not None:
dword12 += int(fua) << 30
if lr is not None:
dword12 += int(lr) << 31
if dword12 != 0:
cmd_str += f' -6 {dword12}'
if dirspec is not None:
cmd_str += f' -7 {dirspec}'
input_file = self.set_copy_bin_file(format_type=descriptor_format,
source_range_entry_list=source_range_entry_list)
cmd_str += f' -i {input_file} -l 512 -w'
dev = dev if dev else self.get_dev_ctrl(sn)
res, stderr = self.io_passthru(dev, *cmd_str)
return res, stderr
# self.rm_file(input_file)