My kernel is dying trying to pull apart an XDR decoded array. And I've got an array of two items, so how do I view the second one?
[0]> ffffff0010c3a5f0::print DS_REPORTAVAILargs
{
ds_id = 0x64
ds_verifier = 0xffffff02efe3b060
ds_addrs = {
ds_addrs_len = 0x1
ds_addrs_val = 0xffffff0307106368
}
ds_attrvers = 1 (DS_ATTR_v1)
ds_storinfo = {
ds_storinfo_len = 0x2
ds_storinfo_val = 0xffffff0304545a80
}
}
We can easily see the first one:
[0]> 0xffffff0304545a80::print ds_storinfo
{
type = 1 (ZFS)
ds_storinfo_u = {
zfs_info = {
guid_map = {
ds_guid = {
stor_type = 1 (ZFS)
ds_guid_u = {
zfsguid = {
zfsguid_len = 0x10
zfsguid_val = 0xffffff02ff6de768
}
}
}
mds_sid_array = {
mds_sid_array_len = 0
mds_sid_array_val = 0
}
}
attrs = {
attrs_len = 0x1
attrs_val = 0xffffff04c8fd6578
}
}
}
}
But how do I get to the second one? I.e., how do I tell if it is just a pointer size away or if some special packing is going on?
I can use the array dcmd:
[0]> 0xffffff0304545a80::array ds_storinfo 2 ffffff0304545a80 ffffff0304545ac0
And that shows us:
[0]> ffffff0304545ac0::print ds_storinfo
{
type = 1 (ZFS)
ds_storinfo_u = {
zfs_info = {
guid_map = {
ds_guid = {
stor_type = 1 (ZFS)
ds_guid_u = {
zfsguid = {
zfsguid_len = 0x10
zfsguid_val = 0xffffff0304def2e0
}
}
}
mds_sid_array = {
mds_sid_array_len = 0
mds_sid_array_val = 0
}
}
attrs = {
attrs_len = 0x1
attrs_val = 0xffffff04bc8f62a0
}
}
}
}
Which looks valid and we can quickly test:
[0]> 0xffffff04bc8f62a0::print ds_zfsattr
{
attrname = {
utf8string_len = 0x4
utf8string_val = 0xffffff0508e88760
}
attrvalue = {
attrvalue_len = 0x15
attrvalue_val = 0xffffff050853f270
}
}
[0]> 0xffffff050853f270::dump -w 2
\/ 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a
b c d e f v123456789abcdef0123456789abcdef
ffffff050853f270: 706e6673 2d392d32 343a6461 7461322f 706e6673 32bbddba cefaed
fe 98140000 pnfs-9-24:data2/pnfs2...........
So either it is valid or it just happens to point to what I expect!