1 ポイント 投稿者 GN⁺ 5 시간 전 | 1件のコメント | WhatsAppで共有
  • Ubuntu Server 16.04 x64 の htop 画面を出発点に、uptime、load average、Tasks、PID、プロセスツリー、状態、CPU 時間、優先度、メモリ指標が実際に何を意味するのかを /proc とコマンド出力でたどる
  • 画面上の多くの値は procfs/etc/passwd/etc/group/etc/shadow/etc/nsswitch.conf といったシステムファイルから来ており、strace でプログラムがどのファイルを読んでいるか確認できる
  • Load average は CPU 使用率と同じ値ではなく、実行中・実行待ち中のプロセスと uninterruptible 状態のプロセスを含む指数減衰移動平均である
  • RSDZTt といった状態コードは signal、killfork/exec/wait の動作と結び付いており、プロセスがなぜ停止したり残ったりしているのかを判断する手がかりになる
  • VIRTRESSHRMEM%仮想メモリ、物理メモリ、共有可能メモリをそれぞれ異なる観点から示すため、1 つの数値だけ見て実際のメモリ使用量を断定するのは難しい

htop の値はどこから来るのか

  • uptime はシステムがどれだけ長く動作しているかを示し、同じ情報は uptime コマンドでも確認できる
  • uptime プログラムは /proc/uptime を読む
    • 1 つ目の数値はシステムが起動していた総秒数
    • 2 つ目の数値はシステムが idle 状態だった秒数
    • マルチコアシステムでは idle 時間がコアごとに合算されるため、全体の uptime より大きくなることがある
  • strace uptime 2>&1 | grep open または strace -e open uptime で、uptime が開くファイルを確認できる
    • 出力例には /proc/uptime/var/run/utmp/proc/loadavg が含まれる
  • /proc/uptime の数値はプログラムやスクリプトで使いやすく、uptime の出力は人間が読みやすい形式に整えられている

Load average と CPU 使用率

  • /proc/loadavg の最初の 3 つの値は、直近 1 分、5 分、15 分 のシステム load average を表す
  • 4 つ目の値は現在実行中のプロセス数と全プロセス数を 1/120 のように示し、最後の値は最後に使われた PID である
  • 新しいプロセスを実行すると PID が割り当てられ、PID は通常増加していき、枯渇すると再利用される
    • PID 1 は起動時に開始される /sbin/init に属する
  • htop で実行中のプロセスが 1 つだけ見えるなら、その 1 つは htop 自身かもしれない
  • sleep 30 は実行中ではなく sleep 状態なので、running process 数は増やさない
  • cat /dev/urandom > /dev/null のように継続して CPU を使う処理は、running process 数と load average を上げる
  • Load number は、実行中または実行待ちのプロセスと uninterruptible 状態のプロセスを数える値である
  • load average は単純平均ではなく、指数減衰移動平均 である
    • 1 分 load average も直近 60 秒だけを反映するのではなく、直近 1 分により大きな重みを置きつつ、それ以前の活動も一部含む
  • 単一 CPU システムで CPU-bound なプロセスが 1 つある場合、load average 1.00 は CPU 100% 使用と単純化して考えられる
    • 2 コアシステムで同じ状況なら、CPU 使用率 50% と見なせる
    • 2 コアシステムの CPU 100% 使用に相当する load average は、単純化すると 2.00 になる
  • この単純化は、uninterruptible 状態のプロセスも load に含まれるため、常に正しいとは限らない
    • load average は高いのに CPU 使用率は高くない、という状況もあり得る
  • 瞬間的な CPU 使用率は mpstat で確認できる
    • sudo apt install sysstat -y
    • mpstat 1

