Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1315852
  • 博文数量: 554
  • 博客积分: 10425
  • 博客等级: 上将
  • 技术积分: 7555
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-09 09:49
文章分类

全部博文(554)

文章存档

2012年(1)

2011年(1)

2009年(8)

2008年(544)

分类:

2008-04-11 16:08:36


第27 章• io 提供器357
b_iodone 字段标识I/O 完成时内核中调用的特定例程。
b_error 字段可能包含发生I/O 错误时从驱动程序返回的错误代码。b_error 将与在b_flags
成员中设置的B_ERROR 位一起设置。
b_edev 字段包含所访问设备的主要和次要设备编号。使用者可使用D子例程getmajor() 和
getminor() 从b_edev 字段中提取主要和次要设备编号。
devinfo_t
devinfo_t 结构提供有关设备的信息。start、done、wait-start 和wait-done 探测器中的
args[1] 指向对应于I/O 的目标设备的devinfo_t 结构。devinfo_t 的成员如下所示:
typedef struct devinfo {
int dev_major; /* major number */
int dev_minor; /* minor number */
int dev_instance; /* instance number */
string dev_name; /* name of device */
string dev_statname; /* name of device + instance/minor */
string dev_pathname; /* pathname of device */
} devinfo_t;
dev_major 字段是设备的主要编号。有关更多信息,请参见getmajor(9F)。
dev_minor 字段是设备的次要编号。有关更多信息,请参见getminor(9F)。
dev_instance 字段是设备的实例编号。设备实例不同于次要编号。次要编号是由设备驱动
程序管理的抽象对象。实例编号是设备节点的一个属性。可使用prtconf(1M) 来显示设备
节点实例编号。
dev_name 字段是用于管理设备的设备驱动程序的名称。可使用prtconf(1M) 的-D 选项显示
设备驱动程序名称。
dev_statname 字段是iostat(1M) 报告的设备名称。此名称同时对应于kstat(1M) 报告的内
核统计信息的名称。提供此字段是为了便于快速地将异常的iostat 或kstat 输出与实际
I/O 活动相关联。
dev_pathname 字段是设备的完整路径。此路径可指定为prtconf(1M) 的参数,以获取详细的
设备信息。dev_pathname 指定的路径包括用于表示设备节点、实例编号和次要节点的组
件。但是,不必在统计信息名称中表示所有这三个元素。对于某些设备,统计信息名称由
参数
358 Solaris 动态跟踪指南• 2006 年7 月
设备名称和实例编号组成。对于其他设备,统计信息名称则由设备名称和次要节点编号组
成。因此,具有相同dev_statname 的两个设备的dev_pathname 可能会不同。
fileinfo_t
fileinfo_t 结构提供有关文件的信息。start、done、wait-start 和wait-done 探测器中的
args[2] 指向I/O 所对应的文件。在分发I/O 请求时,文件信息存在与否将取决于提供此信
息的文件系统。某些文件系统(尤其是第三方文件系统)可能不会提供此信息。I/O 请求也
可能是从不包含任何文件信息的文件系统发出的。例如,对文件系统元数据的任何I/O 请
求,将不会与任何一个文件关联。最后,一些高度优化的文件系统可能将不相交文件中的
I/O 聚集为单个I/O 请求。在此情况下,文件系统可能会为表示大多数I/O 的文件或表示部
分I/O 的文件提供文件信息。或者,在此情况下文件系统可能根本不提供任何文件信息。
fileinfo_t 结构的定义如下所示:
typedef struct fileinfo {
string fi_name; /* name (basename of fi_pathname) */
string fi_dirname; /* directory (dirname of fi_pathname) */
string fi_pathname; /* full pathname */
offset_t fi_offset; /* offset within file */
string fi_fs; /* filesystem */
string fi_mount; /* mount point of file system */
} fileinfo_t;
fi_name 字段包含文件的名称,但不包括任何目录部分。如果没有任何文件信息与I/O 关
联,则fi_name 字段将设置为字符串。在极少数情况下,与文件关联的路径名可能
未知。在此情况下,fi_name 字段将设置为字符串
fi_dirname 字段仅包含文件名的目录部分。与fi_name 一样,如果不存在任何文件信息,则
此字符串可能会设置为;如果与该文件关联的路径名未知,则此字符串可能会设置

