#
ドキュメント

Document

自分のための備忘録です。

Linuxの基礎 補足

Ref

デバイス

デバイスドライバ

デバイスドライバ(略称:ドライバ、ドライバー)とは、ディスプレイモニター、プリンターやイーサネットボード、拡張カードやその他周辺機器など、パソコンに接続されているハードウェアなどをオペレーティングシステム (OS) によって制御可能にするために用意されたソフトウェアである。

-- https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90

デバイスドライバはカーネルモジュールの一部として提供されています(デバイスドライバを抽象化したファイルがデバイスファイル)。
新しいデバイスをインストールすることをロードと呼びます(コマンドはmodprobe ドライバ名)。

lsmodによってインストール済みのカーネルモジュールを表示できます。

デバイスファイル

Linuxではデバイスドライバを抽象化したインターフェースをデバイスファイルと呼びファイルとして扱います。

デバイスファイル(英: Device file)またはスペシャルファイル(英: Special file)とは、ファイルシステム上であたかも通常のファイルのような形で提示されるデバイスドライバのインタフェースである。これにより、ソフトウェアが入出力システムコールを通してデバイスドライバを使うことができ、作業が単純化される。

デバイスファイルは、プリンターなどの周辺機器への単純なインタフェースを提供する。また、ディスクパーティションなどの機器上の特定のリソースへのアクセスにも使える。さらに、/dev/nullや擬似乱数生成器といった特定の機器とは対応しないリソースへのアクセスにも使われる。

-- https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB

devディレクトリ

Linuxでは、デバイスドライバを抽象化してデバイスファイルとして扱います。
デバイスファイルは/devディレクトリに配置されています。

procディレクトリ

現在OSが認識しているデバイス情報は/procにあります。
procディレクトリは実体のない仮想ファイルです。

$ ll /proc | grep -E "(cpuinfo|meminfo)"
-r--r--r--   1 root            root                          0 Jul 15 03:06 cpuinfo
-r--r--r--   1 root            root                          0 Jul 15 03:06 meminfo

それぞれのデバイス情報を表示するlscpulsmemlspcilsusbなどのコマンドがあります。 (※ PCI:拡張スロット Peripheral Components Connection、Peripheral 周辺の)

  • vオプション:詳細表示
  • vv:さらに詳細に表示

Udev

Udev(Userspace Device management)はデバイスファイルを管理します。

  1. デバイス(ハードウェア)を接続
  2. カーネルがデバイスを検知して/sysディレクトリにデバイス情報を作成
  3. udevデーモン(udevd)が/sysディレクトリのデバイス情報を参照して/devディレクトリにデバイスファイルを作成

udevd/devにどのような名前でデバイスファイルを作成するかといった情報は/etc/udevd/rules.dで設定します。
/sysディレクトリのファイルも/procディレクトリ同様に仮想ファイルです。

システム起動フロー

概要

  1. BIOS/UEFI起動
  2. ブートローダー読み込み
  3. カーネルを読み込み
  4. SysVinitinit)/systemdプロセス実行
  5. サービスを管理

詳細

  1. フラッシュROMのBIOS/UEFI[^bios]が起動します
    1. ハードウェアのチェックや初期化をします
    2. 起動デバイス(HDDやSSDなど)に書き込まればブートローダー(boot loader)を読み出した後にブートローダーに制御を移します
  2. ブートローダーが起動デバイスからカーネルをメモリ上に読み込みます
  3. カーネルがメモリの初期化やシステムクロックを設定します
  4. カーネルが仮のルートファイルシステム(initramfs:初期RAMディスク)をマウントします
  5. 初期RAMディスクにはシステムの起動に必要なデバイスドライバが組み込まれており、これを使ってハードディスク等のデバイスへアクセスできるようになります
  6. ルートファイルシステムが使用できるようになるとカーネルはinit(またはsystemd)プロセスを実行します
  7. initまたはsystemdは必要なサービスを順次起動していき最後に、ログインプロンプトを起動します

以上で起動処理が完了します。

[^bios]:「BIOS(Basic Input Output System:入出力基本システム)はキーボードやハードディスクなどのデバイスを制御するもっとも基本的な制御プログラムです。」(Linux教科書 LPIC1 p17) BIOSはフラッシュROMに書き込まれています。

