202104

unix domain sockets debug

  • nc -lU <path>

sshfs

  • brew install --cask osxfuse
  • https://github.com/osxfuse/sshfs/downloads
  • https://hkob.hatenablog.com/entry/2020/12/20/110000
  • https://github.com/libfuse/sshfs

みのくらロボット|ホーム

  • 勝手に入るゴミ箱の人

osとカーネル

  • OSと一言でいっても,ユーザランドとカーネルというように空間が別れている
  • いわゆるシステムコールはカーネルに対して発行し,カーネル管理下のリソースへの操作をしたいときに用いられる.
  • カーネルはシステムのすべてのリソースにアクセスすることができ,物理アドレスをもっている.
    • 逆に,ユーザランドアプリケーションはKernelによって割り当てられたリソース(ex. memory)を論理アドレス等を用いて操作する.
  • ユーザランドアプリケーションはユーザランドに割り当てられた権限(ex. 割り当てられたリソースへの操作)のみしか実施することができない
    • このようなしくみはリングプロテクションと呼んでおり,一般的にはCPUの動作モードを変えることでハードウェアレベルで担保されている

ヒープ領域とJVM

  • 一般にメモリ領域は下記の4領域に分けて考えられる
    • プログラム領域
      • プログラム本体(関数)とかconst指定したりしたやつとか.
    • stack領域
      • stackという言葉の通りLIFO, FILOでしか確保/開放できない.いわゆるローカル変数とかがここになる.
      • 確保領域量はコンパイル時に決定される.(コンパイル時点で確保量が既知である)
      • プログラム実行開始時に確保され,終了時に解放される.
        • ulimit -aとかでOSが割り当てるstackの割当サイズのlimitとかがわかる.
    • heap領域
      • mallocとかで動的に確保する.解放順は確保順によらない.したがってheapはフラグメンテーションが発生する可能性を有する.
        • とはいえ実際のkernel実装としてはover-commitが採用されてたりするのでmallocしただけでは実メモリ空間としては確保されなかったりする
      • 確保はプログラム実行時に動的に実施され,当然割当領域量はプログラム実行時に変化する.
    • static領域
      • プログラム実行開始から終了までアドレスが変化しないものなど.global変数やstatic変数とか.
      • プログラム実行開始時に確保され,終了時に解放される.
  • JVM動かすときにヒープ料を指定できるわけだけどあれってなんなの
    • Javaで動くアプリケーションは,開発者によって記述されたJavaソースコードをJavaコンパイラを通してコンパイルする.生成されたコードはJavaバイトコードと呼ばれる(中間ファイル).
      • このJavaバイトコードはコンパイル環境によらずどの環境でコンパイルしても同一のバイトコードが生成される.
    • JavaランタイムはJITコンパイラを内包しておりJavaアプリケーション実行時にはJavaバイトコードを各環境上のJVM内部のJITコンパイラによって実行時コンパイルされ,各環境のバイナリとなって実行される.
    • JVMはそれ自身がプログラムであるが,このときJVM上で実行されるアプリケーションが利用するメモリ領域に対して十分な量のメモリ空間をJVM側で確保する必要がある.
      • したがって,JVMうごかすときにはヒープ領域をconfigurationとして適切に設定する必要がある.

C言語におけるstatic

  • 2つの意味がある気がする.
    • ソースコードの安全性を担保するためのstatic指定
      • 関数や変数に外部からの参照性を持たせないための修飾子としての役割
        • 指定しているにもかかわらず参照するとコンパイルエラーとなる
    • 変数のメモリ割り当て空間をプログラムメモリ上のstatic領域に確保するための修飾子としての役割
      • local変数としてクラス変数のような振る舞い(同一メモリの値を参照したいケース)をさせるため.
        • とはいえ必要に応じてmutexとかを適切にしないと死にそうだね
          • mutex自体もこのタイプのstaticを使って実装できそうではある