Tasks、PID、プロセスツリー

  • htop 右上の Tasks は、全プロセス数と実行中のプロセス数を表示する
  • Linux カーネルは内部的にプロセスを task と呼び、htop は画面スペースを節約するため Processes ではなく Tasks を使っている
  • Shift+H で thread 表示を切り替えられる
    • Tasks: 23, 10 thr のように見えるなら、thread が表示中である
  • Shift+K で kernel thread 表示を切り替えられる
    • Tasks: 23, 40 kthr のように見えるなら、kernel thread が表示中である
  • 新しいプロセスが開始されるたびに PID が割り当てられる
    • sleep 1000 & のようにバックグラウンド実行すると、job 番号と PID が表示される
    • bash$! は最後のバックグラウンドプロセス ID に展開される
  • プロセス関連情報は /proc/<pid>/ 以下にある
    • /proc/<pid>/cmdline は実行コマンドを保持しており、引数は \0 バイトで区切られている
    • tr '\0' '\n' < /proc/<pid>/cmdline または strings /proc/<pid>/cmdline で読みやすく確認できる
    • /proc/<pid>/cwd は現在の作業ディレクトリへのリンクで、/proc/<pid>/exe は実行されたバイナリへのリンクである
  • htoptopps のような診断ツールは、プロセスの詳細を /proc/<pid>/<file> から読み取っている
  • 新しいプロセスを作った側は parent process、作られた側は child process と呼ばれ、この関係がプロセスツリーを構成する
  • htopF5 を押すと、プロセス階層を確認できる
    • ps fpstree -a も同じ関係を表示する
  • bashdate を実行すると、bashfork で自分のコピーを作り、exec/bin/date をメモリに読み込んだあと、parent である bash が child の終了を待つ
  • /sbin/init は起動時に開始され、sshd を起動し、SSH 接続時には sshd がセッションプロセスを作成し、そのセッションが bash shell を実行する

プロセスのユーザーと権限

  • 各プロセスはユーザーに所有され、ユーザーは数値 ID で表される
  • /proc/<pid>/statusUid 項目でプロセスのユーザー ID を確認できる
  • id 1000 のようなコマンドは、数値 ID に対応するユーザー名とグループを表示する
  • id/etc/nsswitch.conf の設定に従って名前解決のソースを選択する
    • 例のシステムでは /etc/passwd/etc/group を読む
    • compat は Compatibility mode で、files と同じだが特殊項目を許可する
    • ユーザー情報は LDAP のような別のデータベースやサービスにも保存されうる
  • /etc/passwd/etc/group は、数値 ID を人間が読める名前に対応付けるプレーンテキストファイルである
  • 実際のパスワード情報は /etc/shadow にある
    • $6$sha512 ハッシュアルゴリズムを意味する
    • その後には rainbow table 攻撃を防ぐためのランダムな salt と password+salt の hash が続く
  • プログラムは基本的に、実行したユーザーの権限で動作する
    • 実行ファイルの所有者が別ユーザーでも同じである
  • 別のユーザーや root として実行するには sudo を使う
    • sudo idroot の UID 0 で実行される
    • sudo -u daemon id のように特定ユーザーとして実行できる
  • /etc/sudoers に redirect で直接書こうとすると、echo だけが root として実行され、append は現在のユーザーとして行われて失敗することがある
    • echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee -a /etc/sudoers
    • sudo bash -c "echo '$USER ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
  • /etc/sudoerssudo visudo で編集すべきである
    • 保存前に内容を検証し、sudo を使えない状態にしてしまうミスを防ぐ
  • /usr/bin/passwd は一般ユーザーが実行しても /etc/shadow に書き込める
    • ファイル権限に s があり、setuid 実行ファイルとして動作する
    • 実行ファイルの所有者である root 権限で実行される
    • root 所有の setuid 実行ファイルは find /bin -user root -perm -u+s で探せる

