システムコール
            とみたまさひろ
              2011-03-19



システムコール           Powered by Rabbit 0.9.2
自己紹介
    ✓ とみた まさひろ
    ✓ プログラマー
    ✓ mailto:tommy@tmtm.org
    ✓ http://d.hatena.ne.jp/tmtms
    ✓ http://twitter.com/tmtms
                                            1/34
システムコール                          Powered by Rabbit 0.9.2
自己紹介


    ✓ 日本Rubyの会
    ✓ 日本MySQLユーザ会
    ✓ 長野ソフトウェア技術者グループ


                               2/34
システムコール             Powered by Rabbit 0.9.2
自己紹介




          こんな本書きました

                                 3/34
システムコール               Powered by Rabbit 0.9.2
NSEG

    ✓ #1 Rubyの黒魔術
    ✓ #3 はじめてのRuby拡張ライブラ
      リ
    ✓ #6 Ruby紹介
    ✓ #11 RSpecとCucumber
                                      4/34
システムコール                    Powered by Rabbit 0.9.2
今回は初
  非Ruby
                     5/34
システムコール   Powered by Rabbit 0.9.2
システム
  コール                6/34
システムコール   Powered by Rabbit 0.9.2
カーネルの機
   能を直接使う
   ためのインタ
    フェース
システムコール
                     7/34
          Powered by Rabbit 0.9.2
スクリプト言語
  やVMやブラウ
  ザ上の言語か
  らは使えない             8/34
システムコール   Powered by Rabbit 0.9.2
C的には普通の関数



          int fd = open("/etc/passwd", O_RDONLY);




                                                        9/34
システムコール                                      Powered by Rabbit 0.9.2
これはライブラリ関数



          FILE *fp = fopen("/etc/passwd", "r");




                                                   10/34
システムコール                                    Powered by Rabbit 0.9.2
man のセクション


    ✓ 2 - システムコール
    ✓ 3 - ライブラリ関数


                               11/34
システムコール                Powered by Rabbit 0.9.2
違い
    ✓ システムコール
          ✓ カーネルの機能を直接使う
            (open, read, ...)

    ✓ ライブラリ関数
          ✓ カーネルの機能を使わない
            (sqrt, sprintf, ...)
          ✓ 間接的にカーネルの機能を使う
            (fopen, printf,...)
                                           12/34
システムコール                            Powered by Rabbit 0.9.2
違い




                       13/34
システムコール        Powered by Rabbit 0.9.2
違い


    例: コマンドを実行
    ✓ system(3)
    ✓ fork(2), exec(2), wait(2)


                                          14/34
システムコール                           Powered by Rabbit 0.9.2
カーネルの機能
    ✓ ファイル操作
    ✓ プロセス処理
    ✓ ネットワーク
    ✓ デバイスアクセス
    ✓ 端末制御
    ✓ etc...
                             15/34
システムコール              Powered by Rabbit 0.9.2
ファイル操作
    ✓ open, read, write, close
    ✓ stat, pipe
    ✓ chmod, chown
    ✓ link, symlink, unlink
    ✓ rename, mkdir, rmdir
                                         16/34
システムコール                          Powered by Rabbit 0.9.2
プロセス処理
    ✓ fork
    ✓ exec
    ✓ wait
    ✓ kill
    ✓ exit
                              17/34
システムコール               Powered by Rabbit 0.9.2
ネットワーク

    ✓ socket
    ✓ bind, listen, accept
    ✓ connect
    ✓ shutdown

                                     18/34
システムコール                      Powered by Rabbit 0.9.2
その他

    ✓ chdir
    ✓ getuid, setuid
    ✓ getpid, getppid
    ✓ その他、 man syscalls 見て

                                     19/34
システムコール                      Powered by Rabbit 0.9.2
strace


    ✓ システムコールのトレース
    ✓ コマンドの処理を追う
    ✓ プロセスの状態を見る


                             20/34
