Linuxシステムの仕組みと運用、管理

Linuxシステムを組み込みで使うには、通常のLinuxシステムと同様に、その運 用、管理方法についても知っておく必要があります。本章では、Linuxシステム の基本的な運用、管理方法について、その背景となる仕組みも交えながら説明 していきます。

4.1. コマンドの使い方を調べる

Linuxシステムには、便利なコマンドが数多く用意されています。ここでは、 コマンドの使い方を調べる方法について紹介します。

使い方が分からないコマンドに遭遇したら、まず、コマンド自身のヘルプを見 てみましょう。コマンドに--helpオプションをつけ て実行すると、多くの場合ヘルプを表示してくれます。

[ATDE ~]$ cat --help
使用法: cat [オプション]... [ファイル]...
Concatenate FILE(s) to standard output.

FILE の指定がなかったり, - であった場合, 標準入力から読み込みます.

  -A, --show-all           equivalent to -vET
  -b, --number-nonblank    number nonempty output lines, overrides -n
  -e                       equivalent to -vE
(後略)

図4.1 --helpオプションでコマンドの使用方法を調べる


コマンドが--helpオプションをサポートしていない 場合でも、使用方法(usage)を表示してくれることが多いでしょう。

[ATDE ~]$ which --help
Illegal option --
Usage: /usr/bin/which [-a] args

図4.2 コマンドの使用方法を調べる(--helpオプションをサポートしていない場合)


より詳しく調べたい場合、オンラインマニュアル(manページ)が参考になります。 オンラインマニュアルを表示するコマンドは、 manです。manコマンド に引数としてコマンド名を渡すと、指定したコマンドのマニュアルを表示しま す。 

例えば、catコマンドの使い方を調べるには、以下 のようにします。

[ATDE ~]$ man cat

図4.3 catコマンドの使用方法を調べる


manコマンドは、manページの表示はページャーと 呼ばれるテキスト閲覧用の別のプログラムに任せます。ATDE7では、ページャ ーとしてlessを使用します。 lessは、viと同じよう な操作方法ができるページャーです。閲覧を終了するには、 qキーを押してください。 lessの使用方法を調べるには、man lessを実行してください。

manページは、説明している内容によっていくつかのセクションに分かれていま す。セクションには以下のものがあります [8]

  1. 実行プログラムまたはシェルのコマンド
  2. システムコール (カーネルが提供する関数)
  3. ライブラリコール (システムライブラリに含まれる関数)
  4. スペシャルファイル (通常 /dev に置かれている)
  5. ファイルのフォーマットとその約束事。例えば /etc/passwd など
  6. ゲーム
  7. マクロのパッケージとその約束事。例えば man(7), groff(7) など
  8. システム管理用のコマンド (通常は root 専用)
  9. カーネルルーチン [非標準]

同じ名前で、複数のセクションに説明があるmanページもあります。例えば、 writeという名前のページは、writeコマンドと writeシステムコールの二つあります。このような場合、man writeコマンドを実行すると、writeに対応するページを検索し、 もっとも適切と判断したページのみを表示します。他のセクションにあるペー ジを見たい場合は、セクション番号を指定してman コマンドを実行します。writeシステムコールの場合は、man 2 writeとなります。

manコマンドには、内容を検索する機能など様々な 機能があります。例えば、man -k writeとすると、 manページの要約文とページ名から、writeにマッチするページの一覧をすべて 表示します。manコマンドの詳細な使い方を調べる には、man manを実行してください。

[ティップ]英語版manページ

ATDE7では、標準設定では言語設定が日本語になっています。そのため、日本語 訳のあるmanページは日本語で表示されます。

しかし、翻訳がいまいちな場合など、英語で記述されたページを見たい場合もあ るでしょう。そのような場合、LANG=C man manのように、言語を一時的に設定 してmanコマンドを実行することで、英語版のmanペ ージを見ることができます。

4.2. ユーザー管理

Linuxシステムは、マルチユーザー、マルチタスクなシステムです。一つのシス テムに同時に複数のユーザーがログインすることもできますし、それぞれのユー ザーが複数のタスク(プロセス)を実行することもできます。そのため、ユーザー の管理をおこなうことは、Linuxシステム管理の基本といえるでしょう。

ユーザーには、それぞれ一意なユーザー名とユーザーIDが割り当てられます。 これらの情報は、/etcディレクトリにある passwdファイルに記述されています。 passwdファイルには「:」区切りで、ユーザー名 、パスワード、ユーザーID、グループID、コメント、ホームディレクトリ、使 用するシェルが順番に記述されています。 passwdファイルについての詳細は、 man 5 passwdで参照することができます。

有効なユーザー名の一覧を表示するには、以下のようにします。

[ATDE ~]$ cut -d ':' -f 1 /etc/passwd
root
daemon
(中略)
atmark
Debian-exim
sbuild
sshd
[ティップ]パスワード保存ファイル

パスワードは、暗号化されてファイルに保存されます。しかし、暗号文は時間 をかければ解読可能ですので、すべてのユーザーから見える passwdファイルに暗号化したパスワードを書い ておくことは望ましくありません。

そのため、暗号化したパスワードは/etcディレ クトリにあるshadowファイルに保存されていま す。shadowファイルは特権ユーザーしか見るこ とができないようにパーミッションが設定されています。パーミッションにつ いては、「ファイルの所有権とパーミッション」で説明します。

4.2.1. 特権ユーザーと一般ユーザー

Linuxシステムでは、ユーザーを一般ユーザーと特権ユーザーの2種類に大別し ます。

特権ユーザーは、システム管理などをおこなうために用意されているユーザー で、一つのシステムに必ず一つ存在します。WindowsでのAdministratorのよう な役割です。通常、特権ユーザーにはrootという名前を付けることが多いので、 rootユーザーと呼ばれることもあります。

一般ユーザーは、特権ユーザー以外のユーザーのことで、ユーザーごとに行え る作業(権限)に制限があります。Linuxシステムでは、ユーザーごとに必要最小 限の権限を与えることで、システム全体のセキュリティを保ちます。

ATDE7では、特権ユーザーとしてrootユーザー、一般ユーザーとしてatmarkユー ザーが用意されています。

特権ユーザーはすべての権限を持っているため、誤った作業をおこなうと、ファ イルをすべて消してしまうなど、システムを復旧不可能な状態に破壊してしまう 可能性があります。そのため、通常の作業は一般ユーザーでおこないます。し かし、ソフトウェアのインストールなどでは、特権ユーザーの権限が必要にな ります。そのような場合は、一時的にユーザーを切り替えて作業をおこないま す。

一般ユーザーから特権ユーザーにユーザーを切り替えるには、以下のように suコマンドを使用します。特権ユーザーでの作業 が終了したら、exitコマンドを実行し、元のユー ザーに戻ることを忘れないでください。

[ATDE ~]$ su
パスワード: root
[ATDE ~]# 特権ユーザーでの作業
[ATDE ~]# exit
[ATDE ~]$

図4.4 ユーザーの切り替え(suコマンド)


sudoコマンドを使うと、そのコマンドだけ別のユー ザーとして実行することができます。どのユーザーが、どのユーザーとして、 どのコマンドを実行できるかは、/etcディレク トリにあるsudoersファイルに記述します。

ATDE7ではatmarkユーザーがrootユーザーとしてすべてのコマンドを実行でき るように設定してあります。以下のようにsudoコ マンドを実行すると、特権ユーザー権限で somecommandを実行します。なお、 sudoコマンド実行時に入力するパスワードは、 sudoコマンドを実行したユーザー自身(この場合で はatmarkユーザー)のパスワードです。

[ATDE ~]$ sudo somecommand
パスワード: atmark

図4.5 一時的なユーザーの切り替え(sudoコマンド)


4.2.2. ユーザーの追加と削除

システムに新しくユーザーを追加するには、 useraddコマンドを使用します。

newuserというユーザー名のユーザーを追加するには、以下のようにします。 ユーザーの追加には、特権ユーザーの権限が必要なので、 sudoコマンドを介して useraddコマンドを実行します。 -mオプションは、ホームディレクトリを作成するオ プションです。

[ATDE ~]$ sudo useradd -m newuser

図4.6 ユーザーの追加(useraddコマンド)


作成したばかりのユーザーは、パスワードが設定されていないため、そのユー ザーでログインすることができません。パスワードの設定、変更をおこなうに は、passwdコマンドを使用します。