システム起動時のログ

// display message
// カーネルバッファを出力
$ dmesg
// systemdを使用している場合
$ journal -kb

SysVinit

現在はsystemdが多く採用されています。
どちらもLinuxで最初に実行されるプロセス(PIDが1)です。

  • SysVinit/etc/init.d/のスクリプトを実行します
  • SysVinitはランレベルによって実行するスクリプトが異なります(/etc/rcN.d※ Nはランレベル)
  • /etc/rcN.dのファイルは/etc/init.d/へのシンボリックリンクが多いです

例としてApacheをインストールした場合の挙動を記載します。

$ sudo apt install apache2

/etc/init.dapacheの起動スクリプトが作成されます。
また/etc/rc5.dに↑へのシンボリックリンクが作成されます。

$ ll /etc/rc5.d
total 8
// ...
lrwxrwxrwx  1 root root   17 Jul 15 04:32 S01apache2 -> ../init.d/apache2*
// ...

よって/etc/init.d/apache2 start起動できるようになります。

systemdを採用しているUbuntuではsudo systemd start apache2.serviceを使うことを推奨します。
以下はSysVinit経由でも実行できることを例示しているだけです。

$ sudo /etc/init.d/apache2 start

$ systemctl status apache2.service
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-07-15 04:45:40 UTC; 1min 3s ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 3008 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 3012 (apache2)
      Tasks: 55 (limit: 1146)
     Memory: 4.7M
        CPU: 27ms
     CGroup: /system.slice/apache2.service
             ├─3012 /usr/sbin/apache2 -k start
             ├─3018 /usr/sbin/apache2 -k start
             └─3019 /usr/sbin/apache2 -k start

Jul 15 04:45:40 ip-10-2-1-95 systemd[1]: Starting The Apache HTTP Server...
Jul 15 04:45:40 ip-10-2-1-95 systemd[1]: Started The Apache HTTP Server.

Systemd

SysVinitに代わって主流になっています。
Systemdは、initではなくsystemdプロセスが最初に起動(PIDが1)して各種サービスを管理します。 (つまりsystemdプロセスがルートプロセスになります。)

例)自動起動を停止 cronの自動起動を停止します。

$ sudo systemctl disable cron.service

EC2を再起動して確認するとcronは起動していません。

$ sudo systemctl status cron.service
○ cron.service - Regular background program processing daemon
     Loaded: loaded (/lib/systemd/system/cron.service; disabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:cron(8)

自動で起動するサービスにcronがないことを以下コマンドで確認できます。

$ sudo systemctl list-unit-files -t service --state=enabled | grep cron
// なし

cronの自動起動を有効化します。

$ sudo systemctl enable cron.service
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install
.
Executing: /lib/systemd/systemd-sysv-install enable cron
Created symlink /etc/systemd/system/multi-user.target.wants/cron.service → /lib/systemd/system/cron
.service.

自動で起動するサービスにcronが追加されています。

$ sudo systemctl list-unit-files -t service --state=enabled | grep cron
cron.service

この時点ではまだサービスは起動されません。

$ sudo systemctl status cron.service
○ cron.service - Regular background program processing daemon
     Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:cron(8)

sudo systemctl start cron.serviceを実行するかLinuxを再起動します。

共有ライブラリ

Cプログラムで利用するライブラリは以下のものがあります。

  • コンパイル時にロードされる静的ライブラリ
  • 実行時にロードされる動的ライブラリ共有ライブラリ

動的ライブラリを共有ライブラリと呼びます。

共有ライブラリは以下の特徴を持ちます。

  • lib〜.so〜というファイル名
  • /libまたは/usr/libに配置

ldd

実行ファイルに必要な共有ライブラリはldd(list dynamic dependecies)コマンドで調べることができます。 コマンドは絶対パスで指定します。

$ sudo ldd /bin/ls
        linux-vdso.so.1 (0x00007fff88eb1000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f8c55e8d000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c55c65000)
        libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f8c55bce000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8c55ee4000)

パーティション

最低2つのパーティションが必要です。

  • ルートファイルシステムに割り当てるパーティション
  • スワップ領域[^swap]に割り当てるパーティション

[^swap]:仮想メモリ領域。スワップ領域の目安サイズは物理メモリの1から2倍(Linux教科書 LPIC1 p51)。

