らくがきちょう

なんとなく ~所属組織/団体とは無関係であり、個人の見解です~

CentOS8 に psmisc パッケージをインストールしてプロセスの詳細を確認する

Linux の psmisc パッケージにはプロセスの詳細を確認出来る、便利なツールが含まれます。 CentOS8 に psmisc パッケージをインストールし、含まれるツール群を試してみました。

psmisc パッケージのインストール

dnf でインストールします。

dnf -y install psmisc

以下がインストールされました。

  1. /usr/bin/killall
  2. /usr/bin/peekfd
  3. /usr/bin/prtstat
  4. /usr/bin/pslog
  5. /usr/bin/pstree
  6. /usr/bin/pstree.x11
  7. /usr/sbin/fuser

fuser

fuser を使うとファイルやファイルシステムにアクセスしているプロセスを確認することが出来ます。 以下では /var/log/messages へアクセスしているプロセスを表示させています。

# fuser -v /var/log/messages
                     USER        PID ACCESS COMMAND
/var/log/messages:   root       1016 F.... rsyslogd

ファイルシステムへアクセスしているプロセスを表示することも出来ます。 下記は /proc にアクセスしているプロセスを表示した例です。

# fuser -v -m /proc
                     USER        PID ACCESS COMMAND
/proc:               root     kernel mount /proc
                     root          1 f.... systemd
                     root        741 f.... systemd-journal
                     systemd-resolve   1013 f.... systemd-resolve
                     root       8303 f.... systemd

下記は /dev/sda4 (/ としてマウント) にアクセスしているプロセスを表示した例です。

# fuser -v -m /dev/sda4
                     USER        PID ACCESS COMMAND
/dev/sda4:           root     kernel mount /
                     root          1 .rce. systemd
                     root          2 .rc.. kthreadd
                     root          3 .rc.. rcu_gp
                     root          4 .rc.. rcu_par_gp
        ・
        ・
        ・

-k オプションを指定すると、リストアップされたプロセスを停止 (kill) します。

# fuser -v ./test.txt
                     USER        PID ACCESS COMMAND
/root/test.txt:      root      23246 f.... tail
# fuser -v -k ./test.txt
                     USER        PID ACCESS COMMAND
/root/test.txt:      root      23246 f.... tail
# fuser -v ./test.txt
#

killall

プロセスへシグナルを送信することが出来ます。 kill と違い、プロセス名を指定することが出来ます。 但し、PID では無くプロセス名で指定する場合、「同じ名前のプロセスが複数ある場合は全て」対象になる点に注意です。

# fuser -v ./test.txt
                     USER        PID ACCESS COMMAND
/root/test.txt:      root      23257 f.... tail
# killall tail
# fuser -v ./test.txt
# 

peekfd

プロセスがファイルディスクプリタへ読み書きする内容を監視することが出来ます。 sshd などを監視するとよく分かるのですが出力量が多すぎる為、テスト用のプログラムを実行しておきます。

# echo $$; while true; do echo `date`; sleep 1;done
24662
Sat May 9 22:23:29 JST 2020
Sat May 9 22:23:30 JST 2020
Sat May 9 22:23:31 JST 2020
Sat May 9 22:23:32 JST 2020
Sat May 9 22:23:33 JST 2020
Sat May 9 22:23:34 JST 2020
Sat May 9 22:23:35 JST 2020

テスト用プログラム (今回は PID 24662) を監視してみます。

# peekfd 24662

writing fd 1:
Sat May 9 22:23:32 JST 2020
Sat May 9 22:23:33 JST 2020
Sat May 9 22:23:34 JST 2020
Sat May 9 22:23:35 JST 2020

prtstat

プロセスの統計情報を表示することが出来ます。 $BASHPID 環境変数には bash の PID が格納されています。 今回は bash を題材に取り上げます。

# echo $BASHPID
24559

プロセスに関する統計情報は /proc/[PID]/stat に存在します。 ですが、これをそのまま表示すると以下のように分かりやすくはありません。

# cat /proc/24559/stat
24559 (bash) S 24558 24559 24559 34816 24849 4194304 2099 23974 0 0 4 2 13 11 20 0 1 0 43493781 28819456 1313 18446744073709551615 94896771502080 94896772581304 140736278379056 0 0 0 65536 3670020 1266777851 0 0 0 17 0 0 0 0 0 0 94896774679856 94896774727044 94896799875072 140736278380179 140736278380185 140736278380185 140736278380526 0

prtstat で表示させると、これを見やすく補足してくれます。

# prtstat 24559
Process: bash                   State: S (sleeping)
  CPU#:  0              TTY: 136:0      Threads: 1
Process, Group and Session IDs
  Process ID: 24559               Parent ID: 24558
    Group ID: 24559              Session ID: 24559
  T Group ID: 24850

Page Faults
  This Process    (minor major):     2178         0
  Child Processes (minor major):    24067         0
CPU Times
  This Process    (user system guest blkio):   0.04   0.02   0.00   0.00
  Child processes (user system guest):         0.13   0.11   0.00
Memory
  Vsize:       28 MB
  RSS:         5378 kB                   RSS Limit: 18446744073709 MB
  Code Start:  0x564ee05b1000            Code Stop:  0x564ee06b87b8
  Stack Start: 0x7fffb7e13a30
  Stack Pointer (ESP):          0        Inst Pointer (EIP):          0
Scheduling
  Policy: normal
  Nice:   0              RT Priority: 0 (non RT)

pslog

ログファイルの位置を確認出来ます。 Apache でテストしてみる為、まずは Apache の PID を確認してみます。 今回の環境では PID 23833 でした。

