多段NAT

2013/02/23


仮想ネットワークの設定

L2スイッチと仮想NIC

# dladm create-etherstub vsw1 # dladm create-vnic -l vsw1 vnic10 # dladm create-vnic -l vsw1 vnic11 # dladm create-vnic -l vsw1 vnic12 # dladm create-vnic -l vsw1 vnic13 # dladm create-etherstub vsw2 # dladm create-vnic -l vsw2 vnic20 # dladm create-vnic -l vsw2 vnic21 # dladm create-vnic -l vsw2 vnic22 # dladm create-vnic -l vsw2 vnic23 # dladm LINK CLASS MTU STATE OVER net0 phys 1500 up -- vsw1 etherstub 9000 unknown -- vnic10 vnic 9000 up vsw1 vnic11 vnic 9000 up vsw1 vnic12 vnic 9000 up vsw1 vnic13 vnic 9000 up vsw1 vsw2 etherstub 9000 unknown -- vnic20 vnic 9000 up vsw2 vnic21 vnic 9000 up vsw2 vnic22 vnic 9000 up vsw2 vnic23 vnic 9000 up vsw2 # ipadm create-ip net0 # ipadm create-addr -T static -a 192.168.0.35 net0/v4

zone作成

# zonecfg -z zone01 'create; set zonepath=/zones/zone01' # zonecfg -z zone02 'create; set zonepath=/zones/zone02' # zonecfg -z zone03 'create; set zonepath=/zones/zone03' # zoneadm -z zone01 install # zoneadm -z zone02 clone zone01 # zoneadm -z zone03 clone zone01 # zonecfg -z zone01 zonecfg:zone01> remove anet zonecfg:zone01> add net zonecfg:zone01:net> set physical=vnic12 zonecfg:zone01:net> end zonecfg:zone01> info zonename: zone01 zonepath: /zones/zone01 brand: solaris autoboot: false bootargs: file-mac-profile: pool: limitpriv: scheduling-class: ip-type: exclusive hostid: fs-allowed: net: address not specified allowed-address not specified configure-allowed-address: true physical: vnic12 defrouter not specified zonecfg:zone01> commit zonecfg:zone01> exit # zonecfg -z zone02 zonecfg:zone02> remove anet zonecfg:zone02> add net zonecfg:zone02:net> set physical=vnic11 zonecfg:zone02:net> end zonecfg:zone02> add net zonecfg:zone02:net> set physical=vnic20 zonecfg:zone02:net> end zonecfg:zone02> info zonename: zone02 zonepath: /zones/zone02 brand: solaris autoboot: false bootargs: file-mac-profile: pool: limitpriv: scheduling-class: ip-type: exclusive hostid: fs-allowed: net: address not specified allowed-address not specified configure-allowed-address: true physical: vnic11 defrouter not specified net: address not specified allowed-address not specified configure-allowed-address: true physical: vnic20 defrouter not specified zonecfg:zone01> commit zonecfg:zone01> exit # zonecfg -z zone03 zonecfg:zone01> remove anet zonecfg:zone01> add net zonecfg:zone01:net> set physical=vnic22 zonecfg:zone01:net> end zonecfg:zone01> info zonename: zone03 zonepath: /zones/zone03 brand: solaris autoboot: false bootargs: file-mac-profile: pool: limitpriv: scheduling-class: ip-type: exclusive hostid: fs-allowed: net: address not specified allowed-address not specified configure-allowed-address: true physical: vnic22 defrouter not specified zonecfg:zone01> commit zonecfg:zone01> exit

zone01(プロキシ2)設定

# zlogin -C zone01 (以下は手動で設定する場合) # ipadm create-ip vnic12 # ipadm create-addr -T static -a 172.16.0.10 vnic12/v4 # ipadm create-addr -T addrconf vnic12/v6 # dladm LINK CLASS MTU STATE OVER vnic12 vnic 9000 up ? # ipadm NAME CLASS/TYPE STATE UNDER ADDR lo0 loopback ok -- -- lo0/v4 static ok -- 127.0.0.1/8 lo0/v6 static ok -- ::1/128 vnic12 ip ok -- -- vnic12/v4 static ok -- 172.16.0.10/24 vnic12/v6 addrconf ok -- fe80::8:20ff:fe0c:a730/10

zone02(NAT BOX)設定