以下の例では、newuserのパスワードをpasswordに設定しています。

[ATDE ~]$ sudo passwd newuser
新しいUNIXパスワードを入力してください: password
新しいUNIX パスワードを再入力してください: password
passwd: パスワードは正しく更新されました

図4.7 パスワードの設定(passwdコマンド)


ユーザーを削除するには、userdelコマンドを使用 します。-rオプションを付けることで、ユーザーの ホームディレクトリも削除することができます。

[ATDE ~]$ sudo userdel -r newuser

図4.8 ユーザーの削除(userdelコマンド)


[ティップ]ログインできないユーザー

shadowファイルの二番目のフィールドには、暗 号化したパスワードが記述されています。ここに、*や!と書くと、無効なパス ワードになり、そのユーザーでログインすることができなくなります。

ATDEの/etc/shadowを見てみると、有効なパスワ ードが設定されていて、ログインできるのはrootユーザーとatmarkユーザーだ けです。その他のユーザーは、サーバーやシステム管理用のユーザーとして用 意されています。例えば、www-dataはWebサーバー用のユーザーです。

suコマンドを使用しても、ログインできないユー ザーには切り替えることができません。しかし、 sudoコマンドの-uオプシ ョンを指定すると、コマンドを実行するユーザーを指定することができます。 この機能を使用すると、ログインできないユーザーとしてコマンドを実行する こともできます。

[ATDE ~]$ sudo -u www-data whoami
www-data

図4.9 ログインできないユーザーとしてコマンドを実行する(sudoコマンド)


4.2.3. ユーザーとグループ

Linuxシステムでは、ユーザーの集まりをグループという単位で管理することが できます。ユーザーとグループという仕組みを使用して、システム(特にファイ ル)の管理を行う方法は、「ファイルの所有権とパーミッション」で詳しく説明し ます。

新しくグループを作成するコマンドは、groupadd コマンドです。グループを削除には、groupdelコ マンドを使用します。

[ATDE ~]$ sudo groupadd newgroup

図4.10 グループを追加する(groupaddコマンド)


ユーザーは、少なくとも一つのグループに属します。ユーザーが属する一つ目 のグループを、ログイン時初期グループといいます。 useraddコマンドを使用して新しくユーザーを追加 すると、ユーザー名と同名のグループ名が新規に作成され、ログイン時初期グ ループに設定されます。また、ユーザーが属しているログイン時初期グループ 以外のグループを、補助グループといいます。

ユーザーが所属するグループを変更するには、 usermodコマンドを使用します。 usermodコマンドの-gオ プションを使うと、ログイン時初期グループを変更することができます。また 、-Gオプションを使うと、補助グループを変更するこ とができます。

[ATDE ~]$ sudo usermod -G newgroup newuser

図4.11 ユーザーが所属するグループを変更する(usermodコマンド)


ユーザーを別のグループにも所属させるにはusermodコマンドの-aGオプションを使用します。

[ATDE ~]$ sudo usermod -aG newgroup newuser

図4.12 ユーザーを別のグループにも所属させる(usermodコマンド)


ユーザーが所属しているグループを確認するには、groupsコマンドを使用します。

[ATDE ~]$ groups newuser
newuser : newuser newgroup

図4.13 ユーザーが所属しているグループを確認する(groupsコマンド)


4.3. ファイルの操作

Linuxシステムを含む、UNIXシステムでは「すべてのものはファイルである (Everything is a file)」という考え方があります。Linuxシステムでは、デ ィスク上のデータも、動作中のプロセスも、ハードウェアであるデバイスさえ も、ファイルとして表現します。基本的なファイルの操作は、すべてのファイ ルで共通です。テキストファイルの内容を読むのも、プロセスの状態を調べる のも、デバイスからデータを読み出すのも、基本的には同じ操作でできます。

本章では、様々なファイルに対する操作方法について説明していきます。

4.3.1. ファイルの種類

Linuxシステムで扱えるファイルには、以下のような種類があります。

  1. 通常ファイル

    いわゆる普通のファイルです。大抵の場合、ハードディスクドライブなどのス トレージに記録され、テキストファイル、バイナリファイル、実行ファイル、 データファイルなどとして読み書きできます。

  2. ディレクトリ

    他のファイルやディレクトリを格納することができるファイルを、ディレクト リといいます。Windowsでのフォルダと同様の概念です。

  3. デバイスファイル

    Linuxカーネル内のデバイスドライバ[9]とのインターフェースとなるファイルです。スペシャルファ イルやデバイスノードという場合もあります。

    スペシャルファイルには、キャラクタデバイスファイルとブロックデバイスファ イルの2種類があります。キャラクタデバイスファイルへの入出力は、ストリー ムとして扱われ、一度書き込んだ内容は取り消せず、同じ内容を2回読み出すこ ともできません。対して、ブロックデバイスはランダムアクセス(任意の位置へ の読み書き)が可能なので、同じ位置に何度も読み書きすることができます。

    シリアルインターフェースや、マウス、キーボードなどはキャラクタデバイス ファイルで、ハードディスクなどのストレージやメモリはブロックデバイスファ イルとして扱われます。

    デバイスファイルは、必ずしも物理的なデバイスと結びついているわけではあ りません。そのようなデバイスファイルを、疑似デバイスファイルといいます 。読み込むと常に0を返す/dev/zero、ある程度 ランダムな値を返す/dev/urandom、書き込んだ 内容を捨てる/dev/nullなどがあります。

  4. シンボリックリンク

    ファイル名とファイルの実体との関係をリンクといいます。シンボリックリン クは、ファイルのパス名によって別のファイルを参照するリンクです。

    シンボリックに対して、ハードリンクというリンクもあります。これについて は、「ファイルの属性情報(inode)」で説明します。

  5. その他

    その他のファイルの種類として、FIFO(名前付きパイプ)とUNIXドメインソケッ トがあります。これらは、IPC(InterProcess Communication、プロセス間通信) に使われます。

4.3.2. ファイルの属性情報(inode)

すべてのファイルはファイルの内容とは別に、ファイルの属性を表すメタデータ を持っています。このメタデータのことを、inodeといいます。inodeには、以 下の情報が格納されています。

表4.1 inodeが持つ情報

情報 説明

種類

「ファイルの種類」で挙げたファイル種類のどれであるか

所有者情報

ファイルを所有するユーザー(所有者)及び所有するグループ(所有グループ)のID

パーミッション

所有者、所有グループに所属するユーザー、それら以外のユーザーに対する読み出し、書き込み、実行許可情報

ハードリンク数

ファイルに対するハードリンクの数

サイズ

ファイルのサイズ

時刻情報

最終アクセス時刻、最終修正時刻、最終属性状態変更時刻[a]

[a] Linuxシステムでは、ファイルの作成日時は保存されません。


inodeにはファイル名が含まれていないことに注目してください。Linuxシステ ムでは、ファイル名を保持しているのはディレクトリです。inodeにはinode番 号と呼ばれる一意な数値が割り振られており、ディレクトリはファイル名と inode番号の対応のリストを保持します。この、ファイル名とinodeとの対応を ハードリンクといいます。一つのinodeに対し、複数のファイル名を付ける、即 ち、複数のハードリンクを張ることも可能です。

このため、Linuxシステムではファイルを削除することをアンリンク(unlink)と いいます。複数のハードリンクがある場合、アンリンクはディレクトリからリ ンクを削除するだけです。ハードリンク数が0になった時に、実際にファイルの 内容が削除されます。

inodeが持つ情報は、lsコマンドに -lオプションをつけて実行することで確認すること ができます。

[ATDE ~]$ ls -l /bin/cat
-rwxr-xr-x 1 root root 34676  2月 22  2017 /bin/cat

図4.14 inodeが持つ情報を確認する(ls -lコマンド)


最初の一文字は、ファイルの種類を表します。ファイルの種類によって、以下 の表記になります。

表4.2 ファイル種類の表記

表記 ファイル種類

-

通常ファイル

d

ディレクトリ

c

キャラクタデバイスファイル

b

ブロックデバイスファイル

l

シンボリックリンク


「rwxr-xr-x」の部分は、ファイルのパーミッションを表します。パーミッショ ンについては、「ファイルの所有権とパーミッション」で説明します。

続く「1」は、ハードリンクの数を表します。