# lsof -i:80
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   23833   root    4u  IPv6 445183      0t0  TCP *:http (LISTEN)
httpd   23835 apache    4u  IPv6 445183      0t0  TCP *:http (LISTEN)
httpd   23836 apache    4u  IPv6 445183      0t0  TCP *:http (LISTEN)
httpd   23837 apache    4u  IPv6 445183      0t0  TCP *:http (LISTEN)

ログファイルは以下と表示されました。

# pslog 23833
Pid no 23833:
Log path: /var/log/httpd/error_log
Log path: /var/log/httpd/access_log

pstree

プロセスの親子関係をツリー表示することが出来ます。 基本的な使い方として「PID を指定する方法」と「ユーザを指定する方法」があります。 以下は「Apache の PID を指定した場合」の実行結果です。

# pstree 23833
httpd─┬─httpd
      ├─2*[httpd───64*[{httpd}]]
      └─httpd───80*[{httpd}]

以下は「apache というユーザ名を指定した場合」の実行結果です。

# pstree apache
httpd

httpd───64*[{httpd}]

httpd───64*[{httpd}]

httpd───80*[{httpd}]

-p オプションを指定すると子プロセスの PID も表示します。 以下は sshd のプロセスツリーを表示した例です。

# pstree -p 948
sshd(948)─┬─sshd(24545)───sshd(24558)───bash(24559)───pstree(24943)
          └─sshd(24659)───sshd(24661)───bash(24662)

参考

fuser

Usage: fuser [-fIMuvw] [-a|-s] [-4|-6] [-c|-m|-n SPACE]
             [-k [-i] [-SIGNAL]] NAME...
       fuser -l
       fuser -V
Show which processes use the named files, sockets, or filesystems.

  -a,--all              display unused files too
  -i,--interactive      ask before killing (ignored without -k)
  -I,--inode            use always inodes to compare files
  -k,--kill             kill processes accessing the named file
  -l,--list-signals     list available signal names
  -m,--mount            show all processes using the named filesystems or
                        block device
  -M,--ismountpoint     fulfill request only if NAME is a mount point
  -n,--namespace SPACE  search in this name space (file, udp, or tcp)
  -s,--silent           silent operation
  -SIGNAL               send this signal instead of SIGKILL
  -u,--user             display user IDs
  -v,--verbose          verbose output
  -w,--writeonly        kill only processes with write access
  -V,--version          display version information
  -4,--ipv4             search IPv4 sockets only
  -6,--ipv6             search IPv6 sockets only
  -                     reset options

  udp/tcp names: [local_port][,[rmt_host][,[rmt_port]]]

killall

Usage: killall [ -Z CONTEXT ] [ -u USER ] [ -y TIME ] [ -o TIME ] [ -eIgiqrvw ]
               [ -s SIGNAL | -SIGNAL ] NAME...
       killall -l, --list
       killall -V, --version

  -e,--exact          require exact match for very long names
  -I,--ignore-case    case insensitive process name match
  -g,--process-group  kill process group instead of process
  -y,--younger-than   kill processes younger than TIME
  -o,--older-than     kill processes older than TIME
  -i,--interactive    ask for confirmation before killing
  -l,--list           list all known signal names
  -q,--quiet          don't print complaints
  -r,--regexp         interpret NAME as an extended regular expression
  -s,--signal SIGNAL  send this signal instead of SIGTERM
  -u,--user USER      kill only process(es) running as USER
  -v,--verbose        report if the signal was successfully sent
  -V,--version        display version information
  -w,--wait           wait for processes to die
  -n,--ns PID         match processes that belong to the same namespaces
                      as PID or 0 for all namespaces
  -Z,--context REGEXP kill only process(es) having context
                      (must precede other arguments)

peekfd

Usage: peekfd [-8] [-n] [-c] [-d] [-V] [-h] <pid> [<fd> ..]
    -8, --eight-bit-clean        output 8 bit clean streams.
    -n, --no-headers             don't display read/write from fd headers.
    -c, --follow                 peek at any new child processes too.
    -d, --duplicates-removed     remove duplicate read/writes from the output.
    -V, --version                prints version info.
    -h, --help                   prints this help.

  Press CTRL-C to end output.

prtstat

Usage: prtstat [options] PID ...
       prtstat -V
Print information about a process
    -r,--raw       Raw display of information
    -V,--version   Display version information and exit

pslog

Usage: pslog PID...
       pslog -V, --version

  -V,--version display version information

pstree

Usage: pstree [-acglpsStuZ] [ -h | -H PID ] [ -n | -N type ]
              [ -A | -G | -U ] [ PID | USER ]
       pstree -V
Display a tree of processes.

  -a, --arguments     show command line arguments
  -A, --ascii         use ASCII line drawing characters
  -c, --compact       don't compact identical subtrees
  -h, --highlight-all highlight current process and its ancestors
  -H PID,
  --highlight-pid=PID highlight this process and its ancestors
  -g, --show-pgids    show process group ids; implies -c
  -G, --vt100         use VT100 line drawing characters
  -l, --long          don't truncate long lines
  -n, --numeric-sort  sort output by PID
  -N type,
  --ns-sort=type      sort by namespace type (cgroup, ipc, mnt, net, pid,
                                              user, uts)
  -p, --show-pids     show PIDs; implies -c
  -s, --show-parents  show parents of the selected process
  -S, --ns-changes    show namespace transitions
  -t, --thread-names  show full thread names
  -T, --hide-threads  hide threads, show only processes
  -u, --uid-changes   show uid transitions
  -U, --unicode       use UTF-8 (Unicode) line drawing characters
  -V, --version       display version information
  -Z, --security-context
                      show SELinux security contexts
  PID    start at this PID; default is 1 (init)
  USER   show only trees rooted at processes of this user