# zlogin -C zone02 (以下は手動で設定する場合) # ipadm create-ip vnic11 # ipadm create-addr -T static -a 172.16.0.1 vnic11/v4 # ipadm create-addr -T addrconf vnic11/v6 # ipadm create-ip vnic20 # ipadm create-addr -T static -a 10.0.0.254 vnic20/v4 # ipadm create-addr -T addrconf vnic20/v6 # dladm LINK CLASS MTU STATE OVER vnic11 vnic 9000 up ? vnic20 vnic 9000 up ? # ipadm NAME CLASS/TYPE STATE UNDER ADDR lo0 loopback ok -- -- lo0/v4 static ok -- 127.0.0.1/8 lo0/v6 static ok -- ::1/128 vnic11 ip ok -- -- vnic11/v4 static ok -- 172.16.0.1/24 vnic11/v6 addrconf ok -- fe80::8:20ff:fe18:5eaa/10 vnic20 ip ok -- -- vnic20/v4 static ok -- 10.0.0.254/24 vnic20/v6 addrconf ok -- fe80::8:20ff:fecb:6733/10

zone03(端末)設定

# zlogin -C zone03 (以下は手動で設定する場合) # ipadm create-ip vnic22 # ipadm create-addr -T static -a 10.0.0.35 vnic22/v4 # ipadm create-addr -T addrconf vnic22/v6 # dladm LINK CLASS MTU STATE OVER vnic22 vnic 9000 up ? # ipadm NAME CLASS/TYPE STATE UNDER ADDR lo0 loopback ok -- -- lo0/v4 static ok -- 127.0.0.1/8 lo0/v6 static ok -- ::1/128 vnic22 ip ok -- -- vnic22/v4 static ok -- 10.0.0.35/24 vnic22/v6 addrconf ok -- fe80::8:20ff:fe5e:351a/10

ルーティング(NAT)の設定


solaris11(172.16.0.X=>192.168.0.X)変換の設定
動的経路制御は無効にして経路は手動で設定したほうがよい(有効でも動くけど)。

# routeadm -u -d ipv4-routing # routeadm -u -e ipv4-forwarding # routeadm Configuration Current Current Option Configuration System State --------------------------------------------------------------- IPv4 routing disabled disabled IPv6 routing disabled disabled IPv4 forwarding enabled enabled IPv6 forwarding disabled disabled Routing services "route:default ripng:default" Routing daemons: STATE FMRI disabled svc:/network/routing/ripng:default disabled svc:/network/routing/route:default online svc:/network/routing/ndp:default disabled svc:/network/routing/rdisc:default disabled svc:/network/routing/legacy-routing:ipv4 disabled svc:/network/routing/legacy-routing:ipv6

送信元が172.16.0.0/16のパケットを、0/32(実際には192.168.0.35)に変換してnet0へ転送する

# cat /etc/ipf/ipnat.conf map net0 172.16.0.0/16 -> 0/32 portmap tcp/udp auto map net0 172.16.0.0/16 -> 0/32 # svcadm enable network/ipfilter # svcs -l network/ipfilter fmri svc:/network/ipfilter:default name IP Filter enabled true state online next_state none state_time 2013年02月21日 08時42分14秒 logfile /var/svc/log/network-ipfilter:default.log restarter svc:/system/svc/restarter:default contract_id 67 manifest /lib/svc/manifest/network/ipfilter.xml manifest /lib/svc/manifest/network/network-location.xml dependency optional_all/none svc:/network/location:default (online) dependency require_all/none svc:/system/filesystem/minimal (online) dependency require_all/restart svc:/network/physical:default (online) dependency require_all/restart svc:/system/identity:node (online) dependency require_all/restart svc:/system/identity:domain (online) # netstat -rn -f inet Routing Table: IPv4 Destination Gateway Flags Ref Use Interface -------------------- -------------------- ----- ----- ---------- --------- default 192.168.0.1 UG 2 225 net0 127.0.0.1 127.0.0.1 UH 2 254 lo0 172.16.0.0 172.16.0.254 U 4 35 vnic10 192.168.0.0 192.168.0.35 U 5 9380 net0

zone02(10.0.0.X=>172.16.10.X)設定

