Linux

概要

GNU LinuxはオープンソースのOS。 もっとも成功したOSSプロジェクトの1つで、世界中の開発者によって開発が進められている。

Memo

ユーザリソースを確認する方法

ulimit -a

real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 126771 max locked memory (kbytes, -l) 4072104 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 9788 cpu time (seconds, -t) unlimited max user processes (-u) 126771 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

tzdataとは

tzdataは、タイムゾーン(時刻帯)のデータベースであり、主にオペレーティングシステムやプログラミング言語で使用される。タイムゾーンデータは、世界中の異なる地域と時間帯の間の変換や日付・時刻の計算を可能にする。

tzdataには、地域ごとの時差や夏時間の情報が含まれている。このデータベースは、世界各地の政府機関や国際的な規格に基づいて維持され、定期的に更新される。タイムゾーンデータは、UTC(協定世界時)を基準として、地域ごとの時差を正確に表現する。

プログラミング言語やオペレーティングシステムでは、tzdataを使用して、タイムゾーンに関連する情報を取得し、日付や時刻の変換、タイムゾーンの切り替え、夏時間…を処理する。一般的に、タイムゾーンデータはデータベースファイルやライブラリとして提供され、プログラム内で利用される。

タイムゾーンデータは、日々の時間管理や国際的な日付やイベントの処理において重要な役割を果たす。正確な時刻の取得や表示、イベントのスケジュール管理、タイムゾーンに関連する問題の処理において、tzdataは欠かせない要素となっている。

AF_VSOCK(Virtual Socket Family)とは

AF_VSOCKは、Linuxカーネルで利用されるソケットファミリーの1つ。AF_VSOCKは、仮想マシンやコンテナなどの異なるホスト間での通信を可能にするため設計されている。ホストと仮想マシンまたはコンテナ間での高速で効率的な通信ができる。ソケットを介して異なる仮想マシン/コンテナ間でデータを送受信できる。

プロセスとスレッドの違い

構造。プロセス・スレッドというが、別階層の話。

  • OS
    • プロセス
      • スレッド
  • 実行中のプログラム。OSによってプロセスは管理される。プロセス間では別のメモリ空間が割り当てられるので影響を及ぼすことはない。プロセス間でメモリを共有しない
  • プロセスによってスレッドは管理される。プロセス内の同じメモリ領域を共有する。スレッドは、スレッド同士で同じメモリ領域を使う。マルチスレッドにすることで並列処理ができるのがメリット
    • プログラムから見たスレッドは、メモリにロードされたプログラムの現在の実行状態を持つ仮想CPU
    • 仮想CPUのそれぞれに、スタックメモリが割り当てられている
    • OSやCPUから見たスレッドは、時間が凍結されたプログラムの実行状態
    • OSの仕事は、凍結状態のプログラムの実行状態を復元して、各スレッドを順番に短時間ずつ処理を再開させること
    • 複数のプログラムは、時間分割されてCPUコアにマッピングされて実行される
  • シングルスレッドのプロセス: 1つしかスレッドを持たない
  • マルチスレッドのプロセス: 複数スレッドを持つプロセス

特殊なディレクトリ

慣例的に使われる特別なディレクトリがある。

たとえば /etc/skel/ は、ユーザが作成されたときのホームディレクトリのベースになる。前もってここに配置しておくと、ユーザが作られたあとホームディレクトリにコピーされ、ユーザが扱える。

/etc/default/useradd に書いてあり、useraddを経由した変更もできる。

インストールディスク作成

Linux環境でブータブルUSBを作成するとき、よくわからない要因によって失敗することが何度かあった。たいていはブートできないというもの。

既存のベースとなるisoを持ってくる。isoを展開する。展開したシステムディレクトリをマウントする。この時点で、システムはiso内にあるものが使われ、変更もiso内に反映される。

  • unetbootinを使う
  • 焼く前に、USBドライブをext4でフォーマットする。それ以外だとbootに失敗することがある
  • 仮想マシンで素早くテストできる
    • sudo apt install qemu-kvm
    • qemu-system-x86_64 -boot d -cdrom ubuntu.iso -enable-kvm -m 4096