プロセス状態コード

  • htop の状態列は S という名前で表示され、主な値は次のとおり
    • R: running または runnable、実行中か run queue で待機中
    • S: interruptible sleep、イベント完了を待っている
    • D: uninterruptible sleep、通常は I/O 待ち
    • Z: defunct zombie、終了済みだが parent が reap していない
    • T: job control signal により停止
    • t: tracing 中に debugger によって停止
    • X: dead、表示されるべきではない状態
  • psSsR+Ss+ のような substate も表示する
  • R: 実行中または実行可能

    • R 状態は、プロセスが現在実行中か、実行待ちキューで待っている状態である
    • プログラムのソースコードはコンパイル後に CPU 命令となり、実行時にはメモリにロードされて CPU がその命令を実行する
    • 実行中であるとは、CPU が物理的に命令を実行していることを意味する
  • S: 割り込み可能な sleep

    • S 状態では、プロセスの命令は CPU 上で実行されず、イベントや条件を待っている
    • イベントが発生すると、カーネルが状態を running に変える
    • sleep 1000 は指定時間だけ待機する例である
    • この状態は signal で interrupt できる
    • htop では F9 を押して signal を送れる
    • kill は signal を送るシステムコールであり、/bin/kill は userland からそれを呼び出すプログラムである
    • デフォルトの signal は TERM で、プロセスの終了を要求する
    • signal は数値で、名前は通常大文字で書かれ、SIG prefix が付くこともある
    • 例: INT, KILL, STOP, CONT, HUP
    • kill -INT 10089, kill -2 10089, /bin/kill -2 10089 は同じ動作をする
    • CTRL+C を押すと、bash が foreground process に SIGINT を送る
    • SIGINTSIGTERM を送っても、プロセスが必ず終了するとは限らない
    • プログラムは signal handler を設定し、後始末をしてから終了するように処理できる
    • SIGKILL または 9 は、カーネルがプロセスに応答の機会を与えずに強制終了させる
  • D: 割り込み不可能な sleep

    • D 状態は signal で起こせず、SIGKILL も signal なので、このようなプロセスは kill できない
    • この状態は、プロセスが中断なしで待つ必要がある場合や、イベントがすぐ発生すると見込まれる場合に使われる
    • 例: disk read/write
    • uninterruptible process は、通常 page fault の後に I/O を待っている状態であることがある
    • NFS の読み書きの遅延でこの状態になることがある
    • 利用可能メモリが少なすぎて、プロセスが頻繁に swap している状況でも現れることがある
    • 例として sudo mount 8.8.8.8:/tmp /tmp & を実行すると、/sbin/mount.nfsD 状態になる
    • strace で見ると、mount システムコールがプロセスを block している
    • mountintr オプションを付けると interruptible に実行できる
    • sudo mount 8.8.8.8:/tmp /tmp -o intr
  • Z: ゾンビプロセス

    • Z 状態は、プロセスが終了したが parent がまだ reap していない状態である
    • ゾンビプロセスが短時間だけ存在するのは正常な場合がある
    • 長く残っているゾンビプロセスは、プログラムのバグを示している可能性がある
    • ゾンビプロセスはメモリを消費せず、PID だけを占有する
    • ゾンビプロセス自体を kill することはできない
    • parent process に SIGCHLD を送り、ゾンビを reap するよう要求できる
    • parent process を kill すれば、その parent とゾンビを取り除ける
    • fork の後に child が exit(0) し、parent が sleep(20) する C プログラムでゾンビ状態を再現できる
    • parent が終了するとゾンビは消える
    • ゾンビが維持される理由は、parent が wait システムコールで child の exit code を確認できる必要があるためである
  • T と t: 停止したプロセス

    • T 状態は job control signal により停止した状態である
    • cat /dev/urandom > /dev/null の実行中に CTRL+Z を押すと T 状態になる
    • fg で再び実行できる
    • STOP signal で止め、CONT signal で再開することもできる
    • t 状態は debugger が tracing している間に停止した状態である
    • nc -l 1234 & で実行したプロセスに sudo gdb -p <pid> でアタッチすると t 状態になる