# routeadm -u -d ipv4-routing # routeadm -u -e ipv4-forwarding # routeadm Configuration Current Current Option Configuration System State --------------------------------------------------------------- IPv4 routing disabled disabled IPv6 routing disabled disabled IPv4 forwarding enabled enabled IPv6 forwarding disabled disabled Routing services "route:default ripng:default" Routing daemons: STATE FMRI disabled svc:/network/routing/rdisc:default disabled svc:/network/routing/route:default online svc:/network/routing/ndp:default disabled svc:/network/routing/legacy-routing:ipv4 disabled svc:/network/routing/legacy-routing:ipv6 disabled svc:/network/routing/ripng:default

送信元が10.0.0/24のパケットを、0/32(実際には172.16.0.1)に変換してvnic11へ転送する

# cat /etc/ipf/ipnat.conf map vnic11 10.0.0.0/24 -> 0/32 portmap tcp/udp auto map vnic11 10.0.0.0/24 -> 0/32 # svcadm enable network/ipfilter # svcs -l network/ipfilter fmri svc:/network/ipfilter:default name IP Filter enabled true state online next_state none state_time 2013年02月21日 08時47分42秒 logfile /var/svc/log/network-ipfilter:default.log restarter svc:/system/svc/restarter:default contract_id 322 manifest /lib/svc/manifest/network/ipfilter.xml manifest /lib/svc/manifest/network/network-location.xml dependency optional_all/none svc:/network/location:default (online) dependency require_all/none svc:/system/filesystem/minimal (online) dependency require_all/restart svc:/network/physical:default (online) dependency require_all/restart svc:/system/identity:node (online) dependency require_all/restart svc:/system/identity:domain (online) # netstat -rn -f inet Routing Table: IPv4 Destination Gateway Flags Ref Use Interface -------------------- -------------------- ----- ----- ---------- --------- default 172.16.0.254 UG 2 41 vnic11 10.0.0.0 10.0.0.254 U 3 41 vnic20 127.0.0.1 127.0.0.1 UH 2 64 lo0 172.16.0.0 172.16.0.1 U 4 25 vnic11
Read more ...

デッドロック

2013/01/16

ファイルとレコードのロックの使用

UNIX のロック機能を使用すると、デッドロックを検出および防止できます。デッドロックが発生する可能性があるのは、システムがレコードロックインタフェースを休眠させようとするときだけです。このとき、2 つのプロセスがデッドロック状態であるかどうかを判断する検索が行われます。潜在的なデッドロックが検出されると、ロックインタフェースは失敗し、デッドロックを示す値が errno に設定されます。F_SETLK を使用してロックを設定するプロセスは、ロックがすぐに取得できなくても、それを待たないので、デッドロックは発生しません。

事務処理に必須の「ファイル・ロッキング」

F_RDLCK リードロック read lock (シェアードロック shared lock)
F_WRLCK ライトロック write lock (排他ロック exclusive lock)
F_UNLCK アンロック (上記ふたつのロックを解除)

F_WRLCK は、ファイルの特定の領域を、ひとつのプロセスだけがロック可能にするためのもので、これは排他制御そのものですから、「排他ロック」(exclusive lock)と呼ばれることがあります。前記の creat(), link(), open() を使った方式に比べて、ファイルの更新に必要な一部分だけをロックすることができるため、更新の場所が違う限り、複数のプロセスが同時に同じファイルにアクセスすることが可能で、データ処理の効率が良くなります。F_WRLCK は、対象とするファイルに、書き込みのためのパーミションを必要とします。

F_RDLCK の方は、通常、ファイルの読み取りに使用され、ファイルの更新を禁止します。この場合は、既に他のプロセスが F_RDLCK した部分に、オーバーラップした F_RDLCK をかけることができます。F_WRLCK された 部分に F_RDLCK をかけることはできません。
また、F_RDLCK された部分に、F_WRLCKをかけることもできません。書き込みのためのロックと違って、ファイルのロックされた部分を、読み込みを行う複数のプロセスが共有することができるため、「シェアードロック」(shared lock) と呼ばれることがあります。もちろん、これを使うためにはリードのパーミションが必要です。

IPC: ファイル・ロック
アドバイザリロックと強制ロックの選択

サンプルコード

