Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Linuxのディレクトリ構造の話

 Linuxのディレクトリ構造の話

「新しいLinuxの教科書」を読む会 オンライン #4 での発表資料です。
https://linuxbook.connpass.com/event/184754/

Osumi, Yusuke

August 21, 2020
Tweet

More Decks by Osumi, Yusuke

Other Decks in Technology

Transcript

  1. ちょっとだけ細かいLinuxの
    ディレクトリ構造の話
    @ozuma5119
    1
    「新しいLinuxの教科書」を読む会 オンライン #4 2020/08/23

    View Slide

  2. 新しいLinuxの教科書: Chapter04
    2
    > このようにLinuxではすべてがファイルとして表現されているため、

    View Slide

  3. 新しいLinuxの教科書: Chapter04
    3
    > このようにLinuxではすべてがファイルとして表現されているため、
    コマンド → ファイルです。 /bin/cp など
    ディスク → ファイルです。 /dev/sda など
    カーネル → ファイルです。 /boot/vmlinuz-3.10.0-xxxxxxx など
    ディレクトリ → これも実はファイルです!
     ※正確にはファイルシステムによるので、「Linuxでは」はちょっと語弊

    View Slide

  4. 話すと長いので、ここでは以下だけ理解しよう
    1. ディレクトリは、ファイルシステム上ではファイルと
    本質的な違いは無い
    2. ファイルは「ファイル名」を持っていない
    ではどこにファイル名があるのか?
    → ディレクトリが持っています
    4

    View Slide

  5. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    ext2,ext3,ext4 などちょっと前のも基本は同じ
    5
    ディレクトリ
    /home/ozuma/workdir
    ディレクトリ
    subdir
    ファイル
    ls.txt
    ファイル
    abc.txt

    View Slide

  6. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    ext2,ext3,ext4 などちょっと前のも基本は同じ
    6
    /home/ozuma/workdir
    ディレクトリ
    subdir
    ファイル
    ls.txt
    ファイル
    abc.txt
    struct linux_dirent64 {
    u64 d_ino;
    s64 d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[0];
    };
    ディレクトリエントリ
    ● d_ino: iノード番号
    ● d_type: ファイルtype
    ● d_name: ファイル名
    ※ディレクトリは、「ディレクトリエントリを持つファイル」
    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/dirent.h?h=linux-3.10.y

    View Slide

  7. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    7
    #include
    #include
    int main(int argc, char *argv[])
    {
    DIR *dir;
    struct dirent *dentry;
    dir = opendir(argv[1]);
    while (dentry = readdir(dir)) {
    printf("d_ino:%8i, d_type:%2i, d_name:%s\n",
    dentry->d_ino,
    dentry->d_type,
    dentry->d_name);
    }
    closedir(dir);
    return 0;
    }
    struct linux_dirent64 {
    u64 d_ino;
    s64 d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[0];
    };
    https://gist.github.com/ozuma/cbb3952387894f44ab88254ebfa03499
    view_dirent.c

    View Slide

  8. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    8
    /home/ozuma/workdir
    ディレクトリ
    subdir
    ファイル
    ls.txt
    ファイル
    abc.txt
    ディレクトリエントリ
    ● d_ino: iノード番号
    ● d_type: ファイルtype
    ○ 通常ファイル: 8
    ○ ディレクトリ: 4
    ● d_name: ファイル名
    ※ディレクトリは、配下の iノード番号とファイル名のセットを持ってい
    るだけのちょっと変わった「ファイル」
    $ ./view_dirent ./
    d_ino: 64012, d_type: 4, d_name:.
    d_ino:51665359, d_type: 4, d_name:..
    d_ino: 64002, d_type: 8, d_name:abc.txt
    d_ino: 1438999, d_type: 8, d_name:ls.txt
    d_ino:50796252, d_type: 4, d_name:subdir
    $

    View Slide

  9. 新しいLinuxの教科書: Chapter04
    9
    > このようにLinuxではすべてがファイルとして表現されているため、

    View Slide

  10. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    10
    ディレクトリ
    /home/ozuma/workdir
    iノード番号=64012
    ディレクトリ
    subdir
    iノード番号=50796252
    ファイル
    ls.txt
    iノード番号=1438999
    ファイル
    abc.txt
    iノード番号=64002
    $ ./view_dirent ./
    d_ino: 64012, d_type: 4, d_name:.
    d_ino:51665359, d_type: 4, d_name:..
    d_ino: 64002, d_type: 8, d_name:abc.txt
    d_ino: 1438999, d_type: 8, d_name:ls.txt
    d_ino:50796252, d_type: 4, d_name:subdir
    $

    View Slide

  11. ディレクトリの構造 (CentOS 7: xfsファイルシステム)
    11
    ディレクトリ
    subdir
    iノード番号=50796252
    ファイル
    ls.txt
    iノード番号=1438999
    ファイル
    abc.txt
    iノード番号=64002
    $ ./view_dirent ./
    d_ino: 64012, d_type: 4, d_name:.
    d_ino:51665359, d_type: 4, d_name:..
    d_ino: 64002, d_type: 8, d_name:abc.txt
    d_ino: 1438999, d_type: 8, d_name:ls.txt
    d_ino:50796252, d_type: 4, d_name:subdir
    $
    1. Linuxのファイルは iノード番号が本質
    2. iノード番号とファイル名のセットが壊れると、ファイルが
    見つからない(復旧ソフトなどはこれを上手くくっつけ
    る)
    3. ls -i コマンド、df -i コマンドなどを試してみよう

    View Slide

  12. ひとつ紹介:失敗例
    ● プログラムはファイルをiノードで考える
    ● 人間はファイルをファイル名で考える
    このギャップがミスを生む
    12

    View Slide

  13. 実際に私がやらかしたこと (再現イメージです)
    13
    # ./program > out.log
    # tail -f out.log
    [09/May/2020:11:32:36] start A01
    [09/May/2020:11:33:45] end A01
    [09/May/2020:11:33:47] start B01
    ....
    (大丈夫そうだな…)

    View Slide

  14. ログをローテートしたかった
    → 古いログを日付けつきにして、新しいout.logを用意
    14
    # ./program > out.log
    (ログファイル名を昨日の日付にして……)
    # mv out.log out.20200822.log
    (元と同じファイル名のファイルを用意……)
    # touch out.log
    (これでええやろ)
    programは止めずに……

    View Slide

  15. 失敗:これでは out.20200822.log に出力が続く
    15
    # ./program > out.log
    mvではiノード番号は変わりません
    $ ls -i out.log
    2102832 out.log
    $ mv out.log out.20200822.log
    $ ls -i out.20200822.log
    2102832 out.20200822.log
    ※そのためこの場合、out.20200822.logに
    ログは出力され続けます!!

    View Slide

  16. 失敗:これでは out.20200822.log に出力が続く
    16
    # ./program > out.log
    mvではiノード番号は変わりません
    $ ls -i out.log
    2102832 out.log
    $ mv out.log out.20200822.log
    $ ls -i out.20200822.log
    2102832 out.20200822.log
    ※そのためこの場合、out.20200822.logに
    ログは出力され続けます!!
    この数週間後、out.logに吐か
    れていると信じたまま、out.<
    日付>.logは古いログと思って
    消してしまった
    (皆さん同じ失敗しないで)

    View Slide

  17. 参考文献
    このスライドでは、かなりはしょって説明しているので、一部不正確と言える部分もありま
    す。
    より詳しく知りたい方は:
    ● iノードとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 ←
    分かりやすくオススメ
    ● readdir(3) https://linuxjm.osdn.jp/html/LDP_man-pages/man3/readdir.3.html
    ● dirent.h https://man7.org/linux/man-pages/man0/dirent.h.0p.html
    ● Linux/XFS の directory size で 6 byte や 4096 byte が多い理由
    ● 書籍:詳解 Linuxカーネル ← 意欲のある方は……
    17

    View Slide