「root root」は、それぞれ、所有者のユーザー名、所有グループのグループ名 を表します。これらは、パーミッションの設定と密接に関わっています。

「34676」はバイト単位のファイルサイズです。

「2月 22 2017」は、ファイルの最終修正時刻を表します。

4.3.3. ファイルシステムとパス

Linuxシステムでは、ファイル同士の位置関係は階層的な木構造として表現され ます。ファイルシステムとは、ファイルの木構造をある形式に従って構成した ものです。

木構造の最上位に位置するディレクトリをルートディレクトリといいます。全 てのファイルはルートディレクトリから辿ることができます。

また、Linuxシステムのファイルシステムでは、木構造の任意の位置にファイル システムを追加または削除することができます。この操作をそれぞれ、ファイ ルシステムをマウントする、アンマウントするといいます。

システムに最初にマウントされるファイルシステムをルートファイルシステム といいます。ルートファイルシステムは、システム起動時にルートディレクト リにマウントされます。

木構造の中のファイルの位置は、パスで表します。パスはあるディレクトリか らファイルに到達するまでの間にあるディレクトリ名の間にスラッシュ (/)を挟んだものです。ルートディレクトリは /一文字で表します。パスの記述方法には二種類 あり、/から始まるルートディレクトリからの位 置を表したパスを絶対パスといい、ルートディレクトリ以外からの位置を表し たパスを相対パスといいます。パスには、/以外 にもいくつか特殊な意味を持つ文字があります。 .は現在のディレクトリを、 ..は一つ上のディレクトリを意味します。また 、多くのシェルでは~は、ホームディレクトリを 意味します。

ファイルシステムには、構造を構成する形式が異なるいくつかの種類がありま す。Linuxで一般的に使用されるファイルシステムには、ext3ファイルシステム、 ext4ファイルシステムがあります。Armadillo-600シリーズのルートファイルシステムは、 eMMC上に構成されたext4ファイルシステムです。ext4ファイルシステムは、 ジャーナリング機能[10]を持っており、 耐障害性に優れます。また、Windowsで使用される VFAT(FAT32)ファイルシステムも扱うことができます。

これらのファイルシステムは物理的なデバイスと結びついているものですが、 メモリ上にしか存在しないファイルシステムもあります。その一つである仮想 ファイルシステムには、カーネルの内部情報を参照又は設定できるprocfsや sysfsなどがあります。また、疑似ファイルシステム(pseudo filesystem)は、 RAM上に直接ファイルシステムを構成します。擬似ファイルシステムには、 tmpfsやramfsがあります。

さらに、ネットワークファイルシステム(NFS)を使用すると、ネットワーク越し のコンピューターに存在するデータを扱うことができます。

4.3.4. ファイルの所有権とパーミッション

前章で説明したように、Linuxシステムではすべてのファイルに、そのファイルを 所有するユーザー(所有者)とグループ(所有グループ)が設定されています。そ して、所有者、所有グループに所属するユーザー、それ以外のユーザーに対し て、許可する操作を決めることができます。これを、パーミッションといいま す。パーミッションによって、それぞれのユーザーに対して、読み出し、書き 込み、実行の可否を設定できます。

[注記]ディレクトリのパーミッション

ディレクトリもファイルの一種ですので、パーミッションを設定できます。

ディレクトリの読み出し許可がある場合、ディレクトリ内のファイルのリスト を取得することができます。

書き込み許可がある場合、ディレクトリの中にファイルを作成したり、ファイ ルを削除できます。

実行許可がある場合、ディレクトリに中のファイルにアクセスできます。反対 にいうと、実行許可がない場合、ディレクトリ内のファイルに対して、それら のファイルのパーミッションに関わらず、読み、書き、実行のすべてを行うこと ができませんので、注意してください。

図4.14「inodeが持つ情報を確認する(ls -lコマンド)」の例では、パーミッションは「rwxr-xr-x」と表示され ていました。それぞれのユーザーに対するパーミッションは、三文字ずつで表 現されます。順番に、所有者、所有グループに所属するユーザー、その他のユー ザーに対するパーミッションを意味します。rが読み出し許可、wが書き込み許 可、xが実行許可を意味します。「rwxr-xr-x」の場合、所有者に対しては 「rwx」即ち、読み、書き、実行すべてを許可します。所有グループに所属する ユーザーとその他のユーザーに対しては、「r-x」即ち読みと実行だけ許可しま す。

パーミッションは、rwxといったアルファベットでの表記の他に、8進数で表記 する場合もあります。r=4、w=2、x=1として[11]、その合計で表現します。8進数表記でのパーミッションは、 rwxは7、rw-は6、r-xは5、r--は4、---は0となります。そのため、 「rwxr-xr-x」を8進数3桁で表記すると、「755」となります。

パーミッションを変更するには、chmodコマンドを使用します。すべてのユーザー に対して実行を許可する(つまり、実行権限を与える)場合、+xオプションを使 用します。

[ATDE ~]$ chmod +x ファイル名

図4.15 ファイルのパーミッションを変更する(chmodコマンド)


ファイルを新規に作成した場合のパーミッションは、ファイルの種類とumaskと 呼ばれる値によって決まります。標準のパーミッションは、ディレクトリの場 合rwxrwxrwx(777)、その他のファイルはrw-rw-rw-(666)です。この値から umaskを差し引いた値が、ファイルを新規作成した場合のパーミッションとなり ます。

umaskは、一般的には022となっています。そのため、ディレクトリを新規作成 した場合のパーミッションはrwxr-xr-x(755)、通常ファイルの場合は、 rw-r—r--(644)となります。

[ATDE ~]$ umask
0022
[ATDE ~]$ touch file
[ATDE ~]$ mkdir dir
[ATDE ~]$ ls -l
合計 4
drwxr-xr-x 2 atmark atmark 4096  4月  7 16:39 dir
-rw-r--r-- 1 atmark atmark    0  4月  7 16:38 file

図4.16 umaskと新規作成時のファイルパーミッション


touchは、引数に指定したファイルの最終修正時刻 を更新するコマンドです。存在しないファイルを指定した場合、空のファイル を作成します。

ところで、umaskコマンドを実行した際、4桁で表 示されています。この、4桁目の値は、特別なパーミッションを意味します。 特別なパーミッションには、SUIDビット(set-uid bit)、SGIDビット(set-gid bit)、スティッキービット(sticky bit) の3種類があります。

8進数で表すと、SUIDビットがセットされている場合4、SGIDビットは2、スティッ キービットは1となります。この値は、chmodコマ ンドやumaskコマンドでパーミッションを8進数で 指定する場合の4桁目として使用できます。

SUIDビットが設定されていて実行許可が与えられている場合、そのファイルを 実行すると、実行したユーザーに関わらず、ファイル所有者として実行されま す。この仕組みは、例えばpasswdコマンドに使用 されています。passwdコマンドがアクセスする /etc/shadowファイルにはパスワードという重要 な情報が記述されているため、特権ユーザーであるrootユーザーにだけ 読み書きを許可しています。しかし、一般ユーザーが自分のパスワードを変更 できないと不便です。そのため、passwdの実行フ ァイルにはSUIDビットがセットされており、所有者はrootになっています。す ると、一般ユーザーでpasswdを実行した場合でも rootとして実行されるため、/etc/shadowファイ ルにアクセスすることができます。

[ATDE ~]$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1412  4月  7 11:18 /etc/shadow
[ATDE ~]$ ls -l $(which passwd)
-rwsr-xr-x 1 root root 57972  5月 17  2017 /usr/bin/passwd

図4.17 etc/shadowファイルとpasswd実行ファイルのパーミッション


ls -lでは、SUIDビットがセットされていて所有者 の実行が許可されているファイルの場合、所有者の実行許可の表示がxではな くsとなります。

なお、whichコマンドは、引数に指定したコマンド が実際に実行するファイルの絶対パスを表示するコマンドです。

SGIDビットは、SUIDビットと同様の仕組みです。実行したユーザーが所属する グループではなく、所有グループとして実行されます。ls -lでは、SGIDビットがセットされていて所有グループに所属す るユーザーに対する実行が許可されているファイルの場合、所有グループの実 行許可の表示がxではなくsとなります。

スティッキービットは、ディレクトリとその他の実行ファイルに指定された時 では挙動が異なります。

