2.8.5 例: ファイル・システム・デバイス間の累積読取りおよび書込みアクティビティの表示(fsact)

次の例は、ファイル・システムの基礎となるブロック・デバイス上の位置に応じて、埋込みDプログラムを使用してローカル・ファイル・システムの累積読取りおよび書込みブロック数を表示するbash シェル・スクリプトです。 lquantize()集計関数は、結果をデバイス上のブロックの合計数の10分の1として表示するために使用されます。

#!/bin/bash

# fsact -- Display cumulative read and write activity across a file system device
#
#          Usage: fsact [<filesystem>]

# Could load the required DTrace modules, if they were not autoloaded.
# grep profile /proc/modules > /dev/null 2>&1 || modprobe profile
# grep sdt /proc/modules > /dev/null 2>&1 || modprobe sdt

# If no file system is specified, assume /
[ $# -eq 1 ] && FSNAME=$1 || FSNAME="/"
[ ! -e $FSNAME ] && echo "$FSNAME not found" && exit 1

# Determine the mountpoint, major and minor numbers, and file system size
MNTPNT=$(df $FSNAME | gawk '{ getline; print $1; exit }')
MAJOR=$(printf "%d\n" 0x$(stat -Lc "%t" $MNTPNT))
MINOR=$(printf "%d\n" 0x$(stat -Lc "%T" $MNTPNT))
FSSIZE=$(stat -fc "%b" $FSNAME)

# Run the embedded D program
dtrace -qs /dev/stdin << EOF
io:::done
/args[1]->dev_major == $MAJOR && args[1]->dev_minor == $MINOR/
{
  iodir = args[0]->b_flags & B_READ ? "READ" : "WRITE";
  /* Normalize the block number as an integer in the range 0 to 10 */ 
  blkno = (args[0]->b_blkno)*10/$FSSIZE;
  /* Aggregate blkno linearly over the range 0 to 10 in steps of 1 */ 
  @a[iodir] = lquantize(blkno,0,10,1)
}

tick-10s
{
  printf("%Y\n",walltimestamp);
  /* Display the results of the aggregation */
  printa("%s\n%@d\n",@a);
  /* To reset the aggregation every tick, uncomment the following line */
  /* clear(@a); */
}
EOF

Dプログラムをシェル・スクリプトに埋め込み、基礎となるデバイスのメジャー番号とマイナー番号、およびファイル・システムの合計サイズなどのパラメータを設定できるようにします。 次に、これらのパラメータにDコードから直接アクセスします。

注意

Dプログラムに値を渡す別の方法としては、次のようにCプリプロセッサ・ディレクティブを使用する方法があります。

dtrace -C -D MAJ=$MAJOR -D MIN=$MINOR -D FSZ=$FSSIZE -qs /dev/stdin << EOF

シェル名のかわりにマクロ名で、Dプログラム内の変数を参照できるようになります。

/args[1]->dev_major == MAJ && args[1]->dev_minor == MIN/

blkno = (args[0]->b_blkno)*10/FSZ;

次の例は、スクリプトの実行可能ファイルを作成した後fsactコマンドを実行して、cp -Rをディレクトリで実行して、コピーしたディレクトリにrm -rf コマンドを実行した場合の出力を示しています:

# chmod +x fsact
# ./fsact
2018 Feb 16 16:59:46
READ

            value  ------------- Distribution ------------- count
              < 0 | 0
                0 |@@@@@@@ 8
                1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 32
                2 | 0
                3 | 0
                4 | 0
                5 | 0
                6 | 0
                7 | 0
                8 | 0
                9 | 0
            >= 10 |@@@@@@@ 8

WRITE

            value  ------------- Distribution ------------- count
                9 | 0
            >= 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 42                                       0        

^C