fi_pathname 字段包含文件的完整路径名。与fi_name 一样,如果不存在任何文件信息,此
字符串可能会设置为;如果与该文件关联的路径名未知,此字符串可能会设置为

fi_offset 字段包含文件中的偏移,如果文件信息不存在或者文件系统未指定偏移,则此字
段将为1。
参数
第27 章• io 提供器359
示例
以下示例脚本显示了发出每个I/O 时的相关信息:
#pragma D option quiet
BEGIN
{
printf("%10s %58s %2s\n", "DEVICE", "FILE", "RW");
}
io:::start
{
printf("%10s %58s %2s\n", args[1]->dev_statname,
args[2]->fi_pathname, args[0]->b_flags & B_READ ? "R" : "W");
}
在x86 膝上型计算机系统上冷启动Acrobat Reader 时的示例输出与以下示例类似:
# dtrace -s ./iosnoop.d
DEVICE FILE RW
cmdk0 /opt/Acrobat4/bin/acroread R
cmdk0 /opt/Acrobat4/bin/acroread R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/AcroVersion R
cmdk0 R
cmdk0 R
cmdk0 R
示例
360 Solaris 动态跟踪指南• 2006 年7 月
cmdk0 R
cmdk0 R
cmdk0 /usr/lib/locale/iso_8859_1/iso_8859_1.so.3 R
cmdk0 /usr/lib/locale/iso_8859_1/iso_8859_1.so.3 R
cmdk0 /usr/lib/locale/iso_8859_1/iso_8859_1.so.3 R
cmdk0 R
cmdk0 R
cmdk0 R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
示例
第27 章• io 提供器361
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libreadcore.so.4.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/bin/acroread R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libAGM.so.3.0 R
cmdk0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libAGM.so.3.0 R
cmdk0 /opt/Acrobat4/Reader/intelsolaris/lib/libAGM.so.3.0 R
...
输出中的 条目指示I/O 与任何特定文件中的数据都不对应:这些I/O 是由于元数据
的形式不同造成的。输出中的 条目指示该文件的路径名未知。此情况相对较
少。
可通过使用关联数组跟踪每个I/O 所花费的时间来使示例脚本更加完善,如下例所示:
#pragma D option quiet
BEGIN
{
printf("%10s %58s %2s %7s\n", "DEVICE", "FILE", "RW", "MS");
}
示例
362 Solaris 动态跟踪指南• 2006 年7 月
io:::start
{
start[args[0]->b_edev, args[0]->b_blkno] = timestamp;
}
io:::done
/start[args[0]->b_edev, args[0]->b_blkno]/
{
this->elapsed = timestamp - start[args[0]->b_edev, args[0]->b_blkno];
printf("%10s %58s %2s %3d.%03d\n", args[1]->dev_statname,
args[2]->fi_pathname, args[0]->b_flags & B_READ ? "R" : "W",
this->elapsed / 10000000, (this->elapsed / 1000) % 1000);
start[args[0]->b_edev, args[0]->b_blkno] = 0;
}
在将USB 存储设备热插拔到空闲的x86 膝上型计算机系统中时,上述示例的输出将如下例
所示:
# dtrace -s ./iotime.d
DEVICE FILE RW MS
cmdk0 /kernel/drv/scsa2usb R 24.781
cmdk0 /kernel/drv/scsa2usb R 25.208
cmdk0 /var/adm/messages W 25.981
cmdk0 /kernel/drv/scsa2usb R 5.448
cmdk0 W 4.172
示例
第27 章• io 提供器363
cmdk0 /kernel/drv/scsa2usb R 2.620
cmdk0 /var/adm/messages W 0.252
cmdk0 R 3.213
cmdk0 W 3.011
cmdk0 R 2.197
cmdk0 /var/adm/messages W 2.680
cmdk0 W 0.436
cmdk0 /var/adm/messages W 0.542
cmdk0 W 0.339
cmdk0 /var/adm/messages W 0.414
cmdk0 W 0.344
cmdk0 /var/adm/messages W 0.361
cmdk0 W 0.315
cmdk0 /var/adm/messages W 0.421
cmdk0 W 0.349
cmdk0 R 1.524
cmdk0 R 3.648
cmdk0 /usr/lib/librcm.so.1 R 2.553
cmdk0 /usr/lib/librcm.so.1 R 1.332
cmdk0 /usr/lib/librcm.so.1 R 0.222
cmdk0 /usr/lib/librcm.so.1 R 0.228
cmdk0 /usr/lib/librcm.so.1 R 0.927
cmdk0 R 1.189
...
示例
364 Solaris 动态跟踪指南• 2006 年7 月
cmdk0 /usr/lib/devfsadm/linkmod R 1.110
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_audio_link.so R 1.763
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_audio_link.so R 0.161
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_cfg_link.so R 0.819
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_cfg_link.so R 0.168
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_disk_link.so R 0.886
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_disk_link.so R 0.185
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_fssnap_link.so R 0.778
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_fssnap_link.so R 0.166
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_lofi_link.so R 1.634
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_lofi_link.so R 0.163
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_md_link.so R 0.477
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_md_link.so R 0.161
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_misc_link.so R 0.198
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_misc_link.so R 0.168
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_misc_link.so R 0.247
cmdk0 /usr/lib/devfsadm/linkmod/SUNW_misc_link_i386.so R 1.735
...
可以根据此输出从多方面观察该系统的结构。首先,应注意到前几个I/O 操作的执行时间很
长,每个操作所花费的时间大概是25 毫秒。此执行时间可能是由于膝上型计算机上的
cmdk0 设备的电源管理造成的。其次,应观察到由于要处理USB 海量存储设备而装入
scsa2usb(7D) 驱动程序时产生的I/O。第三,应注意到在报告设备时将写入
/var/adm/messages。最后,应观察到对设备链接生成器(文件名以link.so 结尾)的读
取,它们可能用于处理新设备。
通过io 提供器可以深入了解iostat(1M) 输出。假定您观察到类似以下示例的iostat 输出

