いますぐ実践! Linuxシステム管理

いますぐ実践! Linux システム管理 / Vol.237 / 読者数:2305名

こんばんは、うすだです。

1月の終わり頃になると、今年ももう一月経ちました、なんて言われて、 やべえまだ今年の目標立ててねえよ、などと思ったりしますよね。

しかし、2月も終わって3月になると、 今年もあと10ヶ月しか残っていないですよ的なことは、あまり言われません。 ですので、アセる機会を失ったまま、 残りの10ヶ月を光陰矢のごとく過ごしてしまいがちです。

そんなことではいけないと、過去何度も思ったように、今年も思っているのですが、 ふと、タスクリストを眺めたところ、 やらなきゃいけないことのオンパレードであることに気づきました。

…やりたいことはどこへ行ったんだ? と自分に問いたいです。

というわけで、以前からやらなきゃなあと思っていたことを全部リセットして、 自分がやりたいこと、なりたいものを挙げ、リストをごっそり差し替えてしまおう! と思います。

とか言ってる間に、やっぱり1年過ぎてしまうんじゃないの? という疑問を感じつつ、 今回もはりきってまいりましょう。

今回のお題 - Linuxのカーネルパラメータをいじくってみる

サーバにはいろいろな種類があり、役割はそれぞれ異なります。ですが、 どんなサーバにも欠かせないものがあります。その中のひとつがカーネルです。

通常は、ご使用のディストリビューションが提供する標準のカーネルを、 そのまま使われると思います。

そのため、カーネルは、ハードウェアの構成や環境が違っても、 その違いを感じ取り、よきように動作してくださいます。そして、 それを実現するため、あの手この手を尽くされています。
その中のひとつの手が、「カーネルパラメータ」というやつです。

普通にインストールして普通に動いてくださるのなら、特に気にする必要はありません。 ですが、動かなくなったときや、特殊な条件で動かしたいとき、 さらに最適に動いてほしいときなどの際に、 カーネルパラメータを操作する必要が生じます。

てなわけで、今回は、カーネルパラメータについて、ご説明いたします。

カーネルパラメータとは?

そもそも呼び方が、「カーネルパラメータ」だったり「起動オプション」だったり 「引数」だったりと、統一されていないようですが、ここでは、 「カーネルパラメータ」と呼ぶことにします。

で、カーネルパラメータというのは、カーネルの個々の機能やドライバが解釈して、 それぞれの振る舞いを変更できるようにするためのものです。

カーネルパラメータ自体は、1つの文字列です。
具体的には、機能などを表すパラメータ名だけか、 「パラメータ名=値」で値を指定したものを、スペースで連結した形式になります。

「/proc/cmdline」を参照すると、 今動作しているカーネルのパラメータを知ることができます。たとえば、 Ubuntu12.10で確認してみたところ、以下のような結果となりました。

  $ cat /proc/cmdline
  BOOT_IMAGE=/boot/vmlinuz-3.5.0-25-generic root=UUID=値です ro \
  quiet splash vt.handoff=7

主なカーネルパラメータ

唐突ですが、主なパラメータを以下に示します。
よくわからないモノもあるとは思いますが、こういうものがあるのかーという程度に、 ちらっと眺めていただければよいと思います。

パラメータ概 要
root=デバイス等ルートファイルシステムの指定
init=プログラム最初に起動されるプログラムの指定(initの代わり)
quietメッセージの出力を抑制する
debugメッセージの出力を冗長にする(デバッグ用)
vt.handoff=値仮想ターミナルを指定した値に切り替える
singleシングルユーザモードで起動する
splashスプラッシュ画面を表示する
textテキストモードで起動する

カーネルソースを、「__setup」「__setup_param」「module_param」などで探索すると、 もっと見つかります。ただ、得られる数が膨大になりますので、 お暇なときにやってみることをおすすめします。

カーネルパラメータを変更して起動してみる

なにはともあれ、実際に試してみましょう。

GRUB のメニュー画面で、カーネルパラメータを変更できます。Ubuntuの場合、 BIOSの起動中(メーカーのロゴが表示されている際)に [Shift]キーを押しつづけると、 メニュー画面が表示されます。

そこで[e]を押すと、編集する画面に切り替わります。
「linux」か「kernel」で始まる行に、カーネルとそのパラメータが記述されています。 パラメータを変更したら、[Ctrl]+[x]を押す(か[Return]で戻って[b]を押す)と、 変更したパラメータでカーネルが起動します。