Amazon EC2 Ubuntu22.04 t3.nanoを使った例

ボリュームを追加して3つのパーティションを作成します

  1. AWSマネジメントコンソールからボリュームを追加(1GB)
  2. ↑によって追加された(ブロック)デバイスを確認
  3. パーティションを3つ作成
  4. ファイルシステムを構築
  5. /data1にマウント
  6. /data2にマウント
  7. スワップ領域としてマウント

追加された(ブロック)デバイスを確認

ボリュームがnvme1n1として追加されたとします。

$ lsblk -f
NAME         FSTYPE   FSVER LABEL           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0        squashfs 4.0                                                              0   100% /snap/amazon-ssm-agent/5656
// ...
nvme0n1
├─nvme0n1p1  ext4     1.0   cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f    6.1G    19% /
├─nvme0n1p14
└─nvme0n1p15 vfat     FAT32 UEFI            83EA-FFE2                              99.1M     5% /boot/efi
nvme1n1 // <============= ブロックデバイスを追加
$ ll /dev | grep nvme1n1
brw-rw----  1 root disk    259,   4 Jul 16 05:26 nvme1n1

パーティションを作成

$ sudo gdisk /dev/nvme1n1
// インタラクティブにパーティションを作成
// 3回繰り返して3つのパーティションを作成

追加されたパーティションを確認

sudo lsblk -f
NAME         FSTYPE   FSVER LABEL           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0        squashfs 4.0                                                              0   100% /snap/amazon-ssm-agent/5656
loop1        squashfs 4.0                                                              0   100% /snap/core18/2409
loop2        squashfs 4.0                                                              0   100% /snap/core20/1518
loop3        squashfs 4.0                                                              0   100% /snap/snapd/16010
loop4        squashfs 4.0                                                              0   100% /snap/lxd/22923
nvme0n1
├─nvme0n1p1  ext4     1.0   cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f    6.1G    19% /
├─nvme0n1p14
└─nvme0n1p15 vfat     FAT32 UEFI            83EA-FFE2                              99.1M     5% /boot/efi
nvme1n1
├─nvme1n1p1  <========== 追加されたパーティション
├─nvme1n1p2  <========== 追加されたパーティション
└─nvme1n1p3  <========== 追加されたパーティション

ファイルシステムを構築

/data1/data2にマウントするパーティション(nvme1n1p1, nvme1n1p2)のファイルシステムを構築します(この処理をフォーマットと呼ぶことがあります)。 スワップ領域に割り当てるパーティションnvme1n1p3にはファイルシステムを構築しません。

// ext4でファイルシステムを構築
$ sudo mkfs -t ext4 /dev/nvme1n1p1
$ sudo mkfs -t ext4 /dev/nvme1n1p2

ファイルシステムが構築されたことを確認します。

 lsblk -f
NAME         FSTYPE   FSVER LABEL           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0        squashfs 4.0                                                              0   100% /snap/amazon-ssm-agent/5656
// ...
nvme0n1
├─nvme0n1p1  ext4     1.0   cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f    6.1G    19% /
├─nvme0n1p14
└─nvme0n1p15 vfat     FAT32 UEFI            83EA-FFE2                              99.1M     5% /boot/efi
nvme1n1
├─nvme1n1p1  ext4     1.0                   7bf0b8f6-3fdb-4942-b0df-c681c0065f29
├─nvme1n1p2  ext4     1.0                   b1255df1-26ee-4af5-b274-989c73cdb4b9
└─nvme1n1p3

dataにマウント

// data1にマウント
$ sudo mount /dev/nvme1n1p1 /data1
// data2にマウント
$ sudo mount /dev/nvme1n1p2 /data2

スワップ領域にマウント

スワップ領域にマウントするパーティションにはファイルシステムを構築しないことに注意してください。

$ sudo mkswap /dev/nvme1n1p3

マウントを確認します。

