FreeBSD-CURRENT を導入してみた (3) 最新状態に更新してみた
本稿では先にインストールしたFreeBSD-CURRENTを最新状態に更新してみます。 FreeBSD-CURRENTは開発の最前線であり、非常な勢いで変更が加え続けられています。 それらを使用するためにはシステムを更新してゆくしかありません。 システムを自分で更新できることが、CURRENTを使用する上での必須要件なのです。
- (1) 配布物入手して仮想マシン作成してみた
- (2) インストーラを実行してみた
- (3) 最新状態に更新してみた
- (4) portsを使う環境整備したった
- (5) sshログイン環境を整備してみた
- (6) xorgを導入してみた
- (7) Guest Additionを導入してみた
- (1) 必要な資材を集めてみた
- ...
システム構築設定ファイル/etc/make.confを作成する
make.conf(5)[1] はFreeBSD配布物(OSとports)をコンパイルする際にmake(1)から読み込まれる設定ファイルです。 *1 主としてどのようにコンパイル作業を行うかを指定します。 行える設定に関してはmanファイルを参照します。
とはいえ実際にはオンラインマニュアルの記述だけでゼロからフルスクラッチするのは大変ですので、 サンプルファイルをベースに作成します。
# cp /usr/share/examples/etc/make.conf /etc/ # vi /etc/make.conf
サンプルファイルからの変更ポイントは以下のとおりです。
- 最適化スイッチの有効化
以下の行のコメントを外し有効化するCOPTFLAGS= -O -pipe
コンパイラの最適化スイッチを有効にします。 この指定はカーネルをコンパイルする際に最適化処理を有効化すると共に、 コンパイル処理にパイプを使った並列処理を取り入れることで処理の高速化を図ります。 これら有効化することでコンパイル結果のコードの実行速度が向上し、 コンパイル時間も短縮になります。
- ソースコード更新機能の有効化
以下のように該当行を書き換えます。
SUP_UPDATE= yes SUP= /usr/bin/csup SUPFLAGS= -L 2 SUPHOST= cvsup1.jp.freebsd.org SUPFILE= /usr/shar/examples/cvsup/standard-supfile
OSのソースコードを更新する際にどのように更新するかを指定します。 現在ではFreeBSDのソースはsubversionというプログラムで管理されているので、 最新のソースコードはsvn(1)コマンドで入手できます。 しかしながらsvnはまだFreeBSDの標準配布には組み込まれていないため、 portsを使ってインストールしなければなりません。 一方、ここで紹介する方法はcvsupプロトコルという古い方法を用いるやりかたですが、 使うコマンドが標準配布に組み込まれているので設定するだけですぐに使えます。 ひとまずこの古典的方法を用い、あとでsubversionを導入することにします。
まずSUP_UPDATEでSUP方式の使用を指定します。 SUPは使用するプログラムの指定です。 SUPHOST行は使用するSUPサーバを指定します。日本国内では以下のサーバ が存在するようです:
ホスト名 提供者 cvsup.jp.freebsd.org さくらインターネット cvsup1.jp.freebsd.org IIJ cvsup2.jp.freebsd.org yahoo cvsup3.jp.freebsd.org さくらインターネット cvsup4.jp.freebsd.org 大阪大学 cvsup5.jp.freebsd.org さくらインターネット cvsup6.jp.freebsd.org さくらインターネット cvsup7.jp.freebsd.org IIJ cvsup8.jp.freebsd.org IIJ cvsup9.jp.freebsd.org IIJ cvsup10.jp.freebsd.org IIJ ネットワーク的に近いサーバを指定します。 SUPFILE行でCURRENTのOS部分のソースコードを取得することを指定して います。ports木も取得できますが、ports木に関しては後述のportsnap (8)コマンドを使用した方がセキュアであるため、その指定は行いません。
- top(1)コマンドのテーブルサイズの指定
以下の行のコメントアウトを外し、有効化します。TOP_TABLE_SIZE=101
topコマンド内部のテーブルサイズをデフォルトよりも小さくすることで メモリ消費を軽減します。この数字はファイル/etc/passwdの行数の2倍 程度の素数でなければなりません。
- mallocのデバッグ機能の無効化
CURRENTは開発バージョンであるため、様々なデバッグ機能が有効化されています。 それらは皆、RELEASE版では無効化されている機能です。 これらが有効化されているインパクトですが、ファイル/usr/src/UPDATINGには 以下の記述があります。FreeBSD-10.xが遅いと考える人々への注釈
FreeBSD-10.xではとてもたくさんのデバッグ機能がカーネルとユーザランド双方で、 有効化されています。 これらの機能はシステムの基本要素の不正な使用の検出や、正当性チェックや不正停止 でのうるさい警告を補助するために設けられています。 これらは一方でシステムのパフォーマンスに多大な影響を与えます。もしシステムの性 能計測を行う、ベンチマークする、最適化するといった場合には、これらを無効化した くなるでしょう。これらは様々な-WITNESS系カーネルオプション、INVARIANTS、ユーザ ランドのmallocデバッグフラグ、そしてカーネルの様々な冗長メッセージ出力機能が含 まれます。多くの開発者は最高のパフォーマンスを得るために、ビルド時にこれらの機 能を無効しています。 (完全にmallocのデバッグ機能を無効化するには/etc/make.confでMALLOC_PRODUCTIONを 定義します。あるいはほとんどの重いデバッグ機能を無効にするにはln -s 'abort:false,junk:false' /etc/malloc.conf
を実行します。)そこで、以下の行をmake.confの末尾に加えます。 *2
# disable malloc debug features MALLOC_PRODUCTION="YES"
やってはいけない/やらないほうがいいこと
以下はやってはいけない、あるいはやらない方がいいことです。
CPUTYPE行の設定
CPUTYPEで使用しているマシンのCPUを指定することで、コンパイラは そのCPUに最適化したコードを出力できるようになります。 デフォルトコンパイラがgccからclangに変更になり、 指定できるCPUにcorei7-avxなどが追加されました。
しかしながら、FreeBSDのOSのコンパイル時に指定できるのは core2までです。corei7系やcore-avx系の指定を行うと、 ダイナミックリンカが正しく動作しなくなり、 結果としてシステムが破壊されますので現時点では 指定してはいけません。
また、OSコンパイルに使えるcore2などの指定も行わない方が 無難です。 この後ARMのクロスコンパイル環境を作成しますが、その際に CPUTYPE行の指定が行われているとコンパイルがエラー終了します。
CFLAGS/CXXFLAGSの指定
サンプルファイルには以下の例が記述されています。
#CFLAGS+= -msse3 #CXXFLAGS+= -msse3
それぞれ、ユーザランドのコンパイルの際にC/C++コンパイラに渡される 引数の指定を行えます。
これらもクロスコンパイル環境作成時に指定していると エラーとなるため、指定しません。
なお VirtualBoxの仮想環境では、CPUTYPEの指定の有無や CFLAGS/CXXFLAGSの有無でコンパイル結果の実行速度が変化する ことはないようです。 unixbenchやscimark2c、flopsといったベンチマーク試験で確認しています。
そもそもSSE3などのSIMD拡張はコンパイルされるプログラム側が それを使用することを前提に組まれていない限り、 効果は得られません。 こうした対応が行われているソフトウェアに ピクセル操作ライブラリx11/pixmanがあります。 このportsでは、導入時にオプションでSIMD拡張の使用の有無を指定できます。 従い/etc/make.confで指定する必要はありません。
最新のソース木を入手する
以下のコマンドを実行します。
# cd /usr/src # mkdir /var/log/buildlog # make update |& tee /var/log/buildlog/update.[年月日].log
csupプログラムでディレクトリ/usr/src下のソース木をすべて最新に更新 します。その様子は、作成したディレクトリ/var/log/buildlog下のログ ファイル<oupdate.<年月日>.logに記録されます。 updateの様子を記録にとり確認することで、更新がシステムの少なくとも どの領域に行われたのかを知ることができます。
また、必ず以下のファイルを確認しましょう。
# less /usr/src/UPDATING
このファイルは、何らかの特別な注意を必要とする変更があった場合に その内容が記述されます。インストールしたsnapshotの日付以降にそうした 変更がないかチェックします。また変更があった場合に実行する必要のある 手順が存在しないかも確認します。何らかの手順が指示されていたならば、 それに従います。
カーネル設定ファイルを作成する
OSのカーネルがどの様にコンパイルされるかを指定するのがカーネル設定 ファイルです。このファイルを適切に記述しカーネルをコンパイルしなおす ことで以下を行うことができます。 - カーネルの持つ機能の有効化/無効化 - カーネルに組み込むデバイスドライバの指定
実用するシステムのコンパイルを行う場合、不要なデバイスドライバの組み 込みを抑制することでメモリ消費を低減できます。さらに前述の通り不要なデバッグ機 能を削除することで、実行速度の向上が見込めます。
オリジナルのカーネルと、不要なデバイスドライバとデバッグ機能を削除し たカーネルとのサイズを比較するならば、以下の様になります:
# ls -la /boot/kernel.old/kernel -r-xr-xr-x 1 root wheel 19805075 Oct 6 12:21 /boot/kernel.old/kernel # ls -la /boot/kernel/kernel -r-xr-xr-x 1 root wheel 9892045 Nov 8 10:29 /boot/kernel/kernel
大幅なサイズ縮小が行えていることが分かります。
また、FreeBSD-ARMのようなバージョンを触ろうとする場合、動作させ るためにカーネルの設定を操作する必要になることも珍しくありません。
カーネル設定ファイルの作成手順は以下のとおりです。
- GENERIC設定ファイルからコピーする
今、新たに作成する設定ファイル名をVIRTUALBOX
とします。 カーネル設定ファイルではファイル名はすべて大文字で構成するのが伝統です。 雛型ファイルであるGENERICファイルからコピーしてオリジナルのファイルを作成してゆきます。# cd /usr/src/sys/amd64/conf # cp GENERIC VIRTUALBOX
- ファイルVIRTUALBOXを編集する
以下の手順で編集してゆきます。- カーネルの名前をident行で指定する
システム情報を表示するuname(1)コマンドを実行するならば:# uname -a FreeBSD FreeBSD-10.0 10.0-CURRENT FreeBSD 10.0-CURRENT #1: Sun Nov 4 19:01:48 JST 2012 root@FreeBSD-10.0:/usr/obj/usr/src/sys/VIRTUALBOX amd64
この様にカーネルの名前であるカーネル識別子が表示されます。 この識別子は、カーネル設定ファイルのident行で指定します。 GENRICファイルでは
ident GENERIC
と記述されていますが、これを
ident VIRTUALBOX
のように書き換えます。なお、カーネル識別子はカーネル設定ファイル名と同一にするのが 伝統ですが、例外はあります。
- デバッグ機能を無効化する
以下の行を以下の様にコメントアウトします。... #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols ... # options KDB # Enable kernel debugger support. ... # options DDB # Support DDB. # options GDB # Support remote GDB. # options DEADLKRES # Enable the deadlock resolver # options INVARIANTS # Enable calls of extra sanity checking # options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS # options WITNESS # Enable checks to detect deadlocks and cycles # options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed # options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
カーネル設定ファイルでは行を無効にする場合に削除するのではなく コメントアウトするのが流儀です。
- 不要なデバイスを削除する
デバイスドライバはカーネル設定ファイル中に例えばdevice ata # Legacy ATA/SATA controllers
というように
device
行で組み込まれています。 ちなみにこの行の次に書かれているoptions ATA_CAM # Handle legacy controllers with CAM options ATA_STATIC_ID # Static device numbering
という
option
行は、この場合ata
デバイスのオプションになります。 なお、ataデバイスドライバはATA/SATAディスクコントローラのデバイスドライバ であり、削除してはいけません。削除するのは使用している環境(この場合はVirtualBoxの仮想コンピュータ)が 装備していないデバイスのドライバになります。 環境がどの様なデバイスを装備しているかは、コマンドdmesg(8)を実行して調べます。 dmesgの出力とカーネル設定ファイルの
device
行のコメントを 読み比べて判断します。
- カーネルの名前をident行で指定する
ユーザランドをコンパイルする
OSのカーネル以外の部分をユーザランドといいます。まずこれをコンパイルします。 以下のコマンドを実行します。
# cd /usr/src # make buildworld |& tee /var/log/buildlog/buildworld.[年月日].log
稀にコンパイルエラーで停止する場合があります。 そうした場合は、しばらくまってから再度make updateすると、 修正がcommitされている場合があります。 待てない場合は自分でソースコードを修正しましょう。
カーネルをコンパイルする
次にカーネルをコンパイルします。
# make buildkernel KERNCONF=VIRTUALBOX |& tee /var/log/buildlog/buildkernel.[年月日].log
ここでVIRTUALBOXは作成したカーネル設定ファイルの名前です。 ここでもコンパイルエラーなしに終了することを確認します。
カーネルをインストールして、再起動する
コンパイルしたカーネルをインストールし再起動します。
# make installkernel KERNCONF=VIRTUALBOX |& tee /var/log/buildlog/installkernel.[年月日].log # sync; sync; sync; reboot
無事起動することを確認します。
万一起動しない場合は、先の手順で旧いカーネルが/boot/kernel.old/に 自動バックアップされているので、それを使って起動します。 以下の手順に従います。
- 起動時のローダのメニューで、「2」を選択、ローダのプロンプトに抜け(Escape)します。
- 以下の様にunloadコマンドを打ち込みます。
OK unload
ここでOKはプロンプトです。
- loadコマンドで旧いカーネルを読み込みます
OK load boot/kernel.old/kernel boot/kernel.old/kernel text=0xd5fbf8 data=0x1865a0+0x2b91a0 syms=[0xB+0x15d530+0x1b0d13]
ここで起動時にカーネルモジュールを読み込んでいる場合は、 loadコマンドで読み込むべきカーネルモジュールも読み込みます。
/boot/loader.conf
でそうした設定を行っていない場合は心配する必要はありません。 - bootコマンドで起動します
OK boot
ユーザ、グループ情報など基本情報の更新を行う
FreeBSDには様々なシステムアカウントが存在します。 このシステムアカウントは様々なプログラムが動作する時の 実効ユーザとして用いられるだけでなく、 インストールされるファイルの所有者としても使われます。
システムアカウントは、たびたび追加されます。 そのため更新時に追加が行われることは珍しくありません。 追加を正しく行っておかないと、 ファイルのインストール時に必要なアカウントが存在しないことになり、 所有者を設定できず、インストールに失敗することになってしまいます。
この問題を解決するのがmergemaster -p
です。
以下、実行例を示して解説します。
# mergemaster -p *** Creating the temporary root environment in /var/tmp/temproot *** /var/tmp/temproot ready for use *** Creating and populating directory structure in /var/tmp/temproot *** Beginning comparison ====================================================================== *** Displaying differences between ./etc/group and installed version: --- /etc/group 2012-10-06 12:31:36.000000000 +0900 +++ ./etc/group 2012-11-07 21:49:02.000000000 +0900 @@ -1,4 +1,4 @@ -# $FreeBSD: src/etc/group,v 1.36 2011/01/28 22:28:12 pjd Exp $ +# $FreeBSD: src/etc/group,v 1.37 2012/10/22 01:18:41 marcel Exp $ # wheel:*:0:root daemon:*:1: @@ -16,6 +16,7 @@ sshd:*:22: smmsp:*:25: mailnull:*:26: +_atf:*:27: guest:*:31: bind:*:53: proxy:*:62: (END)
まずグループファイル/etc/group
に更新があったことが報告されています。
変更内容はこのようにdiff(1)形式で出力されます。
ここではグループ_atf
が追加され、
ファイルのバージョン番号が更新されていることが分かります。
差分はmoreを使って表示されているので、
キーq
を押して表示を終了させ対応を開始します。
すると以下のメニューが表示されます。
Use 'd' to delete the temporary ./etc/group Use 'i' to install the temporary ./etc/group Use 'm' to merge the temporary and installed versions Use 'v' to view the diff results again Default is to leave the temporary file to deal with by hand How should I deal with this? [Leave it for later]
ここでは以下から処理を選び、対応する1文字'd'~'v'を入力します。 それぞれの意味は以下の通り。
キー | 意味 |
---|---|
d | 変更を無視して更新を行わない |
i | 更新を上書きで適用してしまう |
m | 既存の内容と新規の内容をマージして使用する |
v | 差分を再表示 |
差分内容は純粋に追記だけなので「i
」を選びます。
これでファイル/etc/group
の更新は終了です。
次の更新が表示されます。
*** Displaying differences between ./etc/master.passwd and installed version: --- /etc/master.passwd 2012-11-08 04:17:12.000000000 +0900 +++ ./etc/master.passwd 2012-11-07 21:49:02.000000000 +0900 @@ -1,6 +1,6 @@ -# $FreeBSD: src/etc/master.passwd,v 1.42 2011/01/28 22:29:38 pjd Exp $ +# $FreeBSD: src/etc/master.passwd,v 1.43 2012/10/22 01:18:41 marcel Exp $ # -root:$6$xxxxxx.:0:0::0:0:Charlie &:/root:/bin/csh +root::0:0::0:0:Charlie &:/root:/bin/csh toor:*:0:0::0:0:Bourne-again Superuser:/root: daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin operator:*:2:5::0:0:System &:/:/usr/sbin/nologin @@ -13,6 +13,7 @@ sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin smmsp:*:25:25::0:0:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin mailnull:*:26:26::0:0:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin +_atf:*:27:27::0:0:& pseudo-user:/nonexistent:/usr/sbin/nologin bind:*:53:53::0:0:Bind Sandbox:/:/usr/sbin/nologin proxy:*:62:62::0:0:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin _pflogd:*:64:64::0:0:pflogd privsep user:/var/empty:/usr/sbin/nologin (END)
次はユーザ情報の更新差分です。
ここではユーザ_atfが追加されていますが、
更新データではrootのパスワードが空になっているため、
そのまま更新を適用してしまうとrootパスワードがクリアされてしまいます。
これはまずいので、マージで対応しましょう。まずはq
で差分表示を抜け、
Use 'd' to delete the temporary ./etc/master.passwd Use 'i' to install the temporary ./etc/master.passwd Use 'm' to merge the temporary and installed versions Use 'v' to view the diff results again Default is to leave the temporary file to deal with by hand How should I deal with this? [Leave it for later]
メニュー表示でm
を押してマージモードに入ります。
# $FreeBSD: src/etc/master.passwd,v 1 | # $FreeBSD: src/etc/master.passwd,v 1 %
マージモードでは右が更新データ、左にオリジナルが表示されます。 ?を押すとヘルプが表示されます。
%? ed: Edit then use both versions, each decorated with a header. eb: Edit then use both versions. el or e1: Edit then use the left version. er or e2: Edit then use the right version. e: Discard both versions then edit a new one. l or 1: Use the left version. r or 2: Use the right version. s: Silently include common lines. v: Verbosely include common lines. q: Quit.
ed
などと押してエディタを起動して編集してもよいのですが、
単純にl
とr
キーを押していって、
どちらを選ぶが選択してゆくこともできます。
l
を押すとその差分部分に関してはオリジナル側の内容を、
r
を押すと更新側の内容が選択されます。
バージョン表示は更新された方がうれしいのでr
を、
%r
選択します。次のrootのパスワードは
root:$6$xxxxxxxxxxxxxxxxxxxxx | root::0:0::0:0:Charlie &:/root:/bin/c
クリアされては困るのでl
を選びます
%l
次は_atf
ユーザの追加なのでrを選びます
> _atf:*:27:27::0:0:& pseudo-user:/none %r
これで選択は終わり、メニューが表示されます。
Use 'i' to install merged file Use 'r' to re-do the merge Use 'v' to view the merged file Default is to leave the temporary file to deal with by hand *** How should I deal with the merged file? [Leave it for later]
以上でこのマージ処理は完了です。v
を押してマージ結果を確認し
意図したとおりだったらi
を押してマージ結果を導入、
意図を外していたらr
を押して再度マージに挑戦します。
ユーザアカウントの追加などが行われた場合、追加の確認が行われます。
*** Merged version of ./etc/master.passwd installed successfully *** Comparison complete *** /var/tmp/temproot is empty, deleting *** You installed a new master.passwd file, so make sure that you run '/usr/sbin/pwd_mkdb -p /etc/master.passwd' to rebuild your password files Would you like to run it now? y or n [n]
ユーザアカウントデータは実際には/etc/master.passwdなどのテキストファイルから 生成されたバイナリのデータベースファイルに格納されていて、 OSはそれを参照しているのです。 このためアカウントデータが変更になれば、データベースの更新が必要となるわけです。
ここではそれを行うか聞いているのでy
を押してやります。
Would you like to run it now? y or n [n] y Running /usr/sbin/pwd_mkdb -p /etc/master.passwd
以上でmergemaster -p
は完了です。
mergemaster
は/etc下などの各種ファイルの更新にも用いられます。
その様子は後で詳しく扱います。
ユーザランドをインストールする
以下のコマンドを実行し、ユーザランドをインストールします。
# make installworld |& tee /var/log/buildlog/installworld.[年月日].log
また、すでに使われなくなったファイルを削除します。
# male delete-old |& tee /var/log/buildlog/delete-old.[年月日].log
/etcの下の更新を行う
ディレクトリ
/etcの下にはOSの様々な設定ファイルと各種スクリプトなどが収められています。
当然、例えば起動時の処理に更新が入るならば、
/etcの下のファイルが更新されるわけです。ですが、
/etcの下のファイルはユーザが様々な編集、操作を行います。
例え明示的に編集したものでないとしても、実行した何らかのコマンドが
/etcの下のファイルを書き換えていることはよくあることです。
従い更新処理で勝手に書き換えられてしまっては、
せっかく行った設定が消去されてしまうこともあるのです。
それゆえコマンド
make installworld
では
/etcの下は更新されません。
/etcの下はコマンドmergemaster
を実行することで更新されます。
このmergemaster
が、CURRENTをソースから更新する処理でもっとも高度な
知識を要求する手順となります。
ここで全てを解説する事は不可能ですが、
幾つかの実用的な操作の指針を示すことにします。
mergemaster
の差分表示形式を理解する
mergemaster
の実行操作の流れは-pオプションをつけた
アカウント情報更新操作の流れと同じです。
ただし今度は、アカウント情報ファイルの更新ではなく、
/etc
の下の全ファイルに対して処理が行われる点が異なります。
mergemasterは既にインストールされている/etcの下と、更新しようとする 新しい/etcの下のファイルの内容を比較し、その差分をまず表示します。 この時の差分表示形式はdiff形式と呼ばれ、 コマンドdiff(1)で生成されるものです。具体的には
# diff -u 旧いファイル 新しいファイル
で生成されます。
この表示形式は、相違のあるファイルに関して相違がある行の行頭に以下の 様に記号を置いて違いを表します。
共通行 -削除行 +追加行
変化しなかった行は行頭に半角スペースを置きます。 削除されてしまう行は行頭に-(マイナス)を、追加される行には+(プラス)をつけます。
変化行だけ表示してはファイル中のどこが書き換わるのか分かりにくいので、 変化行の前後3行程度を共通行として表示します。
削除行や追加行は1行だけではなく
共通行 -削除行1 -削除行2 -削除行3 共通行
というように複数行続くこともあります。 また、
-削除行 +追加行
と組み合わさることで、ある行の変更を表します。
以上がdiff形式のあらましとなります。 *3
mergemaster
による更新への対処の基本
基本は単純です。 あなたが行った編集はそのまま保持して更新を適用する、 これが基本方針です。
このことを考えると、幾つかの法則が浮かびます。
- 法則1
- 内容の追加は問題となる可能性は非常に低い。
削除と変更は問題となる可能性がある。
削除と変更は、その対象があなたの行った設定である可能性があるという 意味で問題となる可能性があります。一方、単純な内容の追加は問題とな る可能性は低いと言えます。 - 法則2
- 変更があなたが操作を行ったファイルに対して行われる場合、問題
となる可能性がある。そうでない場合は問題となる可能性は低い
あなたが行った設定はあなたが編集したファイル内にあります。 それ以外が影響することはまずありません。 - 法則3
- 変更が設定ファイルに対するものである場合、問題となる可能性がある。
設定ファイル以外(例えばスクリプトファイル)に対する場合は、
問題となる可能性は低い。
基本的にユーザの編集操作は設定ファイルに対して行われます。 スクリプトファイルを変更して振る舞いを変えることはありえますが、 そもそもそれを行える技術力のある人は、 この文章を読まれることもないでしょう。
設定ファイルは多くの場合~.conf
というファイル名をとります。
スクリプトファイルは様々なものがありますが、
例えばrcで始まるファイル名(ただし/etc/rc.conf
は例外的に設定ファイル。)
や、ディレクトリ/etc/periodic/
下にあるファイルはスクリプトファイルです。
また、設定ファイルは通常、manコマンドでファイル名を引数にオンライン
マニュアルを引けるようになっています。言い換えるならばオンラインマ
ニュアルが引ければ設定ファイルである可能性が高いです。ちなみに設定
ファイルのオンラインマニュアルは(5)にまとめられています。
スクリプトファイルに関していえば、その大半がシェル(sh)スクリプトなので、
ファイルの先頭1行が通常は
#!/bin/sh
で始まります。
設定ファイル以外に安全に更新できるのがデータベースファイルです。 ディスクや端末の構成情報ファイルが/etcの下には存在します。 これらデータベースファイルは歴史的にファイル名が~tabとtabで終わるものがほとんどです。 これらも(5)にオンラインマニュアルがまとめられています。
究極的には/etcの下のファイルの内容をすべて把握し、 変更の意味を理解すれば完全な対応ができます。 が、実質問題としてそれは難しいものです。 上記の法則を考慮すれば多少の判断の役には立つでしょう。
mergemaster
を実行してみる
ではここでmergemaster
を実行してみましょう。
# mergemaster *** Creating the temporary root environment in /var/tmp/temproot *** /var/tmp/temproot ready for use *** Creating and populating directory structure in /var/tmp/temproot + ln -s ../var/named/etc/namedb /var/tmp/temproot/etc/namedb + ln -s mail/aliases /var/tmp/temproot/etc/aliases *** Beginning comparison *** Checking /etc/rc.d for stale files *** No stale files found ======================================================================
mergemaster
はパス/var/tmp/tmproot
下を作業領域に使用します。
この下に新しいファイルを展開し、/etc下と差分(diff)を取ってゆくのです。
この作業領域は削除を指示しない限り削除されません。
そのため、2度め以降のmergemaster
の実行時には
*** The directory specified for the temporary root environment,
/var/tmp/temproot, exists. This can be a security risk if untrusted
users have access to the system.
Use 'd' to delete the old /var/tmp/temproot and continue
Use 't' to select a new temporary root directory
Use 'e' to exit mergemaster
Default is to use /var/tmp/temproot as is
How should I deal with this? [Use the existing /var/tmp/temproot]
この様に「既に/var/tmp/temprootがあるけどどうする?」と聞かれる ことになります。ここでは通常デフォルト動作の、「既存の/var/tmp/temprootを使う」 を選ぶ、すなわち改行打鍵を選びます。
さて、mergemaster
が動作を開始すると、既存の/etcなどとあたらしい
ファイルの差分チェックが開始されます。
以下、その様子と処理の選択の仕方を例示します、なお、mergemaster
で差分が
発生するファイルは、アップデートの度に異なります。
従い以下の記述はあくまでも例として参照するようにしてください。
まず、ファイル.cshrc
の差分が報告されています。
このファイルはシェルcsh(1)のrootユーザ用設定ファイルです。
*** Displaying differences between ./.cshrc and installed version: --- /.cshrc 2012-10-06 12:31:38.000000000 +0900 +++ ./.cshrc 2012-11-09 13:32:22.000000000 +0900 @@ -1,4 +1,4 @@ -# $FreeBSD: src/etc/root/dot.cshrc,v 1.32 2012/04/11 14:13:22 eadler Exp $ +# $FreeBSD: src/etc/root/dot.cshrc,v 1.34 2012/11/04 01:00:35 bapt Exp $ # # .cshrc - csh resource script, read at beginning of execution by each shell # @@ -18,7 +18,7 @@ set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin) setenv EDITOR vi -setenv PAGER less +setenv PAGER more setenv BLOCKSIZE K if ($?prompt) then @@ -26,7 +26,7 @@ if ($uid == 0) then set user = root --More--(byte 690)
.cshrc
の変更点として、
デフォルトの環境変数PAGER
の内容がlessから
moreに変わったことが分かります。
すなわち、例えばmanの表示などに用いられるデフォルトのページャが
lessからmoreに変更になったことが分かります。
スクリーンの末端は--More--
を表示して停止しています。
これはmoreの振る舞いです。半角スペースで次ページに進みます。
ちなみに終了(Quit)qを押すと抜けます。
それ以外のキー操作はヘルプ(Help)hを押すと表示されます。
確認したら、半角スペースを押して最後まで差分を表示させましょう。
endif - set prompt = "%n@%m:%/ %# " + set prompt = "%n@%m:%~ %# " set promptchars = "%#" set filec Use 'd' to delete the temporary ./.cshrc Use 'i' to install the temporary ./.cshrc Use 'm' to merge the temporary and installed versions Use 'v' to view the diff results again Default is to leave the temporary file to deal with by hand How should I deal with this? [Leave it for later]
次の変更点はシェル変数promptに対するものです。 この変数はシェルのプロンプトの表示内容を指定するもので、 カレントディレクトリの表示を絶対パス表示から、 ログインパス起点の表示に切り替える変更です。 これによりプロンプトの表示長さが一般に短縮されます。 詳細はcsh(1)を参照して下さい。
末尾まで表示されると、最後にこの変更の扱いの指定を問われます。 これは以下の4種から選択します。
原文 | 意味 | 操作 |
---|---|---|
Use 'd' to delete the temporary ./.cshrc | 変更を無視して適用しない | d |
Use 'i' to install the temporary ./.cshrc | 変更をすべて既存上書きで導入する | i |
Use 'm' to merge the temporary and installed versions | 新規と既存をマージする | m |
Use 'v' to view the diff results again | 再度差分を表示する | v |
dを押して無視した場合、再度mergemaster
を実行するならば、再び
差分表示で扱いを問われることになります。
デフォルトはこれになります。従い勢いあまって改行キーを押したとしても、再度
mergemaster
を実行すればよいのです。
このファイルの場合、純粋に独自設定を上書きしない変更だけですので iキーを押して導入してしまいます。
/.cshrc
と/.profile
の更新の場合は以下の確認が行われます。
*** Historically BSD derived systems have had a hard link from /.cshrc and /.profile to their namesakes in /root. Please indicate your preference below for bringing your installed files up to date. Use 'd' to delete the temporary ./.cshrc Use 'l' to delete the existing /root/.cshrc and create the link Default is to leave the temporary file to deal with by hand How should I handle ./.cshrc? [Leave it to install later]
「歴史的にBSD由来のシステムでは/.cshrcと/.profileは/rootの下に ハードリンクするものだ。/root下のファイルに対してこの更新をどう するか指定してくれ」と、聞いています。
dを押すと既存/root下のファイルは保存され、変更は無視されます。
lを押すならば伝統どおり既存のファイルは削除され、
先に変更された
/.cshrc
からのハードリンクとして/root/.cshr
cが作られます。
どちらかは好みで選びます。ここではlを選択します。
なお、megemaster
はこれらの他に/root/.login
などの
更新管理も行います。
では次の比較に移ります。
*** There is no installed version of ./etc/atf/FreeBSD.conf Use 'd' to delete the temporary ./etc/atf/FreeBSD.conf Use 'i' to install the temporary ./etc/atf/FreeBSD.conf Default is to leave the temporary file to deal with by hand How should I deal with this? [Leave it for later]
既存ファイルが存在せず新規のファイル追加が行われる場合は、
このような表示となります。
ここではファイル/etc/atf/FreeBSD.conf
が導入されようとしています。
こうした場合は、必ずiを選択し新規ファイルを導入します。
そうしない場合、FreeBSDに新規機能が導入されてもそれが正しく動作しなくなります。
むろん、この時にオンラインマニュアルを検索し、新規導入された
機能がどの様なものであるか調べるようにするのは良い習慣です。
次の例はパス/etc/defaults/
下のファイルの更新です。
--- /etc/defaults/periodic.conf 2012-10-06 12:31:37.000000000 +0900 +++ ./etc/defaults/periodic.conf 2012-11-09 14:12:42.000000000 +0900 @@ -13,7 +13,7 @@ # For a more detailed explanation of all the periodic.conf variables, please # refer to the periodic.conf(5) manual page. # -# $FreeBSD: src/etc/defaults/periodic.conf,v 1.59 2012/07/13 06:46:09 kevlo Exp $ +# $FreeBSD: src/etc/defaults/periodic.conf,v 1.61 2012/10/20 18:13:20 ume Exp $ # # What files override these defaults ? @@ -144,6 +144,7 @@ # 490.status-pkg-changes daily_status_pkg_changes_enable="NO" # Show package changes +pkg_info="pkg_info" # Use this program # 500.queuerun daily_queuerun_enable="YES" # Run mail queue @@ -245,7 +246,7 @@ # 400.status-pkg weekly_status_pkg_enable="NO" # Find out-of-date pkgs pkg_version=pkg_version # Use this program -pkg_version_index=/usr/ports/INDEX-9 # Use this index file +pkg_version_index=/usr/ports/INDEX-10 # Use this index file # 999.local weekly_local="/etc/weekly.local" # Local scripts Use 'd' to delete the temporary ./etc/defaults/periodic.conf Use 'i' to install the temporary ./etc/defaults/periodic.conf Use 'm' to merge the temporary and installed versions Use 'v' to view the diff results again Default is to leave the temporary file to deal with by hand How should I deal with this? [Leave it for later]
パス/etc/defaults
下のファイルは、
各種のデフォルト設定を指定するファイルが格納されています。
デフォルト設定である故に、ユーザの編集は推奨されていません。
この例では/etc/defaults/periodic.conf
が
更新対象ですが、ユーザが設定の指定に使用するのは
/etc/periodic.conf
でありファイルが違うので衝突はおきません。
ちなみにこのperiodic.conf
は日時/週次/月次の様々な定時システム処理を提供する枠組みperiodic(8)
の設定ファイルです。詳細はperiodic.conf(5)を参照するといいでしょう。
/rtc/defaults下のファイルの更新は無条件で適用できるので>kbd>iを押します。
次の例はデータファイルです。
*** Displaying differences between ./etc/disktab and installed version: --- /etc/disktab 2012-10-06 12:31:36.000000000 +0900 +++ ./etc/disktab 2012-11-09 14:12:42.000000000 +0900 @@ -1,4 +1,4 @@ -# $FreeBSD: src/etc/disktab,v 1.26 2006/10/14 16:39:03 ru Exp $ +# $FreeBSD: src/etc/disktab,v 1.27 2012/11/02 00:17:30 eadler Exp $ # # Disk geometry and partition layout tables. # See disktab(5) for format of this file. @@ -42,6 +42,12 @@ :pa#2880:oa#0:ba#4096:fa#512:\ :pc#2880:oc#0:bc#4096:fc#512: +fd2880|2.88MB 3.5in Extra High Density Floppy:\ + :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\ + :pa#5760:oa#0:ba#4096:fa#512:\ + :pb#5760:ob#0:bb#4096:fa#512:\ + :pc#5760:oc#0:bb#4096:fa#512: + # # Stressed floppy-formats. No guarantees given. #
この例からは差分部分のみ示し、末尾のメニューは示しません。
ファイル/etc/disktab
はディスクフォーマットを行うプログラム
newfs(8)などから参照されるディスクの構成情報データベース
ファイルです。詳細はdisktab(5)を参照しましょう。この様な
データベースであるとされるファイルに対する更新はそのままiで
上書き導入してしまいます。
次の例は例外的なものであり、/etc/motdです。 これも結論から 言えば、更新があった場合ほぼ無条件でiして適応してよいものです。
*** Displaying differences between ./etc/motd and installed version: --- /etc/motd 2012-11-08 22:49:56.000000000 +0900 +++ ./etc/motd 2012-11-09 14:12:42.000000000 +0900 @@ -1,4 +1,4 @@ -FreeBSD 10.0-CURRENT (MYKERNEL) #0: Thu Nov 8 10:29:10 JST 2012 +FreeBSD ?.?.? (UNKNOWN) Welcome to FreeBSD! @@ -11,7 +11,7 @@ o The Handbook and FAQ documents are at http://www.FreeBSD.org/ and, along with the mailing lists, can be searched by going to http://www.FreeBSD.org/search/. If the doc package has been installed - (or fetched via pkg_add -r lang-freebsd-doc, where lang is the + (or fetched via pkg install lang-freebsd-doc, where lang is the 2-letter language code, e.g. en), they are also available formatted in /usr/local/share/doc/freebsd.
motd(5)はログイン時の表示メッセージを記述するファイルです。 ログインユーザに何かメッセージを必ず伝えたい場合は、このファイルを 編集するのが歴史的方法でした。 現状では1つのFreeBSD環境を複数人ユーザで共有することは稀であり、 使われることも少なくなってきているかと思います。 motdを本来の意味で使用されているなら別ですが、そうでない場合は iを押して上書きインストールします。
なお、ファイル冒頭のバージョン表示は、必ず一旦は
FreeBSD ?.?.? (UNKNOWN)
に更新されます。これはデフォルトでは起動時の処理で自動的に正しい
バージョン表記に修正されます。
この設定はファイル/etc/defaults/rc.conf
で
update_motd="YES" # update version info in /etc/motd (or NO)
として行われています。
処理自体は/etc/rc.d/motd
で行われているので、
# /etc/rc.d/motd restart
と実行すれば、稼働時でも更新が行われます。
次の例も無条件で更新導入できる例です。
*** Displaying differences between ./etc/mtree/BSD.include.dist and installed version: --- /etc/mtree/BSD.include.dist 2012-10-06 12:31:38.000000000 +0900 +++ ./etc/mtree/BSD.include.dist 2012-11-09 14:12:43.000000000 +0900 @@ -1,4 +1,4 @@ -# $FreeBSD: src/etc/mtree/BSD.include.dist,v 1.159 2012/09/17 21:41:38 jimharris Exp $ +# $FreeBSD: src/etc/mtree/BSD.include.dist,v 1.163 2012/10/22 01:18:41 marcel Exp $ # # Please see the file src/etc/mtree/README before making changes to this file. # @@ -9,6 +9,10 @@ .. arpa .. + atf-c + .. + atf-c++ + .. bsm .. bsnmp
パス/etc/mtree/
の下には、FreeBSDがどの様なディレクトリ構成を持って
いるかを指定するファイルが格納されています。これらファイルはきちん
と更新されねばなりません。iを押して上書き導入します。
次の例はスクリプトファイルの更新です。
*** Displaying differences between ./etc/network.subr and installed version: --- /etc/network.subr 2012-10-06 12:31:36.000000000 +0900 +++ ./etc/network.subr 2012-11-09 14:12:42.000000000 +0900 @@ -22,7 +22,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: src/etc/network.subr,v 1.230 2012/01/22 10:57:32 hrs Exp $ +# $FreeBSD: src/etc/network.subr,v 1.231 2012/10/27 17:06:26 hrs Exp $ # # @@ -504,7 +504,11 @@ # backward compatibility: $ipv6_enable case $ipv6_enable in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) - return 0 + if checkyesno ipv6_gateway_enable; then + return 1 + else + return 0 + fi ;; esac
このファイル/etc/rc.subr
はライブラリとして定義された、
スクリプトファイル用サブルーチンファイルです。
これらへの変更はFreeBSDの動作を変更します。バグ修正の場合もあ
ります。通常はiを押して上書き適用します。
次の例は定時実行ファイルの更新例であり、別途対応が必要な例と なります。
*** Displaying differences between ./etc/periodic/daily/490.status-pkg-changes and installed version: --- /etc/periodic/daily/490.status-pkg-changes 2012-10-06 12:31:37.000000000 +0900 +++ ./etc/periodic/daily/490.status-pkg-changes 2012-11-09 14:12:42.000000000 +0900 @@ -1,6 +1,6 @@ #!/bin/sh # -# $FreeBSD: src/etc/periodic/daily/490.status-pkg-changes,v 1.1 2010/08/05 15:53:33 olli Exp $ +# $FreeBSD: src/etc/periodic/daily/490.status-pkg-changes,v 1.2 2012/10/13 14:45:42 ume Exp $ # # If there is a global system configuration file, suck it in. @@ -23,7 +23,7 @@ if [ -f $bak/pkg_info.bak ]; then mv -f $bak/pkg_info.bak $bak/pkg_info.bak2 fi - /usr/sbin/pkg_info > $bak/pkg_info.bak + ${pkg_info:-/usr/sbin/pkg_info} > $bak/pkg_info.bak cmp -sz $bak/pkg_info.bak $bak/pkg_info.bak2 if [ $? -eq 1 ]; then
パス/etc/periodic/
下には日時/週次/月次で定時実行される様々なスクリプト
ファイルが格納されています。これらへの変更は通常は無条件で適用するべき
です。これ自身もそうするべきです。
注意すべきは内容で、インストールされているパッケージ一覧を表示する目的
で旧い版ではコマンド/usr/sbin/pkg_info
がハードコードされ実行されていました。
これが変数pkg_info
で指定されたコマンドを実行するよう書き換えられています。
なお、変数pkg_info
の初期値はpkg_info
であり、
それは先の実行例にあったファイル
/etc/defaults/periodic.conf
で設定されています。
ここでの問題点は初期値pkg_info
です。
パッケージ管理をpkgng
に切り替えているならば、
pkg_info
を実行しても
# pkg_info pkg_info: Don't use the pkg_ tools if you are using pkgng pkg_info: no packages installed
と怒られるだけでインストール済みパッケージ一覧は得られません。
そしてCURRENTではすでにこの切り替えは行われています。
この場合、
ファイル/etc/periodic.conf
に
pkg_info="pkg info" # Use PKGNG
という行を挿入するべきなのです。
次の例もスクリプトの更新です。
*** Displaying differences between ./etc/rc.d/ipfw and installed version: --- /etc/rc.d/ipfw 2012-10-06 12:31:37.000000000 +0900 +++ ./etc/rc.d/ipfw 2012-11-10 20:22:46.000000000 +0900 @@ -1,6 +1,6 @@ #!/bin/sh # -# $FreeBSD: src/etc/rc.d/ipfw,v 1.26 2012/07/09 07:16:19 hrs Exp $ +# $FreeBSD: src/etc/rc.d/ipfw,v 1.27 2012/10/29 06:31:51 hrs Exp $ # # PROVIDE: ipfw @@ -25,11 +25,11 @@ if checkyesno dummynet_enable; then required_modules="$required_modules dummynet" fi - + if checkyesno natd_enable; then + required_modules="$required_modules ipdivert" + fi if checkyesno firewall_nat_enable; then - if ! checkyesno natd_enable; then - required_modules="$required_modules ipfw_nat" - fi + required_modules="$required_modules ipfw_nat" fi }
パス/etc/rc.d/
の下には各種起動処理を記述したスクリプトファイルが存在して
います。これも通常ユーザが編集するものではありませんので、更新があった場合は
そのままiを押して適用します。
最後にマージ処理を行う例を示します。例としてはあまりおもしろいものではありませんが、 ファイル/root/.loginの更新例です。
*** Displaying differences between ./root/.login and installed version: --- /root/.login 2012-11-10 20:38:14.000000000 +0900 +++ ./root/.login 2012-11-10 20:40:00.000000000 +0900 @@ -1,8 +1,9 @@ -# $FreeBSD: src/etc/root/dot.login,v 1.22 2000/07/15 03:25:14 rwatson Exp $# +# $FreeBSD: src/etc/root/dot.login,v 1.23 2012/11/01 19:38:03 eadler Exp $ +# # .login - csh login script, read by login shell, after `.cshrc' at login. # # see also csh(1), environ(7) # # Uncomment to display a random cookie each login: -[ -x /usr/games/fortune ] && /usr/games/fortune -s +# if ( -x /usr/games/fortune ) /usr/games/fortune -s
ユーザ環境ではログイン時にfortune(6)でメッセージを表示しています。 更新では条件処理文がよりcshらしい書き方になっていますが、コメントアウトされています。 そこでこの部分をマージしてみましょう。 mを押してマージモードに入ります。
How should I deal with this? [Leave it for later] m
# $FreeBSD: src/etc/root/dot.login,v | # $FreeBSD: src/etc/root/dot.login,v
> #
%
この表示はアカウント情報の更新処理の際とまったく同じです。 左が旧い方、右が新しい内容です。この場合、ファイルのバージョン番号の 更新を求めていますので、rを選択します。
[ -x /usr/games/fortune ] && /usr/gam | # if ( -x /usr/games/fortune ) /usr/g %
つぎが肝心のfortuneを起動している部分です。
ここで、プロンプト%
にed と打ち込みます。
すると差分部分がエディタvi
で次の様に開かれます。
-- /root/.login 8 [ -x /usr/games/fortune ] && /usr/games/fortune -s +++ ./root/.login 9 # if ( -x /usr/games/fortune ) /usr/games/fortune -s
そこでこの表示を参考に新しい部分を以下の様に編集し、保存終了します。
if ( -x /usr/games/fortune ) /usr/games/fortune -s
すると、
Use 'i' to install merged file Use 'r' to re-do the merge Use 'v' to view the merged file Default is to leave the temporary file to deal with by hand *** How should I deal with the merged file? [Leave it for later]
この様に聞いてくるので編集結果を確認するためにvを押します。
Use 'i' to install merged file Use 'r' to re-do the merge Use 'v' to view the merged file Default is to leave the temporary file to deal with by hand *** How should I deal with the merged file? [Leave it for later]
望みの結果になったのでiを押して編集結果を導入します。
以上がmergemasterの使用方法です。
再起動する
ここまで来たら後は再起動するだけです。
# sync;sync;sync;reboot
無事起動し、各種起動処理がエラーを発生せずシステムが正常に 起動すれば更新作業は完了です。
CURRENTは非常に頻繁に更新が入ります。そのため頻繁な更新が必要になります。 ソースからの更新手順は煩雑で複雑ですが、何回か繰り返せば 自然に手順も覚えられるでしょう。
作業用一般ユーザを作成する
最後に作業用の一般ユーザとして以下のユーザを作成しておきます。
ユーザ名 | armdevel |
---|---|
プライマリグループ | armdevel |
所属グループ | wheel |
ユーザ作成には複数の方法がありますが、ここでは対話的に作成するadduser(8)を用います。
# adduser Username: armdevel Full name: ARM Developper Uid (Leave empty for default): Login group [armdevel]: Login group is armdevel. Invite armdevel into other groups? []: wheel Login class [default]: Shell (sh csh tcsh nologin) [sh]: tcsh Home directory [/home/armdevel]: Home directory permissions (Leave empty for default): Use password-based authentication? [yes]: Use an empty password? (yes/no) [no]: Use a random password? (yes/no) [no]: Enter password: Enter password again: Lock out the account after creation? [no]: Username : armdevel Password : ***** Full Name : ARM Developper Uid : 1001 Class : Groups : armdevel wheel Home : /home/armdevel Home Mode : Shell : /bin/tcsh Locked : no OK? (yes/no): yes adduser: INFO: Successfully added (armdevel) to the user database. Add another user? (yes/no): no Goodbye!
ここまでのまとめ
FreeBSD-CURRENTを更新する方法を紹介しました。 そもそもCURRENTを使うのは最新版を使いたいがためです。 最新版でありつづける手順は、とても大事です。
次回はFreeBSDでのソフトウェア導入管理システムであるportsの扱いを 紹介します。
*1:本稿のような文章では「hoge(1)を参照」という書き方をよく行います。 これはオンラインマニュアルを参照してね、という意味です。 具体的にはman 1 hogeと実行するとhoge(1)のオンラインマニュアルが参照できます。
*2:定義MALLOC_PRODUCTION
は、
その性質からファイル/etc/src.conf
(src.conf(5)参照)に書かれるべきにも思えます。
実際そのように書かれているFreeBSD.orgのwikiもありますが、
ここではmake.confに記述します。
*3:このdiff形式は正しくはユニファイドdiff形式というもので、 (オリジナル)diff形式→コンテキストdiff形式と続いてきたdiff形式の歴史で 最も新しいものです。現在はこのユニファイド形式が主流となっています。