Eric Kustarz's Weblog

e-street

All | FileBench | NFS | SETUP | ZFS

20080529 Thursday May 29, 2008

 NFSv3 对 .zfs 的支持

Rob 昨天晚上做了一些修补工作,现在 NFSv3 能够访问 .zfs 和快照了!这样的话 v3 和 v4 现在都能够访问了。

fsh-weakfish# mount -o vers=3 fsh-mullet:/pool /mnt
fsh-weakfish# ls /mnt/.zfs/snapshot
krispies
fsh-weakfish# ls /mnt/.zfs/snapshot/krispies
neat.txt
fsh-weakfish# cat /mnt/.zfs/snapshot/krispies/neat.txt
hi
fsh-weakfish# 

在之前的一篇博客中,我讨论了如何实现 v4 支持,其中介绍了一种新的数据结构 "fhandle_ext_t"。 这种数据结构现在被重新命名为 fhandle4_t,这样一来,万一将来我们需要增加 v4 的潜在文件句柄大小(它目前设置为 v3 的协议限额),它可以减少对代码的修改。同样地,NFSv3 使用数据结构 fhandle3_t

这些变化将反映在 nevada 的 build 36 中。



(2008-05-29 19:25:00.0/2008-05-29 19:24:25.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/nfsv3_%E5%AF%B9_zfs_%E7%9A%84%E6%94%AF%E6%8C%81

20080528 Wednesday May 28, 2008

 记录 ZFS VOP 时间的脚本

如果您正在运行某个应用程序,并且您很想知道 zfs 将时间花在了哪些地方。这里有一些脚本可以帮您计算出每个 VOP 用掉了多少时间。

这个脚本 (zfs_get_vop_times.d) 可以显示每个 VOP 被调用的次数、VOP 的平均用时以及每个 VOP 花掉的总时间。这适用于系统上的全部 ZFS 文件系统。它生成如下输出:

# ./zvop_times.d 
dtrace: script './zvop_times.d' matched 66 probes
^C
CPU     ID                    FUNCTION:NAME
 17      2                             :END 
ZFS COUNT


  zfs_fsync                                                        61
  zfs_write                                                       494
  zfs_read                                                        520

ZFS AVG TIME

  zfs_read                                                    2737251
  zfs_write                                                   6992704
  zfs_fsync                                                  73401109


ZFS SUM TIME

  zfs_read                                                 1423370640
  zfs_write                                                3454396080
  zfs_fsync                                                4477467680

这个脚本 (zvop_times_fsid.d) 与上一个的操作相同,但是只针对一个文件系统——也就是您通过 FSID ints 指定的系统。

最后这个脚本 (zvop_times_fsid_large.d) 的操作同上(按每个 FSID 追踪),不同的是它可以在 zfs 的 VOP 调用时间超过 X 时(这里的 X 是传入脚本的值)显示堆栈和量化信息。这使我们可以轻松查看是否存在一些运行非常缓慢的调用。 它生成如下输出(此处略过与上例相同的输出):

# ./zvop_times_fsid_large.d 0x7929404d 0xb3d52b08 50000000
dtrace: script './zvop_times_fsid_large.d' matched 123 probes
CPU     ID                    FUNCTION:NAME
 14  35984                  zfs_read:return 
              genunix`fop_read+0x20
              genunix`read+0x29c
              unix`syscall_trap32+0x1e8

 16  35994               zfs_putpage:return 
              genunix`fop_putpage+0x1c
              nfssrv`rfs3_commit+0x110
              nfssrv`common_dispatch+0x588
              rpcmod`svc_getreq+0x1ec
              rpcmod`svc_run+0x1e8
              nfs`nfssys+0x1b8
              unix`syscall_trap32+0x1e8

 18  35994               zfs_putpage:return 
              genunix`fop_putpage+0x1c
              nfssrv`rfs3_commit+0x110
              nfssrv`common_dispatch+0x588
              rpcmod`svc_getreq+0x1ec
              rpcmod`svc_run+0x1e8
              nfs`nfssys+0x1b8
              unix`syscall_trap32+0x1e8

 12  35972                 zfs_fsync:return 
              genunix`fop_fsync+0x14
              nfssrv`rfs4_createfile+0x500
              nfssrv`rfs4_do_opennull+0x44
              nfssrv`rfs4_op_open+0x380
              nfssrv`rfs4_compound+0x208
              nfssrv`rfs4_dispatch+0x11c
              nfssrv`common_dispatch+0x154
              rpcmod`svc_getreq+0x1ec
              rpcmod`svc_run+0x1e8
              nfs`nfssys+0x1b8
              unix`syscall_trap32+0x1e8

^C


  zfs_fsync                                         
           value  ------------- Distribution ------------- count    
        33554432 |                                         0        
        67108864 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
       134217728 |                                         0        

  zfs_putpage                                       
           value  ------------- Distribution ------------- count    
        33554432 |                                         0        
        67108864 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2        
       134217728 |                                         0        

  zfs_read                                          
           value  ------------- Distribution ------------- count    
        67108864 |                                         0        
       134217728 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
       268435456 |                                         0     

您可以随意使用这些脚本,亦可以随意增减内容。



(2008-05-28 18:25:00.0/2008-05-28 18:24:23.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/%E8%AE%B0%E5%BD%95_zfs_vop_%E6%97%B6%E9%97%B4%E7%9A%84%E8%84%9A%E6%9C%AC

20080527 Tuesday May 27, 2008

 Linux 对镜像挂载的支持


主题:
RFC [PATCH 0/6] 客户端对跨 NFS 服务器挂载点的支持
发信人:
Trond Myklebust 
日期:
2006 年 4 月 11 日(星期二)13:45:43 -0400
收信人:
linux-fsdevel@vger.kernel.org
转发:
nfsv4@linux-nfs.org, nfs@lists.sourceforge.net

以下系列包实现了 NFS 客户端对跨服务器子挂载点的支持(假设服务器使用 'nohide' 选项将它们导出)。我们希望在挂载点的任何一侧都能确保 inode 数量的唯一性。这样,在面对 inode 数量相同,但实际上属于服务器上不同文件系统的文件时,'tar' 和 'rsync' 之类的程序不会出现混淆。

这可以通过以下方式实现:客户端自动生成一个子挂载点,并在服务器上做出它的镜像。

为了避免给用户造成混乱,我们希望这个挂载点对于 'umount' 而言是透明的:换句话说,当用户挂载文件系统 '/foo' 时,NFS 客户端为 /foo/bar 自动生成的子挂载不会导致 'umount /foo'(内核无法为 /etc/mtab 中的 /foo/bar 创建条目之后更是如此)。 为了解决这个问题,我们使用新的标志 MNT_SHRINKABLE 为自动生成的子挂载做标记,并且当用户对父挂载调用 umount 时,允许 NFS 客户端尝试取消挂载。

注:本代码同时也作为对 NFSv4 'referral' 支持的基础,当一个客户端进入一个已经被迁移到其他服务器的文件系统时,该服务器可以将客户端定向到另外一个服务器中。

敬礼,
  Trond
_______________________________________________
NFSv4 邮件列表
NFSv4@linux-nfs.org
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

很有意思。



(2008-05-27 17:24:00.0/2008-05-27 17:23:24.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/linux_%E5%AF%B9%E9%95%9C%E5%83%8F%E6%8C%82%E8%BD%BD%E7%9A%84%E6%94%AF%E6%8C%81

20080526 Monday May 26, 2008

 AIX 对引用和复制的支持

Spencer 向我推荐了这篇文档。看起来 5.3.0.30 及之后版本的 AIX 可以支持引用和复制!请注意这只适用于 NFSv4。还有一个好消息:v4 这趟列车正在加速进行!



(2008-05-26 11:23:00.0/2008-05-26 11:22:24.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/aix_%E5%AF%B9%E5%BC%95%E7%94%A8%E5%92%8C%E5%A4%8D%E5%88%B6%E7%9A%84%E6%94%AF%E6%8C%81

20080525 Sunday May 25, 2008

 启用写高速缓存功能

要启用写高速缓存功能,您可以使用 format(1M) 命令:

i_like_corruption# format -e
Searching for disks...done


AVAILABLE DISK SELECTIONS:
       0. c0t0d0 
          /pci@1c,600000/scsi@2/sd@0,0
       1. c0t1d0 
          /pci@1c,600000/scsi@2/sd@1,0
Specify disk (enter its number): 1
selecting c0t1d0
[disk formatted]
/dev/dsk/c0t1d0s0 is in use by zpool zfs_tar. Please see zpool(1M).


FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        inquiry    - show vendor, product and revision
        scsi       - independent SCSI mode selects
        cache      - enable, disable or query SCSI disk cache
        volname    - set 8-character volume name
        !     - execute , then return
        quit
format> cache


CACHE MENU:
        write_cache - display or modify write cache settings
        read_cache  - display or modify read cache settings
        !      - execute , then return
        quit
cache> write      


WRITE_CACHE MENU:
        display     - display current setting of write cache
        enable      - enable write cache
        disable     - disable write cache
        !      - execute , then return
        quit
write_cache> display
Write Cache is disabled
write_cache> enable
write_cache> display
Write Cache is enabled
write_cache> q

进行这个操作的时候一定要小心,因为有可能发生数据损坏!

对我来说这样做很有好处,因为我使用的是一个简单的 v20z 服务器并带有一个 SCSI 磁盘,运行一些初步的 specSFS 数据,写高速缓存将多少有助于减轻同步写入/提交的压力。当然,为了获得真正的 specSFS 数据,您所需要的远远不止一个 SCSI 磁盘。

如果您希望使用更流行的方法,Neil 写了一个脚本实现以下内容:

i_like_corruption# write_cache display c0t1d0
Write Cache is disabled
i_like_corruption# write_cache enable c0t1d0 
Write Cache is enabled
i_like_corruption# write_cache display c0t1d0
Write Cache is enabled
i_like_corruption# 

脚本如下:

#!/bin/ksh
#
# issue write cache commands to format(1M).
# commands can be to individual disks or all disks.
#
# usage: write_cache [-v] display|enable|disable all|
# E.g.:
#    write_cache disable all
#    write_cache -v enable c2t1d0

id=`id | sed -e 's/uid=//' -e 's/(.*//'`
if [ $id != "0" ] ; then
        printf "No permissions"
        exit 1
fi

# tmp files
cmds=/tmp/write_cache_commands.txt.$$
disks=/tmp/all_disk_list.txt.$$

silent=-s
if [ "$1" = "-v" ] ; then
        # in verbose mode turn off silent format option
        silent=
        shift
fi

cat > $cmds << EOF
cache
write_cache
$1
EOF

if [ "$2" = "all" ]; then
        echo disk | format 2>/dev/null | fgrep ". c" \
            | nawk '{ print $2 }' > $disks
        for i in `cat $disks`
        do
                format -e $silent -f $cmds $i 2>/dev/null
                if [ "$silent" = "-s" ]; then
                        # print write cache state using recursion
                        printf "%s : " $i
                        write_cache -v display $i | fgrep "Write Cache is"
                fi
        done
else
        format -e $silent -f $cmds $2
        if [ "$silent" = "-s" ]; then
                # print write cache state using recursion
                write_cache -v display $2 | fgrep "Write Cache is"
        fi
fi

rm -f $cmds $disks

好了,要确保它位于您的路径中。它的运行情况如下:

hodur# write_cache enable c4t2d0 
Write Cache is enabled
hodur# write_cache disable c4t2d0
Write Cache is disabled
hodur# 


(2008-05-25 20:26:00.0/2008-05-25 20:25:25.0) Permalink Comments [1]
Trackback: http://blogs.sun.com/erickustarz/zh/entry/%E5%90%AF%E7%94%A8%E5%86%99%E9%AB%98%E9%80%9F%E7%BC%93%E5%AD%98%E5%8A%9F%E8%83%BD

 MacOSX 10.4 系统中的 NFSv4 客户端

刚才从 Rick 发出的 nfsv4.org 邮件列表中看到了以下内容,这真是个好消息!

如果有人有兴趣在 xnu-792.6.70(PPC 上的 Mac OSX 10.4.6 或 x86 上的 Darwin8.0.1)上
试用 NFS Version 4 的客户端(包括 Kerberos 支持),
可以从以下地址下载包(目前只是 Beta 测试):
ftp.cis.uoguelph.ca:/pub/nfsv4/darwin-port/xnu-client.tar.gz

这里还有一个 "Readme" 文件和一个原始网页:
http://www.cis.uoguelph.ca/~nfsv4

如果您有兴趣查看更多的相关公告,
请加入:openbsd-nfsv4@sfobug.org。
我将尽量不向这些邮箱发送大多数人都不感兴趣的公告。

仅供需要者使用,Rick
另: 如果您已经下载了这个包,请您再下载一次,因为我在几分钟之前刚刚更新过。
   

或许很快我的笔记本上将安装 NFSv4 和 ZFS。



(2008-05-25 19:24:00.0/2008-05-25 19:23:55.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/macosx_10_4_%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84_nfsv4

20080524 Saturday May 24, 2008

 FS perf 201:Postmark

现在让我们运行一个简单但很流行的基准程序——Netapp 的 postmark 工具。让我们看看它执行 1,000,000 次操作需要多少时间:

首先试一下 ZFS:

mcp# ./postmark                  
PostMark v1.5 : 3/27/01
pm>set location=/scsi_zfs
pm>set transactions=1000000
pm>run
Creating files...Done
Performing transactions..........Done
Deleting files...Done
Time:
        220 seconds total
        214 seconds of transactions (4672 per second)

Files:
        519830 created (2362 per second)
                Creation alone: 20000 files (4000 per second)
                Mixed with transactions: 499830 files (2335 per second)
        500124 read (2337 per second)
        494776 appended (2312 per second)
        519830 deleted (2362 per second)
                Deletion alone: 19660 files (19660 per second)
                Mixed with transactions: 500170 files (2337 per second)

Data:
        3240.97 megabytes read (14.73 megabytes per second)
        3365.07 megabytes written (15.30 megabytes per second)
pm>

运行期间,我使用我们的好帮手 zpool(1M) 工具查看执行了多少次 IO:

mcp# zpool iostat 1
               capacity     operations    bandwidth
pool         used  avail   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
scsi_zfs    32.5K  68.0G      0    207      0  6.25M
scsi_zfs    32.5K  68.0G      0    821      0  24.1M
scsi_zfs    32.5K  68.0G      0    978      0  28.6M
scsi_zfs    32.5K  68.0G      0  1.04K      0  30.3M
scsi_zfs    32.5K  68.0G      0  1.01K      0  27.6M
scsi_zfs     129M  67.9G      0    797      0  16.2M
scsi_zfs     129M  67.9G      0    832      0  27.4M

接下来试一下 UFS:

mcp# ./postmark 
PostMark v1.5 : 3/27/01
pm>set location=/export/scsi_ufs
pm>set transactions=1000000
pm>run
Creating files...Done
Performing transactions..........Done
Deleting files...Done
Time:
        3450 seconds total
        3419 seconds of transactions (292 per second)

Files:
        519830 created (150 per second)
                Creation alone: 20000 files (909 per second)
                Mixed with transactions: 499830 files (146 per second)
        500124 read (146 per second)
        494776 appended (144 per second)
        519830 deleted (150 per second)
                Deletion alone: 19660 files (2184 per second)
                Mixed with transactions: 500170 files (146 per second)

Data:
        3240.97 megabytes read (961.96 kilobytes per second)
        3365.07 megabytes written (998.79 kilobytes per second)
pm>

同样,在运行期间使用 iostat 查看 UFS 的 IO 执行情况:

mcp# iostat -Mxnz 1
                    extended device statistics              
    r/s    w/s   Mr/s   Mw/s wait actv wsvc_t asvc_t  %w  %b device
    0.0  820.9    0.0    3.4 142.5 256.0  173.5  311.9 100 100 c4t1d0
                    extended device statistics              
    r/s    w/s   Mr/s   Mw/s wait actv wsvc_t asvc_t  %w  %b device
    0.0  797.0    0.0    3.1 129.2 256.0  162.1  321.2 100 100 c4t1d0
                    extended device statistics              
    r/s    w/s   Mr/s   Mw/s wait actv wsvc_t asvc_t  %w  %b device
    0.0  777.0    0.0    3.1 128.0 256.0  164.7  329.5 100 100 c4t1d0
                    extended device statistics              
    r/s    w/s   Mr/s   Mw/s wait actv wsvc_t asvc_t  %w  %b device
    0.0  827.1    0.0    4.0 128.8 256.0  155.7  309.5 100 100 c4t1d0

啊!让我们看一下吞吐量(每秒钟事务处理数量), 在这个基准程序上,ZFS 的运行速度是 UFS 的 16 倍左右。当然,ZFS 并不是在每个基准程序上都比 UFS 性能优越这么多,但是都大同小异。

本测试运行在一个两通路 Opteron 机箱上,ZFS 和 UFS 都使用相同的 SCSI 磁盘。



(2008-05-24 20:25:00.0/2008-05-24 20:24:25.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/fs_perf_201_postmark1

 iSCSI 设置

既然 iSCSI 的目标和启动器都在 Solaris 中,让我们看一下如何建立一个 iSCSI。在目标机器上,我们进行如下操作:

首先,使用 'iscsitadm' 提供一个目录,将 iSCSI 系统信息库和配置信息储存在这里。如果您创建磁盘模拟文件 lun(默认),这也是存储逻辑单元的目录。

hodur# iscsitadm modify admin -d /var/tmp/iscsi

现在实际创建 lun。我选择创建直通 (pass-through) 裸设备而不是基于文件的磁盘模拟 lun。

hodur# iscsitadm create target --type raw --backing-store /dev/rdsk/c4t2d0 c4t2d0
hodur# iscsitadm create target --type raw --backing-store /dev/rdsk/c4t4d0 c4t4d0
hodur# iscsitadm create target --type raw --backing-store /dev/rdsk/c4t8d0 c4t8d0
hodur# iscsitadm create target --type raw --backing-store /dev/rdsk/c4t12d0 c4t12d0

让我们取得这台机器上目标的列表:

hodur# iscsitadm list target 
Target: c4t2d0
    iSCSI Name: iqn.1986-03.com.sun:02:aaf6d680-6681-e36e-8497-855decbf8038.c4t2d0
    Connections: 0
Target: c4t4d0
    iSCSI Name: iqn.1986-03.com.sun:02:f935aa89-d195-6ed9-9a1a-febe8d0550d2.c4t4d0
    Connections: 0
Target: c4t8d0
    iSCSI Name: iqn.1986-03.com.sun:02:5af80810-aa7c-c8c2-e566-af70bd579219.c4t8d0
    Connections: 0
Target: c4t12d0
    iSCSI Name: iqn.1986-03.com.sun:02:b3120e6c-896c-e3e3-c908-8a43789997d9.c4t12d0
    Connections: 0
hodur#

现在是启动器:

fsh-mullet# iscsiadm add discovery-address 
fsh-mullet# iscsiadm modify discovery -t enable

我们等几秒钟,然后检验目标机器上的状态(注意,现在 4 个 lun 已经从离线状态变为在线状态):

hodur# iscsitadm list target -v
Target: c4t2d0
    iSCSI Name: iqn.1986-03.com.sun:02:aaf6d680-6681-e36e-8497-855decbf8038.c4t2d0
    Connections: 1
        Initiator:
            iSCSI Name: iqn.1986-03.com.sun:01:0003ba73b35b.44d23863
            Alias: fsh-mullet
    ACL list:
    TPGT list:
    LUN information:
        LUN: 0
            GUID: 010000e0812a8f5300002a0044d3ef91
            VID: SUN
            PID: SOLARIS
            Type: raw
            Size:   34G
            Backing store: /dev/rdsk/c4t2d0
            Status: online
Target: c4t4d0
    iSCSI Name: iqn.1986-03.com.sun:02:f935aa89-d195-6ed9-9a1a-febe8d0550d2.c4t4d0
    Connections: 1
        Initiator:
            iSCSI Name: iqn.1986-03.com.sun:01:0003ba73b35b.44d23863
            Alias: fsh-mullet
    ACL list:
    TPGT list:
    LUN information:
        LUN: 0
            GUID: 010000e0812a8f5300002a0044d3ef8e
            VID: SUN
            PID: SOLARIS
            Type: raw
            Size:   34G
            Backing store: /dev/rdsk/c4t4d0
            Status: online
Target: c4t8d0
    iSCSI Name: iqn.1986-03.com.sun:02:5af80810-aa7c-c8c2-e566-af70bd579219.c4t8d0
    Connections: 1
        Initiator:
            iSCSI Name: iqn.1986-03.com.sun:01:0003ba73b35b.44d23863
            Alias: fsh-mullet
    ACL list:
    TPGT list:
    LUN information:
        LUN: 0
            GUID: 010000e0812a8f5300002a0044d3ef8a
            VID: SUN
            PID: SOLARIS
            Type: raw
            Size:   34G
            Backing store: /dev/rdsk/c4t8d0
            Status: online
Target: c4t12d0
    iSCSI Name: iqn.1986-03.com.sun:02:b3120e6c-896c-e3e3-c908-8a43789997d9.c4t12d0
    Connections: 1
        Initiator:
            iSCSI Name: iqn.1986-03.com.sun:01:0003ba73b35b.44d23863
            Alias: fsh-mullet
    ACL list:
    TPGT list:
    LUN information:
        LUN: 0
            GUID: 010000e0812a8f5300002a0044d3ef87
            VID: SUN
            PID: SOLARIS
            Type: raw
            Size:   34G
            Backing store: /dev/rdsk/c4t12d0
            Status: online
hodur# 

现在回到启动器,我们检查一下是否能看到这些设备:

fsh-mullet# format
Searching for disks...done


AVAILABLE DISK SELECTIONS:
       0. c0t0d0 
          /pci@1c,600000/scsi@2/sd@0,0
       1. c0t1d0 
          /pci@1c,600000/scsi@2/sd@1,0
       2. c2t1d0 
          /iscsi/disk@0000iqn.1986-03.com.sun%3A02%3Ab3120e6c-896c-e3e3-c908-8a43789997d9.c4t12d00001,0
       3. c2t2d0 
          /iscsi/disk@0000iqn.1986-03.com.sun%3A02%3A5af80810-aa7c-c8c2-e566-af70bd579219.c4t8d00001,0
       4. c2t4d0 
          /iscsi/disk@0000iqn.1986-03.com.sun%3A02%3Af935aa89-d195-6ed9-9a1a-febe8d0550d2.c4t4d00001,0
       5. c2t5d0 
          /iscsi/disk@0000iqn.1986-03.com.sun%3A02%3Aaaf6d680-6681-e36e-8497-855decbf8038.c4t2d00001,0
Specify disk (enter its number): ^C
fsh-mullet# 

我甚至有可能通过那些 lun 创建一个 RAID-Z。

fsh-mullet# zpool create -f iscs-me raidz c2t1d0 c2t2d0 c2t4d0 c2t5d0
fsh-mullet# zpool status
  pool: iscs-me
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        iscs-me     ONLINE       0     0     0
          raidz1    ONLINE       0     0     0
            c2t1d0  ONLINE       0     0     0
            c2t2d0  ONLINE       0     0     0
            c2t4d0  ONLINE       0     0     0
            c2t5d0  ONLINE       0     0     0

errors: No known data errors
fsh-mullet# 

我刚才是不是听见“Mr. Koolaid”的声音了? ... “太棒了!”



(2008-05-24 19:55:00.0/2008-05-24 19:54:25.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/iscsi_%E8%AE%BE%E7%BD%AE

20080523 Friday May 23, 2008

 zil_disable

人们慢慢发现,设置 'zil_disable' 似乎可以提高他们系统的性能——尤其是 NFS/ZFS 的性能。但是将 'zil_disable' 设置为 1 会产生什么样的结果?它会完全禁用 ZIL。那么,这又意味着什么呢?

禁用 ZIL 的结果是使 ZFS 不能将同步操作立即写入硬盘或存储器中。在禁用 ZIL 的情况下,同步操作(例如 fsync()、O_DSYNC 和 OP_COMMIT for NFS 等等)写入硬盘的速度与异步操作一样。这意味着在数据被提交到稳定的存储器之前,您可以成功返回到应用程序或 NFS 客户端。在遭遇服务器崩溃事件时,如果数据还没有写入到存储器,那么这些数据将永远丢失。

如果 ZIL 禁用,将不会写入 ZIL 日志记录。

注:禁用 ZIL 并不会影响文件系统的完整性。禁用 ZIL 也不会导致 ZFS 的破坏。

但禁用 ZIL 肯定会出现一些问题并造成应用程序的混乱。在以下情况下禁用 ZIL 会导致 NFS 客户端的破坏:在服务器崩溃之前完成对客户端的应答;在数据被提交到稳定存储器之前服务器崩溃。如果您无法忍受这样的事情发生,请不要关闭 ZIL。

修正 6280630 zil synchronicity 后,将不再有可调的 'zil_disable'。

可能有人会质疑,为什么我们要将 'zil_disable' 添加到代码库中?其实,这个功能并不是供人们使用的,而是作为性能测量的一种简便方法(从 ZIL 中隔离出一个区域)。

如果您想了解关于 ZIL 的更多信息,请参考 Neil 的博客 Neelakanth 的博客



(2008-05-23 19:55:00.0/2008-05-23 19:54:24.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/zil_disable1

 zpool 历史记录

ZFS 现在有历史记录了!

出现系统灾难时,您当然很想知道人们对您的池做了些什么,那么您将怎样做呢?到目前为止,还没有很好的方法。进入 'zpool history'。

# zpool create hewitt c1d0
# zfs create hewitt/jen
# zfs create hewitt/jen/love
# zpool history
History for 'hewitt':
2006-10-16.17:54:02 zpool create hewitt c1d0
2006-10-16.17:54:11 zfs create hewitt/jen
2006-10-16.17:54:15 zfs create hewitt/jen/love

#

在 zfs(1M) 和 zpool(1M) 中,所有关于修改池状态的子命令都将持续写入日志。这意味着不管您将池带到了哪里,不管当前访问池的是什么机器(如 SunCluster 故障转移情况),历史记录都将一路跟踪。这就像是您的永久记录。

现在,您可以通过一个简便的方式查看是否有人对您的池做了什么坏事……

bad_admin# zfs set checksum=off hewitt
bad_admin# zfs destroy hewitt/jen/love

good_admin# zpool history              
History for 'hewitt':
2006-10-16.17:54:02 zpool create hewitt c1d0
2006-10-16.17:54:11 zfs create hewitt/jen
2006-10-16.17:54:15 zfs create hewitt/jen/love
2006-10-16.17:54:35 zfs set checksum=off hewitt
2006-10-16.17:57:29 zfs destroy hewitt/jen/love

# 

历史日志使用一个<压缩记录长度、记录 nvlist>元组组成的环状缓冲区实现。更多详细信息,请参考 spa_history.c,它包含了 'zpool history' 的主要核心代码的变更。历史日志的大小是池的 1%,最大值为 32MB,最小值为 128KB。注:通过 'zpool create' 初始创建的池不会被覆盖。

如果您要向 zfs(1m) 或 zpool(1M) 添加一个新的子命令,您需要做的只是调用 zpool_log_history()。如果您想新建一个 'zpool history' 使用者(如 GUI),您需要调用 zpool_get_history(),并且解析它的 nvlist。get_history_one() 是一个很好的例子。

将来,我们还将添加日志 uid、主机名和域名。我们也在考虑向日志中添加“内部事件”,因为实际上一些子命令占用了一个以上的 txg,并且我们希望将每个 txg 的历史记录都记录到日志中(这一点对于开发人员和调试人员比对管理员更有用)。

这些变更将在 snv_51 中反映,我也期待着 s10_u4 能尽快面世(尽管它还没有登上日程)。

享受创造历史记录的快乐吧!



(2008-05-23 18:25:00.0/2008-05-23 18:24:25.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/zpool_%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95

20080522 Thursday May 22, 2008

 通过 zvol 设置 iSCSI 存储器

既然 ZFS 中内置了对 iSCSI 的支持,那么让我们看一下如何通过 zvol 设置存储器。

在服务器上,我们首先建立一个池和一个 zvol,然后在 iSCSI 上共享这个 zvol:

fsh-suzuki# zpool create iscsistore c0t1d0
fsh-suzuki# zfs create -s -V 10gb iscsistore/zvol
fsh-suzuki# zfs set shareiscsi=on iscsistore/zvol
fsh-suzuki# iscsitadm list target -v
Target: iscsistore/zvol
    iSCSI Name: iqn.1986-03.com.sun:02:a7f19760-5d17-ee50-f011-c4c749add692
    Alias: iscsistore/zvol
    Connections: 0
    ACL list:
    TPGT list:
    LUN information:
        LUN: 0
            GUID: 0x0
            VID: SUN
            PID: SOLARIS
            Type: disk
            Size:   10G
            Backing store: /dev/zvol/rdsk/iscsistore/zvol
            Status: online
fsh-suzuki# 

现在在客户端上,我们需要搜索 iSCSI 共享(服务器的 IP 地址是 192.168.16.135):

fsh-weakfish# iscsiadm list discovery
Discovery:
        Static: disabled
        Send Targets: enabled
        iSNS: disabled
fsh-weakfish# iscsiadm modify discovery --sendtargets enable
fsh-weakfish# iscsiadm add discovery-address 192.168.16.135
fsh-weakfish# svcadm enable network/iscsi_initiator
fsh-weakfish# iscsiadm list target
Target: iqn.1986-03.com.sun:02:a7f19760-5d17-ee50-f011-c4c749add692
        Alias: iscsistore/zvol
        TPGT: 1
        ISID: 4000002a0000
        Connections: 1
fsh-weakfish# 

现在我们可以使用 iSCSI 设备在客户端上创建一个池:

fsh-weakfish# format
Searching for disks...done


AVAILABLE DISK SELECTIONS:
       0. c1t1d0 
          /pci@0,0/pci1022,7450@a/pci17c2,10@4/sd@1,0
       1. c2t01000003BAAAE84F00002A0045F86E49d0 
          /scsi_vhci/disk@g01000003baaae84f00002a0045f86e49
Specify disk (enter its number): ^C
fsh-weakfish# zpool create i c2t01000003BAAAE84F00002A0045F86E49d0
fsh-weakfish# zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
i                      9.94G     89K   9.94G     0%  ONLINE     -
fsh-weakfish# zpool status
  pool: i
 state: ONLINE
 scrub: none requested
config:

        NAME                                     STATE     READ WRITE CKSUM
        i                                        ONLINE       0     0     0
          c2t01000003BAAAE84F00002A0045F86E49d0  ONLINE       0     0     0

errors: No known data errors
fsh-weakfish# 

很好,就是这样!



(2008-05-22 16:21:00.0/2008-05-22 16:20:22.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/%E9%80%9A%E8%BF%87_zvol_%E8%AE%BE%E7%BD%AE_iscsi_%E5%AD%98%E5%82%A8%E5%99%A8

 sharemgr——一种新的共享方式

2006 年 11 月(snv_53),Doug 介绍了 sharemgr(1M) 工具,这是一种用于帮助您在 Solaris 上管理 NFS 共享的新方法

他还有一篇相关的博客:sharemgr 当前如何与 ZFS 交互

感谢分享
Eric



(2008-05-22 15:24:00.0/2008-05-22 15:23:23.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/sharemgr_%E4%B8%80%E7%A7%8D%E6%96%B0%E7%9A%84%E5%85%B1%E4%BA%AB%E6%96%B9%E5%BC%8F

20080521 Wednesday May 21, 2008

 结束“穷人群集”的破坏

补丁 6282725 hostname/hostid should be stored in the label 在导入池时引入了主机 ID 检测。
如果上次访问这个池的是另一个系统,那么这个导入操作将被拒绝(当然可以通过 '-f' 标志重写)。

这对于那些使用他们自己的群集(也就是所谓“穷人群集”)的人来说尤其重要。人们需要的是:

1)clientA 创建池(使用共享存储器)
2)clientA 重启/崩溃
3)clientB 强制导入这个池
4)clientA 启动完成
5)clientA 通过 /etc/zfs/zpool.cache 自动导入池

在这里,clientA 和 clientB 导入了同样的池,并且两者都可以对它写入——但是 ZFS 本身
不支持多个写入器,因此这两个客户端将很快破坏这个池,因为它们看到的池的状态不同。

既然我们在标签中储存了主机 ID,并且验证了导入池的系统是最后一个访问该池的系统,
那么上面提到的穷人群集的破坏则无法再发生。下面是一个使用 iSCSI 上的共享存储器的例子。
在这个例子当中,clientA 是 'fsh-weakfish',clientB 是 'fsh-mullet'。

首先,让我们在 clientA 上创建一个池(假设两个客户端都已经在 iSCSI 上设置完毕):

fsh-weakfish# zpool create i c2t01000003BAAAE84F00002A0045F86E49d0
fsh-weakfish# zpool status
  pool: i
 state: ONLINE
 scrub: none requested
config:

        NAME                                     STATE     READ WRITE CKSUM
        i                                        ONLINE       0     0     0
          c2t01000003BAAAE84F00002A0045F86E49d0  ONLINE       0     0     0

errors: No known data errors
fsh-weakfish# zfs create i/wombat
fsh-weakfish# zfs create i/hulio 
fsh-weakfish# zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
i          154K  9.78G    19K  /i
i/hulio     18K  9.78G    18K  /i/hulio
i/wombat    18K  9.78G    18K  /i/wombat
fsh-weakfish#

注意对 clientB 报告中的增强信息 'zpool import':

fsh-mullet# zpool import
  pool: i
    id: 8574825092618243264
 state: ONLINE
status: The pool was last accessed by another system.
action: The pool can be imported using its name or numeric identifier and
        the '-f' flag.
   see: http://www.sun.com/msg/ZFS-8000-EY
config:

        i                                        ONLINE
          c2t01000003BAAAE84F00002A0045F86E49d0  ONLINE
fsh-mullet# zpool import i
cannot import 'i': pool may be in use from other system, it was last accessed by
fsh-weakfish (hostid: 0x4ab08c2) on Tue Apr 10 09:33:07 2007
use '-f' to import anyway
fsh-mullet#

我们希望在 clientA 关机之前不要强制导入这个池。因此在重启 clientA (fsh-weakfish) 之后,
在 clientB (fsh-mullet) 上强制导入:

fsh-weakfish# reboot
....

fsh-mullet# zpool import -f i
fsh-mullet# zpool status
  pool: i
 state: ONLINE
 scrub: none requested
config:

        NAME                                     STATE     READ WRITE CKSUM
        i                                        ONLINE       0     0     0
          c2t01000003BAAAE84F00002A0045F86E49d0  ONLINE       0     0     0

errors: No known data errors
fsh-mullet#

clientA 完成启动之后,我们通过 syslog 来看一下这个消息:

WARNING: pool 'i' could not be loaded as it was last accessed by another system
(host: fsh-mullet hostid: 0x8373b35b).  See: http://www.sun.com/msg/ZFS-8000-EY

然后仔细检查,确认池 'i' 事实上没有被加载:

fsh-weakfish# zpool list
no pools available
fsh-weakfish# 

之后核实一下,这个池从 clientB 的角度来看还没有被破坏,我们看到:

fsh-mullet# zpool scrub i
fsh-mullet# zpool status
  pool: i
 state: ONLINE
 scrub: scrub completed with 0 errors on Tue Apr 10 10:28:03 2007
config:

        NAME                                     STATE     READ WRITE CKSUM
        i                                        ONLINE       0     0     0
          c2t01000003BAAAE84F00002A0045F86E49d0  ONLINE       0     0     0

errors: No known data errors
fsh-mullet# zfs list
NAME       USED  AVAIL  REFER  MOUNTPOINT
i          156K  9.78G    21K  /i
i/hulio     18K  9.78G    18K  /i/hulio
i/wombat    18K  9.78G    18K  /i/wombat
fsh-mullet# 

很好,永别了,穷人群集的破坏。

我想指出的一个细节是,您需要对强制导入一个池的*时间*多加注意。例如,
如果您在重启 clientA *之前*在 clientB 上强制导入一个池,那么破坏仍然会发生。这是因为
命令 reboot(1M) 会完全占用系统,这意味着它将取消所有文件系统的挂载,而取消 文件系统的挂载将对池写入一些数据。

您可以使用 zdb(1M) 查看标签上的最新信息:

fsh-mullet# zdb -l /dev/dsk/c2t01000003BAAAE84F00002A0045F86E49d0s0
--------------------------------------------
LABEL 0
--------------------------------------------
    version=6
    name='i'
    state=0
    txg=665
    pool_guid=8574825092618243264
    hostid=2205397851
    hostname='fsh-mullet'
    top_guid=5676430250453749577
    guid=5676430250453749577
    vdev_tree
        type='disk'
        id=0
        guid=5676430250453749577
        path='/dev/dsk/c2t01000003BAAAE84F00002A0045F86E49d0s0'
        devid='id1,ssd@x01000003baaae84f00002a0045f86e49/a'
        whole_disk=1
        metaslab_array=14
        metaslab_shift=26
        ashift=9
        asize=10724048896
        DTL=30
--------------------------------------------
LABEL 1
--------------------------------------------
...


(2008-05-21 20:36:55.0/2008-05-21 19:24:24.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/%E7%BB%93%E6%9D%9F_%E7%A9%B7%E4%BA%BA%E7%BE%A4%E9%9B%86_%E7%9A%84%E7%A0%B4%E5%9D%8F

 NFSv4 的大文件句柄 —— NFSv2 的末日

通过 Solaris NFS 服务器创建的文件句柄看起来是什么样子的呢?如果我们看一看 fhandle_t 结构, 就可以看到它的布局:

struct svcfh {
    fsid_t	fh_fsid;			/* filesystem id */
    ushort_t    fh_len;			        /* file number length */
    char	fh_data[NFS_FHMAXDATA];		/* and data */
    ushort_t    fh_xlen;			/* export file number length */
    char	fh_xdata[NFS_FHMAXDATA];	/* and data */
};
typedef struct svcfh fhandle_t;

其中 fh_len 表示 fh_data 中有效字节的长度,同样,fh_xlenfh_xdata 的长度。注意,NFS_FHMAXDATA 以前是这样定义的:

#define	NFS_FHMAXDATA	((NFS_FHSIZE - sizeof (struct fhsize) + 8) / 2)

为了避免混淆,我移除了 fhsize,并将它缩短为:

#define NFS_FHMAXDATA    10

好了, 但是 fh_data 是从哪里来的呢?它是本地文件系统的 FID (通过 VOP_FID)。fh_data 表示文件句柄的真实文件,fh_xdata 表示导出的文件/目录。所以对于 NFSv2 和 NFSv3, 文件句柄基本上都是这种形式:
fsid + file FID + exported FID

NFSv4 也几乎完全一样,不同之处是在结尾处添加了两个字段。您可以在 nfs_fh4_fmt_t 中看到它的基本布局:

struct nfs_fh4_fmt {
 	fhandle_ext_t fh4_i;
 	uint32_t      fh4_flag;
 	uint32_t      fh4_volatile_id;
};

fh4_flag 用于从“常规的”文件中区分指定的属性,fh4_volatile_id 目前仅仅用做测试目的——当然是为了测试各种可变的文件句柄。因为 Solaris 没有本地文件系统,也没有稳定的文件句柄,所以我们并不十分需要使用 fh4_volatile_id

好,让我们回到 NFS_FHMAXDATA 中那个不可思议的“10”,那里到底发生了什么? 将这些字段加起来, 您得到: 8(fsid) + 2(len) + 10(data) + 2(xlen) + 10(xdata) = 32 字节。NFSv2 的协议限制是什么?——查一下 "FHSIZE" 就知道了。目前 Solaris 服务器将文件句柄限定为 10 字节的 FID 只是为了与 NFSv2 兼容。注意,为了正常运行,特意将这个限制带到本地文件系统中。检验 UFS 的 ufid:

/*
 * This overlays the fid structure (see vfs.h)
 *
 * LP64 note: we use int32_t instead of ino_t since UFS does not use
 * inode numbers larger than 32-bits and ufid's are passed to NFS
 * which expects them to not grow in size beyond 10 bytes (12 including
 * the length).
 */
struct ufid {
 	ushort_t ufid_len;
 	ushort_t ufid_flags;
	int32_t	ufid_ino;
 	int32_t	ufid_gen;
};

注意,NFSv3 的协议限制是 64 字节,NFSv4 的协议限制是 128 字节。所以这两种文件系统理论上可以发布大文件句柄,但是它们对现有数据还不能这样做,这主要有两个原因: 首先还没有这样的需求,更重要的是,在做出任何改动之前,文件句柄必须在通信上保持一致。如果这个问题得不到解决,那么当更长的文件句柄被引入时,所有有活动挂载点的客户端将得到一个 STALE 错误。想象一下,一个服务器在 NFSV3 上为一个文件发放一个 32 字节的文件句柄,然后这个服务器被升级,现在可以发放 64 字节的文件句柄——即使所有多出的 32 字节都被设为 0,那也是一个不同的句柄,客户端将视其为一个 STALE 引用。这种情况下,使用强制取消挂载或者重启客户端可以解决这个问题。但是,为了一个简单的(也应该是无害的)服务器升级,而强制让所有活动的客户端执行一些手动的管理操作似乎有点可笑。

所以我的博客标题应该是:如何让文件句柄变得更大——这与我上文几乎是矛盾的。要注意的关键一点是,那些从没有通过 NFS 提供的文件也绝不会有一个为它们生成的文件句柄,所以它们可以是协议允许的任意长度,我们不用担心 STALE 文件句柄问题。

如果您不熟悉 ZFS 的 .zfs/snapshot,很快会有一个关于它的博客文章。通常它会在根目录的 "main" 文件系统下放置一个 .zfs 文件,所有创建的快照将放到 .zfs/snapshot 下的命名空间中。示例如下:

fsh-mullet# zfs snapshot bw_hog@monday
fsh-mullet# zfs snapshot bw_hog@tuesday
fsh-mullet# ls -a /bw_hog
.         ..        .zfs      aces.txt  is.txt    zfs.txt
fsh-mullet# ls -a /bw_hog/.zfs/snapshot
.        ..       monday   tuesday
fsh-mullet# ls -a /bw_hog/.zfs/snapshot/monday
.         ..        aces.txt  is.txt    zfs.txt
fsh-mullet#

通过对 .zfs/snapshot 的介绍,我们现在左右为难 —— 要么只使可以做“镜像挂载(mirror mounts)”的 NFS 客户端访问 .zfs 目录,要么为 .zfs 下的文件增加 ZFS 的 fid。“镜像挂载”将允许我们执行技术上正确的解决方案:为 "main" 文件系统及其所有快照设置一个唯一的 FSID。这就需要 NFS 客户端跨越服务器挂载点。后一种选择是,为 "main" 文件系统及其所有快照设置一个 FSID。这意味着 "main" 文件系统下相同的文件及其任意一个快照看起来是一样的 —— 所以 NFS 上 "cp" 这样的命令不会喜欢它。

“镜像挂载”是我们的专有词汇,它是为了让客户端跨越服务器文件系统的边界 —— 正如 FSID (文件系统标识符)规定的那样。这在 NFSv4 中是完全合法的(请参见 rfc 3530 中的以下章节:"7.7 Mount Point Crossing" 和 "5.11.7. mounted_on_fileid")。NFSv3 并不是真正允许这个功能(请参见这里 "3.3.3 Procedure 3: LOOKUP - Lookup filename")。尽管需要一些技巧,我还是确信它能够实现(也许通过自动挂载程序)。

镜像挂载的问题是,还没有人曾经真正实现过它们。所以如果我们执行技术上更加正确的解决方案,为 "main" 的本地文件系统及其全部快照设置一个唯一的 FSID,只有 Solaris Update 2(?)NFSv4 客户端能够在初始传递的 ZFS 上访问 .zfs 文件。这看起来很傻。

如果我们能够在这个唯一的 FSID 上稍做让步,那么所有现存的 NFS 客户端都可以访问 .zfs 文件。这看起来更有吸引力。哦,等一下,有一个小问题。我们希望至少 "main" 文件系统中文件的文件句柄与快照的文件句柄是不一样的,这样可以保证 NFS 不至于完全混乱。一个小问题是,我们现在发放的文件句柄是 32 字节的 NFSv2 协议限制(见上文)下的最高值。如果我们向文件句柄中添加任何特殊位(如一个快照标识符),那么 v2 就无法处理了。

您知道吗?糟糕的 v2。说真的,这真是个老古董,早该到一边去了。既然快照标识符并不需要被添加到 "main" 文件系统中,non-.zfs 快照文件的 FID 将保留同样的大小,使之能在 NFSv2 的限制之内。 这样我们就可以在 NFSv2 上访问 ZFS,只是会被拒绝。这就是 ZFS 的好处。

fsh-weakfish# mount -o vers=2 fsh-mullet:/bw_hog /mnt
fsh-weakfish# ls /mnt/.zfs/snapshot/      
monday   tuesday
fsh-weakfish# ls /mnt/.zfs/snapshot/monday
/mnt/.zfs/snapshot/monday: Object is remote
fsh-weakfish# 

那么 v3 和v4 的情况如何?既然 v4 是 Solaris 所默认的,并且它的代码相对简单,那么现在我改变 v4 来处理大文件句柄。NFSv3 很快就会推出。我们除了通过 fhandle4_t 将它扩展了一点点之外,它的结构基本上与 fhandle_t 相同。

/*
 * This is the in-memory structure for an NFSv4 extended filehandle.
 */
typedef struct {
        fsid_t  fhx_fsid;                       /* filesystem id */
        ushort_t fhx_len;                       /* file number length */
        char    fhx_data[NFS_FH4MAXDATA];    /* and data */
        ushort_t fhx_xlen;                      /* export file number length */
        char    fhx_xdata[NFS_FH4MAXDATA];   /* and data */
} fhandle4_t;

因此,唯一的区别是 FID 最多可以有 26 字节而不是 10 字节。那么,为什么是 26?NFSv3 的协议限制是 64 字节。如果我们需要为 NFSv4 提供比 64 字节更大的文件句柄,也很容易修改 —— 只要创建一个适用于更大 FID 的新结构,并且应用到 NFSv4。为什么将来做这个修改比过去更容易呢?为了使 NFSv4 文件句柄向后兼容,我需要做的部分工作是:当文件句柄确实是 XDR'd 时,我们需要对它们进行解析,这样过去以 10 字节 FID(基于 fhandle_t 结构)发放的文件句柄将在 10 字节 FID 的基础上继续发放,但与此同时,也允许返回比 10 字节更大的 FID的VOP_FID()(如 .zfs)。因此,根据本地文件系统的需求,NFSv4 将返回不同长度的文件句柄。

查看老代码 xdr_nfs_resop4(了解到文件句柄作为一个连续字节集是安全的),只需执行以下操作:

case OP_GETFH:
	if (!xdr_int(xdrs,
		     (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
		return (FALSE);
	if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
		return (TRUE);
	return (xdr_bytes(xdrs,
	    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
	    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
	    NFS4_FHSIZE));

现在,我们并不是简单地做一个 xdr_bytes,而是使用了 fhandle_ext_t 模板并且内部永远留有 26 字节 FID 的空间。但是对于 OTW,我们跳过了一些字节,这取决于 fhx_lenfhx_xlen,请参见 xdr_encode_nfs_fh4

2005 年关于文件句柄的内容,这些就足够了。



(2008-05-21 20:37:29.0/2008-05-21 18:24:23.0) Permalink Comments [4]
Trackback: http://blogs.sun.com/erickustarz/zh/entry/nfsv4_%E7%9A%84%E5%A4%A7%E6%96%87%E4%BB%B6%E5%8F%A5%E6%9F%84_nfsv2_%E7%9A%84%E6%9C%AB%E6%97%A5

20080520 Tuesday May 20, 2008

 被破坏的文件和 'zpool status -v'

如果 ZFS 探测到一个校验和错误或者 I/O 读取失败,并且无法修正这个错误(比方说通过从镜像的另一方成功读取),那么系统会为持久破坏的对象储存一个日志(可能由于无提示破坏)。

以前(即 snv_57 之前),我们的输出起到的作用很小:

# zpool status -v
  pool: monkey
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        monkey      ONLINE      26     0     0
          c1t1d0s7  ONLINE      12     0     0
          c1t1d0s6  ONLINE      14     0     0

errors: The following persistent errors have been detected:

          DATASET  OBJECT  RANGE
          0x0      0x13    lvl=0 blkid=0
          0x5      0x4     lvl=0 blkid=0
          0x17     0x4     lvl=0 blkid=0
          0x1d     0x4     lvl=0 blkid=0
          0x24     0x5     lvl=0 blkid=0
          0x2a     0x4     lvl=0 blkid=0
          0x2a     0x6     lvl=0 blkid=0
          0x30     0x4     lvl=0 blkid=0
          0x36     0x0     lvl=0 blkid=2

幸运的话,DATASET 对象编号将被转换成一个数据集名称。否则,您将需要使用 zdb(1M) 来确定数据集名称和挂载点。之后,您还需要使用 find(1) 的 '-inum' 选项来确定实际文件(请参考 opensolaris 线程)。拥有这样的功能真的很有用,ZFS 将为您完成所有苦活累活,这真是太棒了——毕竟,我们一直希望管理能够变得更加轻松。

回顾 6410433 'zpool status -v' would be more useful with filenames 可以发现,它的可观察性也大大提高了!

# zpool status -v
  pool: monkey
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        monkey      ONLINE      24     0     0
          c1t1d0s6  ONLINE      10     0     0
          c1t1d0s7  ONLINE      14     0     0

errors: Permanent errors have been detected in the following files:

        /monkey/a.txt
        /monkey/bananas/b.txt
        /eric/c.txt
        /monkey/sub/dir/d.txt
        monkey/ghost:/e.txt
        monkey/ghost:/boo/f.txt
        monkey/dnode:<0x0>
        <metadata>:<0x13>

对于上面的列表,我们尝试打印出文件的完整路径。如果成功地找到完整路径和挂载的数据集,则打印出带有前缀 "/" 的完整路径(比如上例中的 "/monkey/a.txt")。如果我们成功地找到完整路径,但是数据集并没有被挂载,则打印出数据集名称(没有前缀 "/"),后跟数据集内部的文件路径(参见上例中的 "monkey/ghost:/e.txt")。

如果我们不能成功地将对象编号转化为一个文件路径(或许是由于错误;或许是由于对象没有一个与之关联的真实文件路径,比如 dnode_t 就是这种情况),则打印出数据集名称,后跟对象编号(正如上例中的 "monkey/dnode:<0x0>")。如果 MOS 中的一个对象被破坏,则打印出特殊的标签 <metadata>,后跟对象编号。

通过对上述内容的了解,您应该对 ZFS 的故障管理和可观察性有了深刻的印象。其他的文件系统或存储器系统能为您提供这样的功能吗?

注:这些变化出现在 snv_57 中,很有可能会集成到 s10u4,甚至 Leopard 中。:)

如果您迷恋于老式二进制位(没有上面提到的变化),并且希望将对象编号转化到文件名中,可以参考此线程



(2008-05-21 20:52:14.0/2008-05-20 19:24:24.0) Permalink
Trackback: http://blogs.sun.com/erickustarz/zh/entry/%E8%A2%AB%E7%A0%B4%E5%9D%8F%E7%9A%84%E6%96%87%E4%BB%B6%E5%92%8C_zpool_status_v


« 十二月 2009
星期日星期一星期二星期三星期四星期五星期六
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today


XML





Today's Page Hits: 184