ディレクトリの場合、ディレクトリ内にあるファイルは、ファイル所有者とデ ィレクトリ所有者のみが削除できます。この仕組みは、 /tmpディレクトリで使用されています。一時的 に使用するファイルを置く/tmpディレクトリに は、すべてのユーザーに対して読み、書き、実行を許可していますが、ファイ ルを作成したユーザーか/tmpディレクトリの所 有者であるrootユーザーしかファイルを削除することができません。 ls -lでは、スティッキービットがセットされてい てその他のユーザーに対する実行が許可されている場合、その他のユーザーの 実行許可の表示がxではなくtとなります。

[ATDE ~]$ ls -ld /tmp
drwxrwxrwt 16 root root 4096  4月  7 17:17 /tmp

図4.18 /tmpディレクトリのパーミッション


実行可能ファイルに対してスティッキービットを設定した場合、そのコードを スワップ上に維持します。こちらの機能はあまり使用されていないようです。

4.3.5. デバイスファイルの管理

デバイスファイルは、メジャー番号とマイナー番号という二つの番号によって、 対応するデバイスドライバを識別します。メジャー番号は、デバイスの種類を 表します。デバイスの型(キャラクタ型かブロック型)とメジャー番号が同じデ バイスファイルは、ほとんどの場合、同じデバイスドライバを使用します。また、 マイナー番号によって、同じデバイスの型とメジャー番号を持つデバイスのグ ループ内のデバイスを識別します。

デバイスファイルは、通常/devディレクトリ以 下に配置されます。

ls -lでデバイスファイルを調べた場合、他のファ イルとは異なった出力となります。

[ATDE ~]$ $ ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64  4月  7 09:41 /dev/ttyS0
crw-rw---- 1 root dialout 4, 65  4月  7 09:41 /dev/ttyS1
crw-rw---- 1 root dialout 4, 66  4月  7 09:41 /dev/ttyS2
crw-rw---- 1 root dialout 4, 67  4月  7 09:41 /dev/ttyS3

図4.19 デバイスファイルの例


最初の一文字は、デバイスファイルの型を表します。「c」がキャラクタデバイ スファイル、「b」がブロックデバイスファイルを意味します。所有者、所有グ ループの後に表示されている「4, 64」という番号が、それぞれメジャー番号と マイナー番号を表します。メジャー番号4は、シリアルポートに対応するデバイ スファイルを意味します。メジャー番号とデバイスの対応は、Linuxカーネルの ドキュメントに記載されています。 linux-[version]-at/Documentation/admin-guide/devices.txtを 参照してください。

デバイスファイルを作成するには、mknodコマンド を使用します。例えば、5個目のシリアルポートに対応するデバイスファイル を作成するには、以下のようにします。

[ATDE ~]$ sudo mknod /dev/ttyS4 c 4 68

図4.20 デバイスファイルの作成(mknodコマンド)


通常は、上記のようにmknodコマンドを使用してデ バイスファイルを作成します。しかし、Linuxシステムはデバイスのホットプ ラグ[12]が可能です。シ ステム動作中接続される可能性のあるデバイスに対するデバイスファイルをあ らかじめすべて作っておくことは、現実的ではありません。そこで、デバイス が接続された時点でデバイスファイルを作成するudevという仕組みがあります 。udevを使用すると、デバイスファイルの自動作成の他、デバイスが接続また は切断された時点で任意のコマンドを実行する、といったことが可能になりま す。

4.4. プログラムとプロセス

プログラムの実行可能ファイルは、機械語の実行コードとデータから構成され ます。多くのLinuxシステムでは、実行可能ファイルはELFと呼ばれる形式で保 存されています。

実行可能ファイルは、ローダーと呼ばれるプログラムによってメモリにロード され、実行が開始されます。この際、ローダーはプログラムの再配置やメモリ の初期化などをおこないます。

実行中のプログラムをプロセスといいます。

Linuxシステムは、マルチタスクなので複数のプロセスを同時に実行できます。 しかし、CPUは通常1個[13]しかありません。そこで、プロセスには仮想的なCPUとメモリ空 間が与えられます。カーネルは、各プロセスがCPUを使う時間とメモリ領域を管 理します。カーネルは、プロセスがCPUを使ってよい時間が過ぎたら、そのプロ セスの実行を停止し別のプロセスの実行を開始します。また、プロセスから見 えている仮想的なメモリ空間と物理メモリとの橋渡しをおこないます。そのた め、プロセスはあたかもシステム全体を占有しているように振る舞う事ができ ます。

プロセスが使用するメモリ空間は、いくつかの領域(セクション)に分かれており、 それぞれ用途が異なります。セクションには以下のものがあります。

  1. テキストセクション: 機械語の実行や定数などを収めた、読み取り専用で実 行可能な領域。
  2. データセクション: グローバル変数やスタティック変数のうち初期値が設定 されたデータを収めた領域。
  3. BSSセクション: グローバル変数やスタティック変数のうち初期値が設定され ていないデータを収めた領域。0で初期化される。
  4. スタック: 関数呼び出し時に一時的なデータ用に使用される領域。
  5. ヒープ: プロセスが要求する動的なメモリ用に使用される領域。

psコマンドを使用すると、現在実行中のプロセスの一覧を見ることができます。

[ATDE ~]$ ps
  PID TTY          TIME CMD
 3580 pts/0    00:00:00 bash
 4233 pts/0    00:00:00 ps

図4.21 プロセス一覧の確認(psコマンド)


「CMD」の欄に表示されているものが、プロセスを実行したコマンドです。 「PID」は、プロセスIDと呼ばれるプロセスを一意に識別する数値です。

プロセスは、プロセスの状態や所有するリソース(タイマー、ファイル、ハード ウェア、ネットワーク接続、プロセス間通信で使用するもの)、そのプロセスを 実行したプロセスのID(親プロセスID、PPID)などの情報を保持しています。

4.5. シグナル

シグナルとは、カーネル又はプロセスからプロセスに対して送られる非同期な メッセージです。通常、メモリアクセス保護違反(segmentation fault)や特殊 なキー入力(例えば CtrlC)な どのイベントが起こったことをプロセスに通知するために使用されます。

プロセスにシグナルが送られた場合、プロセスは以下の挙動のうちいずれかを 行います。

  1. 終了する
  2. シグナルを無視する
  3. プロセスのコア[14]をダンプ(表示)し て終了する
  4. 一時停止する
  5. 停止中であれば再開する
  6. シグナルを捕捉し、プロセス自身で指定したシグナルハンドラーで処理を行う

シグナルは、シグナル名かシグナル番号(整数値)で表されます。

代表的なシグナルを以下に示します。シグナルハンドラーを設定していない場 合、標準の挙動をおこないます。捕捉できないシグナルは、必ず標準の挙動を おこないます。

表4.3 代表的なシグナル

シグナル名 番号 捕捉可能か 標準の挙動 説明

SIGHUP

1

Yes

終了

制御端末のハングアップ、制御しているプロセスの死

SIGINT

2

Yes

終了

キーボードからの割り込み(CtrlC)

SIGQUIT

3

Yes

コアダンプ

キーボードからの割り込み

SIGABRT

5

Yes

コアダンプ

abort関数による終了

SIGKILL

9

No

終了

強制的な終了

SIGSEGV

11

Yes

コアダンプ

不正なメモリ参照

SIGTERM

15

Yes

終了

終了シグナル

SIGUSR1

10,16,30

Yes

終了

ユーザー定義シグナル1

SIGUSR2

12,17,31

Yes

終了

ユーザー定義シグナル1

SIGSTOP

17,19,23

No

停止

プロセスの一時停止

SIGCONT

18,20,24

Yes

再開

プロセスの再開


killコマンドで、プロセスに任意のシグナルを送 ることができます。killコマンドには、シグナル を送るプロセス名とシグナル名(SIGを除いたもの)を指定することができます 。killコマンドでシグナル名を指定しない場合、 SIGTERMが送られます。

4.6. プロセス間通信

それぞれのプロセスは、独立した仮想的なメモリ空間を与えられて動作するた め、基本的に他のプロセスのデータにアクセスすることはできません。この特 徴により、あるプロセスが誤って他のプロセスのデータを書き換えるというこ とがないため、セキュリティやシステムの堅牢性を保つことができます。

しかし、場合によっては複数のプロセスが協調動作をしたり、情報のやりとり を行う必要があったりします。そのために、Linuxカーネルはプロセス間通信 (Inter Process Communication、IPC)の仕組みを提供しています。

