zfs get all [volume]命令实现中构造数据结构
一、zfs get all [volume]命令源代码C实现中用到的数据结构有zprop_get_cbdata 和 callback_data,如下所示:
508 typedef struct zprop_get_cbdata { 509 int cb_sources; 510 zfs_get_column_t cb_columns[ZFS_GET_NCOLS]; 511 int cb_colwidths[ZFS_GET_NCOLS + 1]; 512 boolean_t cb_scripted; 513 boolean_t cb_literal; 514 boolean_t cb_first; 515 zprop_list_t *cb_proplist; 516 zfs_type_t cb_type; 517 } zprop_get_cbdata_t;
zprop_get_cbdata结构中主要用到的部分为zprop_list_t *cb_proplist;zfs_type_t cb_type;
54 typedef struct callback_data { 55 uu_avl_t *cb_avl; 56 int cb_flags; 57 zfs_type_t cb_types; 58 zfs_sort_column_t *cb_sortcol; 59 zprop_list_t **cb_proplist; 60 int cb_depth_limit; 61 int cb_depth; 62 uint8_t cb_props_table[ZFS_NUM_PROPS]; 63 } callback_data_t;
callback_data结构中主要用到的部分为cb_props_table[ZFS_NUM_PROPS]
二、设计的python数据结构
1 props_list = POINTER(zprop_list_t)() 2 props_table = (c_ubyte * ZFS_NUM_PROPS)() 3 props_table[:] = [B_TRUE] * ZFS_NUM_PROPS 4 5 props_reslist = dict() 6 iter_data = dict() 7 iter_data['props_list'] = props_list 8 iter_data['props_table'] = props_table 9 iter_data['props_reslist'] = props_reslist 10 iter_data['zfs_type'] = ZFS_TYPE_VOLUME
iter_data为构造的python数据结构,说明如下:
1.props_table = (c_ubyte * ZFS_NUM_PROPS)() -- 类型定义
props_table[:] = [B_TRUE] * ZFS_NUM_PROPS -- 初始化
iter_data['props_table'] = props_table
以上对应的为:uint8_t cb_props_table[ZFS_NUM_PROPS];
2. iter_data['zfs_type'] = ZFS_TYPE_VOLUME
以上对应的为:zfs_type_t cb_type;
3. props_list = POINTER(zprop_list_t)()
iter_data['props_list'] = props_list
以上对应的为:zprop_list_t *cb_proplist;
4.iter_data['props_reslist'] = props_reslist
用于存放数据(dict 属性值),用作返回
三、整体代码如下:
1 def py_iter_zfs_list(zhp, arg): 2 3 iter_data = arg.value 4 5 props_reslist = iter_data['props_reslist'] 6 props_list = iter_data['props_list'] 7 props_table = iter_data['props_table'] 8 zfs_type = iter_data['zfs_type'] 9 cur_type = libzfs.zfs_get_type(zhp) 10 11 CBFUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) 12 iter_zfs = CBFUNC(py_iter_zfs_list) 13 14 user_props = nvlist_p() 15 16 if cur_type & zfs_type: 17 libzfs.zfs_prune_proplist(zhp, props_table) 18 libzfs.zfs_expand_proplist(zhp, byref(props_list), 0, 0) 19 20 prop = create_string_buffer(ZFS_MAXPROPLEN) 21 strval = c_char_p() 22 userprops = libzfs.zfs_get_user_props(zhp) 23 propval = nvlist_p() 24 sourcetype = c_int() 25 libzfs.zfs_prop_to_name.restype = c_char_p 26 27 while props_list: 28 pn = props_list.contents 29 propname = '-' 30 propstr = '-' 31 32 if pn.pl_prop != ZPROP_INVAL: 33 if libzfs.zfs_prop_get(zhp, pn.pl_prop, prop, 34 ZFS_MAXPROPLEN, 0, 0, 0, B_FALSE) != 0: 35 if pn.pl_all : 36 props_list = cast(pn.pl_next, POINTER(zprop_list_t)) 37 continue 38 if libzfs.zfs_prop_valid_for_type(pn.pl_prop, 39 ZFS_TYPE_VOLUME) : 40 props_list = cast(pn.pl_next, POINTER(zprop_list_t)) 41 continue 42 propstr = '-' 43 else: 44 propstr = prop.value.decode() 45 propname = libzfs.zfs_prop_to_name(pn.pl_prop).decode() 46 elif libzfs.zfs_prop_userquota(pn.pl_user_prop) : 47 if libzfs.zfs_prop_get_userquota(zhp, pn.pl_user_prop, 48 prop, ZFS_MAXPROPLEN, B_FALSE) == 0: 49 propstr = prop.value.decode() 50 else: 51 propstr = '-' 52 propname = pn.pl_user_prop.decode() 53 elif libzfs.zfs_prop_written(pn.pl_user_prop) : 54 if libzfs.zfs_prop_get_written(zhp, pn.pl_user_prop, 55 prop, ZFS_MAXPROPLEN, B_FALSE) == 0: 56 propstr = prop.value.decode() 57 else: 58 propstr = '-' 59 propname = pn.pl_user_prop.decode() 60 else: 61 if lbnvpair.nvlist_lookup_nvlist(user_props, pn.pl_user_prop, 62 byref(propval)) != 0 : 63 if pn.pl_all : 64 props_list = cast(pn.pl_next, POINTER(zprop_list_t)) 65 continue 66 propstr = '-' 67 else : 68 lbnvpair.nvlist_lookup_string(propval, 69 ZPROP_VALUE, byref(strval)) 70 propstr = strval.value.decode() 71 propname = pn.pl_user_prop.decode() 72 props_reslist.update({propname:propstr}) 73 props_list = cast(pn.pl_next, POINTER(zprop_list_t)) 74 75 libzfs.zfs_close(zhp) 76 return 0 77 78 def zvol_get_all_props(name): 79 ret = [0, ''] 80 props_list = POINTER(zprop_list_t)() 81 props_table = (c_ubyte * ZFS_NUM_PROPS)() 82 props_table[:] = [B_TRUE] * ZFS_NUM_PROPS 83 84 props_reslist = dict() 85 iter_data = dict() 86 iter_data['props_list'] = props_list 87 iter_data['props_table'] = props_table 88 iter_data['props_reslist'] = props_reslist 89 iter_data['zfs_type'] = ZFS_TYPE_VOLUME 90 91 g_zfs = libzfs.libzfs_init() 92 libzfs.libzfs_error_description.restype = c_char_p 93 94 zhp = libzfs.zfs_path_to_zhandle(g_zfs, 95 bytes(name, encoding='ascii'), ZFS_TYPE_VOLUME) 96 97 if not zhp: 98 ret[0] = libzfs.libzfs_errno(g_zfs) 99 ret[1] = libzfs.libzfs_error_description(g_zfs).decode() 100 return None 101 102 libzfs.zprop_free_list(iter_data['props_list']) 103 py_iter_zfs_list(zhp, py_object(iter_data)) 104 105 libzfs.libzfs_fini(g_zfs) 106 return props_reslist
代码说明:
1.构造数据调用的方法:
py_iter_zfs_list(zhp, py_object(iter_data))
def py_iter_zfs_list(zhp, arg):
iter_data = arg.value