lsのソースコード

while ((ch = getopt(argc, argv, “1AaBbCcdFfghikLlMmnOoPpqRrSsTtuWwXx”)) != -1) { switch (ch) { /*

  • The -1, -C, -l, -m and -x options all override each other so
  • shell aliasing works correctly.

*/ case '1': f_singlecol = 1; f_column = f_columnacross = f_longform = f_stream = 0; break; case ’C’: f_column = 1; f_columnacross = f_longform = f_singlecol = f_stream = 0; break;

cdのソースコード

/*

  • The cd and pwd commands.

*/

echoのソースコード

* $NetBSD: echo.c,v 1.23 2021/11/16 21:38:29 rillig Exp $ *

nflag = *++argv != NULL && strcmp(*argv, “-n”) == 0;

  • getopt関数を使っていない

ctrl+shiftが機能しない

インプットメソッドによって、入力方法の変更ショートカットが奪われる。 https://superuser.com/questions/358749/how-to-disable-ctrlshiftu

fcitxを使っている場合、 fcitx-configtool で設定できる。 全体の設定 → 入力メソッドの切り替えで、別のキーボードの組み合わせを選択する。

ディスプレイマネージャーを再起動

壊れたときにシステム再起動よりはやく復帰できる。

systemctl restart display-manager

linux mintでsnapをインストールする

sudo rm /etc/apt/preferences.d/nosnap.pref

bluetoothが動かないとき

新しくクリーンインストールしたところ、Bluetooth接続ができなかった。 インストール前はできていたから、ハードウェアに問題はない。

前はデフォルトでできてたはずだが、bluetooth周辺ライブラリをインストールしてサービスを再起動する。 どれが効いたのかはさだかではないが、接続できるようになった。

sudo apt-get install bluetooth bluez bluez-tools rfkill blueman

# 強制的に全てのブロックを解除
sudo rfkill unblock all
# Bluetoothを再起動
sudo systemctl restart bluetooth.service

caps_lockをコマンドで切り替える

Caps LockをControlに入れ替えていると、xmodmapをいじったときに大文字のまま元に戻せなくなることがある。 代替のキーはないので困る。コマンドでできる。

sudo apt-get install xdotool
xdotool key Caps_Lock

Tasks

TODO 低レベルプログラミング(Igor Zhirkov 吉川 邦夫 吉川 邦夫)|翔泳社の本

低レベルプログラミングの本。

メモ。

  • フォン・ノイマンのモデルの問題点
    • インタラクティブでない
    • マルチタスクに適してない
    • 誰でもどの種類の命令を実行できる
  • Intel64での、フォン・ノイマンのモデル拡張
    • レジスタ群
    • ハードウェアスタック
    • 割り込み
    • プロテクションリング
    • 仮想メモリ
  • ファイルをメモリにマッピングする手順
    • openシステムコールでファイルを開く。ファイルディスクリプタを得る
    • mmapシステムコールでメモリにマッピングする。引数でファイルディスクリプタを渡す
xor rax, rax

TODO その47 日常ソースコードリーディング pgrepの使い方を間違えたのをきっかけにLinuxカーネルのコードを読む - YouTube

読む様子の動画。勉強になる。

  • 構造体の固定長配列フィールドが16バイトで、ヌル終端だから15バイト分しか入らない
    • 文字数制限は脆弱性対策のよう
  • psの検索結果として出てくるのはコマンド名かと思いきや、basenameで切り取られた結果。パスは含まれない
  • basenameはシェルコマンドにもある
  • 15バイト制限を回避する f オプションがある。情報源を/proc/[pid]/cmdlineに変えているが、このファイルでのパスはbasenameを取ってなかったり引数も含まれたりといろいろ不都合がある。行頭マッチは使えない
cat /proc/177525/cmdline

home/orange.guix-profile/bin/emacs

TODO Amazon.co.jp: Binary Hacks ―ハッカー秘伝のテクニック100選 : 高林 哲, 鵜飼 文敏, 佐藤 祐介, 浜地 慎一郎, 首藤 一幸: 本

バイナリ本。

readelf -h /bin/ls

ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2’s complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Position-Independent Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x6ab0 Start of program headers: 64 (bytes into file) Start of section headers: 136224 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 13 Size of section headers: 64 (bytes) Number of section headers: 31 Section header string table index: 30

readelf -l /bin/ls

Elf file type is DYN (Position-Independent Executable file) Entry point 0x6ab0 There are 13 program headers, starting at offset 64

Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000002d8 0x00000000000002d8 R 0x8 INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 0x000000000000001c 0x000000000000001c R 0x1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000003428 0x0000000000003428 R 0x1000 LOAD 0x0000000000004000 0x0000000000004000 0x0000000000004000 0x0000000000013146 0x0000000000013146 R E 0x1000 LOAD 0x0000000000018000 0x0000000000018000 0x0000000000018000 0x0000000000007458 0x0000000000007458 R 0x1000 LOAD 0x0000000000020000 0x0000000000021000 0x0000000000021000 0x0000000000001278 0x0000000000002540 RW 0x1000 DYNAMIC 0x0000000000020a98 0x0000000000021a98 0x0000000000021a98 0x00000000000001c0 0x00000000000001c0 RW 0x8 NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000030 0x0000000000000030 R 0x8 NOTE 0x0000000000000368 0x0000000000000368 0x0000000000000368 0x0000000000000044 0x0000000000000044 R 0x4 GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000030 0x0000000000000030 R 0x8 GNU_EH_FRAME 0x000000000001cdcc 0x000000000001cdcc 0x000000000001cdcc 0x000000000000056c 0x000000000000056c R 0x4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10 GNU_RELRO 0x0000000000020000 0x0000000000021000 0x0000000000021000 0x0000000000001000 0x0000000000001000 R 0x1

Section to Segment mapping: Segment Sections… 00 01 .interp 02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 03 .init .plt .plt.got .plt.sec .text .fini 04 .rodata .eh_frame_hdr .eh_frame 05 .ctors .dtors .data.rel.ro .dynamic .got .data .bss 06 .dynamic 07 .note.gnu.property 08 .note.gnu.build-id .note.ABI-tag 09 .note.gnu.property 10 .eh_frame_hdr 11 12 .ctors .dtors .data.rel.ro .dynamic .got

readelf -S /bin/ls

There are 31 section headers, starting at offset 0x21420:

Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000000318 00000318 000000000000001c 0000000000000000 A 0 0 1 [ 2] .note.gnu.pr[…] NOTE 0000000000000338 00000338 0000000000000030 0000000000000000 A 0 0 8 [ 3] .note.gnu.bu[…] NOTE 0000000000000368 00000368 0000000000000024 0000000000000000 A 0 0 4 [ 4] .note.ABI-tag NOTE 000000000000038c 0000038c 0000000000000020 0000000000000000 A 0 0 4 [ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b0 000000000000004c 0000000000000000 A 6 0 8 [ 6] .dynsym DYNSYM 0000000000000400 00000400 0000000000000b88 0000000000000018 A 7 1 8 [ 7] .dynstr STRTAB 0000000000000f88 00000f88 00000000000005a6 0000000000000000 A 0 0 1 [ 8] .gnu.version VERSYM 000000000000152e 0000152e 00000000000000f6 0000000000000002 A 6 0 2 [ 9] .gnu.version_r VERNEED 0000000000001628 00001628 00000000000000c0 0000000000000000 A 7 2 8 [10] .rela.dyn RELA 00000000000016e8 000016e8 00000000000013e0 0000000000000018 A 6 0 8 [11] .rela.plt RELA 0000000000002ac8 00002ac8 0000000000000960 0000000000000018 AI 6 25 8 [12] .init PROGBITS 0000000000004000 00004000 0000000000000025 0000000000000000 AX 0 0 4 [13] .plt PROGBITS 0000000000004030 00004030 0000000000000650 0000000000000010 AX 0 0 16 [14] .plt.got PROGBITS 0000000000004680 00004680 0000000000000030 0000000000000010 AX 0 0 16 [15] .plt.sec PROGBITS 00000000000046b0 000046b0 0000000000000640 0000000000000010 AX 0 0 16 [16] .text PROGBITS 0000000000004cf0 00004cf0 0000000000012441 0000000000000000 AX 0 0 16 [17] .fini PROGBITS 0000000000017134 00017134 0000000000000012 0000000000000000 AX 0 0 4 [18] .rodata PROGBITS 0000000000018000 00018000 0000000000004dcc 0000000000000000 A 0 0 32 [19] .eh_frame_hdr PROGBITS 000000000001cdcc 0001cdcc 000000000000056c 0000000000000000 A 0 0 4 [20] .eh_frame PROGBITS 000000000001d338 0001d338 0000000000002120 0000000000000000 A 0 0 8 [21] .ctors PROGBITS 0000000000021000 00020000 0000000000000010 0000000000000000 WA 0 0 8 [22] .dtors PROGBITS 0000000000021010 00020010 0000000000000010 0000000000000000 WA 0 0 8 [23] .data.rel.ro PROGBITS 0000000000021020 00020020 0000000000000a78 0000000000000000 WA 0 0 32 [24] .dynamic DYNAMIC 0000000000021a98 00020a98 00000000000001c0 0000000000000010 WA 7 0 8 [25] .got PROGBITS 0000000000021c58 00020c58 00000000000003a0 0000000000000008 WA 0 0 8 [26] .data PROGBITS 0000000000022000 00021000 0000000000000278 0000000000000000 WA 0 0 32 [27] .bss NOBITS 0000000000022280 00021278 00000000000012c0 0000000000000000 WA 0 0 32 [28] .gnu_debugaltlink PROGBITS 0000000000000000 00021278 0000000000000049 0000000000000000 0 0 1 [29] .gnu_debuglink PROGBITS 0000000000000000 000212c4 0000000000000034 0000000000000000 0 0 4 [30] .shstrtab STRTAB 0000000000000000 000212f8 0000000000000125 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), l (large), p (processor specific)

objdump -p /bin/ls

/bin/ls: file format elf64-x86-64

Program Header: PHDR off 0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3 filesz 0x00000000000002d8 memsz 0x00000000000002d8 flags r– INTERP off 0x0000000000000318 vaddr 0x0000000000000318 paddr 0x0000000000000318 align 2**0 filesz 0x000000000000001c memsz 0x000000000000001c flags r– LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12 filesz 0x0000000000003428 memsz 0x0000000000003428 flags r– LOAD off 0x0000000000004000 vaddr 0x0000000000004000 paddr 0x0000000000004000 align 2**12 filesz 0x0000000000013146 memsz 0x0000000000013146 flags r-x LOAD off 0x0000000000018000 vaddr 0x0000000000018000 paddr 0x0000000000018000 align 2**12 filesz 0x0000000000007458 memsz 0x0000000000007458 flags r– LOAD off 0x0000000000020000 vaddr 0x0000000000021000 paddr 0x0000000000021000 align 2**12 filesz 0x0000000000001278 memsz 0x0000000000002540 flags rw- DYNAMIC off 0x0000000000020a98 vaddr 0x0000000000021a98 paddr 0x0000000000021a98 align 2**3 filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags rw- NOTE off 0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3 filesz 0x0000000000000030 memsz 0x0000000000000030 flags r– NOTE off 0x0000000000000368 vaddr 0x0000000000000368 paddr 0x0000000000000368 align 2**2 filesz 0x0000000000000044 memsz 0x0000000000000044 flags r– 0x6474e553 off 0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3 filesz 0x0000000000000030 memsz 0x0000000000000030 flags r– EH_FRAME off 0x000000000001cdcc vaddr 0x000000000001cdcc paddr 0x000000000001cdcc align 2**2 filesz 0x000000000000056c memsz 0x000000000000056c flags r– STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4 filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- RELRO off 0x0000000000020000 vaddr 0x0000000000021000 paddr 0x0000000000021000 align 2**0 filesz 0x0000000000001000 memsz 0x0000000000001000 flags r–

Dynamic Section: NEEDED libselinux.so.1 NEEDED libc.so.6 INIT 0x0000000000004000 FINI 0x0000000000017134 GNU_HASH 0x00000000000003b0 STRTAB 0x0000000000000f88 SYMTAB 0x0000000000000400 STRSZ 0x00000000000005a6 SYMENT 0x0000000000000018 DEBUG 0x0000000000000000 PLTGOT 0x0000000000021c58 PLTRELSZ 0x0000000000000960 PLTREL 0x0000000000000007 JMPREL 0x0000000000002ac8 RELA 0x00000000000016e8 RELASZ 0x00000000000013e0 RELAENT 0x0000000000000018 FLAGS 0x0000000000000008 FLAGS_1 0x0000000008000001 VERNEED 0x0000000000001628 VERNEEDNUM 0x0000000000000002 VERSYM 0x000000000000152e RELACOUNT 0x00000000000000c7

Version References: required from libselinux.so.1: 0x0edb87f0 0x00 08 LIBSELINUX_1.0 required from libc.so.6: 0x06969188 0x00 11 GLIBC_2.28 0x06969194 0x00 10 GLIBC_2.14 0x069691b3 0x00 09 GLIBC_2.33 0x06969197 0x00 07 GLIBC_2.17 0x0d696914 0x00 06 GLIBC_2.4 0x069691b4 0x00 05 GLIBC_2.34 0x09691974 0x00 04 GLIBC_2.3.4 0x09691a75 0x00 03 GLIBC_2.2.5 0x0d696913 0x00 02 GLIBC_2.3

WIP Linuxのしくみ ―実験と図解で学ぶOS、仮想マシン、コンテナの基礎知識【増補改訂版】 | Gihyo Digital Publishing … 技術評論社の電子書籍

  • 42, 147

動かして学ぶ本。

  • 論理CPUが実行している命令の割合は sar コマンドを使う
sar -P 0 1 1

Linux 5.15.0-41-generic (orange-ThinkPad-X1-Carbon-Gen-10) 01/05/2024 x86_64 (16 CPU)

10:35:45 PM CPU %user %nice %system %iowait %steal %idle 10:35:46 PM 0 15.31 0.00 1.02 0.00 0.00 83.67 Average: 0 15.31 0.00 1.02 0.00 0.00 83.67

  • tasksetコマンドで、論理CPUを指定してタスクを実行できる
ldd /bin/echo

linux-vdso.so.1 (0x00007ffd65ef3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc6a02a6000) /lib64/ld-linux-x86-64.so.2 (0x00007fc6a04ef000)

ldd /bin/echo

linux-vdso.so.1 (0x00007ffccff55000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f308c86a000) /lib64/ld-linux-x86-64.so.2 (0x00007f308cab3000)

ldd /usr/bin/python3

linux-vdso.so.1 (0x00007fffc69f0000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f754c0a9000) libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f754c078000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f754c05c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f754be34000) /lib64/ld-linux-x86-64.so.2 (0x00007f754c791000)

ps aux --no-header | wc -l

451

  • プロセスのメモリマップは `cat /proc/{{pid}}/maps` で調べられる
pstree -p
  • 多くのプロセスで、CPUを使った時間は1秒に満たない
    • 各プロセスは起動してから、CPUを使わずに何らかのイベントが発生するのを待つ、スリープ状態になっていた
    • STATフィールドの1文字目がSであるプロセスはスリープ状態にあることを示す
    • プロセスがCPUを使いたいというプロセスは実行可能状態であるという。このときSTATフィールドの1文字目はRになる
    • 実際にCPUを使っている状態は実行状態
    • プロセスが終了するとゾンビ状態(STATフィールドはZ)になり、その後消滅する
ps aux
false &
wait $! # falseプロセスの終了を待ち合わせる。falseコマンドのpidは$!変数から得られる
echo "falseコマンドが終了しました: $?" # wait後にfalseプロセスの戻り値は$?変数から得られる

falseコマンドが終了しました: 1

  • 親プロセスは子プロセスの終了状況を適宜回収して、リソースをカーネルに解放する
man 7 signal | head -n 10

SIGNAL(7) Linux Programmer’s Manual SIGNAL(7)

NAME signal - overview of signals

DESCRIPTION Linux supports both POSIX reliable signals (hereinafter “standard sig‐ nals”) and POSIX real-time signals.

Signal dispositions

ps ajx | head -n 10

PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 1:16 /sbin/init splash 0 2 0 0 ? -1 S 0 0:04 [kthreadd] 2 3 0 0 ? -1 I< 0 0:00 [rcu_gp] 2 4 0 0 ? -1 I< 0 0:00 [rcu_par_gp] 2 5 0 0 ? -1 I< 0 0:00 [netns] 2 10 0 0 ? -1 I< 0 0:00 [mm_percpu_wq] 2 11 0 0 ? -1 S 0 0:00 [rcu_tasks_rude_] 2 12 0 0 ? -1 S 0 0:00 [rcu_tasks_trace] 2 13 0 0 ? -1 S 0 0:41 [ksoftirqd/0]

  • プロセスグループを使うと、当該プロセスグループに所属する全プロセスに対してシグナルを投げられる
sleep 1 &
ps ajx | egrep "$PPID|$!"

1 148772 148310 148310 ? -1 Sl 1000 409:32 home/orange.guix-profile/bin/emacs 148772 148817 148817 148817 ? -1 Ss 1000 0:10 /usr/bin/cmigemo -q –emacs -d /usr/share/cmigemo/utf-8/migemo-dict 148772 153047 153047 153047 pts/11 153047 SLsl+ 1000 1347:41 /opt/google/chrome/chrome 148772 153626 153626 153626 pts/6 153626 Ss+ 1000 0:00 /bin/bash 148772 153657 153657 153657 pts/3 153657 Ss+ 1000 0:00 /bin/bash 148772 153776 153776 153776 pts/4 153776 Ss+ 1000 0:00 /bin/bash 148772 153837 153837 153837 pts/0 153837 Ss+ 1000 0:00 /bin/bash 148772 156827 156827 156827 ? -1 Ss 1000 0:44 usr/bin/mozc_emacs_helper –suppress_stderr 148772 449717 449717 449717 ? -1 Ssl 1000 0:09 /home/orange.emacs.d/.cask/.cache/lsp/rust/rust-analyzer 148772 956786 956786 956786 pts/2 956786 Ss+ 1000 0:00 /bin/bash 148772 1030938 1030938 1030938 pts/7 1030938 Ss+ 1000 1:40 /usr/bin/python3 -m http.server 8000 148772 1052415 1052415 1052415 pts/8 1052415 Ss+ 1000 0:00 /bin/bash 148772 1203772 1203772 1203772 pts/9 1203772 Ss+ 1000 0:00 /bin/bash 148772 1215308 1215308 1215308 ? -1 Ssl 1000 0:50 /home/orange/go/bin/gopls -remote=auto 148772 1224161 1224161 1224161 ? -1 Ssl 1000 0:29 /home/orange/go/bin/gopls -remote=auto 148772 1260197 1260197 1260197 ? -1 Ssl 1000 0:27 /home/orange/go/bin/gopls -remote=auto 148772 1260667 1260667 1260667 pts/10 1260667 Ss+ 1000 0:00 /bin/bash 148772 1278406 1278406 1278406 ? -1 Ssl 1000 1:35 /home/orange/go/bin/gopls -remote=auto 148772 1386122 1386122 1386122 ? -1 Ssl 1000 0:36 /home/orange/go/bin/gopls -remote=auto 148772 1633877 1633877 1633877 pts/12 1633877 Ss+ 1000 0:00 /bin/bash 148772 2345920 2345920 2345920 ? -1 Ssl 1000 0:12 /home/orange/go/bin/gopls -remote=auto 148772 2463164 2463164 2463164 pts/13 2463164 Ss+ 1000 0:00 /bin/bash 148772 2791028 2791028 2791028 pts/14 2791028 Ss+ 1000 0:00 /bin/bash 148772 2798220 2798220 2798220 ? -1 Ssl 1000 0:06 /home/orange/go/bin/gopls -remote=auto 148772 2798497 2798497 2798497 pts/15 2798497 Ss+ 1000 0:00 /bin/bash 148772 3126717 3126717 3126717 ? -1 Ss 1000 0:00 /bin/bash 3126717 3126718 3126717 3126717 ? -1 S 1000 0:00 sleep 1 3126717 3126720 3126717 3126717 ? -1 S 1000 0:00 grep -E 148772|3126718

  • 親 ppid: 1, pid: 148772 //home/orange/.guix-profile/bin/emacs
  • 子 ppid: 148772, pid: 3126717 /bin/bash
  • 子 ppid: 3126717, pid: 3126718 sleep 1
  • /bin/bash, sleep 1, grep -E 148772|3126718 はPGID(プロセスグループID)が同じである

デーモンの特徴。

  • 端末から入出力する必要がないので、端末が割り当てられていない
  • あらゆるログインセッションが終了しても影響を受けないように、独自のセッションを持つ
  • デーモンを生成したプロセスがデーモンの終了を気にしなくていいように、initが親になっている
ps ajx | grep dockerd

PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1 2952095 2952095 2952095 ? -1 Ssl 0 23:14 usr/bin/dockerd -H fd:/ –containerd=/run/containerd/containerd.sock 3130365 3130367 3130365 3130365 ? -1 S 1000 0:00 grep dockerd

  • 親プロセスはinit(PPIDが1)
  • TTYは割り当てられていない
  • セッションIDがPIDと同じ
time sleep 1
# real  0m1.002s
# user  0m0.002s
# sys   0m0.001s
  • realはほぼ1秒。開始直後にCPUを手放しスリープ状態になり、1秒後にCPUをまた使いはじめても終了処理をするだけなので、userとsysはほぼ0
  • カーネルに「コンテナ」という名前の機能があるわけではない。namespace機能をうまく活用して実現している

TODO シェルとファイルデスクリプタのお話 - Qiita

ファイルディスクリプタをシェルで扱う。

TODO ハロー“Hello, World” OSと標準ライブラリのシゴトとしくみ

printを実行するとき何が起こっているかの解説。

TODO The Linux Kernel

Linuxカーネルの解説。

TODO Introduction · Linux Inside

Linuxカーネルの解説。

TODO O’Reilly Japan - Linuxシステムプログラミング

システムプログラミングの本。

TODO O’Reilly Japan - 詳解 Linuxカーネル 第3版

  • 15

カーネルのソースコードを読む本。

Reference

What Every Programmer Should Know About Memory

ハードウェアとしてのメモリを解説した本。

SadServers - Troubleshooting Linux Servers

壊れたLinuxサーバを解くサイト。

Filesystem Hierarchy Standard

パス名の標準仕様。

i386って何? - Linux技術者認定 LinuC | LPI-Japan

今ではCPUの名前というと「Core 2 Duo」とか「Athlon」、あるいは「Xeon」や「Opteron」といったかっこいい名前で呼ばれるように なりましたが、Linuxが産声を上げた頃はCPUは重要なパーツではありますが一部品でしかなく、型番で呼ばれるものでした。

なぜあの無機質な名前なのか不思議だった。

imladris.surriel.com

Linuxまわりのリンク集。

Linux_Kernel_Newbies - Linux Kernel Newbies

新米カーネル開発者が見るページ。

SquashFSをマウントするまで - Qiita

システムをファイルに圧縮するとき使う。

新規ユーザ作成時のデフォルト値の設定

ユーザの設定方法。ここでデフォルトディレクトリに /etc/skel 指定している。

Man page of SUDO

sudoの解説。特にプロセスモデルに関する詳しい解説。

Linuxカーネルの読み方

Linuxカーネルのソースコードを読むコツと参考文献がある。

Archives

DONE ふつうのLinuxプログラミング 第2版 Linuxの仕組みから学べるgccプログラミングの王道 Amazon

Linuxの仕組みから学べるシステムプログラミング。

  • Linuxはファイルシステムとプロセスとストリームでできている
  • Linux上において、活動する主体はユーザではなく、プロセス
  • ログイン時にクレデンシャルが作られ、プロセスに渡している
  • シェルと端末は異なる
    • 端末はユーザとのインターフェースになる部分。現代では仮想化されていて無数にある。端末に対応するデバイスファイル /dev/tty0 などがある
    • シェルはユーザからの命令を解釈し実行するプログラムのこと。ストリームからコマンドを読み込んで実行するプログラムにすぎない
  • ttyの語源はテレタイプ。ディスプレイがなかったので長い紙に結果を出力していた
  • tabの語源はtable
  • キーボード → 端末ドライバ → ストリーム → プロセス → ストリーム → 端末ドライバ → ディスプレイ
  • Linuxの入出力の主な4つのシステムコール
    • ストリームからバイト列を読み込むread
    • ストリームにバイト列を書き込むwrite
    • ストリームを作るopen
    • 用済みのストリームを始末するclose
  • ファイルディスクリプタは整数値にすぎない
  • 固定のファイルディスクリプタ
    • 0: 標準入力
    • 1: 標準出力
    • 2: 標準エラー出力
  • 標準エラー出力がある理由。標準出力は次のプログラムの標準入力につながれている場合が多いので、ここでエラーを出しても気づかない可能性が高いから
  • ストリームはファイルディスクリプタで表現され、read()またはwrite()で操作できるもののこと
  • システムコールは遅いので、バッファに溜まってからシステムコールするとよい
  • gets()はバッファオーバーフローを起こす可能性があり、使ってはいけない。世界初のインターネットワームはバッファオーバーフローの脆弱性を利用した
  • ビルド
    • プリプロセス
      • 純粋なC言語のソースコードを出力する
    • コンパイル
      • C言語のソースコードをアセンブリ言語のソースコードに変換する
    • アセンブル
      • アセンブリ言語のソースコードを機械語を含むオブジェクトファイルに変換する
    • リンク
      • オブジェクトファイルから実行ファイルを生成する
  • /proc にはプロセスの情報がファイルに格納されている
  • ダイナミックロードは、すべてのリンク作業を実行時に行う手法
  • 0は成功、1はエラーというのはLinuxに特有の決まりごと
  • プロセスの親子関係を調べる pstree
  • ログインシェルを調べる w, last
  • HTTPの仕組みとファイルシステムはよく似ている
  • HTTPで公開されるのはファイルシステムの一部だけ。これをドキュメントツリーという。ドキュメントツリーのルートディレクトリをドキュメントルートという。デフォルト設定のWebサーバでいうところの /var/www/html のことか
  • HTTPサーバのしごと: HTTPリクエストをドキュメントルート以下のファイルにマップし、レスポンスとして送り返すこと

DONE 私はどのようにしてLinuxカーネルを学んだか

Linuxカーネルの学び方についての本。

  • 動かしながら読む
  • マクロが多用されているので、あらかじめ展開して読む
  • 図を書く

DONE はじめてのOSコードリーディング ――UNIX V6で学ぶカーネルのしくみ | Gihyo Digital Publishing … 技術評論社の電子書籍

Unixコードリーディングの本。

準備方法。

# https://www.utam0k.jp/blog/2019/03/05/xv6_intro/ から
sudo apt install git nasm build-essential qemu gdb
git clone git@github.com:mit-pdos/xv6-public.git
make qemu     # GUIありの起動
make qemu-nox # GUIなしの起動
make qemu-nox-gdb # Booting with gdbserver

cd <path to xv6>
gdb
(gdb) source .gdbinit