IPフラグメンテーションとTCP MSS

  • IPフラグメンテーションはパケットサイズに対して転送経路の許容パケット長が短い場合に発生する.
    • 具体的にはMTUよりもパケット長が長い場合.
  • それに対してTCPのMSSははセッション層の機能なので,基本的にサーバとクライアントでネゴシエーションするためのもの.
    • サーバ/クライアントががどのくらいのバッファを持っているか,とかそういうことだな.
  • しかし,あるMSS値でサーバ/クライアントアプリケーションがネゴシエーションされたとしても,それによって生成されるIPパケット長はMTUを超えてしまう可能性がある.
    • 純粋なモデルでは,クライアントアプリケーションが仮にMSS=3000だったとしても,そのクライアントに刺さっているネットワークのMTUが1500だったらそもそもクライアントホストでフラグメントされてしまう.
      • 実際の実装はクライアントホストにおいてはたぶんMTUをみてMSSをきめたりしている.しかしクライアントホストに直接接続されていないネットワーク経路について同様の可能性がある.
  • これではフラグメンテーションが発生し非効率なので,TCPハンドシェイクする際のMSSを途中経路のネットワーク機器で書き換え,経路のMTUを考慮したMSSとなるようにすることができる.
    • これがいわゆるMDD clampingとか呼ばれるやつ.ciscoのコマンドだとip tcp adjust-mss <mss>とか.もともと入っているMSSと自分のMSSを比較して小さい方を採用する.
    • 純粋なモデルでは途中経路の機器がTCPレイヤに関与するべきではないが,有益性の観点から介入しているケースだと思う.
  • 余談だがIPv4では途中でフラグメント化されて宛先に到達するが,ipv6ではそうはならない.パケットサイズが転送不可能なサイズであった時点でICMPv6のPacket Too Big メッセージが送信元に返される.
    • 送信元はこれをもって,より小さいサイズのパケットに分割して再送する必要がある.
    • しかし,このICMPv6パケットを途中経路のノードが破棄してしまったり,パケットが破棄されるノードでPacket Too BigのICMPv6パケットを生成しないケースがある.これをPMTUD Blackhole(Path MTU Discovery Blackhole)と呼んでいる.
      • icmp rate limitとかFW Policyとか,Load Balancerの問題とかいろいろ被疑となりそうな対象はある.
    • PMTUD Blackholeが発生すると,再送時に考慮すべきドロップされたリンクのMTUを知ることができず,再送すべき送信元端末が途中経路でのパケットドロップを検知しなかったり,より短いパケットでの再送を実施しない可能性がある.これは送信元から宛先に正常に通信できないことを意味する.
      • PMUTDは始点ノードのMTUを初期値とし,ICMPv6,Packet Too Bigメッセージ中のMTUに変更して始点ノードが再送することを繰り返すことによりend-to-endでの最適MTUの探索を行う.途中経路のノードがフラグメント化することはない.
    • なのでipv6においては特にicmpv6が正常なパケット転送のために非常に重要になってくることに気をつけておきたい.

OOM killer (Out-of-Memory Killer)

  • Referencesで示した引用元の実行結果をコピーして自分の理解を書く.
  • OOM killerが実施されたときのログはsyslogで得られる.
$ cat /var/log/messages | grep Kill
Nov  8 13:22:24 localhost kernel: Out of memory: Kill process 17143 (java) score 468 or sacrifice child
Nov  8 13:22:24 localhost kernel: Killed process 17143 (java), UID 1001, total-vm:7790724kB, anon-rss:4108910kB, file-rss:6822kB, shmem-rss:0kB
  • OOM killerでkillされる順序はスコアの高いものから順に低いものがkillされていくしくみになっている.
  • スコアはプロセスごとに存在し,下記のようにして確認できる.
$ ps -ef | grep httpd
root       177     1  0 Nov08 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache     178   177  0 Nov08 ?        00:00:03 /usr/sbin/httpd -DFOREGROUND
...
$ cat /proc/177/oom_score_adj
0
$ cat /proc/177/oom_score
154
  • score_adjによりスコアにオフセットをもたせることが可能である.そのまま当該ファイルのスコアを変更してよい.
  • ただし面倒なので,systemdを利用しているばあいはserviceファイルのserviceセクションに下記のような記載をいれるとよい.
[Service]
OOMScoreAdjust=-1000

これによりsystemdによる起動時には当該adjustが適用されることになる.

  • ちなみにOOM scoreの基本的な計算式は下記のようになっているようだ.
Allcated memory to process/(Total MEM + Swap) / 1000
# つまりメモリ使用率の1000分率(パーミル)か.
# で,root権限だと-30されるらしい.

CCA tester, pulse charger, electric load with logger

IC-9700 周波数安定度の問題