sysinfo 提供器提供了与按名称 sys 分类的内核统计信息对应的探测器。因为这些统计信息为系统监视实用程序(如 mpstat(1M))提供输入,所以 sysinfo 提供器可以快速调查观察到的异常行为。
sysinfo 提供器提供了对应于 sys 命名的内核统计信息中字段的探测器:sysinfo 提供的探测器就在递增相应的 sys 值之前触发。以下示例说明了如何使用 kstat(1M) 命令显示 sys 命名的内核统计信息的名称和当前值。
$ kstat -n sys module: cpu instance: 0 name: sys class: misc bawrite 123 bread 2899 bwrite 17995 ... |
表 23–1 中对 sysinfo 探测器进行了说明。
表 23–1 sysinfo 探测器
bawrite |
要将缓冲区异步写出到设备中时将触发的探测器。 |
bread |
从设备中实际读取缓冲区时将触发的探测器。bread 在从设备中请求缓冲区之后,但在阻塞暂挂的请求完成之前触发。 |
bwrite |
要将缓冲区写出(无论同步或异步)到设备中时将触发的探测器。 |
idlethread |
CPU 进入空闲循环时将触发的探测器。 |
intrblk |
中断线程阻塞时将触发的探测器。 |
inv_swtch |
强制正在运行的线程被迫放弃 CPU 时将触发的探测器。 |
lread |
逻辑上从设备中读取缓冲区时将触发的探测器。 |
lwrite |
逻辑上将缓冲区写入设备时将触发的探测器。 |
modload |
装入内核模块时将触发的探测器。 |
modunload |
卸载内核模块时将触发的探测器。 |
msg | |
mutex_adenters |
尝试获取已拥有的自适应锁定时将触发的探测器。如果触发此探测器,则会同时触发 lockstat 提供器的 adaptive-block 或 adaptive-spin 探测器。有关详细信息,请参见第 18 章。 |
namei |
尝试在文件系统中进行名称查找时将触发的探测器。 |
nthreads |
创建线程时将触发的探测器。 |
phread |
要执行原始 I/O 读取时将触发的探测器。 |
phwrite |
要执行原始 I/O 写入时将触发的探测器。 |
procovf |
由于系统缺乏进程表项而无法创建新进程时将触发的探测器。 |
pswitch |
CPU 从执行某个线程切换到执行另一个线程时将触发的探测器。 |
readch |
每次成功读取后,但在将控制返回到执行该读取的线程之前将触发的探测器。可以通过 read(2)、readv(2) 或 pread(2) 系统调用进行读取。arg0 包含已成功读取的字节数。 |
rw_rdfails |
如果在写入者暂挂锁定或写入者需要锁定时,尝试读取并锁定读取者/写入者,则将触发的探测器。如果触发此探测器,则 lockstat 提供器的 rw-block 探测器也将触发。有关详细信息,请参见第 18 章。 |
rw_wrfails |
如果在一定数量的读取者或另一个写入者暂挂锁定时,尝试写入并锁定读取者/写入者锁定,则将触发的探测器。如果触发此探测器,则 lockstat 提供器的 rw-block 探测器也将触发。有关详细信息,请参见第 18 章。 |
sema |
执行 semop(2) 系统调用(但在执行任何信号操作之前)时将触发的探测器。 |
sysexec |
执行 exec(2) 系统调用时将触发的探测器。 |
sysfork |
执行 fork(2) 系统调用时将触发的探测器。 |
sysread | |
sysvfork |
执行 vfork(2) 系统调用时将触发的探测器。 |
syswrite | |
trap |
发生处理器陷阱时将触发的探测器。请注意,一些处理器(特别是 UltraSPARC 变体)通过不会引起此探测器触发的机制处理一些轻权陷阱。 |
ufsdirblk |
从 UFS 文件系统中读取目录块时将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。 |
ufsiget |
检索 inode 时将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。 |
ufsinopage |
可重用不包含任何关联数据页的内核 inode 之后将触发的探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。 |
ufsipage |
可重用包含任何关联数据页的内核 inode 之后将触发的探测器。在将关联的数据页刷新到磁盘之后将触发此探测器。有关 UFS 的详细信息,请参见 ufs(7FS)。 |
writech |
每次成功写入后,但在将控制返回到执行该写入的线程之前将触发的探测器。可以通过 write(2)、writev(2) 或 pwrite(2) 系统调用进行写入。arg0 包含已成功写入的字节数。 |
xcalls |
要进行交叉调用时将触发的探测器。交叉调用是一个 CPU 请求另一个 CPU 的即时工作的操作系统机制。 |
sysinfo 探测器的参数如下所示:
arg0 |
统计信息将递增的值。对于大多数探测器,此参数始终为 1,但对于一些探测器,此参数可以采用其他值。 |
arg1 |
指向要递增的统计信息当前值的指针。此值是一个 64 位数,将按 arg0 中的值递增。取消引用此指针可以使使用者确定对应于该探测器的统计信息的当前计数。 |
arg2 |
指向 cpu_t 结构的指针,该结构对应于要递增统计信息的 CPU。此结构在 <sys/cpuvar.h> 中定义,但它为内核实现的一部分,应视为“专用”。 |
对于大多数 sysinfo 探测器,arg0 的值为 1。但是,readch 和 writech 探测器将 arg0 分别设置为已读取或已写入的字节数。使用以下功能可以确定按可执行名称读取的大小,如下例所示:
# dtrace -n readch'{@[execname] = quantize(arg0)}' dtrace: description 'readch' matched 4 probes ^C xclock value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 64 | 0 acroread value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3 64 | 0 FvwmAuto value ------------- Distribution ------------- count 2 | 0 4 |@@@@@@@@@@@@@ 13 8 |@@@@@@@@@@@@@@@@@@@@@ 21 16 |@@@@@ 5 32 | 0 xterm value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@ 19 64 |@@@@@@@@@ 7 128 |@@@@@@ 5 256 | 0 fvwm2 value ------------- Distribution ------------- count -1 | 0 0 |@@@@@@@@@ 186 1 | 0 2 | 0 4 |@@ 51 8 | 17 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 503 64 | 9 128 | 0 Xsun value ------------- Distribution ------------- count -1 | 0 0 |@@@@@@@@@@@ 269 1 | 0 2 | 0 4 | 2 8 |@ 31 16 |@@@@@ 128 32 |@@@@@@@ 171 64 |@ 33 128 |@@@ 85 256 |@ 24 512 | 8 1024 | 21 2048 |@ 26 4096 | 21 8192 |@@@@ 94 16384 | 0 |
sysinfo 提供器将 arg2 设置为指向 cpu_t(内核实现的一种内部结构)的指针。sysinfo 探测器在要递增统计信息的 CPU 中触发。使用 cpu_t 的 cpu_id 成员可确定关注的 CPU。
通过 mpstat(1M) 检查以下输出:
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl 12 90 22 5760 422 299 435 26 71 116 11 1372 5 19 17 60 13 46 18 4585 193 162 431 25 69 117 12 1039 3 17 14 66 14 33 13 3186 405 381 397 21 58 105 10 770 2 17 11 70 15 34 19 4769 109 78 417 23 57 115 13 962 3 14 14 69 16 74 16 4421 437 406 448 29 77 111 8 1020 4 23 14 59 17 51 15 4493 139 110 378 23 62 109 9 928 4 18 14 65 18 41 14 4204 494 468 360 23 56 102 9 849 4 17 12 68 19 37 14 4229 115 87 363 22 50 106 10 845 3 15 14 67 20 78 17 5170 200 169 456 26 69 108 9 1119 5 21 25 49 21 53 16 4817 78 51 394 22 56 106 9 978 4 17 22 57 22 32 13 3474 486 463 347 22 48 106 9 769 3 17 17 63 23 43 15 4572 59 34 361 21 46 102 10 947 4 15 22 59 |
从上面的输出可以总结出 xcal 字段似乎太高,特别是所指定的系统相对空闲程度。mpstat 通过检查 sys 内核统计信息的 xcalls 字段确定 xcal 字段的值。因此,通过启用 xcalls sysinfo 探测器可以轻松地研究此异常,如下例所示:
# dtrace -n xcalls'{@[execname] = count()}' dtrace: description 'xcalls' matched 4 probes ^C dtterm 1 nsrd 1 in.mpathd 2 top 3 lockd 4 java_vm 10 ksh 19 iCald.pl6+RPATH 28 nwadmin 30 fsflush 34 nsrindexd 45 in.rlogind 56 in.routed 100 dtrace 153 rpc.rstatd 246 imapd 377 sched 431 nfsd 1227 find 3767 |
该输出说明了查找交叉调用的源的位置。一些数量的 find(1) 处理导致大多数交叉调用。以下 D 脚本可用于进一步详细了解该问题:
syscall:::entry /execname == "find"/ { self->syscall = probefunc; self->insys = 1; } sysinfo:::xcalls /execname == "find"/ { @[self->insys ? self->syscall : "<none>"] = count(); } syscall:::return /self->insys/ { self->insys = 0; self->syscall = NULL; }
此脚本使用 syscall 提供器将来自 find 的交叉调用归结到特定系统调用。一些交叉调用(如由于页面错误产生的系统调用)可能不是通过系统调用发出。此脚本在这些情况下将列显 "<none>"。运行此脚本将会生成与以下示例类似的输出:
# dtrace -s ./find.d dtrace: script './find.d' matched 444 probes ^C <none> 2 lstat64 2433 getdents64 14873 |
此输出指示由 find 触发的大多数交叉调用又被 getdents(2) 系统调用触发。进一步的了解取决于您要了解的具体方面。如果要了解为什么 find 进程进行 getdents 调用,可以编写 D 脚本在 find 触发交叉调用时聚集 ustack()。如果要了解为什么 getdents 调用触发交叉调用,可以编写 D 脚本在 find 触发交叉调用时聚集 stack()。无论下一步执行什么,xcalls 探测器的存在都将使您快速发现异常监视输出的根本原因。
sysinfo 提供器使用 DTrace 的稳定性机制说明其稳定性,如下表所示。有关稳定性机制的更多信息,请参见第 39 章。
元素 |
名称稳定性 |
数据稳定性 |
相关性类 |
---|---|---|---|
提供器 |
发展中 |
发展中 |
ISA |
模块 |
专用 |
专用 |
未知 |
功能 |
专用 |
专用 |
未知 |
名称 |
发展中 |
发展中 |
ISA |
参数 |
专用 |
专用 |
ISA |