システムコール              Powered by Rabbit 0.9.2
strace ls

          % strace ls
          execve("/bin/ls", ["ls"], [/* 41 vars */]) = 0
          ...
          open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
          ...
          getdents64(3, /* 8 entries */, 32768) = 264
          getdents64(3, /* 0 entries */, 32768) = 0
          close(3)                                = 0
          ...
          write(1, "MyBooks.jpg SystemCall.rd Syst"..., 62) = 62
          ...




                                                                                 21/34
システムコール                                                                 Powered by Rabbit 0.9.2
strace cp

          % strace cp a b
          execve("/bin/cp", ["cp", "a", "b"], [/* 41 vars */]) = 0
          ...
          stat64("b", 0xbfd726c0)                 = -1 ENOENT (No such file or directory)
          stat64("a", {st_mode=S_IFREG|0644, st_size=96324, ...}) = 0
          stat64("b", 0xbfd724e0)                 = -1 ENOENT (No such file or directory)
          open("a", O_RDONLY|O_LARGEFILE)         = 3
          fstat64(3, {st_mode=S_IFREG|0644, st_size=96324, ...}) = 0
          open("b", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0644) = 4
          fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
          read(3, "177ELF11100000000020"..., 32768) = 32768
          write(4, "177ELF11100000000020"..., 32768) = 32768
          read(3, "610000020337023075l361"..., 32768) = 32768
          write(4, "610000020337023075l361"..., 32768) = 32768
          read(3, "00021124$350215303773771"..., 32768) = 30788
          write(4, "00021124$350215303773771"..., 30788) = 30788
          read(3, "", 32768)                      = 0
          close(4)                                = 0
          close(3)                                = 0



                                                                                            22/34
システムコール                                                                           Powered by Rabbit 0.9.2
第一部まとめ
    ✓ 今回はRubyじゃない
    ✓ システムコールで低レベルの制御
      が可能
    ✓ strace でプログラムの処理を調
      べられる
    ✓ スクリプト言語やVMばっかりじゃ
      なくて、Cからシステムコール使う
      のも楽しいよ          23/34
システムコール               Powered by Rabbit 0.9.2
mmap
                  24/34
システムコール   Powered by Rabbit 0.9.2
ファイルを
    メモリに
   マッピング
システムコール
                  25/34
          Powered by Rabbit 0.9.2
read
     通常は open して少しずつ read




                                26/34
システムコール                 Powered by Rabbit 0.9.2
mmap
     ファイル全体(または一部)をメモリにマップ




                               27/34
システムコール                Powered by Rabbit 0.9.2
mmap


    ✓ 速い
    ✓ メモリを食わない
    ✓ 大きなファイルで有用


                           28/34
システムコール            Powered by Rabbit 0.9.2
スクリプト言語からは使いにく
          い

    ✓ メモリを直接さわれない
    ✓ 文字列として扱う時はコピーが必
      要

                            29/34
システムコール             Powered by Rabbit 0.9.2
MmapScanner
    ✓ Ruby の拡張ライブラリ
    ✓ StringScanner の mmap 版
    ✓ mmap 領域から正規表現で取り
      出す
    ✓ 取り出したものも
      MmapScanner
                                   30/34
システムコール                    Powered by Rabbit 0.9.2
MmapScanner
     部分的に取り出しても同じメモリを
     共有




                                31/34
システムコール                 Powered by Rabbit 0.9.2
MmapScanner


          f = File.open("filename")
          m = MmapScanner.new(f)
          word = m.scan(/[a-z0-9_]+/i)
          word       # => MmapScanner
          word.to_s # => String

                                           32/34
システムコール                            Powered by Rabbit 0.9.2
課題

    ✓ 速くない
    ✓ ASCII-8BIT only
    ✓ 明に munmap できない
    ✓ 徐々に改善予定

                                33/34
