服务器:192.168.2.122

root@2236:~# mdb -k
> ::spa
ADDR                 STATE NAME                                                
ffffff02dfaea000    ACTIVE p3way
ffffff02e38c0000    ACTIVE p98          //选取存储池 p98 作为调试对象
ffffff02e7fb3000    ACTIVE p99
ffffff02d55b0000    ACTIVE rpool
> ffffff02e38c0000::print -at spa_t
ffffff02e38c0000 spa_t {
    ffffff02e38c0000 char [256] spa_name = [ "p98" ]
    ffffff02e38c0100 char *spa_comment = 0
    ffffff02e38c0108 avl_node_t spa_avl = {
        ffffff02e38c0108 struct avl_node *[2] avl_child = [ 0xffffff02dfaea108,
0xffffff02d55b0108 ]
        ffffff02e38c0118 uintptr_t avl_pcb = 0x2
    }
    ffffff02e38c0120 nvlist_t *spa_config = 0xffffff02dfaae820
    ffffff02e38c0128 nvlist_t *spa_config_syncing = 0
    ffffff02e38c0130 nvlist_t *spa_config_splitting = 0
    ffffff02e38c0138 nvlist_t *spa_load_info = 0xffffff02dfaae7f0

//spa_t 结构体中元素 nvlist_t *spa_config 的所有信息

> 0xffffff02dfaae820::print -at nvlist_t
ffffff02dfaae820 nvlist_t {
    ffffff02dfaae820 int32_t nvl_version = 0
    ffffff02dfaae824 uint32_t nvl_nvflag = 0x1
    ffffff02dfaae828 uint64_t nvl_priv = 0xffffff02e1f78b18
    ffffff02dfaae830 uint32_t nvl_flag = 0
    ffffff02dfaae834 int32_t nvl_pad = 0
}

> 0xffffff02e1f78b18::print -at nvpriv_t
ffffff02e1f78b18 nvpriv_t {
    ffffff02e1f78b18 i_nvp_t *nvp_list = 0xffffff02dfa99398
    ffffff02e1f78b20 i_nvp_t *nvp_last = 0xffffff02dfa305a8
    ffffff02e1f78b28 i_nvp_t *nvp_curr = 0
    ffffff02e1f78b30 nv_alloc_t *nvp_nva = nv_alloc_sleep_def
    ffffff02e1f78b38 uint32_t nvp_stat = 0
}
> 0xffffff02dfa99398::print -at i_nvp_t
ffffff02dfa99398 i_nvp_t {
    ffffff02dfa99398 union  _nvi_un = {
        ffffff02dfa99398 uint64_t _nvi_align = 0xffffff02e12eea78
        ffffff02dfa99398 struct  _nvi = {
            ffffff02dfa99398 i_nvp_t *_nvi_next = 0xffffff02e12eea78
            ffffff02dfa993a0 i_nvp_t *_nvi_prev = 0
        }
    }
    ffffff02dfa993a8 nvpair_t nvi_nvp = {
        ffffff02dfa993a8 int32_t nvp_size = 0x20
        ffffff02dfa993ac int16_t nvp_name_sz = 0x8
        ffffff02dfa993ae int16_t nvp_reserve = 0
        ffffff02dfa993b0 int32_t nvp_value_elem = 0x1
        ffffff02dfa993b4 data_type_t nvp_type = 8 (DATA_TYPE_UINT64)
    }
}

//nvpair_t 类型的大小
> ::sizeof nvpair_t
sizeof (nvpair_t) = 0x10

//nvpair_t 地址为 ffffff02dfa993a8 的属性名称为 version
> ffffff02dfa993b8::print -at char
ffffff02dfa993b8 char 'v'
> ffffff02dfa993b9::print -at char
ffffff02dfa993b9 char 'e'
> ffffff02dfa993ba::print -at char
ffffff02dfa993ba char 'r'
> ffffff02dfa993bb::print -at char
ffffff02dfa993bb char 's'
> ffffff02dfa993bc::print -at char
ffffff02dfa993bc char 'i'
> ffffff02dfa993bd::print -at char
ffffff02dfa993bd char 'o'
> ffffff02dfa993be::print -at char
ffffff02dfa993be char 'n'
> ffffff02dfa993bf::print -at char
ffffff02dfa993bf char '\0'

//地址为 ffffff02dfa993a8 的 nvpair_t 指向的下一个 nvpair_t 地址
> 0xffffff02e12eea78::print -at i_nvp_t
ffffff02e12eea78 i_nvp_t {
    ffffff02e12eea78 union  _nvi_un = {
        ffffff02e12eea78 uint64_t _nvi_align = 0xffffff02e1454d80
        ffffff02e12eea78 struct  _nvi = {
            ffffff02e12eea78 i_nvp_t *_nvi_next = 0xffffff02e1454d80
            ffffff02e12eea80 i_nvp_t *_nvi_prev = 0xffffff02dfa99398
        }
    }
    ffffff02e12eea88 nvpair_t nvi_nvp = {
        ffffff02e12eea88 int32_t nvp_size = 0x20
        ffffff02e12eea8c int16_t nvp_name_sz = 0x5
        ffffff02e12eea8e int16_t nvp_reserve = 0
        ffffff02e12eea90 int32_t nvp_value_elem = 0x1
        ffffff02e12eea94 data_type_t nvp_type = 9 (DATA_TYPE_STRING)
    }
}

//nvpair_t 地址为 ffffff02e12eea88 的属性名称为 name
> ffffff02e12eea98::print -at char      //计算得来
ffffff02e12eea98 char 'n'
> ffffff02e12eea99::print -at char
ffffff02e12eea99 char 'a'
> ffffff02e12eea9a::print -at char
ffffff02e12eea9a char 'm'
> ffffff02e12eea9b::print -at char
ffffff02e12eea9b char 'e'
> ffffff02e12eea9c::print -at char
ffffff02e12eea9c char '\0'
//nvpair_t 地址为 ffffff02e12eea88 的属性名称对应的属性值为 p98
> ffffff02e12eeaa0::print -at char       //计算得来
ffffff02e12eeaa0 char 'p'
> ffffff02e12eeaa1::print -at char
ffffff02e12eeaa1 char '9'
> ffffff02e12eeaa2::print -at char
ffffff02e12eeaa2 char '8'
> ffffff02e12eeaa3::print -at char
ffffff02e12eeaa3 char '\0'

//地址为 0xffffff02dfa305a8 的 nvpair_t 结构(spa_config的最后一个nvpair_t结构==>i_nvp_t *nvp_last = 0xffffff02dfa305a8)
> 0xffffff02dfa305a8::print -at i_nvp_t
ffffff02dfa305a8 i_nvp_t {
    ffffff02dfa305a8 union  _nvi_un = {
        ffffff02dfa305a8 uint64_t _nvi_align = 0
        ffffff02dfa305a8 struct  _nvi = {
            ffffff02dfa305a8 i_nvp_t *_nvi_next = 0
            ffffff02dfa305b0 i_nvp_t *_nvi_prev = 0xffffff02e3e72780
        }
    }
    ffffff02dfa305b8 nvpair_t nvi_nvp = {
        ffffff02dfa305b8 int32_t nvp_size = 0x40
        ffffff02dfa305bc int16_t nvp_name_sz = 0x12
        ffffff02dfa305be int16_t nvp_reserve = 0
        ffffff02dfa305c0 int32_t nvp_value_elem = 0x1
        ffffff02dfa305c4 data_type_t nvp_type = 0t19 (DATA_TYPE_NVLIST)
    }
}
> ffffff02dfa305c8::print -at char
ffffff02dfa305c8 char 'f'
> ffffff02dfa305c9::print -at char
ffffff02dfa305c9 char 'e'
> ffffff02dfa305ca::print -at char
ffffff02dfa305ca char 'a'
> ffffff02dfa305cb::print -at char
ffffff02dfa305cb char 't'
> ffffff02dfa305cc::print -at char
ffffff02dfa305cc char 'u'
> ffffff02dfa305cd::print -at char
ffffff02dfa305cd char 'r'
> ffffff02dfa305ce::print -at char
ffffff02dfa305ce char 'e'
> ffffff02dfa305cf::print -at char
ffffff02dfa305cf char 's'
> ffffff02dfa305d0::print -at char
ffffff02dfa305d0 char '_'
> ffffff02dfa305d1::print -at char
ffffff02dfa305d1 char 'f'
> ffffff02dfa305d2::print -at char
ffffff02dfa305d2 char 'o'
> ffffff02dfa305d3::print -at char
ffffff02dfa305d3 char 'r'
> ffffff02dfa305d4::print -at char
ffffff02dfa305d4 char '_'
> ffffff02dfa305d5::print -at char
ffffff02dfa305d5 char 'r'
> ffffff02dfa305d6::print -at char
ffffff02dfa305d6 char 'e'
> ffffff02dfa305d7::print -at char
ffffff02dfa305d7 char 'a'
> ffffff02dfa305d8::print -at char
ffffff02dfa305d8 char 'd'
> ffffff02dfa305d9::print -at char
ffffff02dfa305d9 char '\0'
==> 属性名称:features_for_read

//计算出属性值存放的地址为: ffffff02dfa305e0 -- DATA_TYPE_NVLIST类型
> ffffff02dfa305e0::print -at nvlist_t
ffffff02dfa305e0 nvlist_t {
    ffffff02dfa305e0 int32_t nvl_version = 0
    ffffff02dfa305e4 uint32_t nvl_nvflag = 0x1
    ffffff02dfa305e8 uint64_t nvl_priv = 0xffffff02e1b0cb08
    ffffff02dfa305f0 uint32_t nvl_flag = 0
    ffffff02dfa305f4 int32_t nvl_pad = 0
}

> 0xffffff02e1b0cb08::print -at nvpriv_t
ffffff02e1b0cb08 nvpriv_t {
    ffffff02e1b0cb08 i_nvp_t *nvp_list = 0
    ffffff02e1b0cb10 i_nvp_t *nvp_last = 0
    ffffff02e1b0cb18 i_nvp_t *nvp_curr = 0
    ffffff02e1b0cb20 nv_alloc_t *nvp_nva = nv_alloc_sleep_def
    ffffff02e1b0cb28 uint32_t nvp_stat = 0x1
}

//源代码中如何从 nvlist_t 获取 nvpair_t (name/value) 对

usr/src/lib/smbsrv/libmlsvc/common/dfs.c
rc = nvlist_lookup_string(nvl, "comment", &cmnt);
rc |= nvlist_lookup_string(nvl, "guid", &guid); int
nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
{
return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
} static int
nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
uint_t *nelem, void *data)
{
nvpriv_t *priv;
nvpair_t *nvp;
i_nvp_t *curr; if (name == NULL || nvl == NULL ||
(priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
return (EINVAL); if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
return (ENOTSUP); for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
nvp = &curr->nvi_nvp; if (strcmp(name, NVP_NAME(nvp)) == && NVP_TYPE(nvp) == type)
//116 #define NVP_NAME(nvp) ((char *)(nvp) + sizeof (nvpair_t))
return (nvpair_value_common(nvp, type, nelem, data));
} return (ENOENT);
} static int
nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
{
if (nvp == NULL || nvpair_type(nvp) != type)
return (EINVAL); /*
1256 * For non-array types, we copy the data.
1257 * For array types (including string), we set a pointer.
1258 */
switch (type) {
case DATA_TYPE_BOOLEAN:
if (nelem != NULL)
*nelem = ;
break; case DATA_TYPE_BOOLEAN_VALUE:
case DATA_TYPE_BYTE:
case DATA_TYPE_INT8:
case DATA_TYPE_UINT8:
case DATA_TYPE_INT16:
case DATA_TYPE_UINT16:
case DATA_TYPE_INT32:
case DATA_TYPE_UINT32:
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
case DATA_TYPE_HRTIME:
#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE:
#endif
if (data == NULL)
return (EINVAL);
bcopy(NVP_VALUE(nvp), data,
(size_t)i_get_value_size(type, NULL, ));
/*
112 #define NV_ALIGN(x) (((ulong_t)(x) + 7ul) & ~7ul)
119 #define NVP_VALUE(nvp) ((char *)(nvp) + NV_ALIGN(sizeof (nvpair_t) \
120 + (nvp)->nvp_name_sz))
*/
if (nelem != NULL)
*nelem = ;
break; case DATA_TYPE_NVLIST:
case DATA_TYPE_STRING:
if (data == NULL)
return (EINVAL);
*(void **)data = (void *)NVP_VALUE(nvp);
if (nelem != NULL)
*nelem = ;
break; case DATA_TYPE_BOOLEAN_ARRAY:
case DATA_TYPE_BYTE_ARRAY:
case DATA_TYPE_INT8_ARRAY:
case DATA_TYPE_UINT8_ARRAY:
case DATA_TYPE_INT16_ARRAY:
case DATA_TYPE_UINT16_ARRAY:
case DATA_TYPE_INT32_ARRAY:
case DATA_TYPE_UINT32_ARRAY:
case DATA_TYPE_INT64_ARRAY:
case DATA_TYPE_UINT64_ARRAY:
case DATA_TYPE_STRING_ARRAY:
case DATA_TYPE_NVLIST_ARRAY:
if (nelem == NULL || data == NULL)
return (EINVAL);
if ((*nelem = NVP_NELEM(nvp)) != )
*(void **)data = (void *)NVP_VALUE(nvp);
else
*(void **)data = NULL;
break; default:
return (ENOTSUP);
} return ();
}
//相关数据结构如下
/* nvlist header */
typedef struct nvlist {
int32_t nvl_version;
uint32_t nvl_nvflag; /* persistent flags */
uint64_t nvl_priv; /* ptr to private data if not packed */
uint32_t nvl_flag;
int32_t nvl_pad; /* currently not used, for alignment */
} nvlist_t; typedef struct {
i_nvp_t *nvp_list; /* linked list of nvpairs */
i_nvp_t *nvp_last; /* last nvpair */
i_nvp_t *nvp_curr; /* current walker nvpair */
nv_alloc_t *nvp_nva; /* pluggable allocator */
uint32_t nvp_stat; /* internal state */
} nvpriv_t; /*
44 * implementation linked list for pre-packed data
45 */
typedef struct i_nvp i_nvp_t; struct i_nvp {
union {
uint64_t _nvi_align; /* ensure alignment */
struct {
i_nvp_t *_nvi_next; /* pointer to next nvpair */
i_nvp_t *_nvi_prev; /* pointer to prev nvpair */
} _nvi;
} _nvi_un;
nvpair_t nvi_nvp; /* nvpair */
}; typedef struct nvpair {
int32_t nvp_size; /* size of this nvpair */
int16_t nvp_name_sz; /* length of name string */
int16_t nvp_reserve; /* not used */
int32_t nvp_value_elem; /* number of elements for array types */
data_type_t nvp_type; /* type of value */
/* name string */
/* aligned ptr array for string arrays */
/* aligned array of data for value */
} nvpair_t;

(一)利用 mdb 调试获取 nvlist_t 中 nvpair_t(name/value) 对的更多相关文章

  1. SharePoint开发——利用CSOM逐级获取O365中SharePoint网站的List内容

    博客地址:http://blog.csdn.net/FoxDave 本文介绍如何利用SharePoint客户端对象模型(.NET)逐级获取Office 365网站中List的内容,仅仅是示例,没有 ...

  2. android 利用反射机制获取drawable中所有的图片资源

    public List<Map<String,Object>> getGridData() { list=new ArrayList<Map<String,Obje ...

  3. 利用PPPOE认证获取路由器中宽带账号密码

    前言 回家时买了一台极路由准备换掉家里老掉牙的阿里路由器,想进后台看一下宽带账号密码,咦???后台密码是什么来着??? 我陷入了沉思,家里的路由器一般都是pppoe拨号,而路由器在与pppoe认证服务 ...

  4. 利用函数回调获取setInterval中返回的值

    我们都知道,定时器里面想返回值如果你用return根本没作用,那么怎么拿到定时器所返回的值呢, 现在只需要利用回调函数,给主函数传一个函数类型的参数callback,然后把想要返回的num再传给cal ...

  5. java利用反射机制获取list中的某个字段并以list形式返回

    public static<T> List<Object> listToList(Collection<T> list,String fieldName) thro ...

  6. 十九、利用OGNL获取ValueStack中:根栈和contextMap中的数据

    利用OGNL获取ValueStack中:根栈和contextMap中的数据 原则:OGNL表达式如果以#开头,访问的contextMap中的数据 如果不以#开头,是访问的根栈中的对象的属性(List集 ...

  7. 利用POI获取Excel中图片和图片位置

    利用POI获取Excel中图片和图片位置(支持excel2003or2007多sheet) 转自:http://blog.csdn.net/delongcpp/article/details/8833 ...

  8. java 中利用反射机制获取和设置实体类的属性值

    摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...

  9. 利用 tee 命令调试shell脚本中的管道

    在编写shell脚本时,调试是个比较麻烦的事,特别是涉及到多层管道命令的时候,会产生多个中间结果,tee命令的作用是从标准输入中读取数据写入标准输出或文件中,利用它可以从管道中读取中间结果并写入本地临 ...

随机推荐

  1. Caffe使用step by step:使用自己数据对已经训练好的模型进行finetuning

    在经过前面Caffe框架的搭建以及caffe基本框架的了解之后,接下来就要回到正题:使用caffe来进行模型的训练. 但如果对caffe并不是特别熟悉的话,从头开始训练一个模型会花费很多时间和精力,需 ...

  2. 是否升级IOS11?IOS11不支持32位程序 查看手机哪些APP不支持

    查看苹果32位APP具体步骤:设置-通用-关于本机-应用程序.如果手机中下载了32位应用的话,苹果会给出应用兼容性提醒:如果手机里没有安装32位应用,右侧没有小三角,点击“应用程序”也会没有反应. I ...

  3. Angular中sweetalert弹框的使用详解

    最近太忙了,项目中使用的弹框老板嫌太丑,让我们优化一下,我在网上找了一下,找到了sweetalert弹框,算是比较好看的弹框了.所以我就想办法将sweetalert用到项目中,在项目中引入sweeta ...

  4. java将字符串存入GridF并通过id或文件名查询

    import static org.bson.codecs.configuration.CodecRegistries.fromProviders; import static org.bson.co ...

  5. Acdream1311_Apple

    无聊的时候看到上一次acdream群赛的一个题目,中间居然是有alice和bob的博弈题目,于是就去做了. 给n,m,两人轮流操作,每次操作可以使n+1,或者m+1,谁操作后满足nm>=A,那么 ...

  6. linux 实践到的命令 collection

    查看文件夹/文件 大小:du   :(disk usage) 要通过 1024 字节块概述一个目录树及其每个子树的磁盘使用情况,请输入: du -k /home/fran/filename 这在/ho ...

  7. 【比赛】NOIP2017 时间复杂度

    恶心的模拟题,考场上犯了一堆错误,多组数据清空没清完.数组开小...民间都是50分,结果CCF90.. 考完后随便改改就过了,还好只少了10分,如果真的是50,我估计会疯掉. 因为考场的时候没写好,所 ...

  8. 数据挖掘领域经典分类算法 —— C4.5算法(附python实现代码)

    目录 理论介绍 什么是分类 分类的步骤 什么是决策树 决策树归纳 信息增益 相关理论基础 计算公式 ID3 C4.5 python实现 参考资料 理论介绍 什么是分类 分类属于机器学习中监督学习的一种 ...

  9. BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】

    题目链接 BZOJ4919 题解 链上的\(LIS\)维护一个数组\(f[i]\)表示长度为\(i\)的\(LIS\)最小的结尾大小 我们可以用\(multiset\)来维护这个数组,子树互不影响,启 ...

  10. @Html.DropDownListFor默认选中项

    http://q.cnblogs.com/q/73902/ 项目使用mvc4,给dropDownList指定默认值未选中 页面代码是: 1.未有默认选中值 Html.DropDownListFor(m ...