CPU時間、niceness、priority

  • LinuxはマルチタスクOSなので、単一CPUでも複数のプロセスが同時に実行されているように見える
  • 実際には単一CPUは一度に1つの命令しか実行できないため、time sharingを使用する
    • あるプロセスが短時間実行されて中断される
    • 実行待ちの別のプロセスが順番に実行される
    • 1つのプロセスが実行される短い区間をtime sliceと呼ぶ
  • time sliceは通常数ミリ秒なので、システムloadが高くなければあまり体感できない
  • 単一コアでload averageが1.0なら、CPUが100%使用されていると見なせる
    • 1.0より高ければ、実行しようとするプロセス数がCPUの処理能力を超えており、slowdownやdelayが発生する可能性がある
    • 1.0より低ければ、CPUはときどきidle状態にある
  • プロセスのrunning timeが実際の経過時間と正確に一致しないことがある理由も、time sharingで説明できる
  • 利用可能なCPU core数より実行すべきtaskが多い場合、どのtaskを先に実行するかを決める必要がある
  • Linuxカーネルのschedulerはrun queueから次のプロセスを選び、カーネルのschedulerアルゴリズムに依存する
  • 一般にはschedulerを直接制御することはできないが、どのプロセスがより重要かを伝えることはできる
  • NIと表示されるnicenessはuser-space priorityである
    • 範囲は-20から19まで
    • -20が最も高い優先度で、19が最も低い優先度である
    • よりniceなプロセスは、そうでないプロセスにより多く譲ると考えられる
  • PRIはLinuxカーネルが使用するkernel-space priorityである
    • 範囲は0から139
    • 0~99はreal time、100~139はuser向けの範囲である
  • nice値とpriorityの関係はPR = 20 + NIで説明される
    • NI-20~+19PR0~39となり、これは100~139にマッピングされる
  • 実行前のnicenessはnice -n niceness programで設定する
  • 実行中のプロセスのnicenessはrenice -n niceness -p PIDで変更する
  • CPU使用率の色分けは次の通り
    • Blue: 低優先度thread、nice > 0
    • Green: 通常優先度thread
    • Red: kernel thread

メモリ指標: VIRT, RES, SHR, MEM%

  • プロセスは、自分だけがメモリ上に存在しているかのように見え、これは仮想メモリによって実現されている
  • プロセスは物理メモリに直接アクセスせず、独自のvirtual address spaceを持つ
  • カーネルはvirtual memory addressをphysical memoryに変換したり、一部をdiskにマッピングしたりできる
  • このため、プロセスがコンピュータに搭載されたメモリより多くのメモリを使っているように見えることがある
  • プロセスのメモリ使用量は、次の項目を含めるかどうかによって変わる
    • shared library
    • disk-mapped memory
    • swapped out memory
  • メモリ使用量の色分けは次の通り
    • Green: used memory
    • Blue: buffers
    • Orange: cache
  • VIRT/VSZ

    • VIRTはtaskが使用する全virtual memory量である
    • code、data、shared library、swapped out page、マッピングされているが未使用のpageを含む
    • アプリケーションが1GBを要求して1MBしか使っていなくても、VIRTは1GBと表示されることがある
    • 1GBのファイルをmmapして実際には使っていなくても、VIRTは1GBと表示されることがある
    • ほとんどの場合、VIRTは有用な数値ではない
  • RES/RSS

    • RESはswapped outされていないphysical memory、つまり現在物理メモリ上にあるresident memoryの使用量である
    • RESVIRTより実際のメモリ使用量をよく表すことがあるが、限界もある
    • swapped out memoryは含まない
    • 一部のメモリは他のプロセスと共有されている可能性がある
    • プロセスが1GBのメモリを使用した後にfork()すると、2つのプロセスのRESがそれぞれ1GBに見えることがあるが、Linuxのcopy-on-writeにより実際には1GBしか使っていない場合がある
  • SHR

    • SHRはtaskが使用するshared memory量である
    • 他のプロセスと潜在的に共有されうるメモリを反映する
    • 例のCプログラムは、malloc、一部メモリ使用、fork、追加メモリ書き込みを経て、VIRTRESSHRの値がどう変わるかを示している
    • 該当するメモリ例のセクションはTODOのままである
  • MEM%

    • MEM%はtaskが現在使用しているavailable physical memoryの割合である
    • RESを総RAMで割った値である
    • 例: RES400MでRAMが8GBなら、400/8192*100 = 4.88%