extended device statistics
示例
第27 章• io 提供器365
device r/s w/s kr/s kw/s wait actv svc_t %w %b
cmdk0 8.0 0.0 399.8 0.0 0.0 0.0 0.8 0 1
sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
sd2 0.0 109.0 0.0 435.9 0.0 1.0 8.9 0 97
nfs1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
nfs2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
可使用iotime.d 脚本来查看所发生的I/O,如下例所示:
DEVICE FILE RW MS
sd2 /mnt/archives.tar W 0.856
sd2 /mnt/archives.tar W 0.729
sd2 /mnt/archives.tar W 0.890
sd2 /mnt/archives.tar W 0.759
sd2 /mnt/archives.tar W 0.884
sd2 /mnt/archives.tar W 0.746
sd2 /mnt/archives.tar W 0.891
sd2 /mnt/archives.tar W 0.760
sd2 /mnt/archives.tar W 0.889
cmdk0 /export/archives/archives.tar R 0.827
sd2 /mnt/archives.tar W 0.537
sd2 /mnt/archives.tar W 0.887
sd2 /mnt/archives.tar W 0.763
sd2 /mnt/archives.tar W 0.878
sd2 /mnt/archives.tar W 0.751
sd2 /mnt/archives.tar W 0.884
示例
366 Solaris 动态跟踪指南• 2006 年7 月
sd2 /mnt/archives.tar W 0.760
sd2 /mnt/archives.tar W 3.994
sd2 /mnt/archives.tar W 0.653
sd2 /mnt/archives.tar W 0.896
sd2 /mnt/archives.tar W 0.975
sd2 /mnt/archives.tar W 1.405
sd2 /mnt/archives.tar W 0.724
sd2 /mnt/archives.tar W 1.841
cmdk0 /export/archives/archives.tar R 0.549
sd2 /mnt/archives.tar W 0.543
sd2 /mnt/archives.tar W 0.863
sd2 /mnt/archives.tar W 0.734
sd2 /mnt/archives.tar W 0.859
sd2 /mnt/archives.tar W 0.754
sd2 /mnt/archives.tar W 0.914
sd2 /mnt/archives.tar W 0.751
sd2 /mnt/archives.tar W 0.902
sd2 /mnt/archives.tar W 0.735
sd2 /mnt/archives.tar W 0.908
sd2 /mnt/archives.tar W 0.753
此输出似乎说明正在从cmdk0(在/export/archives 中)读取文件archives.tar,且正在将
该文件写入到设备sd2(在/mnt 中)。这种并行地对名为archives.tar 的两个文件进行独
立处理的情况似乎不可能存在。为了进一步地深入了解,可对设备、应用程序、进程ID 和
所传送的字节数进行聚集,如下例所示:
#pragma D option quiet
示例
第27 章• io 提供器367
io:::start
{
@[args[1]->dev_statname, execname, pid] = sum(args[0]->b_bcount);
}
END
{
printf("%10s %20s %10s %15s\n", "DEVICE", "APP", "PID", "BYTES");
printa("%10s %20s %10d ", @);
}
运行此脚本几秒钟后将生成与以下示例类似的输出:
# dtrace -s ./whoio.d
^C
DEVICE APP PID BYTES
cmdk0 cp 790 1515520
sd2 cp 790 1527808
此输出说明此活动是将文件archives.tar 从一个设备复制到另一个设备。此结论会很自然
地引出另一个问题: 这些设备中是否有一个设备的运行速度比另一个设备的运行速度更快
? 哪个设备限制了复制操作?要回答这些问题,您需要知道每个设备的有效吞吐量而不是
每个设备每秒传送的字节数。可以使用以下示例脚本来确定吞吐量:
#pragma D option quiet
io:::start
{
start[args[0]->b_edev, args[0]->b_blkno] = timestamp;
示例
368 Solaris 动态跟踪指南• 2006 年7 月
}
io:::done
/start[args[0]->b_edev, args[0]->b_blkno]/
{
/*
* We want to get an idea of our throughput to this device in KB/sec.
* What we have, however, is nanoseconds and bytes. That is we want
* to calculate:
*
* bytes / 1024
* ------------------------
* nanoseconds / 1000000000
*
* But we can’t calculate this using integer arithmetic without losing
* precision (the denomenator, for one, is between 0 and 1 for nearly
* all I/Os). So we restate the fraction, and cancel:
*
* bytes 1000000000 bytes 976562
* --------- * ------------- = --------- * -------------
* 1024 nanoseconds 1 nanoseconds
*
* This is easy to calculate using integer arithmetic; this is what
* we do below.
示例
第27 章• io 提供器369
*/
this->elapsed = timestamp - start[args[0]->b_edev, args[0]->b_blkno];
@[args[1]->dev_statname, args[1]->dev_pathname] =
quantize((args[0]->b_bcount * 976562) / this->elapsed);
start[args[0]->b_edev, args[0]->b_blkno] = 0;
}
END
{
printa(" %s (%s)\n%@d\n", @);
}
运行示例脚本几秒钟后会产生以下输出:
sd2 (/devices/pci@0,0/pci1179,1@1d/storage@2/disk@0,0:r)
value ------------- Distribution ------------- count
32 | 0
64 | 3
128 | 1
256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2257
512 | 1
1024 | 0
cmdk0 (/devices/pci@0,0/pci-ide@1f,1/ide@0/cmdk@0,0:a)
示例
370 Solaris 动态跟踪指南• 2006 年7 月
value ------------- Distribution ------------- count
128 | 0
256 | 1
512 | 0
1024 | 2
2048 | 0
4096 | 2
8192 |@@@@@@@@@@@@@@@@@@ 172
16384 |@@@@@ 52
32768 |@@@@@@@@@@@ 108
65536 |@@@ 34
131072 | 0
该输出说明sd2 很明显是限制设备。sd2 的吞吐量介于256K/秒和512K/秒之间,而cmdk0 在
任何位置传送I/O 的速率都是8 MB/秒到超过64 MB/秒。该脚本列显了设备的名称(可在
iostat 中看到)和完整路径。要了解有关设备的更多信息,可向prtconf 指定设备路径,
如下例所示:
# prtconf -v /devices/pci@0,0/pci1179,1@1d/storage@2/disk@0,0
disk, instance #2 (driver name: sd)
Driver properties:
name=’lba-access-ok’ type=boolean dev=(29,128)
name=’removable-media’ type=boolean dev=none
name=’pm-components’ type=string items=3 dev=none
value=’NAME=spindle-motor’ + ’0=off’ + ’1=on’
name=’pm-hardware-state’ type=string items=1 dev=none
value=’needs-suspend-resume’
示例
第27 章• io 提供器371
name=’ddi-failfast-supported’ type=boolean dev=none
name=’ddi-kernel-ioctl’ type=boolean dev=none
Hardware properties:
name=’inquiry-revision-id’ type=string items=1
value=’1.04’
name=’inquiry-product-id’ type=string items=1
value=’STORAGE DEVICE’
name=’inquiry-vendor-id’ type=string items=1
value=’Generic’
name=’inquiry-device-type’ type=int items=1
value=00000000
name=’usb’ type=boolean
name=’compatible’ type=string items=1
value=’sd’
name=’lun’ type=int items=1
value=00000000
name=’target’ type=int items=1
value=00000000
如强调项中所指示的那样,此设备是可移除的USB 存储设备。
本节中的示例已经研究了所有I/O 请求。但是,您可能只关注一种请求类型。以下示例将
跟踪要进行写操作的目录以及执行写操作的应用程序:
#pragma D option quiet
io:::start
示例
372 Solaris 动态跟踪指南• 2006 年7 月
/args[0]->b_flags & B_WRITE/
{
@[execname, args[2]->fi_dirname] = count();
}
END
{
printf("%20s %51s %5s\n", "WHO", "WHERE", "COUNT");
printa("%20s %51s ", @);
}
在台式机上运行此示例脚本一段时间会生成一些值得关注的结果,如以下示例输出所示:
# dtrace -s ./whowrite.d
^C
WHO WHERE COUNT
su /var/adm 1
fsflush /etc 1
fsflush / 1
fsflush /var/log 1
fsflush /export/bmc/lisa 1
esd /export/bmc/.phoenix/default/78cxczuy.slt/Cache 1
fsflush /export/bmc/.phoenix 1
esd /export/bmc/.phoenix/default/78cxczuy.slt 1
vi /var/tmp 2
vi /etc 2
示例
第27 章• io 提供器373
cat 2
bash / 2
vi 3
xterm /var/adm 3
fsflush /export/bmc 7
MozillaFirebird 8
vim /export/bmc 9
MozillaFirebird /export/bmc 10
fsflush /var/adm 11
devfsadm /dev 14
ksh 71
ksh /export/bmc 71
fsflush /export/bmc/.phoenix/default/78cxczuy.slt 119
MozillaFirebird /export/bmc/.phoenix/default/78cxczuy.slt 119
fsflush 211
MozillaFirebird /export/bmc/.phoenix/default/78cxczuy.slt/Cache 591
fsflush /export/bmc/.phoenix/default/78cxczuy.slt/Cache 666
sched 2385
如以上输出所示,所有写操作实际上都与Mozilla Firebird 高速缓存关联。标有 的写
操作可能是由文件系统中的其他与UFS 日志关联的写操作而引发的。有关日志记录的详细
信息,请参见ufs(7FS)。此示例说明如何使用io 提供器来发现更高层次的软件问题。在此
情况下,脚本显示存在配置问题: 如果Web 浏览器的高速缓存位于tmpfs(7FS) 文件系统的
某个目录中,则它引起的I/O 会少得多(并且很可能根本没有任何I/O)。
前面的示例中仅使用了start 和done 探测器。可使用wait-start 和wait-done 探测器来了
解为什么应用程序会因为I/O 阻塞以及阻塞多长时间。以下示例脚本同时使用io 探测器和
sched 探测器(请参见第26 章)来获取CPU 时间(相对于StarSuite 软件的I/O 等待时间)

