zoukankan      html  css  js  c++  java
  • (一)利用 mdb 调试获取 nvlist_t 中 nvpair_t(name/value) 对

    服务器: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 ''

    //地址为 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 ''
    //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 ''

    //地址为 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 ''
    ==> 属性名称: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
    1332     rc = nvlist_lookup_string(nvl, "comment", &cmnt);                                       
    1333     rc |= nvlist_lookup_string(nvl, "guid", &guid);
    
    1423 int 
    1424 nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)                           
    1425 {
    1426     return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
    1427 } 
    
    1323 static int
    1324 nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
    1325     uint_t *nelem, void *data)
    1326 {
    1327     nvpriv_t *priv;
    1328     nvpair_t *nvp;
    1329     i_nvp_t *curr;
    1330 
    1331     if (name == NULL || nvl == NULL ||
    1332         (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
    1333         return (EINVAL);
    1334 
    1335     if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
    1336         return (ENOTSUP);
    1337 
    1338     for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
    1339         nvp = &curr->nvi_nvp;
    1340 
    1341         if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type)
    //116 #define NVP_NAME(nvp)       ((char *)(nvp) + sizeof (nvpair_t))
    1342             return (nvpair_value_common(nvp, type, nelem, data));
    1343     }
    1344 
    1345     return (ENOENT);
    1346 }
    
    1249 static int
    1250 nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
    1251 {
    1252     if (nvp == NULL || nvpair_type(nvp) != type)
    1253         return (EINVAL);
    1254 
    1255     /*
    1256      * For non-array types, we copy the data.
    1257      * For array types (including string), we set a pointer.
    1258      */
    1259     switch (type) {
    1260     case DATA_TYPE_BOOLEAN:
    1261         if (nelem != NULL)
    1262             *nelem = 0;
    1263         break;
    1264 
    1265     case DATA_TYPE_BOOLEAN_VALUE:
    1266     case DATA_TYPE_BYTE:
    1267     case DATA_TYPE_INT8:
    1268     case DATA_TYPE_UINT8:
    1269     case DATA_TYPE_INT16:
    1270     case DATA_TYPE_UINT16:
    1271     case DATA_TYPE_INT32:
    1272     case DATA_TYPE_UINT32:
    1273     case DATA_TYPE_INT64:
    1274     case DATA_TYPE_UINT64:
    1275     case DATA_TYPE_HRTIME:
    1276 #if !defined(_KERNEL)
    1277     case DATA_TYPE_DOUBLE:
    1278 #endif
    1279         if (data == NULL)
    1280             return (EINVAL);
    1281         bcopy(NVP_VALUE(nvp), data,
    1282             (size_t)i_get_value_size(type, NULL, 1));
    /*
    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))
    */
    1283         if (nelem != NULL)
    1284             *nelem = 1;
    1285         break;
    1286 
    1287     case DATA_TYPE_NVLIST:
    1288     case DATA_TYPE_STRING:
    1289         if (data == NULL)
    1290             return (EINVAL);
    1291         *(void **)data = (void *)NVP_VALUE(nvp);
    1292         if (nelem != NULL)
    1293             *nelem = 1;
    1294         break;
    1295 
    1296     case DATA_TYPE_BOOLEAN_ARRAY:
    1297     case DATA_TYPE_BYTE_ARRAY:
    1298     case DATA_TYPE_INT8_ARRAY:
    1299     case DATA_TYPE_UINT8_ARRAY:
    1300     case DATA_TYPE_INT16_ARRAY:
    1301     case DATA_TYPE_UINT16_ARRAY:
    1302     case DATA_TYPE_INT32_ARRAY:
    1303     case DATA_TYPE_UINT32_ARRAY:
    1304     case DATA_TYPE_INT64_ARRAY:
    1305     case DATA_TYPE_UINT64_ARRAY:
    1306     case DATA_TYPE_STRING_ARRAY:
    1307     case DATA_TYPE_NVLIST_ARRAY:
    1308         if (nelem == NULL || data == NULL)
    1309             return (EINVAL);
    1310         if ((*nelem = NVP_NELEM(nvp)) != 0)
    1311             *(void **)data = (void *)NVP_VALUE(nvp);
    1312         else
    1313             *(void **)data = NULL;
    1314         break;
    1315 
    1316     default:
    1317         return (ENOTSUP);
    1318     }
    1319 
    1320     return (0);
    1321 }
    //相关数据结构如下
     88 /* nvlist header */
     89 typedef struct nvlist {
     90     int32_t     nvl_version;
     91     uint32_t    nvl_nvflag; /* persistent flags */
     92     uint64_t    nvl_priv;   /* ptr to private data if not packed */
     93     uint32_t    nvl_flag;
     94     int32_t     nvl_pad;    /* currently not used, for alignment */
     95 } nvlist_t;   
     
     
     61 typedef struct {
     62     i_nvp_t     *nvp_list;  /* linked list of nvpairs */
     63     i_nvp_t     *nvp_last;  /* last nvpair */ 
     64     i_nvp_t     *nvp_curr;  /* current walker nvpair */
     65     nv_alloc_t  *nvp_nva;   /* pluggable allocator */
     66     uint32_t    nvp_stat;   /* internal state */
     67 } nvpriv_t; 
    
     
     43 /*
     44  * implementation linked list for pre-packed data
     45  */
     46 typedef struct i_nvp i_nvp_t;
     47 
     48 struct i_nvp {
     49     union {
     50         uint64_t    _nvi_align; /* ensure alignment */
     51         struct {
     52             i_nvp_t *_nvi_next; /* pointer to next nvpair */
     53             i_nvp_t *_nvi_prev; /* pointer to prev nvpair */
     54         } _nvi; 
     55     } _nvi_un;
     56     nvpair_t nvi_nvp;           /* nvpair */ 
     57 }; 
     
     
     77 typedef struct nvpair {
     78     int32_t nvp_size;   /* size of this nvpair */
     79     int16_t nvp_name_sz;    /* length of name string */
     80     int16_t nvp_reserve;    /* not used */
     81     int32_t nvp_value_elem; /* number of elements for array types */
     82     data_type_t nvp_type;   /* type of value */
     83     /* name string */
     84     /* aligned ptr array for string arrays */
     85     /* aligned array of data for value */
     86 } nvpair_t;
  • 相关阅读:
    UVa10050 Hartals
    UVa540 Team Queue
    UVa 11234 Expressions (二叉树重建&由叶往根的层次遍历)
    stl lower_bound upper_bound binary_search equal_range
    【windows】使用键盘代替鼠标的快捷键
    【Linux】xshell连接中断后就无法连接虚拟机中的Linux
    【Linux命令】ls命令
    【DB2】NULLS LAST与NULLS FIRST
    【PPT】PPT倒计时动画的制作方法 5.4.3.2.1...
    【Datastage】函数大全
  • 原文地址:https://www.cnblogs.com/fendou-999/p/3895572.html
Copyright © 2011-2022 走看看