Ubuntu Server 16.04 の基本プロセス

  • fresh Digital Ocean droplet の Ubuntu Server 16.04.1 LTS x64 で起動されるプロセスを調査

  • /sbin/init

    • /sbin/init は boot process の残りを調整し、ユーザー環境を構成する
    • 自動的に起動されるプロセスの parent または grandparent になる
    • dpkg -S /sbin/init の結果は systemd-sysv: /sbin/init で、このシステムでは systemd である
    • kill しても何も起こらない
  • /lib/systemd/systemd-journald

    • systemd-journald は logging data を収集・保存する system service
    • 複数の source から受け取ったログ情報をもとに、structured で indexed な journal を作成・維持する
    • 単純な平文ログファイルの代わりに、ログメッセージに最適化された特殊なファイル形式を使う
    • journalctl で確認する
    • journalctl _COMM=sshd
    • journalctl _COMM=sshd -o json-pretty
    • journalctl --since yesterday
    • journalctl -b
    • journalctl -f
    • journalctl --disk-usage
    • journalctl --vacuum-size=1G
    • 削除や無効化はできないようで、logging を切ることしかできない
  • /sbin/lvmetad -f

    • lvmetad は LVM metadata を cache し、LVM コマンドが disk scan なしで metadata を読めるようにする
    • disk scan には時間がかかり、システムや disk の通常の処理を妨げることがある
    • LVM は Linux の実行中に logical volume を作成・resize・削除できる「dynamic partitions」と見なせる
    • LVM を使っているなら維持すべきと整理されている
  • /lib/systemd/udevd

    • systemd-udevd は kernel uevent を監視し、各 event に対して udev rules の matching instruction を実行する
    • udev は Linux kernel の device manager で、主に /dev directory の device node を管理する
    • virtual server で必要かどうかは確信が持てない
  • /lib/systemd/timesyncd

    • systemd-timesyncd は remote NTP server と local system clock を同期する system service
    • ntpd の代替となる
    • 例のシステムでは timedatectl status が network time と NTP synchronized を yes と表示する
    • netstat の出力では SSH port だけが listening 状態で、Ubuntu 14.04 の ntpd のように複数の UDP 123 port は開かない
  • /usr/sbin/atd -f

    • atd は後で実行するために queue に入れた job を実行する
    • atbatch は stdin またはファイルからコマンドを読み取り、後で実行する
    • 繰り返し実行を予約する cron とは違い、at は特定の時刻に一度だけ実行する
    • 例では echo "touch /tmp/yolo.txt" | at now + 1 minute で 1 分後にファイルを作成する
    • 使わないなら sudo apt remove at -y --purge で削除する
  • /usr/lib/snapd/snapd

    • Snappy Ubuntu Core は transactional update を使う Ubuntu の rendition として紹介されている
    • snap は 1 つの binary package が Linux desktop、server、cloud、device で動作する universal Linux package format と説明されている
    • dependency を single snap に束ねて配布する simplified deb package のようなものとして理解されている
    • サーバーで snappy によるアプリケーションの deploy や distribute をしたことがないため、sudo apt remove snapd -y --purge で削除している
  • /usr/bin/dbus-daemon

    • D-Bus は同じ machine 上で同時に動作する複数の process 間の IPC および RPC mechanism
    • desktop environment には必要だが、web app を動かす server で必要かは疑問としている
    • dbus を削除すると timedatectl statusFailed to create bus connection: No such file or directory で失敗した
    • そのため、保持しておくほうがよいと整理されている
  • /lib/systemd/systemd-logind

    • systemd-logind は user login を管理する system service
  • /usr/sbin/cron -f

    • cron は scheduled command を実行する daemon
    • -f は foreground mode で daemonize しないことを意味する
    • 定期的に実行する作業は cron で予約できる
    • crontab -e
    • Ubuntu では /etc/cron.hourly/etc/cron.daily などを使うことが多いと整理されている
    • ログは次の方法で確認できる
    • grep cron /var/log/syslog
    • journalctl _COMM=cron
    • journalctl _COMM=cron --since="date" --until="date"
    • cron は維持する可能性が高い
    • 削除しない場合は sudo systemctl stop cronsudo systemctl disable cron で停止・無効化できる
    • apt remove cron は postfix などをインストールしようとすることがある
    • cron が mail transport agent を suggest するため
  • /usr/sbin/rsyslogd -n

    • rsyslogd は message logging を支援する system utility
    • /var/log/auth.log のような /var/log/ 配下のログファイルを埋める役割を持つ
    • 設定ファイルは /etc/rsyslog.d にある
    • リモートサーバーへログを送って centralized logging を構成できる
    • logger コマンドを使えば background script から /var/log/syslog にメッセージを残せる
    • systemd-journald がすでにあっても、rsyslog と journal にはそれぞれ異なる特徴があり、併用が有用な場合がある
    • そのため、ひとまず維持する
  • /usr/sbin/acpid

    • acpid は ACPI event daemon
    • user-space program に ACPI event を通知するよう設計されている
    • ACPI は hardware component の discovery/configuration、power management、status monitoring などに使われる
    • virtual server で suspend/resume を意図していないため削除を試した
    • reboot は成功したが、halt の後も Digital Ocean はまだ電源が入っていると認識し、web interface から Power Off する必要があった
    • したがって、維持するほうがよいと整理されている
  • /usr/bin/lxcfs /var/lib/lxcfs/

    • lxcfs は LXC container 向けに設計された FUSE filesystem
    • /proc の一部ファイルの virtualized view と、host cgroup filesystem への filtered access を提供する
    • container 内で uptime や top などがより「correct」な結果を返すようになる
    • LXC container を使わないなら sudo apt remove lxcfs -y --purge で削除できる
  • /usr/lib/accountservice/accounts-daemon

    • AccountsService は user account 情報を query・操作するための D-Bus interface と実装を提供する
    • 実装は usermod(8)useradd(8)userdel(8) コマンドに基づいている
  • 削除後に何が壊れるかは「Time will tell」のままとされている

  • /sbin/mdadm

    • mdadm は software RAID device を管理・監視する Linux utility である
    • RAID は複数の hard drive を1つのように使う方式である
    • RAID 0 は drive capacity を拡張する
    • RAID 1、RAID 5、RAID 6、RAID 10 は drive failure 時の data loss を防ぐ目的がある
    • sudo apt remove mdadm -y --purge で削除できる
  • /usr/lib/policykit-1/polkitd --no-debug

    • polkitd は PolicyKit daemon であり、polkit は Authorization Framework である
    • fine-grained sudo のようなものとして理解できる
    • non-privileged user に root として特定の action を実行する権限を与えられる
    • 例: desktop Linux で reboot を許可する
    • server では sudo apt remove policykit-1 -y --purge で削除できるとまとめられている
    • 何が壊れるのかは依然として疑問のままである
  • /usr/sbin/sshd -D

    • sshd は OpenSSH Daemon である
    • -D オプションは detach せず daemon 化もしないようにし、monitoring を容易にする
  • /sbin/iscsid

    • iscsid は iSCSI configuration に従って動作し、connection を管理する background daemon である
    • iSCSI は IP ベースの storage networking standard で、SCSI command を IP network 経由で伝送し、remote storage を local disk のように使えるようにする
    • sudo apt remove open-iscsi -y --purge で削除できる
  • /sbin/agetty --noclear tty1 linux

    • agetty は alternative Linux getty である
    • getty は physical または virtual terminal を管理し、接続が検出されると username prompt を表示した後に login プログラムを実行する
    • Digital Ocean では droplet details の Console を通じて、この terminal と browser 上でやり取りできる
    • getty@tty1.service 関連ファイルを削除して reboot すると SSH 接続は可能だったが、Digital Ocean web console では login できなかった
  • SSH セッション、bash、htop

    • sshd: root@pts/0 は、ユーザー root の SSH session が pseudoterminal pts/0 に設定されたことを意味する
    • pseudoterminal は実際の text terminal を emulate する
    • bash は使用中の shell である
    • -bash のように先頭に dash が付いていれば login shell として開始されたことを意味する
    • argument zero の先頭文字が - であるか、--login option で開始された shell は login shell である
    • この場合は別の configuration file set を読む
    • htop は screenshot で実行中の interactive process viewer である