アドバイザリロック
fcntl(2)
flock_sample1-1.c
#include #include #include #include #include int main() { struct flock fl1; struct flock fl2; int fd; fl1.l_type = F_WRLCK; fl1.l_whence = SEEK_SET; fl1.l_start = 0; fl1.l_len = 1; fl1.l_pid = getpid(); fl2.l_type = F_WRLCK; fl2.l_whence = SEEK_SET; fl2.l_start = 1; fl2.l_len = 1; fl2.l_pid = getpid(); if ((fd = open("lock.txt", O_RDWR)) == -1) { perror("open"); exit(1); } printf("Press to try to get lock(1): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Locked(1)."); printf("Press to try to get lock(2): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Locked(2)."); printf("Press to release lock(2): "); getchar(); fl2.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(2)."); printf("Press to release lock(1): "); getchar(); fl1.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(1)."); close(fd); return 0; }
flock_sample1-2.c
#include #include #include #include #include int main() { struct flock fl1; struct flock fl2; int fd; fl1.l_type = F_WRLCK; fl1.l_whence = SEEK_SET; fl1.l_start = 0; fl1.l_len = 1; fl1.l_pid = getpid(); fl2.l_type = F_WRLCK; fl2.l_whence = SEEK_SET; fl2.l_start = 1; fl2.l_len = 1; fl2.l_pid = getpid(); if ((fd = open("lock.txt", O_RDWR)) == -1) { perror("open"); exit(1); } printf("Press to try to get lock(2): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Locked(2)."); printf("Press to try to get lock(1): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Locked(1)."); printf("Press to release lock(1): "); getchar(); fl1.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(1)."); printf("Press to release lock(2): "); getchar(); fl2.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(2)."); close(fd); return 0; }
実行例
# ./flock_sample1-1 Press to try to get lock(1): waiting...Locked(1). Press to try to get lock(2): waiting...Locked(2). Press to release lock(2): Unlocked(2). Press to release lock(1): Unlocked(1).
# ./flock_sample1-2 Press to try to get lock(2): waiting...Locked(2). Press to try to get lock(1): fcntl: Deadlock situation detected/avoided
Deadlock situation detected/avoided

原因
プログラミングのデッドロック状態が検出され、回避されました。

対処方法
システムがデッドロックを検出し回避しなかった場合は、ソフトウェアの一部がハングします。そのプログラムを再度実行してください。デッドロックが再び起こることはないかもしれません。

テクニカルノート
このエラーは、通常、ファイルとレコードのロックに関連しています。ただし、mutex、セマフォ、条件変数、読み取り/書き込みロックが対象になる場合もあります。

このエラーの記号名は、EDEADLK、errno=45 です。

強制ロック
read(2), write(2)
flock_sample2-1.c
#include #include #include #include #include int main() { struct flock fl1; struct flock fl2; int fd; char buff[256] = "2222222222"; ssize_t n; fl1.l_type = F_WRLCK; fl1.l_whence = SEEK_SET; fl1.l_start = 0; fl1.l_len = 10; fl1.l_pid = getpid(); fl2.l_type = F_WRLCK; fl2.l_whence = SEEK_SET; fl2.l_start = 10; fl2.l_len = 10; fl2.l_pid = getpid(); if ((fd = open("sample.txt", O_RDWR|O_CREAT, 0600)) == -1) { perror("open"); exit(1); } printf("Press to try to get lock(1): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Locked(1)."); printf("Press to try to read record(2): "); getchar(); fputs("waiting...", stdout); n = pread(fd, buff, fl2.l_len, fl2.l_start); if (n < 0) { printf("Read(2) fail. errno=%d\n", errno); } else { buff[n] = '\0'; printf("Read(2) success. buff=\"%s\"\n", buff); } printf("Press to release lock(1): "); getchar(); fl1.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl1) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(1)."); close(fd); return 0; }
flock_sample2-2.c
#include #include #include #include #include int main() { struct flock fl1; struct flock fl2; int fd; char buff[256] = "1111111111"; ssize_t n; fl1.l_type = F_WRLCK; fl1.l_whence = SEEK_SET; fl1.l_start = 0; fl1.l_len = 10; fl1.l_pid = getpid(); fl2.l_type = F_WRLCK; fl2.l_whence = SEEK_SET; fl2.l_start = 10; fl2.l_len = 10; fl2.l_pid = getpid(); if ((fd = open("sample.txt", O_RDWR|O_CREAT, 0600)) == -1) { perror("open"); exit(1); } printf("Press to try to get lock(2): "); getchar(); fputs("waiting...", stdout); if (fcntl(fd, F_SETLKW, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Locked(2)."); printf("Press to try to write record(1): "); getchar(); fputs("waiting...", stdout); n = pwrite(fd, buff, fl1.l_len, fl1.l_start); if (n < 0) { printf("Write(1) fail. errno=%d\n", errno); } else { buff[n] = '\0'; printf("Write(1) success. buff=\"%s\"\n", buff); } printf("Press to release lock(2): "); getchar(); fl2.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl2) == -1) { perror("fcntl"); exit(1); } puts("Unlocked(2)."); close(fd); return 0; }
実行例
# chmod +l sample.txt root@solaris11:~# ls -l sample.txt -rw-r-lr-- 1 root root 31 1月 17日 08:02 sample.txt # ./flock_sample2-1 Press to try to get lock(1): ★1. レコード1をロックする waiting...Locked(1). Press to try to read record(2): ★4. レコード2を読み込み waiting...Read(2) fail. errno=45 Press to release lock(1): Unlocked(1). # ./flock_sample2-2 Press to try to get lock(2): ★2. レコード2をロックする waiting...Locked(2). Press to try to write record(1): ★3. レコード1に書き込み waiting...Write(1) success. buff="1111111111" Press to release lock(2): Unlocked(2).
  1. flock_sample2-1 で sample.txt のレコード1(先頭から10文字)をロックする。
  2. flock_sample2-2 でレコード2(10文字目から10文字)をロックする。
  3. flock_sample2-2 でレコード1を書き込む。レコード1はflock_sample2-1でロックされていて書き込めない。writeはスリープしてロックの解除を待機する。
  4. flock_sample2-1 でレコード2を読み込みむ。レコード2はflock_sample2-2でロックされているので読めない。lock_sample2-2は、flock_sample2-1が持つロックの解除を、スリープ状態で待っている。この状態で、flock_sample2-1がスリープ状態に入れば、デッドロックになる。そのためreadはEDEADLK(45)を返して失敗する。