IPCを行う方法には、以下のものがあります。

  1. パイプ
  2. 名前付きパイプ(FIFO)
  3. メッセージキュー
  4. 共有メモリ
  5. セマフォ
  6. インターネットソケット
  7. 名前付きソケット(UNIXドメインソケット)

4.7. 端末

端末(ターミナル)とは、ディスプレイと入力装置(キーボード)から構成され、 コンピューターの使用者がホストコンピューターとのやりとりを行うために使 用される装置です。ホストコンピューターと端末は、シリアル通信線や電話線、 Ethernetなどで接続されます。コンピューターが高価で、一つのコンピューター を複数人で共有していた時代は、一つのホストコンピューターに複数の端末を 接続して使用していました。コンピューターが十分に安くなり、一人一台の 「パーソナルな」コンピューター(PC)を持てるようになった現在では、端末専 用装置を見かけることはほとんどありません。

今日では、端末専用装置の代わりに、PC上で動作する端末エミュレーターを使 用します。Armadilloと開発用PCをシリアルケーブルで接続し、シリアル通信ソ フトウェアで操作をおこなう場合、シリアル通信ソフトウェアを端末エミュレー ターとして使用していることになります。大抵の端末エミュレーターでは、端 末専用装置として事実上の標準であったVT100の互換機能を持っています。

Linuxシステムでは、様々な装置を端末とみなして、互いに通信することができ ます。PCに接続されたモニターはコンソール端末、シリアルポートを介して接 続されているコンピューターはシリアル端末、ネットワークを介して接続され ているコンピューターは擬似端末とみなします。Linuxシステムでは、端末との 通信をtty[15]という名前のついたデバイスファイル(ttyデバイス) を介しておこないます。

4.7.1. シリアル端末

Linuxシステムでは、シリアルポートに対する読み書きは、シリアルポートに対 応するttyデバイスへの読み書きとして扱います。つまり、シリアルポートの先 にシリアル端末が繋がっているとみなしています。例えば、WindowsではCOM1と 表現される、PCの一番目のシリアルポートへの読み書きは、Linuxシステムでは 通常、/dev/ttyS0に対しておこないます。

[ATDE ~]$ echo hello > /dev/ttyS0  1
[ATDE ~]$ cat file > /dev/ttyS0  2
[ATDE ~]$ cat /dev/ttyS0  3

図4.22 シリアルポートの読み書き


1

文字列「hello」をシリアルポートから送信します。

2

fileの内容をシリアルポートから送信します。

3

シリアルポートに受信した内容を表示します。

シリアルポートの通信速度等の設定確認や変更は、 sttyコマンドで行うことができます。 sttyコマンドでは、-F オプションで設定の確認や変更をおこなうttyデバイスを指定します。詳細は 、man 1 sttyを参照してください。

[ATDE ~]$ stty -F /dev/ttyS0
speed 9600 baud; line = 0;
-brkint -imaxbel

図4.23 シリアルポートの設定確認(sttyコマンド)


Armadilloでは、シリーズによってシリアルポート(シリアルインターフェース )に割り当てているデバイスファイル名が異なります。Armadillo-600シリーズ では、 /dev/ttymxc# (#は10進数値文字)となり、/dev/ttymxc0がシリア ルインターフェース1に割り当てられています。詳細は、「Armadillo-600 シ リーズ 製品マニュアル」の「Linux ドライバ一覧」の「UART」をご参照ください。

USB to シリアル変換ケーブルを使った場合、変換ケーブル内のICによってデバ イスファイル名が異なります。通常、 /dev/ttyUSB# や /dev/ttyACM# になります。

4.7.2. コンソール端末

コンソール端末、あるいは単にコンソールとは、システム管理用の端末のこと です。通常、ホストコンピューターに接続されたディスプレイとキーボードを コンソールとして使用します[16]。Linuxシステムでは、ホストコンピューターに接続されたディス プレイに表示できる、仮想的なコンソールを複数持つことができます。仮想コ ンソールには、 /dev/tty# を介してアクセスします。/dev/tty0は特別な意 味を持ち、現在の仮想コンソールを意味します。

Debian GNU/Linux 9.0では、 CtrlAltF# を入力することで、仮想コンソールを切り替えることができます [17]。 CtrlAltF1 で一番目の仮想コンソール(/dev/tty1)に切り替 えます。Debian GNU/Linux 9.0では、F3から F6までがテキストコンソールに割り当てられていま す。 CtrlAltF2 で元のGUI画面に戻ることができます。

端末が使用しているttyデバイスは、ttyコマンド で調べることができます。 CtrlAltF3 で仮想コンソールを切り替え、ログインしてから ttyコマンドを実行すると、以下のように表示され ます。

[ATDE ~]$ tty
/dev/tty3

図4.24 端末が使用しているttyデバイスの確認(ttyコマンド)


/dev/consoleは、システムメッセージを表示す るコンソール(システムコンソール)用のデバイスファイルです。カーネルメッ セージは/dev/consoleに送信されます。

どの端末をシステムコンソールとして使用するかは、カーネルの起動時に渡す カーネルパラメーターで指定できます。Armadillo-600シリーズでは、標準状態 のカーネルパラメーターとして「console=ttymxc0,115200」を渡しているので、 シリアルインターフェース1がシステムコンソールとして使用されます。ATDE7 では「BOOT_IMAGE=/vmlinuz-4.9.0-12-686-pae root=/dev/mapper/atde7—vg-root ro quiet 」を渡しており、システムコンソールを明示的に指定していません。 この場合、カーネルは最初に /dev/tty#を調べ、 次にシリアルデバイスを順番に調べます。そして、最初に使用可能であったも のをシステムコンソールとして使用します。

カーネルパラーメーターは、/proc/cmdlineファ イルで調べることができます。

[ATDE ~]$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-4.9.0-12-686-pae root=/dev/mapper/atde7--vg-root ro quiet

図4.25 カーネルパラメーターの確認(proc/cmdlineファイル)


4.7.3. 擬似端末

擬似端末は、シリアル端末やコンソール端末のように、必ずしも物理的に接続 されているとは限らない端末との通信に使用されます。ATDE7の[アクティビティ] -[アプリケーションを表示する]-[ユーティリティ]-[端末]メニューで起動できる 端末エミュレーター(Gnome端末)でttyコマンドを実行すると、 /dev/pts/0のように表示されます。

[ATDE ~]$ tty
/dev/pts/0

図4.26 Gnome端末でのttyデバイス


擬似端末は、マスターとスレーブがセットになって使用されます。スレーブへ 書き込んだデータは、マスターから読み出すことができ、また、マスターへ書 き込んだデータはスレーブから読み出すことができます。 /dev/pts/#はス レーブで、マスターは常に/dev/ptmxです。マス ターは/dev/ptmx一つだけですが、プロセスが /dev/ptmxをオープンすると、都度 /dev/ptsディレクトリに対応するスレーブ用の デバイスファイルが作成され、以後そのスレーブとやりとりを行うことができ るようになっています。このような命名規則をUNIX98 pty namingといいます 。詳細は、man 4 ptsを参照してください。

4.8. 時間の管理

Linuxシステムでは時間の管理は二つの時計、システムクロックとハードウェア クロックでおこなっています。

システムクロックはLinuxカーネルが管理している時計で、タイマー割り込みに よって駆動されます。システムクロックは、UTC(Universal Time, Coordinated、協定世界時) 1970年1月1日 00時00分00秒(紀元、エポック)から の経過秒数で表されます。Linuxシステムでは、システムクロックがすべての動作 の基準となります。システムクロックを参照、設定するには、 dateコマンドを使用します。

[ATDE ~]$ date
2020年  4月  8日 水曜日 10:20:58 JST

図4.27 システムクロックの参照(dateコマンド)


ハードウェアクロックは、CPUとは独立したRTC(リアルタイムクロック)によっ て管理される時計です。システムに電源が供給されていない間も、バッテリや 外部電源などで動作しつづけます。Linuxシステムは、起動時にハードウェアク ロックを参照し、システムクロックを設定します。

[ATDE ~]$ sudo hwclock
2020-04-08 10:22:26.888416+0900

図4.28 ハードウェアクロックの参照(hwclockコマンド)


4.8.1. タイムゾーン