サービス削除の実験

  • 一般的な削除対象一覧は次のとおり
    • sudo apt remove lvm2 -y --purge
    • sudo apt remove at -y --purge
    • sudo apt remove snapd -y --purge
    • sudo apt remove lxcfs -y --purge
    • sudo apt remove mdadm -y --purge
    • sudo apt remove open-iscsi -y --purge
    • sudo apt remove accountsservice -y --purge
    • sudo apt remove policykit-1 -y --purge
  • Extreme edition では次の作業を含む
    • sudo apt remove dbus -y --purge
    • sudo apt remove rsyslog -y --purge
    • sudo apt remove acpid -y --purge
    • sudo systemctl stop cron && sudo systemctl disable cron
    • sudo rm /etc/systemd/system/getty.target.wants/getty@tty1.service
    • sudo rm /lib/systemd/system/getty@.service
  • unattended installation of WordPress on Ubuntu Server の手順に従った nginx、PHP7、MySQL の構成は動作する

付録: 調査ツールと shell の動作

  • ソースコードを探す

    • strace だけでは不十分なときは source code を見ることができる
    • which uptime で binary の場所を見つけ、dpkg -S /usr/bin/uptime で Ubuntu package を調べる
    • 例では uptimeprocps package に属する
    • packages.ubuntu.com で package を検索し、source repository link を見つけられる
  • file descriptor と redirection

    • stderr を stdout に redirect するときは 2>&1 を使う
    • echo something > file は stdout を file に書くことで、echo something 1> file と同じ
    • echo something 2> file は stderr を file に書く
    • echo something 2>1 は stderr を 1 という filename に redirect する意味
    • & を付けた 2>&1 での 1 は filename ではなく stream ID
  • PuTTY の色の問題

    • PuTTY で htop の要素が欠けて見える場合は Window → Colours 設定で解決できる
    • title bar を右クリック
    • Change settings...
    • Window → Colours
    • Both radio button を選択
    • Apply
  • Cで作った簡単な shell

    • C で書いた簡単な shell は forkexecwait システムコールの使い方を示している
    • 入力が exit なら shell built-in として終了する
    • それ以外のコマンドは fork の後、child で execlp により実行し、parent は waitpid で終了状態を待つ
    • datetruefalse の実行例では child exit code がそれぞれ出力される
    • sleep 1 & のような background process の終了メッセージが Enter を押したあとでようやく表示される理由は、shell が入力待ちの間は待機し、コマンド入力時に background process の状態を確認するため