Read more ...

dmu_buf

2012/10/21

dmu_buf 定義

typedef struct dmu_buf {
        uint64_t db_object;         /* この buffer が所属する object */
        uint64_t db_offset;         /* この object 中の byte offset */
        uint64_t db_size;           /* buffer のサイズ(byte) */
       void *db_data;              /* buffer 中の data */
} dmu_buf_t;

dmu_buf_impl 定義

typedef struct dmu_buf_impl {
        /*
         * 以下のメンバーは db_mtx によって保護されており、
         * db.db_data を除いて、不変です。
         */

        /* 公開されるている構造体 */
        dmu_buf_t db;

        /* 所属する objset */
        struct objset *db_objset;

        /*
         * dnode に安全にアクセスするための handle (NULL when evicted)
         */
        struct dnode_handle *db_dnode_handle;

        /*
         * our parent buffer; if the dnode points to us directly,
         * db_parent == db_dnode_handle->dnh_dnode->dn_dbuf
         * only accessed by sync thread ???
         * (NULL when evicted)
         * May change from NULL to non-NULL under the protection of db_mtx
         * (see dbuf_check_blkptr())
         */
        struct dmu_buf_impl *db_parent;

        /*
         * link for hash table of all dmu_buf_impl_t's
         */
        struct dmu_buf_impl *db_hash_next;

        /* our block number */
        uint64_t db_blkid;

        /*
         * Pointer to the blkptr_t which points to us. May be NULL if we
         * don't have one yet. (NULL when evicted)
         */
        blkptr_t *db_blkptr;

        /*
         * Our indirection level.  Data buffers have db_level==0.
         * Indirect buffers which point to data buffers have
         * db_level==1. etc.  Buffers which contain dnodes have
         * db_level==0, since the dnodes are stored in a file.
         */
        uint8_t db_level;

        /* db_mtx protects the members below */
        kmutex_t db_mtx;

        /*
         * Current state of the buffer
         */
        dbuf_states_t db_state;

        /*
         * Refcount accessed by dmu_buf_{hold,rele}.
         * If nonzero, the buffer can't be destroyed.
         * Protected by db_mtx.
         */
        refcount_t db_holds;

        /* buffer holding our data */
        arc_buf_t *db_buf;

        kcondvar_t db_changed;
        dbuf_dirty_record_t *db_data_pending;

        /* pointer to most recent dirty record for this buffer */
        dbuf_dirty_record_t *db_last_dirty;

        /*
         * Our link on the owner dnodes's dn_dbufs list.
         * Protected by its dn_dbufs_mtx.
         */
        list_node_t db_link;

        /* Data which is unique to data (leaf) blocks: */

        /* stuff we store for the user (see dmu_buf_set_user) */
        void *db_user_ptr;
        void **db_user_data_ptr_ptr;
        dmu_buf_evict_func_t *db_evict_func;

        uint8_t db_immediate_evict;
        uint8_t db_freed_in_flight;

        uint8_t db_dirtycnt;
} dmu_buf_impl_t;