ATDE7でdateコマンドを実行すると、 図4.27「システムクロックの参照(dateコマンド)」で示したようにJST(Japan Standard Time、日本標準時) で表示されます。システムクロックは、カーネル内部では常にUTCを基準とし たエポックからの経過秒数で管理されています。しかし、 dateコマンドはシステムの設定に従ってローカル タイムでの表示を行います。

dateコマンドなどの時間を扱うコマンドでどのタ イムゾーンを使用するか、即ちローカルタイムのタイムゾーンはTZ環境変数で 指定することができます。環境変数については、 「環境変数」を参照してください。また、TZ環境変 数の指定方法については、man 3 tzsetを参照し てください。

[ATDE ~]$ date
2020年  4月  8日 水曜日 10:29:58 JST
[ATDE ~]$ TZ=UTC date
2020年  4月  8日 水曜日 01:30:10 UTC
[ATDE ~]$ TZ=America/New_York date
2020年  4月  7日 火曜日 21:30:26 EDT

図4.29 システムクロックの参照(タイムゾーンを指定)


TZ環境変数が指定されていない場合、 /etc/localtimeファイルで指定されているタイ ムゾーンが使用されます。ATDE7ではTZ環境変数は設定されていないので、 図4.27「システムクロックの参照(dateコマンド)」で表示がJSTになっていたのは、このファイルの設定に よるものです。/etc/localtimeファイルは、タ イムゾーンディレクトリ(/usr/share/zoneinfo) にあるtzfile形式のファイルのコピーとなっています。ATDE7の標準設定では 、/usr/share/zoneinfo/Asia/Tokyoです。 Debian GNU/Linux 9.0では、タイムゾーンの設定は dpkg-reconfigure tzdataで変更することができま す。

ハードウェアクロックはUTCで保存するかローカルタイムで保存するか、選択す ることができます。UTCで保存しておけば、タイムゾーンを変更してもハードウェ アクロックを変更しなくとも良いので、通常は問題ないでしょう。しかしなが ら、Windowsではローカルタイムで保存します。そのため、PC Linuxではローカ ルタイムをハードウェアクロックに保存することが多いようです。

[ATDE ~]$ sudo hwclock --systohc --utc

図4.30 システムクロックをハードウェアクロックに設定する(UTC)


[ATDE ~]$ sudo hwclock --systohc --localtime

図4.31 システムクロックをハードウェアクロックに設定する(ローカルタイム)


4.8.2. 時刻を正確に保つ

システムクロックとハードウェアクロックは、長期的な視点ではどちらも正確 ではありません。通常、二つの時計は異なるクロックソースを元にして動作す るので、相対的にずれていきます。また、国際原子時(TAI)と比較すると、どち らの時計も精度が低いので、絶対的な時刻も徐々にずれていきます。

時刻を正しく保つには、いくつかの方法があります。

最も信頼性の高い方法は、NTP(Network Time Protocol)を使用することです。 インターネットに接続できるか、信頼できるNTPサーバーを使用できる場合、 NTPによりシステムクロックを設定することができます。Debian GNU/Linux 9.0では、systemd-timesyncdというプログラムが自動的にNTPサーバーを 使用して時刻設定をしてくれます。

NTPを使用できない場合、クロックの規則的なずれ(ドリフト)を利用して補正を 行なうことができます。システムクロックとハードウェアクロックは、時刻が 進むか遅れる方向に同じ程度ずれると想定して、定期的にずれた分時刻を設定 しなおすという方法です。

hwclockコマンドの時刻合わせ機能を使用すると、 ハードウェアクロックのドリフトを補正することができます。 hwclockコマンドは、 --setオプションまたは --systohcオプションを伴って実行されると、ハード ウェアクロックを設定します。このとき、 /etc/adjtimeファイルに現在の時刻を最後に時 計合わせ(calibration)をした時刻として記録します。ハードウェアクロック がずれた後、再度、--setオプションまたは --systohcオプションによりハードウェアクロックが 設定されると、hwclockコマンドは /etc/adjtimeファイルの最後に時計合わせをし た時刻を更新するとともに、1日あたりの時刻のずれを記録します。以降は、 --adjustを伴って hwclockコマンドを実行すると、1日あたりの時刻 のずれから補正すべき時刻を計算してハードウェアクロックを設定します。ま た、/etc/adjtimeファイルに最後に時刻を補正 (adjustment)した時刻を記録します。詳細は、man 8 hwclockを参照してください。

adjtimexコマンドを使用すると、システムクロッ クのドリフトを徐々に補正することができます。 adjtimexコマンドでは、NTPやハードウェアクロッ クを参照して、システムクロックのドリフトを測定し、それを補正するための 値をカーネルに設定します。例として、NTPサーバーを参照する方法を以下に 示します。

まず、systemd-timesyncdを停止してください。 adjtimexコマンドでドリフトを測定している途中 に、systemd-timesyncdがシステムクロックを更新してしまうと、正確な測定ができなくなり ます。

[ATDE ~]$ sudo systemctl stop systemd-timesyncd.service

図4.32 adjtimexによるシステムクロックの補正1: systemd-timesyncdの停止


次に、adjtimexをインストールします。NTPの参照には ntpdateコマンドを使用するので、同時にインスト ールします。

[ATDE ~]$ sudo apt install adjtimex ntpdate

図4.33 adjtimexによるシステムクロックの補正2: adjtimexのインストール


adjtimexコマンドに --hostオプションを指定すると、 ntpdateを使用して補正のためのデータを取得しま す。この例では、NTPサーバーには独立行政法人情報通信研究機構(NICT)のサ ーバーである、ntp.nict.jpを指定しています。 --logオプションも同時に指定することで、補正のた めのデータをログファイル (/var/log/clocks.log)に書き込みます。ハード ウェアクロックやシステムクロックをadjtimex以 外で書き換えていない場合は、二つの質問に yと答えてください。

[ATDE ~]$ sudo adjtimex --log --host ntp.nict.jp
      reference time is Wed Apr  8 11:07:11 2020
reference time - system time = 1586311631.836 - 1586311631.836 = 0.000 sec
Last clock comparison was at Wed Apr  8 11:05:51 2020
Kernel time variables are unchanged - good.
System clock is synchronized (by ntpd?) - bad.
Checking wtmp file...
System has not booted since Wed Apr  8 11:05:51 2020 - good.
System time has not been changed since Wed Apr  8 11:05:51 2020 - good.
Checking /etc/adjtime...
/sbin/hwclock has not set system time and adjusted the cmos clock
since Wed Apr  8 11:05:51 2020 - good.

Are you sure that, since Wed Apr  8 11:05:51 2020,
  the system clock has run continuously,
  it has not been reset with `date' or `/sbin/hwclock`,
  the kernel time variables have not been changed, and
  the computer has not been suspended? (y/n) [n] y
The estimated error in system time is -0.2372 +- 6.9418 ppm

Are you sure that, since Wed Apr  8 11:05:51 2020,
  the real time clock (cmos clock) has run continuously,
  it has not been reset with `/sbin/hwclock',
  no operating system other than Linux has been running, and
  ntpd has not been running? (y/n) [y]
The estimated error in the cmos clock is -5179 +- 7 ppm

図4.34 adjtimexによるシステムクロックの補正3: ntpdateによる補正データの測定


--printオプションを指定すると、現在の設定を確認 することができます。また、補正のためのデータをカーネルに設定するには、 --adjustオプションを使用します。その際、 --reviewオプションを付けると、ログファイルに記 録したデータをもとに設定します。

[ATDE ~]$ sudo adjtimex --print
         mode: 0
       offset: 90244
    frequency: 28746
     maxerror: 296500
     esterror: 0
       status: 8193
time_constant: 7
    precision: 1
    tolerance: 32768000
         tick: 10000
     raw time:  1586311688s 534312689us = 1586311688.534312689
[ATDE ~]$ sudo adjtimex --adjust --review
start                     finish                    days    sys - cmos (ppm)
Wed Apr  8 11:05:51 2020  Wed Apr  8 11:07:11 2020  0.0009  5185.1 +- 0.2
start                     finish                    days    cmos_error (ppm)
Wed Apr  8 11:04:41 2020  Wed Apr  8 11:05:51 2020  0.0008  -5886 +- 5
Wed Apr  8 11:05:51 2020  Wed Apr  8 11:07:11 2020  0.0009  -5211 +- 5
start                     finish                    days    sys_error (ppm)
Wed Apr  8 11:05:51 2020  Wed Apr  8 11:07:11 2020  0.0009  1 +- 5
least-squares solution:
   cmos_error = -5580 +- 4 ppm
      suggested adjustment = 482.1483 sec/day
        current adjustment = 0.0000 sec/day
   sys_error = -367 +- 4 ppm
      suggested tick = 10004  freq =  -2161506
        current tick = 10000  freq =     28746