たとえば、設定ミスなどにより通常に起動しなくなった場合、 「single」か「emergency」を指定すると、 シングルユーザモード等で起動することができます。


…というのは、一回ポッキリです。恒久的にそのパラメータで起動したいという場合は、 GRUBの設定ファイルに記述する必要があります。

たとえば Ubuntu では、「/etc/default/grub」に指定します。
「GRUB_CMDLINE_LINUX」か「GRUB_CMDLINE_LINUX_DEFAULT」に追記して、 「update-grub2」コマンドをrootの権限で(sudo経由で)実行すると、 実際の設定ファイル「/boot/grub/grub.cfg」に反映されます。
(GRUB_CMDLINE_LINUXに書くと通常、 GRUB_CMDLINE_LINUX_DEFAULTに書くとすべてのエントリに反映されます。)

  $ grep GRUB_CMDLINE_LINUX /etc/default/grub
  GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
  GRUB_CMDLINE_LINUX="text"
  $ sudo update-grub2

上記では、通常の際にテキストモードで起動するよう設定しています。

あるいは、「/boot/grub/menu.lst」というファイルがあるなら、 それを直接編集します。(古いバージョンの GRUB の場合です。)

カーネルじゃなくても利用できる

カーネルパラメータは、カーネルがすべて使わなければならない… というわけではありません。

使われなかったパラメータがあっても、カーネルは文句を言いません。
実際、前述の表の「single」以降のパラメータは、 サービスなどが起動時に処理しています。
(たとえば、single は /etc/init/rc-sysinit.conf で解釈されます。)

ですので、たとえばどこかの起動スクリプトに、以下のような処理を記述しておくと、 カーネルパラメータに apache2 があるときだけ apache2 が起動する、 という細工が可能になります。

  if [ -n "`grep apache2 /proc/cmdline`" ]; then
      service apache2 start
  fi

カーネルモジュールに渡す

モジュールをロードするときに、パラメータを指定こともできます。
たとえば、以下のような何にもしないドライバで試してみましょう。

#include <linux/module.h>

static int param = 0;
module_param(param, int, 0);

static int __init driver237_init(void)
{
    printk("%s: param=%d\n", __FUNCTION__, param);
    return 0;
}

static void __exit driver237_exit(void)
{
    printk("%s: bye...\n", __FUNCTION__);
}

module_init(driver237_init);
module_exit(driver237_exit);

これを、安直に driver237.c というファイル名で保存し、 以下のようなMakefile を用意します。

obj-m = driver237.o
all:
	$(MAKE) -C "/lib/modules/$(shell uname -r)/build" M="$(shell pwd)"

そして、make してできたモジュールを「insmod」コマンドでロードする際に、 引数に指定すると、それがドライバに渡って解釈してくれます。

  $ make
  $ sudo insmod driver237.ko param=123
  $ dmesg | grep driver237
  [62797.236052] driver237_init: param=123
  $ sudo rmmod driver237

また、「/etc/modprobe.d/」以下に設定しておき、 「modprobe」コマンドでロードするという手もあります。

  $ cat /etc/modprobe.d/driver237.conf
  options driver237 param=999
  $ sudo cp -pi driver237.ko /lib/modules/`uname -r`/misc/
  $ sudo depmod
  $ sudo modprobe driver237
  $ dmesg | grep driver237
  [67676.807839] driver237_init: param=999
  $ sudo rmmod driver237

おわりに

以上、Linuxカーネルパラメータについて、簡単にご紹介しました。

某Linux専門誌をくまなくご覧になられている貴兄であれば、 いつぞやの特集でさらっと触れたことがあり、そのときの焼き回しなのではないか、 と思われたかもしれません。

…はい、まったくその通りです。

ですが、単なるノウハウだけでなく、 仕組みや使用例をちゃんと書かないといけないなと、常々思っていたことは事実です。 今回、あらためて書き直したということで、ご了承いただけますと幸いです。

…と、いうことにしておいてください。

宿題の答え

前回の宿題は、

  第1引数はオプション、第2引数はディレクトリのコマンドの補完を設定
  してみましょう。

でした。

何番目の引数かは「COMP_CWORD」という変数を見ればわかります。
補完の候補は「compgen」コマンドで生成できます。
そして、その候補を変数「COMPREPLY」に放り込めばよかったわけです。