サンプルデータ

# mdb -k
> !ls -li /var/adm
total 14144
      1067 drwxrwxr-x   5 adm      adm            5 10月 21日 2011年 acct
      6155 -rw-------   1 uucp     bin            0 10月 21日 2011年 aculog
      1070 drwxr-xr-x   2 adm      adm            4  7月 25日  16:58 exacct
     12389 -r--r--r--   1 root     root          28 10月 19日  16:13 lastlog
      1068 drwxr-xr-x   2 adm      adm            2 10月 21日 2011年 log
    438616 -rw-r--r--   1 root     root           0 10月 17日  03:10 messages
    438556 -rw-r--r--   1 root     root        3566 10月 16日  11:35 messages.0
    438505 -rw-r--r--   1 root     root        1242 10月  9日  11:00 messages.1
    438452 -rw-r--r--   1 root     root         133  9月 28日  18:08 messages.2
    413763 -rw-r--r--   1 root     root      241942  9月 25日  16:24 messages.3
      1069 drwxr-xr-x   2 root     sys            2 10月 21日 2011年 pool
      1066 drwxrwxr-x   2 adm      sys            2 10月 21日 2011年 sa
      1064 drwxr-xr-x   2 root     sys            2 10月 21日 2011年 sm.bin
      1065 drwxr-xr-x   2 root     sys            2 10月 21日 2011年 streams
    315396 -rw-------   1 root     root        1366  3月 20日 2000年 sulog
      6154 lrwxrwxrwx   1 root     root          27  2月 21日 2012年 utmpx -> ../../system/volatile/utmpx
      6153 -rw-r--r--   1 adm      adm      6818760 10月 19日  16:13 wtmpx
> ::dbufs -n rpool/ROOT/solaris-4/var -o 0t438556
0x3001e0aa1c8
0x3082ab43e18
> 0x3001e0aa1c8::dbuf
        addr object lvl blkid holds os
3001e0aa1c8    6b11c 0     bonus  1 rpool/ROOT/solaris-4/var
> 3001e0aa1c8::print -a dmu_buf_impl_t
3001e0aa1c8 {
    3001e0aa1c8 db = {
        3001e0aa1c8 db_object = 0x6b11c
        3001e0aa1d0 db_offset = 0xffffffffffffffff
        3001e0aa1d8 db_size = 0x140
        3001e0aa1e0 db_data = 0x30010943800
    }
    3001e0aa1e8 db_objset = 0x300121fdb80
    3001e0aa1f0 db_dnode_handle = 0x3082b0650d0
    3001e0aa1f8 db_parent = 0x30a662dc9e0
    3001e0aa200 db_hash_next = 0
    3001e0aa208 db_blkid = 0xffffffffffffffff
    3001e0aa210 db_blkoff = 0
    3001e0aa214 db_level = 0
    3001e0aa218 db_mtx = {
        3001e0aa218 _opaque = [ 0 ]
    }
    3001e0aa220 db_birth = 0
    3001e0aa228 db_state = 4 (DB_CACHED)
    3001e0aa230 db_holds = {
        3001e0aa230 rc_count = 0x1
    }
    3001e0aa238 db_writers_waiting = 0
    3001e0aa240 db_ref = 0x3001200fdf0
    3001e0aa248 db_changed = {
        3001e0aa248 _opaque = 0
    }
    3001e0aa250 db_last_dirty = 0
    3001e0aa258 db_data_pending = 0
    3001e0aa260 db_link = {
        3001e0aa260 list_next = 0
        3001e0aa268 list_prev = 0
    }
    3001e0aa270 db_user_ptr = 0x300153f27d8
    3001e0aa278 db_user_data_ptr_ptr = 0
    3001e0aa280 db_evict_func = sa_evict
    3001e0aa288 db_immediate_evict = 0x1
    3001e0aa289 db_freed_in_flight = 0
    3001e0aa28a db_managed = 0x1
    3001e0aa28b db_dirtycnt = 0
}
Read more ...