示例
374 Solaris 动态跟踪指南• 2006 年7 月
#pragma D option quiet
sched:::on-cpu
/execname == "soffice.bin"/
{
self->on = vtimestamp;
}
sched:::off-cpu
/self->on/
{
@time[""] = sum(vtimestamp - self->on);
self->on = 0;
}
io:::wait-start
/execname == "soffice.bin"/
{
self->wait = timestamp;
}
io:::wait-done
/self->wait/
{
示例
第27 章• io 提供器375
@io[args[2]->fi_name] = sum(timestamp - self->wait);
@time[""] = sum(timestamp - self->wait);
self->wait = 0;
}
END
{
printf("Time breakdown (milliseconds):\n");
normalize(@time, 1000000);
printa(" %-50s ", @time);
printf("\nI/O wait breakdown (milliseconds):\n");
normalize(@io, 1000000);
printa(" %-50s ", @io);
}
在StarSuite 软件冷启动期间运行示例脚本将产生以下输出:
Time breakdown (milliseconds):
3634
13114
I/O wait breakdown (milliseconds):
soffice.tmp 0
Office 0
unorc 0
示例
376 Solaris 动态跟踪指南• 2006 年7 月
sbasic.cfg 0
en 0
smath.cfg 0
toolboxlayout.xml 0
sdraw.cfg 0
swriter.cfg 0
Linguistic.dat 0
scalc.cfg 0
Views.dat 0
Store.dat 0
META-INF 0
Common.xml.tmp 0
afm 0
libsimreg.so 1
xiiimp.so.2 3
outline 4
Inet.dat 6
fontmetric 6
...
libucb1.so 44
libj641si_g.so 46
libX11.so.4 46
liblng641si.so 48
swriter.db 53
示例
第27 章• io 提供器377
libwrp641si.so 53
liblocaledata_ascii.so 56
libi18npool641si.so 65
libdbtools2.so 69
ofa64101.res 74
libxcr641si.so 82
libucpchelp1.so 83
libsot641si.so 86
libcppuhelper3C52.so 98
libfwl641si.so 100
libsb641si.so 104
libcomphelp2.so 105
libxo641si.so 106
libucpfile1.so 110
libcppu.so.3 111
sw64101.res 114
libdb-3.2.so 119
libtk641si.so 126
libdtransX11641si.so 127
libgo641si.so 132
libfwe641si.so 150
libi18n641si.so 152
libfwi641si.so 154
libso641si.so 173
示例
378 Solaris 动态跟踪指南• 2006 年7 月
libpsp641si.so 186
libtl641si.so 189
189
libucbhelper1C52.so 195
libutl641si.so 213
libofa641si.so 216
libfwk641si.so 229
libsvl641si.so 261
libcfgmgr2.so 368
libsvt641si.so 373
libvcl641si.so 741
libsvx641si.so 885
libsfx641si.so 993
1096
libsw641si.so 1365
applicat.rdb 1580
如此输出所示,大部分StarSuite 冷启动时间是由于等待I/O 造成的。(等待I/O 花费13.1
秒,启动CPU 花费3.6 秒。) 在热启动StarSuite 软件时,运行该脚本显示出页面高速缓存
已经消除了I/O 时间,如以下示例输出所示:
Time breakdown (milliseconds):
0
2860
I/O wait breakdown (milliseconds):
temp 0
示例
第27 章• io 提供器379
soffice.tmp 0
0
Office 0
冷启动输出显示,与任何其他文件相比,文件applicat.rdb 引起的I/O 等待时间最长。此
结果可能是由于对文件执行了许多I/O 操作造成的。要研究对此文件执行的I/O 操作,可使
用以下D脚本:
io:::start
/execname == "soffice.bin" && args[2]->fi_name == "applicat.rdb"/
{
@ = lquantize(args[2]->fi_offset != -1 ?
args[2]->fi_offset / (1000 * 1024) : -1, 0, 1000);
}
此脚本使用fileinfo_t 结构的fi_offset 字段来了解要访问文件的哪些部分(以兆字节为
单位)。在StarSuite 软件冷启动期间运行此脚本将产生与以下示例类似的输出:
# dtrace -s ./applicat.d
dtrace: script ’./applicat.d’ matched 4 probes
^C
value ------------- Distribution ------------ count
< 0 | 0
0 |@@@ 28
1 |@@ 17
2 |@@@@ 35
3 |@@@@@@@@@ 72
示例
380 Solaris 动态跟踪指南• 2006 年7 月
4 |@@@@@@@@@@ 78
5 |@@@@@@@@ 65
6 | 0
此输出指示仅访问文件的前六兆字节,这可能是因为文件的大小为六兆字节。输出还指示
未访问整个文件。如果要缩短StarSuite 的冷启动时间,则可能需要了解文件的访问模式。
如果文件的各个必需部分大多数是相连的,则可能缩短StarSuite 冷启动时间的一个方法是
在运行应用程序之前先运行侦察线程,从而提前执行文件所需的I/O 操作。(如果通过使用
mmap(2) 来访问文件,则此方法最简单。)此策略可使冷启动时间缩短大约1.6 秒,但会额
外增加应用程序的复杂程度和维护负担。通过任一方法,使用io 提供器收集的数据有助于
更好地了解此类工作最终带来的好处。
稳定性
io 提供器使用DTrace 的稳定性机制来说明其稳定性,如下表所示。有关稳定性机制的更多
信息,请参见第39 章。
元素名称稳定性数据稳定性相关性类
提供器发展中发展中ISA
模块专用专用未知
函数专用专用未知
名称发展中发展中ISA
参数发展中发展中ISA
稳定性
第27 章• io 提供器381
382
mib 提供器
mib 提供器提供了与Solaris 管理信息库(management information base, MIB) 中的计数器对应
的探测器。MIB 计数器可供简单网络管理协议(simple network management protocol, SNMP)
使用,以便对异构联网实体进行远程监视。此外,也可以通过kstat(1M) 和netstat(1M) 命
令查看这些计数器。mib 提供器便于快速查看通过使用远程或本地联网监视器观察到的异常
联网行为。
探测器
mib 提供器为多个MIB 中的计数器提供了探测器。在表28–1 中,列出了各种协议,这些协
议可导出由mib 提供器检测的MIB。该表中列出了指定部分或全部MIB 的文档、可用于访
问正在运行的计数器(使用kstat(1M) -n statistic 选项)的内核统计信息名称,以及列出探
测器完整定义的表。另外,还可通过netstat(1M) 的-s 选项来查看所有MIB 计数器。
表28–1 mib 探测器
协议MIB 描述内核统计信息mib 探测器表
ICMP RFC 1213 icmp 表28–2
IP RFC 1213 ip 表28–3
IPsec — ip 表28–4
IPv6RFC 2465 — 表28–5
SCTP “SCTP MIB”(Internet
草稿)
sctp 表28–7
TCP RFC 1213 tcp 表28–8
UDP RFC 1213 udp 表28–9
28 第2 8 章
383
表28–2ICMPmib 探测器
icmpInAddrMaskReps 接收ICMP(Internet Control Message Protocol,Internet 控制消息协议)
地址掩码回复消息时将触发的探测器。
icmpInAddrMasks 接收ICMP 地址掩码请求消息时将触发的探测器。
icmpInBadRedirects 接收在某些方面确定存在格式错误(未知的ICMP 代码、发送器或目标
断开链接等)的ICMP 重定向消息时将触发的探测器。
icmpInCksumErrs 接收校验和错误的ICMP 消息时将触发的探测器。
icmpInDestUnreachs 接收ICMP 目标不可访问的消息时将触发的探测器。
icmpInEchoReps 接收ICMP 回显回复消息时将触发的探测器。
icmpInEchos 接收ICMP 回显请求消息时将触发的探测器。
icmpInErrors 接收确定存在ICMP 特定错误(错误的ICMP 校验和、错误长度等)的
ICMP 消息时将触发的探测器。
icmpInFragNeeded 接收ICMP 目标不可访问(需要分段)的消息,指示发送的包由于大于
某一MTU,并且设置了“不分段”标志而丢失时将触发的探测器。
icmpInMsgs 接收ICMP 消息时将触发的探测器。触发此探测器时,如果该消息确定
存在ICMP 特定错误,则可能会同时触发icmpInErrors 探测器。
icmpInOverflows 由于缺少缓冲区空间,导致接收的ICMP 消息随后被删除时将触发的探
测器。
icmpInParmProbs 接收ICMP 参数问题消息时将触发的探测器。
icmpInRedirects 接收ICMP 重定向消息时将触发的探测器。
icmpInSrcQuenchs 接收ICMP 源抑制消息时将触发的探测器。
icmpInTimeExcds 接收ICMP 超时的消息时将触发的探测器。
icmpInTimestampReps 接收ICMP 时间标记回复消息时将触发的探测器。
icmpInTimestamps 接收ICMP 时间标记请求消息时将触发的探测器。
icmpInUnknowns 接收类型未知的ICMP 消息时将触发的探测器。
icmpOutAddrMaskReps 发送ICMP 地址掩码回复消息时将触发的探测器。
icmpOutDestUnreachs 发送ICMP 目标不可访问的消息时将触发的探测器。
icmpOutDrops 由于某些原因(如内存分配失败、广播/多址广播源或目标等),导致
外发ICMP 消息被删除时将触发的探测器。
icmpOutEchoReps 发送ICMP 回显回复消息时将触发的探测器。
icmpOutErrors 由于在ICMP 中发现问题(如缓冲区不足)而导致无法发送ICMP 消息
时将触发的探测器。如果在ICMP 层外面发现错误(如IP 无法路由生
成的数据报),将不会触发该探测器。
探测器
384 Solaris 动态跟踪指南• 2006 年7 月
表28–2 ICMPmib 探测器(续)
icmpOutFragNeeded 发送ICMP 目标不可访问(需要分段)的消息时将触发的探测器。
icmpOutMsgs 发送ICMP 消息时将触发的探测器。触发此探测器时,如果该消息确定
存在ICMP 特定错误,则可能会同时触发icmpOutErrors 探测器。
icmpOutParmProbs 发送ICMP 参数问题消息时将触发的探测器。
icmpOutRedirects 发送ICMP 重定向消息时将触发的探测器。对于主机,由于它不发送重
定向消息,因此不会触发该探测器。
icmpOutTimeExcds 发送ICMP 超时的消息时将触发的探测器。
icmpOutTimestampReps 发送ICMP 时间标记回复消息时将触发的探测器。
表28–3 IP mib 探测器
ipForwDatagrams 接收未将此计算机设为最终IP 目标的数据报,并尝试查找将数据报转
发至该最终目标的路由时触发的探测器。在未充当IP 网关的计算机
上,此探测器将仅针对通过该计算机进行源路由,以及源路由选项处
理成功的包进行触发。
ipForwProhibits 接收未将此计算机设为最终IP 目标的数据报,但由于禁止将该计算机
用作路由器,因此未尝试查找将数据报转发至该最终目标的路由时触
发的探测器。
ipFragCreates 由于分段作用生成IP 数据报分段时将触发的探测器。
ipFragFails 由于无法分段(例如需要分段,但设置了“不分段”标志),导致IP
数据报被废弃时将触发的探测器。
ipFragOKs IP 数据报成功分段时将触发的探测器。
ipInCksumErrs 由于IP 数据包头校验和错误,导致输入数据报被废弃时将触发的探测
器。
ipInDelivers 将输入数据报成功传送至IP 用户协议(包括ICMP)时触发的探测器。
ipInDiscards 由于某些与包无关的原因(例如,缺少缓冲区空间)而导致输入IP 数
据报被废弃时将触发的探测器。对于在等待重汇编时废弃的任何数据
报,不会触发该探测器。
ipInHdrErrors 由于IP 数据包头错误(如版本号不匹配、格式错误、生成时间超时、
处理IP 选项时发现错误等),导致输入数据报被废弃时将触发的探测
器。
ipInIPv6 IPv6 包错误地到达IPv4 队列时将触发的探测器。
ipInReceives 从某接口接收数据报(即使该数据报被错误接收)时将触发的探测
器。
ipInUnknownProtos 由于未知或不受支持的协议导致本地处理数据报在成功接收后被废弃
时将触发的探测器。
探测器
 
 
以上文章转自于 : http://developers.sun.com.cn/
阅读(547) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~