note: clock variations and unstated data errors may mean that the
least squares solution has a bigger error than estimated here
new tick = 10004  freq = -2161506
[ATDE ~]$ sudo adjtimex --print
         mode: 0
       offset: 72356
    frequency: -2161506
     maxerror: 353000
     esterror: 0
       status: 8193
time_constant: 7
    precision: 1
    tolerance: 32768000
         tick: 10004
     raw time:  1586311801s 957000028us = 1586311801.957000028

図4.35 adjtimexによるシステムクロックの補正4: 補正データの設定と確認


4.8.3. タイマーの分解能

システムクロックの分解能は、カーネルコンフィギュレーションで定義される HZ定数によって決まります。HZが100の場合、タイマー割り込みの間隔(jiffy) は1秒間に100回、つまり、0.01秒(10ミリ秒)に1回です。タイマー割り込みの度 に、カーネル内で管理されているjiffiesと呼ばれる値が1ずつ増加していきま す。システムクロックはjiffiesを元に計算されます。i386やx86_64アーキテク チャで動作するLinuxでは、HZは100、250(標準の値)、300、1000を選択するこ とができます。Armadillo-600シリーズでは、HZは100です。

Linux 2.6.21より前のカーネルでは、プロセスをスリープさせたりタイマー [18]を扱うシステムコールの精度はシステムクロックの分解能に依存してい ました。そのため、HZが100の場合、10ミリ秒以下の時間スリープするといった 動作はできませんでした。

しかし、Linux 2.6.21からハイレゾリューションタイマー(High-Resolusion Timers)がサポートされました。ハイレゾリューションタイマーが有効なシステ ムでは、スリープやタイマーに関するシステムコールの精度はHZによる制約を 受けず、CPUが処理できる限りの短い時間で反応できます。Linux 2.6.21以降の カーネルを採用しているシステムがすべてハイレゾリューションタイマーを使用 できるわけではなく、アーキテクチャごとにサポート状況は異なります。i386 やx86_64アーキテクチャのPC Linuxでは、通常ハイレゾリューションタイマー が有効になっていますが、VMware Player上で動作するATDE7では無効です。 Armadillo-600シリーズではハイレゾリューションタイマーが有効になっていま す。

4.9. ロケール

ロケールとは、多言語を扱うプログラムがどのようなルールに基づいて処理す るべきかを定めたルールの集合です。プログラムは、ロケールに基づいて適切 な言語や表記でメッセージを表示したり、文字集合を扱うことができます。

ロケールはいくつかのカテゴリに分かれており、それぞれ個別に設定できます。 カテゴリには以下のものがあります。

  1. LC_COLLATE: アルファベット文字列の比較方法を定義します。
  2. LC_CTYPE: 文字の判定、変換操作や多バイト文字操作の方法を定義します。
  3. LC_MONETARY: 小数点やカンマの位置など、通貨に関する数字の表示方法を定義します。
  4. LC_MESSAGES: メッセージ表示に使用する言語を定義します。
  5. LC_NUMERIC: 数字の扱いを定義します。
  6. LC_TIME: 時刻の表示方法を定義します。

ロケールは、LANGUAGEとLC_ALL及び上記のカテゴリに対応する環境変数によっ て設定できます。複数の環境変数が設定された場合、以下の優先順位に従って 反映されます。

  1. 環境変数LC_ALLが設定されている場合、LC_ALLの値が使用されます。
  2. LC_ALL以外のLC_で始まる環境変数が設定されている場合、そのカテゴリには その値が使用されます。
  3. 環境変数LANGが設定されている場合には、LANGの値が使用されます。
  4. いずれの環境変数も設定されていない場合、標準のロケール(Cロケール [19])が使用されます。

環境変数は端末やプロセスごとに設定できます。そのため、ロケールの設定も 端末やプロセスごとに行われることになります。

それぞれの環境変数に設定するロケール名は、 language[_territory][.codeset]+ という書式になります。languageはISO 639[20]で 規程される言語コードです。また、 territoryはISO 3166で規程される国名コー ド [21] です。codesetは、ISO-8859-1やUTF-8のよ うな文字集合や文字符号化識別子です。

localeコマンドに-aオプ ションを付けて実行することで、システムでサポートされているすべてのロケ ールを得ることができます。

[ATDE ~]$ locale -a
C
C.UTF-8
POSIX
ja_JP.utf8

図4.36 システムでサポートされているすべてのロケールを得る(locale -aコマンド)


また、localeコマンドを引数なしで実行すると、現在の設定を確認することが できます。

[ATDE ~]$ locale
LANG=ja_JP.UTF-8
LANGUAGE=
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=

図4.37 現在のロケールを確認する(localeコマンド)


図4.27「システムクロックの参照(dateコマンド)」で示したように、ATDE7で dateコマンドを実行すると日本語で表示されます 。これを、英語で表示するには環境変数LANGを設定して dateコマンドを実行します。

[ATDE ~]$ date
2020年  4月  8日 水曜日 14:43:16 JST
[ATDE ~]$ LANG=en_US date
Wed Apr  8 14:43:30 JST 2020

図4.38 ロケールを指定してdateコマンドを実行


4.10. ネットワーク

近年の組み込みシステムでは、ネットワークシステムを持つものが増えていま す。Armadilloシリーズのすべての製品も、ネットワーク機能を有しています。 Linuxシステムは様々なネットワーク機能を備えており、このことが組み込みシ ステムでLinuxを採用する動機となることも多いようです。ここでは、Linuxシ ステムでネットワークを扱う方法について説明します。

4.10.1. ネットワークインターフェース

Linuxシステムでは、「すべてのものはファイルである(Everything is a file)」 という考え方の元、様々なものをファイルとして扱いますが、ネットワークイ ンターフェースは例外です。ブロックデバイスやキャラクタデバイスの場合、 デバイスファイル名を指定してファイルをオープンすることで、カーネル内の デバイスドライバにアクセスすることができます。ネットワークインターフェー スの場合、インターフェース名でアクセスするインターフェースを指定します。

ネットワークインターフェースの状態を取得、設定するには、ipコマンドを使用します。

[注記]

ipコマンドと同等の機能を提供するコマンドにifconfigというものもありますが、 現在ではipコマンドの使用が推奨されています。

ipコマンドは以下のような構文で、オブジェクトと呼ばれるものとサブコマンドを組み合わせて 実行します。

ip [オブジェクト] [サブコマンド]

図4.39 ipコマンドの構文


オブジェクトには以下のようなものがあります。

表4.4 ipコマンドのオブジェクト(一部)

オブジェクト 省略形 意味

address

addr, a

ネットワークインターフェースのIPアドレス

link

l

ネットワークインターフェース

route

r

ルーティングテーブル


サブコマンドには以下のようなものがあります。

表4.5 ipコマンドのサブコマンド(一部)

サブコマンド 動作

show, list

表示する

add

設定する

del

削除する


ここで取り上げたオブジェクトやサブコマンドは一部です。詳細は ipコマンドのmanページや、ipコマンド自体のhelpを参照してください。

例えば、addressオブジェクトに対してどのようなサブコマンドが用意されているのか 確認するには、以下のように実行します。

[ATDE ~]$ ip address help

図4.40 helpの表示する(ipコマンド)


ip address showとして実行すると、動作中の(アップ状態の)すべてのインターフェースの状態を表示します。

[ATDE ~]$ ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0 1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx 2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.xxx.xxx/24 3 brd 192.168.xxx.xxx 4 scope global dynamic enp1s0
       valid_lft 3011sec preferred_lft 3011sec
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 5 scope link
       valid_lft forever preferred_lft forever

図4.41 ネットワークインターフェースの状態を取得する(ipコマンド)


1

インターフェース名です。

2

MACアドレスです。

3

IPv4のIPアドレスです。

4

ブロードキャストアドレスです。

5

IPv6のIPアドレスです。

「lo」はローカルループバックインターフェースです。 自分自身がサーバーにもクライアントにもなるような場合に使用します。

特定のインターフェースの状態を取得する場合は以下のように指定します。