lsblk -f
NAME         FSTYPE   FSVER LABEL           UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0        squashfs 4.0                                                              0   100% /snap/amazon-ssm-agent/5656
loop1        squashfs 4.0                                                              0   100% /snap/core18/2409
loop2        squashfs 4.0                                                              0   100% /snap/core20/1518
loop3        squashfs 4.0                                                              0   100% /snap/snapd/16010
loop4        squashfs 4.0                                                              0   100% /snap/lxd/22923
nvme0n1
├─nvme0n1p1  ext4     1.0   cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f    6.1G    19% /
├─nvme0n1p14
└─nvme0n1p15 vfat     FAT32 UEFI            83EA-FFE2                              99.1M     5% /boot/efi
nvme1n1
├─nvme1n1p1  ext4     1.0                   7bf0b8f6-3fdb-4942-b0df-c681c0065f29  416.9M     0% /data1
├─nvme1n1p2  ext4     1.0                   b1255df1-26ee-4af5-b274-989c73cdb4b9  205.8M     0% /data2
└─nvme1n1p3  swap     1                     0ddfdd2a-d70a-48ce-b327-12f510cf2f76

パーティ🅂hンテーブルを確認

パーティションを操作するコマンドは、fdiskgdiskpartedがあります。

  • fdisk:MBRパーティションテーブルに対応(MBR:マスターブートレコード)
  • gdisk:GPTパーティションテーブルに対応(GPT:GUIDパーティションテーブル)
  • parted:MBR、GPT両方に対応
$ sudo parted /dev/nvme0n1
GNU Parted 3.4
Using /dev/nvme0n1 <=============== ブロックデバイスを表示
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p  // <==================== パーティションテーブルを表示
Model: Amazon Elastic Block Store (nvme)
Disk /dev/nvme0n1: 8590MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name  Flags
14      1049kB  5243kB  4194kB                     bios_grub
15      5243kB  116MB   111MB   fat32              boot, esp
 1      116MB   8590MB  8474MB  ext4
$ lsblk
NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0          7:0    0 25.1M  1 loop /snap/amazon-ssm-agent/5656
// ...
nvme0n1      259:0    0    8G  0 disk
├─nvme0n1p1  259:1    0  7.9G  0 part /           <======= 1
├─nvme0n1p14 259:2    0    4M  0 part             <======= blos_grb
└─nvme0n1p15 259:3    0  106M  0 part /boot/efi   <======= boot
nvme1n1      259:4    0    1G  0 disk /data
└─nvme1n1p1  259:5    0  512B  0 part

EC2のボリューム

パーティションを作成してマウントしているボリュームを前提にします。

  • アンマウントしなくてもデタッチできます
  • 再度マウントするとパーティションは維持されるがマウントポイントは維持されないのでマウントする必要があります

備考

ハードディスク接続形態

  • SATA
  • SAS
  • SCSI
  • USB

ファイルシステム一覧

  • ext2
  • ext3
  • ext4:標準
  • XFS:Red Hat Enterprise Linux 7やCentOS7で標準のファイルシステム
  • VFAT:Windows 95の時代から使用でき、Linuxではおもにブートローダーの格納パーティションなどで使用される
  • exFAT
  • Btrfs:Linux向けの最新のファイルシステム(B-tree file system)

/bin, /sbin, /usr/bin, /usr/sbin

コマンド語源

  • dmesg:display message
  • uname:unix name
  • depmod:dependence modules
  • grub-mkconfig:grub make config
  • ldd:list dynamic dependecies

ref. https://tech.pjin.jp/blog/2016/10/31/lpic%e3%82%88%e3%81%8f%e3%81%82%e3%82%8b%e8%b3%aa%e5%95%8f%e9%9b%86%e7%ac%ac%e2%91%a1%e5%9b%9e%ef%bd%9e%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e7%94%b1%e6%9d%a5%e7%b7%a8%ef%bd%9e%e3%81%9d%e3%81%ae2/

  • dpkg:Debian Package

ref. https://tech.pjin.jp/blog/2017/01/12/lpicyokuarushitsumonsyudai2kaikomandoyuraihensono3/

  • fdisk:format disk
  • mke2fs:make ext2 filesystem
  • fsck:filesystem check

ref. https://tech.pjin.jp/blog/2017/02/06/the-questions-of-lpic-part2-the-origin-of-commands-no6/

  • df:disk free(ディスクの空き容量)
  • du:disk usage(ディスク使用量)

ref. https://tech.pjin.jp/blog/2017/02/07/the-questions-of-lpic-part2-the-origin-of-commands-no7/