/var/log/messages

Sep 14, 2014 - 4 minute read - Comments - Linux

cgroup 関連の記事読んだ

とりあえず kernel source 取得、って結構時間がかかっているな。とりあえず以下から目を通し始めています。

kernel/fork.c を出発点として cgroup がプロセス ID の割当てに絡んでいるあたりの確認をしている模様。alloc_pid という手続きから掘削が始まっています。

また、データ構造の確認、ということで

  • alloc_pid で空間を確保している struct pid 型について
  • alloc_pid に渡されている struct pid_namespace 型について

確認をしています。

clone 終了

GNU Global とか gtags とかが忘却の彼方で後天性記憶不全が進んでいることが分かり、かなりヘコんでいます。ともあれ

$ gtags -v

して emacs 起動。kernel/fork.c を開きます。

続行

ええと、alloc_pid 手続きを呼び出しているのは copy_process って手続きですね。そうか fork か。

            pid = alloc_pid(p->nsproxy->pid_ns_for_children);

p って何だ、と思い逆向けにめくってみると以下な記述を発見。

    retval = -ENOMEM;
    p = dup_task_struct(current);
    if (!p)
            goto fork_out;

task_struct の複製を作っているあたり。この手続きの定義は以下でした。

static struct task_struct *dup_task_struct(struct task_struct *orig)
{

task_struct を戻すのは当然ですね。ちょっと alloc_pid に渡されているソレを手繰ってみようと思います。

struct task_struct 型は include/linux/sched.h で定義されてます。nsproxy という属性の定義は以下な部分でした。

/* namespaces */
        struct nsproxy *nsproxy;

struct nsproxy 型を確認してみます。定義は include/linux/nsproxy.h でした。pid_ns_for_children という属性の型は何かというと

    struct pid_namespace *pid_ns_for_children;

ということで当り前ですが struct pid_namespace 型でした。

fork する時に task_struct を dup するのだけれど、その時に pid namespace な親子関係が云々、という事なのかどうか。

alloc_pid に戻る

引数で渡された pid_namespace について親に向かった手繰っていきながら struct pid の members という属性に id および pid namespace を設定してますね。

ドキュメントには pidmap というものは pid namespace の_割り当て状況を記録するためのビットマップ_という記載があります。

成程

こうした仕組みを持っておけばコンテナの中の pid 1 とその外の pid 1 って形で重複した pid を割り当てることができる、ということなのか。

次行きます。

こんどは仮想記憶。ここでも始点が fork らしい。他にも

  • page fault
  • mmap

などが起点としてあり得るらしいです。つうか最初からいきなりアレゲなネタが出てますね。ということで do_fork から掘削開始な模様、というか copy_process からなのか。

子プロセスの struct task_struct を戻す、というあたりから仮想アドレス空間に関することも、との事でした。そして諸々を略して copy_mm 手続きから dup_mm へ。

    retval = -ENOMEM;
    mm = dup_mm(tsk);
    if (!mm)
            goto fail_nomem;

dup_mm の手続き定義なコメントが以下。

/*
 * Allocate a new mm structure and copy contents from the
 * mm structure of the passed in task structure.
 */

allocate_mm という手続きでおそらくは新しく struct mm_struct の領域を確保して current->mm からコピィをして云々、な模様。ドキュメントではここで struct mm_struct について確認をしています。include/linux/mm_types.h にて定義されています。

とりあえずドキュメントのメモを以下に列挙。

  • 「プロセスアドレス空間内の様々な領域」を表現したものが vm_area_struct 構造体
  • do_mmap の先頭あたりに出てくる anon_vma_fork という手続き
  • anon は Annonymous Memory を指していると思われる
  • Annonymous Memory とはスタックや .data などの「バッキングストア (元ネタとなるファイル) のないデータを格納するためのメモリ領域」

で、anon_vma_fork 起点で掘削が始まっています。

  • anon_vma_fork
  • anon_vma_clone
  • struct anon_vma_chain とか struct anon_vma など
  • anon_vma は private “related” vmas のリストの先頭
  • struct anon_vma_chain は struct list_head な same_vma という属性を持っている

む、clone てリスト手繰って親のソレを参照してるだけなのか。

Annonymous Memory と物理ページ

そろそろ限界なカンジorz

struct page に Annonymous Memory がどう紐付けられているか、について。

  • page->mapping の末端 2 bit で ANON, KSM, それ以外を区別している?
  • linear_page_index という手続きで仮想アドレスを page->index に変換
  • Annonymous Memory の場合、vm_pgoff に vma の先頭アドレスをページ単位に丸めた値が格納

page->index はオフセットというかインデクスなのか。確かに仮想アドレスから変換してる、というのは分かったような分からないような。

時間切れ

ネタ見つけた、なエントリの残りよっつも月曜とかで読めれば良いな。

今日のもくもく Ingress Lv.8

comments powered by Disqus