[ATDE ~]$ ip address show enp1s0
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.xxx.xxx/24 brd 192.168.xxx.xxx scope global dynamic enp1s0
       valid_lft 3319sec preferred_lft 3319sec
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link
       valid_lft forever preferred_lft forever

図4.42 特定のネットワークインターフェースの状態を取得する(ipコマンド)


ipコマンドはインターフェース名を指定して実行することで、 特定のネットワークインターフェースの状態を設定できます。 例えば、enp1s0のIPアドレスを「192.168.0.2」に変更するには、以 下のようにします。

[警告]

ここで説明するaddやdelによる設定は、Armadillo上でも行えますがArmadillo-X1やG3シリーズでは、 NetworkManagerが自動的に実行しています。 これらの製品では、各製品の製品マニュアルに従ってNetworkManager経由での設定を実施してください。

すでにIPアドレスが設定されている場合は、削除します。

[ATDE ~]$ sudo ip address del 192.168.xxx.xxx/24 dev enp1s0

図4.43 ネットワークインターフェースからIPアドレスを削除する(ipコマンド)


次にIPアドレスを設定します。

[ATDE ~]$ sudo ip address add 192.168.0.2/24 dev enp1s0
[ATDE ~]$ ip address show enp1s0
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.2/24 scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link
       valid_lft forever preferred_lft forever

図4.44 ネットワークインターフェースにIPアドレスを設定する(ipコマンド)


IPアドレスが設定されていることが確認できます。

ipコマンドで設定したネットワークインターフェースの状態は、 一時的なもので、再起動すると失われてしまいます。 恒久的な設定は、/etc/network/interfacesファイルに記述します。 interfacesファイルに記述した設定は、networking.serviceを 再起動すると適用されます。

[ATDE ~]$ sudo systemctl restart networking.service

図4.45 networking.serviceを再起動する


ATDE7の標準設定では、interfacesファイルは以下のようになっています。

[ATDE ~]$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

図4.46 ATDE7のinterfacesファイル


「auto lo」という行は、「lo」を自動的に起動するよう指示しています。

「iface lo inet loopback」では、「lo」をTCP/IPネットワークのローカルルー プバックインターフェースのインターフェース名として指定しています。

/etc/network/interfacesファイルの設定方法の 詳細は、man 5 interfacesを参照してください。

4.10.2. IPアドレスとポート番号

ネットワークで結ばれたコンピューター同士で通信を行う場合、実際にはそれ ぞれのコンピューター上で動作するプロセス間で通信を行うことになります。 IPアドレスによって、ネットワーク上にあるコンピューターを識別することが できます。しかし、IPアドレスだけでは、コンピューター上で動作するプロセ スを識別することはできません。そこで、ポート番号を使用します。

接続を受け付けるプロセスは、ポート番号を指定して他のプロセスからの接続 を待ち受けます。接続を行うプロセスは、IPアドレスとポート番号を指定して 接続することで、特定のプロセスとの通信を開始することができます。

ポート番号は、0〜65535の範囲内の数値を取ります。このうち、いくつかの番 号は用途が決まっています。このようなポート番号をウェルノウンポート (well-known port)と呼びます。どのポート番号がどのような用途に使用される かは、/etc/servicesファイルに記述されていま す。また、man 5 servicesにも説明がありますの で、参照してください。

ssコマンドを使用すると、どのポートが現在 使用されているか調べることができます。例えば、SSHサーバー(22番ポートを 使用)とHTTPサーバー(80番ポートを使用)が動作している場合、以下のように表示されます。

[ATDE ~]$ ss -tanp
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:80                       *:*
LISTEN     0      128          *:22                       *:*
LISTEN     0      20     127.0.0.1:25                       *:*
LISTEN     0      128         :::80                      :::*
LISTEN     0      128         :::22                      :::*
LISTEN     0      20         ::1:25                      :::*

図4.47 使用中のポート番号を調べる(ssコマンド)


4.10.3. ホスト名とリゾルバ

ネットワークに繋がっているコンピューターのことを、ホストまたはノードと 呼びます。クロス開発においては、クロスコンパイルを行う作業用PCをホスト と呼び、開発対象をターゲットと呼んでいましたが、ここでは単にネットワー クに接続されているコンピューターという意味でホストという言葉を使用しま す。

IPアドレスを使用すると、ネットワーク上のホストを識別することができます。 しかし、IPアドレスは人間にとっては覚えにくいものです。そこで、IPアドレ スに対応する名前を付けることができます。この、ホストを識別する名前をホ スト名(hostname)といいます。ホスト名は、 hostnameコマンドを使用して調べることができま す。

[ATDE ~]$ hostname
atde7

図4.48 ホスト名を調べる(hostnameコマンド)


ホスト名とIPアドレスの対応は、/etc/hostsフ ァイルに記述されています。ATDE7では、以下の内容になっています。

[ATDE ~]$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       atde7

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

図4.49 /etc/hostsファイル


「localhost」というホスト名が「127.0.0.1[22]」、「atde7」というホスト名が 「127.0.1.1」に対応付けられています。ホスト名からIPアドレスを特定するこ とを、名前解決といいます。

ホスト名はローカルネットワークだけではなく、インターネットでも使用でき ます。例えば、「www.atmark-techno.com」や「armadillo.atmark-techno.com」 はホスト名です。「www.atmark-techno.com」のようなインターネット上にある ホストのIPアドレスをすべてhostsファイルに書 くわけにはいきませんので、インターネットドメインネームシステム(DNS)と いう名前解決の仕組みがあります。DNSサーバーにホスト名を問い合わせると 、対応するIPアドレスを返してくれます。

DNSへのアクセスに使用する機能は、Cライブラリが提供します。この機能のこ とをリゾルバ(resolver)といいます。リゾルバの設定ファイルは /etc/resolv.confファイルです。 resolv.confにDNSサーバーのIPアドレスを指定 することができます。詳細は、man 5 resolv.conf を参照してください。

4.10.4. ネットワークの状態を調べる

ネットワーク設定が正しく行われたことを確認するため、ホスト同士で通信が 可能かを調べるには、pingコマンドが使用できま す。pingコマンドは、対象のホストへパケットを 送信し、対象のホストはパケットを受信すると応答パケットを返信します。対 象ホストのパケットのやりとりが正常にできれば、最低限のネットワーク設定 は正しいことを確認することができます。

通信可能なホストを指定してpingコマンドを実行 すると、以下のようにホストからの応答が表示されます。

[ATDE ~]$ ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.017 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.033 ms
^C
--- 192.168.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3079ms
rtt min/avg/max/mdev = 0.017/0.033/0.043/0.012 ms

図4.50 ネットワークの到達確認: 成功(pingコマンド)


ホストとの通信ができなかった場合、以下のような表示になります。

[ATDE ~]$ ping 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
From 172.16.23.10 icmp_seq=2 Destination Host Unreachable
From 172.16.23.10 icmp_seq=3 Destination Host Unreachable
From 172.16.23.10 icmp_seq=4 Destination Host Unreachable
^C
--- 192.168.100.2 ping statistics ---
5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4004ms

図4.51 ネットワークの到達確認: 失敗(pingコマンド)




[8] manコマンドのmanページより引用。

[9] 物理的なデバイスを操作する ためのプログラム

[10] 定期的にファイルシス テムの状態を保存しておく機能。不意なシステムシャットダウン時にもファイ ルシステムの破損を防止し、記録された状態に復旧することが可能となる。

[11] rwxを2進数の各桁に見立 てています。

[12] システム動作中にデバイスを追加すること。

[13] 最近は、マルチコアなCPUも当たり前になって きましたが。

[14] プロセスの状態を保存したもの。

[15] ttyは「TeleTYpe」の略です。テレタイプとは電動機械式 のタイプライターのことで、初期の端末として使用されていたため、このよう な名前になっています。

[16] シリアルケーブルで接続された端末を コンソールとして使用することもあります。この場合、シリアルコンソールと 呼びます。

[17] ATDEはVMware Player上で動作しているため、ホットキーをそのまま 入力することができません。 CtrlAltスペース を入力したあと、 CtrlAltを 押したままで、 CtrlAltF# を入力してください。

[18] ここでのタイマーは、プロセスが使用する仮想的なタイマーのこと です。

[19] Linuxシステムで互換性のあるロケール。POSIXロケールとも呼ばれ ます。

[22] ローカルループバック インターフェースのIPアドレス。