swapリストでのCのお勉強
Rev.4を表示中。最新版はこちら。
swapon関数内でスワップ領域のプライオリティに応じ、そのリストを作成する箇所である。pが新規にリストにつなごうとするswap_infoで、swap_info[]がそれぞれのスワップ領域を表している。swap_list_t構造対はheadとnextの2つのメンバーをもつ構造体で、swap_info[]リストのヘッドとなる。初期値は-1,-1である。static struct swap_list_t swap_list = {-1, -1}; static struct swap_info_struct swap_info[MAX_SWAPFILES]; /* insert swap space into swap_list: */ prev = -1; for (i = swap_list.head; i >= 0; i = swap_info[i].next) { if (p->prio >= swap_info[i].prio) { break; } prev = i; } p->next = i; if (prev < 0) { swap_list.head = swap_list.next = p - swap_info; } else { swap_info[prev].next = p - swap_info; }初めてスワップを登録するとき、swap_list の初期値が-1であることとi >= 0条件で、forループはスキップする。従ってprev = -1で、swap_list.headとswap_list.nextにはp - swap_infoが設定される。
2回目以降はforループでチェックされ、pより小さいプライオリティのswap_infoがあると、そこでループを抜ける。そして直前のpより大きいプライオリティのswap_infoはprevに設定されており、そのswap_info.nextにp - swap_infoを設定し、p->nextにpより次に小さいプライオリティの位置となるiを設定することでリストを作成している。このリストはswap_info[]内の配列インデックスで構成していることになるのだが。で・・・・
p - swap_infoは配列インデックスを算出するわけである。実はアドレスpからアドレスswap_infoまでの差とばっかし思い込んでいたため、ここの理解に悩んでしまった。でCのお勉強。
struct test { int dummy1; int dummy2; }; struct test a[10]; main() { struct test *p; p = a; p++; p++; printf("%d\n", a); printf("%d\n", p); printf("%d\n", p - a); }結果は以下の通りであった。
[root@KURO-BOXHG kitamura]# ./a.out 268503276 268503292 2
通常/ets/fstabでプライオリティを設定しないでスワップを設定する(たぶん)、この場合0でl初期化されているスタテックな変数least_priorityから-1したものをそのプライオリティとしている。従ってデフォルトのスワップ領域のプライオリティは-1となっている。
[root@KURO-BOXHG ~]# swapon -s Filename Type Size Used Priority /dev/sda2 partition 530136 0 -1swapon -pで設定できるプライオリティは0 から 32767 の間の数値である。従ってleast_priorityはシステムのスワップ領域の一番小さいプライオリティとなる。プライオリティを設定しないでスワップ領域を追加すると、least_priorityから-1を引いたものをプライオリティとしていく。ここで新規にプライオリティを設定しないでスワップを設定すると、そのプライオリティは-2となる。
ここで、スワップ領域としてファイルを指定するのは周知の事実。ddで一連のファイルイメージを作成し、それをmkswapでフォーマットしswaponすればよい。実はこのファイルイメージddで作成する必要はない。ためしに既存のでかいファイルをmkswapしてswaponするとswapon -sでちゃんとスワップファイルとして登録されているのが確認できる。ただスワップの領域(ページ単位)と物理的なブロックが連続している方が効率がいいだけの話だ。内部的にはswap_exten構造体にブロックとページをマップするリストを作成する。非連続のイメージだと、そのリストが複数作成されてしまう。
また、ファイルでのスワップとデバイスでのスワップの内部的差はそのブロックデバイスの取得方法だけである。ファイルの場合swap_info->bdevはinodeのスーパブロックから取得する。デバイスの場合はデバイススペシャルファイルから取得し、ブロックサイズとしてページサイズを設定する。それ以外の処理でかかる違いはない。(と思う。)従ってスワップ領域が足りなくなれば再度パーティションを切りなおして作成しなくても、ファイルでスワップを作成してもパフォーマンス的には問題無さそうである。まあ、当初のスワップが足らなくなるぐらいなら物理メモリを増設するのが今日のアプローチか? かりにスワップが足りなくなっても、ただちにシステムそのものに支障がでてくるケースは稀であり、支障がでてくるのであればシステム構成を見直すのがベストのアプローチか。
このプライオリティをスワップアウトするときのスワップ領域を決定する唯一の指針となる。これはget_swap_page関数で行う。まず優先度の一番高いものからスワップ領域として選択していく。そして同じ優先度がラウンドロビンで選択していく。