というのを踏まえた関数を、さらっと書いてみました。
オプションは、適当に「-d」「-f」をご用意しました。

comptest () {
    case "$COMP_CWORD" in
    1)
        COMPREPLY=( `compgen -W "-d -f" $2` );;
    2)
        COMPREPLY=( `compgen -d $2` );;
    *)
        COMPREPLY=( `compgen -o default $2` );;
    esac
}

試しに、barというコマンドに適用してみましたが、想定したように動作するようです。

  $ complete -F comptest bar
  $ bar -(ここで[TAB]キーを押す)
  -d  -f
  $ bar -f d(ここで[TAB]キーを押す)
  dir1              dir2              dir3

せっかく(?)ですので、長いオプションにも対応させてみましょう。

comptest () {
    case "$COMP_CWORD" in
    1)
        COMPREPLY=( `compgen -W "-d -f --debug --force" -- $2` );;
    2)
        COMPREPLY=( `compgen -d $2` );;
    *)
        COMPREPLY=( `compgen -o default $2` );;
    esac
}

$2 の前に「--」とありますが、これは、入力途中の文字($2)が「--」のとき、 compgen が勘違いしないよう、 ここから先は補完対象の文字ですよとわかってもらうために挿入しています。
もしこれがないと、compgen のエラーメッセージが出力されます。

  $ bar --(ここで[TAB]キーを押す)
  bash: compgen: --: 無効なオプションです
  compgen: 使用法: compgen [-abcdefgjksuv] [-o option]...以下略...

なにはともあれ、実際にやってみて、試行錯誤してみてくださいませ。

今回の宿題

今回の宿題は、

  カーネルパラメータの長さの上限がいくつか、調べましょう。

です。

できれば、検索などせず、実際に入力して確かめたり、 ソースコードから攻めたりしていただけますと、 経験値アップにつながるのではないか、と思ったりしております。いかがでしょうか。

あとがき

以降は120%グチですので、お暇な方だけにおすすめいたします。

諸般の事情により、USBメモリにUbuntuを入れていたときのことです。

PCに差して電源を入れたらUbuntuが立ち上がってくれればいいだけだったのですが、 ついでにBIOSの設定も変えてしまおう、なんて思ってしまったのが運のつきでした。

設定を保存して再起動すると、メーカーのロゴが表示された後、 OSが立ち上がってきません。起動時にファンクションキーを押し、 BIOSの設定画面やデバイスの選択画面にしようとしましたが、ロゴが消えた後、 無応答。
あれもこれもどれも何もかも、叶わない状態になってしまいました。

泣きながらネットで検索しまくったところ、 似たようなケースに遭遇したヒトが少なからずいらっしゃいました。
その方々の魂の叫び(?)を参考に、マザーボードの電池を引っこ抜く、 という対処をしたら、無事に起動するようになりました。
(つまり、BIOSの設定が工場出荷状態に戻ったということだと思います。)

なにか問題が発生したときに、状況がわかる何かを示すこと、 なんらかの対処の手段を用意しておくこと、の重要さを、身をもって知りました。

こういうところの作り込みは買ってからしかわかりませんので、 商品購入の選択肢にはなりえません。ですが、 このあたりの良し悪しの差が信頼に大きく影響して、 次の商品購入につながったりつながらなかったりするのでは、 という気がしております。

そして、おのれの作ったソフトウェアだけでなく、 普段の行動にも言えることではないか、とも思ったりしています。

というわけで、納期が近づいてきて、 もろもろの帳尻を合わせようとしている自分への戒めとして、書いてみました。

みなさまにおかれましても、滅多に使われないからとか、 仕様書には明確に記載されていないからといった誘惑に負けず、 ユーザの視線でよきものに作りあげることを、心がけていただければと思います。

 

…まあ、本音は、貴重な土日の半分を持っていかれた恨みを、 書かずにはいられなかった、というだけなのですが。

この、おのれの小さき器を、何とかしたいと思う、今日この頃です…。

 

今回も、ここまで読んでいただき、誠にありがとうございました。
次回は、3月17日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- 能動的に描きたい! と思う今日この頃です。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)
http://twitter.com/kuriking/ (栗つぶやき)
http://facebook.com/kuriking3 (栗顔本)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本