システムコール                 Powered by Rabbit 0.9.2
第二部まとめ


    ✓ MmapScanner 作ってみた
    ✓ やっぱりRubyか


                                  34/34
システムコール                   Powered by Rabbit 0.9.2

システムコール

  • 1.
    システムコール とみたまさひろ 2011-03-19 システムコール Powered by Rabbit 0.9.2
  • 2.
    自己紹介 ✓ とみた まさひろ ✓ プログラマー ✓ mailto:tommy@tmtm.org ✓ http://d.hatena.ne.jp/tmtms ✓ http://twitter.com/tmtms 1/34 システムコール Powered by Rabbit 0.9.2
  • 3.
    自己紹介 ✓ 日本Rubyの会 ✓ 日本MySQLユーザ会 ✓ 長野ソフトウェア技術者グループ 2/34 システムコール Powered by Rabbit 0.9.2
  • 4.
    自己紹介 こんな本書きました 3/34 システムコール Powered by Rabbit 0.9.2
  • 5.
    NSEG ✓ #1 Rubyの黒魔術 ✓ #3 はじめてのRuby拡張ライブラ リ ✓ #6 Ruby紹介 ✓ #11 RSpecとCucumber 4/34 システムコール Powered by Rabbit 0.9.2
  • 6.
    今回は初 非Ruby 5/34 システムコール Powered by Rabbit 0.9.2
  • 7.
    システム コール 6/34 システムコール Powered by Rabbit 0.9.2
  • 8.
    カーネルの機 能を直接使う ためのインタ フェース システムコール 7/34 Powered by Rabbit 0.9.2
  • 9.
    スクリプト言語 やVMやブラウ ザ上の言語か らは使えない 8/34 システムコール Powered by Rabbit 0.9.2
  • 10.
    C的には普通の関数 int fd = open("/etc/passwd", O_RDONLY); 9/34 システムコール Powered by Rabbit 0.9.2
  • 11.
    これはライブラリ関数 FILE *fp = fopen("/etc/passwd", "r"); 10/34 システムコール Powered by Rabbit 0.9.2
  • 12.
    man のセクション ✓ 2 - システムコール ✓ 3 - ライブラリ関数 11/34 システムコール Powered by Rabbit 0.9.2
  • 13.
    違い ✓ システムコール ✓ カーネルの機能を直接使う (open, read, ...) ✓ ライブラリ関数 ✓ カーネルの機能を使わない (sqrt, sprintf, ...) ✓ 間接的にカーネルの機能を使う (fopen, printf,...) 12/34 システムコール Powered by Rabbit 0.9.2
  • 14.
    違い 13/34 システムコール Powered by Rabbit 0.9.2
  • 15.
    違い 例: コマンドを実行 ✓ system(3) ✓ fork(2), exec(2), wait(2) 14/34 システムコール Powered by Rabbit 0.9.2
  • 16.
    カーネルの機能 ✓ ファイル操作 ✓ プロセス処理 ✓ ネットワーク ✓ デバイスアクセス ✓ 端末制御 ✓ etc... 15/34 システムコール Powered by Rabbit 0.9.2
  • 17.
    ファイル操作 ✓ open, read, write, close ✓ stat, pipe ✓ chmod, chown ✓ link, symlink, unlink ✓ rename, mkdir, rmdir 16/34 システムコール Powered by Rabbit 0.9.2
  • 18.
    プロセス処理 ✓ fork ✓ exec ✓ wait ✓ kill ✓ exit 17/34 システムコール Powered by Rabbit 0.9.2
  • 19.
    ネットワーク ✓ socket ✓ bind, listen, accept ✓ connect ✓ shutdown 18/34 システムコール Powered by Rabbit 0.9.2
  • 20.
    その他 ✓ chdir ✓ getuid, setuid ✓ getpid, getppid ✓ その他、 man syscalls 見て 19/34 システムコール Powered by Rabbit 0.9.2
  • 21.
    strace ✓ システムコールのトレース ✓ コマンドの処理を追う ✓ プロセスの状態を見る 20/34 システムコール Powered by Rabbit 0.9.2
  • 22.
    strace ls % strace ls execve("/bin/ls", ["ls"], [/* 41 vars */]) = 0 ... open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3 ... getdents64(3, /* 8 entries */, 32768) = 264 getdents64(3, /* 0 entries */, 32768) = 0 close(3) = 0 ... write(1, "MyBooks.jpg SystemCall.rd Syst"..., 62) = 62 ... 21/34 システムコール Powered by Rabbit 0.9.2
  • 23.
    strace cp % strace cp a b execve("/bin/cp", ["cp", "a", "b"], [/* 41 vars */]) = 0 ... stat64("b", 0xbfd726c0) = -1 ENOENT (No such file or directory) stat64("a", {st_mode=S_IFREG|0644, st_size=96324, ...}) = 0 stat64("b", 0xbfd724e0) = -1 ENOENT (No such file or directory) open("a", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=96324, ...}) = 0 open("b", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0644) = 4 fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 read(3, "177ELF11100000000020"..., 32768) = 32768 write(4, "177ELF11100000000020"..., 32768) = 32768 read(3, "610000020337023075l361"..., 32768) = 32768 write(4, "610000020337023075l361"..., 32768) = 32768 read(3, "00021124$350215303773771"..., 32768) = 30788 write(4, "00021124$350215303773771"..., 30788) = 30788 read(3, "", 32768) = 0 close(4) = 0 close(3) = 0 22/34 システムコール Powered by Rabbit 0.9.2
  • 24.
    第一部まとめ ✓ 今回はRubyじゃない ✓ システムコールで低レベルの制御 が可能 ✓ strace でプログラムの処理を調 べられる ✓ スクリプト言語やVMばっかりじゃ なくて、Cからシステムコール使う のも楽しいよ 23/34 システムコール Powered by Rabbit 0.9.2
  • 25.
    mmap 24/34 システムコール Powered by Rabbit 0.9.2
  • 26.
    ファイルを メモリに マッピング システムコール 25/34 Powered by Rabbit 0.9.2
  • 27.
    read 通常は open して少しずつ read 26/34 システムコール Powered by Rabbit 0.9.2
  • 28.
    mmap ファイル全体(または一部)をメモリにマップ 27/34 システムコール Powered by Rabbit 0.9.2
  • 29.
    mmap ✓ 速い ✓ メモリを食わない ✓ 大きなファイルで有用 28/34 システムコール Powered by Rabbit 0.9.2
  • 30.
    スクリプト言語からは使いにく い ✓ メモリを直接さわれない ✓ 文字列として扱う時はコピーが必 要 29/34 システムコール Powered by Rabbit 0.9.2
  • 31.
    MmapScanner ✓ Ruby の拡張ライブラリ ✓ StringScanner の mmap 版 ✓ mmap 領域から正規表現で取り 出す ✓ 取り出したものも MmapScanner 30/34 システムコール Powered by Rabbit 0.9.2
  • 32.
    MmapScanner 部分的に取り出しても同じメモリを 共有 31/34 システムコール Powered by Rabbit 0.9.2
  • 33.
    MmapScanner f = File.open("filename") m = MmapScanner.new(f) word = m.scan(/[a-z0-9_]+/i) word # => MmapScanner word.to_s # => String 32/34 システムコール Powered by Rabbit 0.9.2
  • 34.
    課題 ✓ 速くない ✓ ASCII-8BIT only ✓ 明に munmap できない ✓ 徐々に改善予定 33/34 システムコール Powered by Rabbit 0.9.2
  • 35.
    第二部まとめ ✓ MmapScanner 作ってみた ✓ やっぱりRubyか 34/34 システムコール Powered by Rabbit 0.9.2