残っている調査項目と更新履歴

  • さらに調べたい項目は process state substatus、kernel thread、/dev/ptsCODEDATASWAP メモリ、time slice の長さ、Linux scheduler アルゴリズム、core pinning、manual page、CPU/memory bar の色、process ID limit と fork bomb、lsofioniceschedtool など
  • 主な修正・更新には次が含まれる
    • /proc/uptime の idle time は全 core の合計
    • zombie C の例で parent/child の printf が修正された
    • apt remove cron が MTA dependency のため postfix をインストールしようとする点が追加された
    • id/etc/nsswitch.conf を通じて /etc/passwd 以外の source からも情報をロードできる
    • /etc/shadow の password hash format の説明が追加された
    • /etc/sudoers は安全に visudo で編集すべき
    • MEM% の説明が追加された
    • load average セクションが書き直された
    • kill 1234 のデフォルト signal は INT ではなく TERM であるよう修正された
    • CPU と memory color bar の説明が追加された

1件のコメント

 
GN⁺ 5 시간 전
Hacker News のコメント
  • 最近は btop に乗り換えた。必要なだけモダンで便利、情報量も十分なインターフェースだった。
    他の人が言っているように消費電力(Watts)も表示するようだし、ネットワーク、GPU、ディスク情報も一緒に出る。
    https://github.com/aristocratos/btop

    • btop は良いが欠点もある: zram/zswap の統計がなく(htop も zram だけ対応)、ZFS 統計の詳細な内訳がなく、まだ Arc GPU をサポートしていない。
      ディスク使用量バーをオフにできないので、コンソールウィンドウがかなり大きくないと I/O 速度グラフがひどく押しつぶされて見える。
    • btop を長く使ってきたが、足りないのは他の列の横に ポート列が1つあることくらい。
      CPU/GPU グラフは大きく取りすぎで、全体としては開いているファイルテーブルにもっと多くのスペースを割いてほしい。
    • 今でもたまにコンテナのベースイメージに Alpine を使うが、btop は musl をサポートしていないようなので候補から外れる。
    • btop 信者なので、新しい MacBook では iStatMenu まで置き換えた。
  • htop を使うたびに変える設定が2つあり、これで大きく変わる。
    1つ目は、ユーザースレッドをオフにすること。たいてい htop の画面を雑然とさせるだけで、有用な情報はほとんどくれない。
    2つ目は、プロセスツリー表示をオンにすること。プロセスがどこから起動されたかは他の情報より重要なことが多く、多くのファイルを処理しながら CPU を食うコンパイラプロセスなども追跡しやすくなる。
    個人的には、どちらも htop のデフォルト動作であるべきだと思う。

    • プロセスツリー表示は良いが、オンにするとプロセス一覧の 動的更新と再ソートが止まるのが残念。
  • 仮想メモリは信用しにくいという説明がうれしい。Windows タスクマネージャーがデフォルトで見せる方式がこちらなので、ひどい。
    常駐セットサイズ(RSS) が最も信頼できる指標で、それ以外の値は、実際には問題を起こしていないメモリマップトファイルのようなもののせいで不当に膨らむことがある。
    例えば 2GB のログファイルをメモリマップしても、その部分を読むときにだけページに載るので実メモリを使っているわけではないのに、ユーザーはプロセスを見て「なぜこのアプリはこんなにメモリを使っているのか」と言う。
    Chrome も一時期この問題に悩まされ、メモリマップトファイルの使用を減らしたが、それはメモリマップトファイルが悪いからではなく、ユーザーが実際の物理メモリ使用量ではない値を見て過剰反応したからだ。
    Web には仮想メモリ割り当て量で使用量を判断せよというガイドもあるが、この記事は少なくともその点をきちんと押さえている。

    • 実際には 比例セットサイズ(PSS) のほうが RSS より正確。
      参考: https://en.wikipedia.org/wiki/Proportional_set_size
    • メモリマップトファイルを使うと、キャッシュされたページがそのプロセスの 常駐セットサイズに含まれる。
      通常のファイル I/O を使うと含まれない。各ジョブのメモリ使用量を監視して、要求量を超えると殺す HPC クラスターでは、なかなか面白い結果が生じる。
    • 常駐セットサイズはプロセスが欲しがっているメモリ量ではなく、OS がそのプロセスに与えることにした量である。
      メモリ圧迫が始まると、もはや代表的な値ではなくなる。この誤解のせいで誤った判断を何度か見たし、チームメンバーが逆の判断をしないようにチャートからこの値を外したこともある。
    • 正確に言うと、Windows タスクマネージャーはプロセスのメモリ使用量のデフォルトとして Private Working Set を使っており、ライブラリやメモリマップトファイルのように他のプロセスと共有されるページは含まない。
      名前の通り、プロセスごとにプライベートに割り当てられた物理メモリにマップされた部分だけを表示し、Unix の Resident Set により近い。
      おそらくパフォーマンスタブのメモリ使用量を指しているのだと思うが、すべてのメモリ使用量項目と誤解されかねないので区別しておく。
  • top で > 文字を使うと メモリ使用量順のソートになる。
    ホストが遅くなる理由を探すときにたまに使うし、swapd が CPU を食っているのも見られる。

    • メモリは大文字の M、CPU は大文字の P を使うほうが好み。
  • こういう記事を読むと、Linux を20年以上毎日使ってきたのに、まだ 潜在能力の一部しか活用していないことに気づかされる。良い記事だ。

  • HN がまた持ち直している感じがする。
    これが HN の歩く死者の時期でなければいいのだが。

    • トップページに AI 関連の記事が3本あるが、1つは低品質な生成物を批判する記事なので希望を持ってみる。
    • 7年前の スロップ以前の記事に戻りながら回復中なのかもしれない。
  • nmon を知らない人は、これも一度見てみる価値がある。
    h を押すと利用可能なモニター一覧が出て、もう一度押すと消え、q で終了する。
    https://nmon.sourceforge.io/pmwiki.php
    特に dD キーで見る ディスクスループットと I/O はかなり便利。

    • 職場で使っている AIX マシンで知ったもので、topas も思い出す。
    • 非常に便利なツールなので、自分が管理できるすべてのマシンに入れている。
      Wide CPU 使用率グラフが多数のコアを扱いやすくしてくれるのが良い。
  • *top 系とは違う使い方として、落ち着いた ps 風の差分レポートや vmstat のようなシステム全体のレポートのほうを好むようになった。
    こうすれば、すべての内容がターミナルのスクロールバックバッファに残る: https://github.com/c-blake/procs
    珍しく効率的で表現力のある Nim 言語で書かれている。

  • この記事を2016年からブックマークしていて、何年もの間に何度も参照し直してきた。