<!-- The FreeBSD Documentation Project The FreeBSD Japanese Documentation Project Original revision: 1.80 $FreeBSD: doc/ja_JP.eucJP/books/handbook/cutting-edge/chapter.sgml,v 1.27 2001/07/25 15:05:59 hrs Exp $ --> <chapter id="cutting-edge"> <title>開発の最前線</title> <para><emphasis>改訂: &a.jim;, 2000 年 3 月.</emphasis></para> <para><emphasis>原作: &a.jkh;, &a.phk;, &a.jdp;, &a.nik;, およびたくさんのフィードバック.</emphasis></para> <sect1> <title>この章では</title> <para>あるリリースから次のリリースまでの期間にも, &os; の開発は休みなく続けられています. この開発の最前線に興味を持っている人のために, 手元のシステムを最新の開発ツリーに同期させておくための, とても使いやすい仕掛けが何種類も用意されています. 注意: 開発の最前線は, 誰もが扱えるという性質のものではありません! もしもあなたが, 開発途中のシステムを追いかけようか, それともリリースバージョンのどれかを使い続けようかと迷っているのなら, きっとこの章が参考になるでしょう.</para> </sect1> <sect1 id="current-stable"> <title>&os.current; vs. &os.stable;</title> <indexterm><primary>-CURRENT</primary></indexterm> <indexterm><primary>-STABLE</primary></indexterm> <para>FreeBSD には二つの開発ブランチがあります. それは &os.current; と &os.stable; です. この章ではそれぞれについて簡単に説明し, どのようにしてあなたのシステムを対応するツリーに対して, どうやって常に最新の状態に保つかについて扱います. まずは &os.current;, 次に &os.stable; について説明します.</para> <para><emphasis>訳: &a.hanai;, 1996 年 11 月 6 日.</emphasis></para> <sect2 id="current"> <title>最新の &os; を追いかける</title> <para>これを読む前に, 心にとめておいて欲しいことがあります. &os.current; とは &os; の開発の<quote>最前線</quote>だということです. もし &os; を使い始めたばかりなら, これを運用することについて十分検討を重ねた方が良いでしょう.</para> <sect3> <title>&os.current; ってなに?</title> <para>&os.current; とは文字通り, 日々変更されている &os; のソースのスナップショット以外の何ものでもありません. 中には現在開発途上のソフトウェア, 実験的な変更, あるいは過渡的な機能などが含まれています. また, この中に入っている機能がすべて, 次の公式リリースに入るとは限りません. &os.current; をソースからほぼ毎日コンパイルしている人は たくさんいますが, 時期によってはコンパイルさえできない状態になっていることもあります. 一般的に, これらの問題は可能な限り迅速に解決されますが, &os.current; のソースが不幸をもたらすか, それとも非常に素晴らしい機能をもたらすかというのは文字通り, ある与えられた 24 時間の間の, どの部分であなたがソースを手に入れたかによる場合もあるのです.</para> </sect3> <sect3> <title>誰が &os.current; を必要としてるの?</title> <para>&os.current; は, 主に次の三つの重要なグループを対象としています.</para> <orderedlist> <listitem> <para>ソースツリーのある部分に関して活発に作業している &os; グループのメンバ. 彼らにとっては<quote>最新のもの</quote>にしておくのが 絶対に必要なことなのです.</para> </listitem> <listitem> <para>活発にテストしている &os; グループのメンバ. 彼らは, &os.current; が<quote>健全である</quote>ことを可能な限り確認するために, 種々の問題と戦う時間を惜しまない人々です. 彼らはまた, 様々な変更に関する提案や &os; の大まかな方向付けを行ないたいと思っている 人々でもあります.</para> </listitem> <listitem> <para>単に, 様々な事に目を向け, 参考のために (たとえば動かすためではなく<emphasis>読むため</emphasis>に) 最新のソースを使いたいと思っている &os; (または他の) グループのまわりにいるメンバ. これらの人々はまた, 時々コメントやコードを寄稿してくれます.</para> </listitem> </orderedlist> </sect3> <sect3> <title>&os.current; に期待しては<emphasis>いけない</emphasis>ことは?</title> <orderedlist> <listitem> <para>なにか新しくカッコイイモノがあると聞き, 自分の周囲では一番にそれを持ちたいがために, リリース前のコードの断片を追いかけること.</para> </listitem> <listitem> <para>バグを修正するための素早い方法.</para> </listitem> <listitem> <para>わたしたちが<quote>公式にサポートする</quote>こと. わたしたちは 3 つの<quote>公式な</quote> &os.current; のグループの一つに, 実際に属する人々を助けるのにベストを尽くしますが, 技術的なサポートを行なうには, 単に「時間が足りない」のです. これはわたしたちが外の人を助けるの好まない, ケチで意地悪い人間だということではなく (もしそうなら &os; なんかやっていません), 文字通りわたしたちは一日に 400 ものメッセージに答え, <emphasis>かつ</emphasis> &os; の作業をすることなど出来ない! ということなのです. もし, &os; の改良作業を続けるか, それともたくさんの質問に答えるか, という二者択一が与えられたとしたら, 開発者とユーザのほとんどは後者を支持するでしょう.</para> </listitem> </orderedlist> </sect3> <sect3> <title>&os.current; を使う</title> <orderedlist> <listitem> <para>&a.current; と &a.cvsall; に加わってください. これは単に良い考えであるというだけでなく, <emphasis>必須の</emphasis>ことなのです. もし <emphasis>&a.current;</emphasis> メーリングリストに入っていなければ, さまざまな人がシステムの現在の状態について 述べているコメントを見ることは決してありませんし, 従って他の人が既に見つけて解決している 多くの問題に戸惑ってあきらめてしまうでしょう. さらに言うと, システムを正常に保つための 重要な情報を見逃してしまう可能性もあります.</para> <para>&a.cvsall; メーリングリストでは, それぞれの変更についての commit ログを見ることができます. また, それに関して起こり得る副作用の情報を得ることができますので, 参加する価値のあるメーリングリストです.</para> <para>これらのメーリングリストに入るには, &a.majordomo; へ</para> <programlisting>subscribe freebsd-current subscribe cvs-all</programlisting> <indexterm> <primary><application>majordomo</application></primary> </indexterm> <para>と書いたメールを送ってください. オプションとして本文に <literal>help</literal> と書けば, Majordomo からあなたへ, わたしたちがサポートする様々なメーリングリストに参加 /脱退する方法に関する, 詳しいヘルプが送られます.</para> </listitem> <listitem> <para><hostid role="fqdn">ftp.FreeBSD.org</hostid> からのソースの入手. 以下の 3 つの方法で行なうことができます.</para> <orderedlist> <indexterm> <primary><command>cvsup</command></primary> </indexterm> <indexterm> <primary><command>cron</command></primary> </indexterm> <indexterm> <primary>-CURRENT</primary> <secondary>CVSup を使った同期</secondary> </indexterm> <listitem> <para><link linkend="cvsup">cvsup</link> を <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/src/share/examples/cvsup/standard-supfile">この supfile</ulink> を用いて使用する. これは 2 番目に推薦される方法です. なぜなら, <command>cvsup</command> によって一度全体を入手し, 後は変更されたところだけを入手することができるからです. たくさんの人が自動的にソースを最新のものに保つために <command>cvsup</command> を <command>cron</command> から起動しています. これを行なうための非常に簡単な方法は, 単に</para> <blockquote><screen>&prompt.root; <userinput>pkg_add -f ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CVSup/cvsupit.tgz</userinput></screen></blockquote> <para>とタイプすることです.</para> </listitem> <indexterm> <primary>-CURRENT</primary> <secondary>ftp によるダウンロード</secondary> </indexterm> <listitem> <para><command>ftp</command> を使う. &os.current; のソースツリーは常に <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/"> ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/</ulink> で<quote>公開</quote>されています. わたしたちはまた, 全体を compress/tar して入手できる <command>wu-ftpd</command> を使っています. たとえば,</para> <screen>usr.bin/lex</screen> <para>があったとすると,</para> <screen><prompt>ftp></prompt> <userinput>cd usr.bin</userinput> <prompt>ftp></prompt> <userinput>get lex.tar</userinput></screen> <para>とすることにより, ディレクトリ全体(この場合, usr.bin/lex以下全体) を tar ファイルとして入手することができます.</para> </listitem> <indexterm> <primary>-CURRENT</primary> <secondary>CTM を使った同期</secondary> </indexterm> <listitem> <para><application><link linkend="ctm">CTM</link></application>を用いる. (接続料が高額だったり, email でのアクセスしかできないような) あまり良質でない TCP/IP 接続の場合には, <application>CTM</application> を利用すると良いでしょう. ただし, これには多くの手間がかかりますし, 壊れたファイルを受けとってしまう可能性もあります. そのため, 最近ではあまり使われなくなっており, 長い間使用できなくなってしまう事態が発生する可能性があります (訳注: 保守する人が少ないためです). 9600bps 以上の速度で接続しているなら, <application><link linkend="cvsup">CVSup</link></application> を利用されることを推奨します. </para> </listitem> </orderedlist> </listitem> <listitem> <para>もし, ソースを眺めるだけでなく, 走らせるために入手しているのであれば, 一部だけ選ぶのではなく, &os.current; の<emphasis>全体</emphasis>を手に入れてください. なぜなら, ソースのさまざまな部分が他の部分の更新に依存しており, 一部のみをコンパイルしようとすると, ほぼ間違いなくトラブルを起こすからです.</para> <para>&os.current; をコンパイルする前に <filename>/usr/src</filename> にある Makefile を良く読んでください. アップグレードの処理の一部として, 少なくとも一回は最初に <link linkend="makeworld">make world</link> を行なうべきでしょう. &a.current; を読めば, 次のリリースへ向けて時々必要になる他のブートストラップの方法に関して, 常に最新情報を得ることが出来ます.</para> </listitem> <listitem> <para>アクティブになって下さい! もし &os.current; を走らせているなら, わたしたちはそれに関するコメント, 特に拡張やバグ潰しに関する提案, を欲しています. コードを伴う提案はもっとも歓迎されるものです!</para> </listitem> </orderedlist> </sect3> </sect2> <sect2 id="stable"> <title>安定版の &os; を使う</title> <para><emphasis>訳: &a.jp.iwasaki;.</emphasis></para> <sect3> <title>&os.stable; ってなに?</title> <indexterm><primary>-STABLE</primary></indexterm> <para>&os.stable; とは定期的に公開されるリリースを作成するための開発ブランチです. このブランチに加えられる変更は原則として, 事前に &os.current; で試験ずみであるという特徴があります. ただ<emphasis>そうであっても</emphasis>, これは開発用ブランチの一つであるということに注意してください. つまり, ある時点における &os.stable; のソースが どんな場合にも使えるものであるとは限らないということです. このブランチはもう一つの開発の流れというだけであって, エンドユーザ向けのものではありません.</para> </sect3> <sect3> <title>誰が &os.stable; を必要としているの?</title> <para>もしあなたが FreeBSD の開発過程に興味があるとか, それに対する貢献を考えていて, 特にそれが 次回の<quote>ポイント</quote>リリースに関係するもの であるなら &os.stable; を追うことを考えると良いでしょう.</para> <para>セキュリティ上の修正は &os.stable; ブランチに対して行なわれますが, そのために &os.stable; を追う<emphasis>必要</emphasis>はありません. すべての FreeBSD セキュリティ勧告には 影響のあるリリースで問題点を修正する方法が説明されており, セキュリティ上の理由のみから開発用ブランチ全体を追いかけることは, 同時に望ましくない変更点まで取り込んでしまう可能性があるからです.</para> <para>わたしたちは &os.stable; ブランチがいつも安定に動作するように 努めていますが, それが保証されているというわけではありません. また, コードは &os.stable; に加えられる前に &os.current; で開発されるのですが, &os.stable; のユーザは &os.current; よりも多いため, &os.current; で発見されなかった バグが &os.stable; で発見され, 時々それが問題となることがあるのは 避けることができません.</para> <para>このような理由から, わたしたちは盲目的に &os.stable; を追いかけることを推奨<emphasis>しません</emphasis>. 特に, 最初に開発環境でコードを十分に試験せずに プロダクション品質が要求されるサーバを &os.stable; にアップグレードしてはいけません.</para> <para>もしそうするための資源的な余裕がない場合は, リリース間のバイナリアップデート機能を利用して, 最新の FreeBSD リリースを使うことを推奨します.</para> </sect3> <sect3> <title>&os.stable; を使う</title> <indexterm> <primary>-STABLE</primary> <secondary>利用する</secondary> </indexterm> <orderedlist> <listitem> <para>&a.stable; へ加わってください. このメーリングリストでは, &os.stable; の構築に関連する事柄や, その他の注意すべき点 に関する情報が流れています. また開発者は議論の余地がある修正や変更を考えている場合に, このメーリングリストで公表し, 提案された変更に関して問題が生じるかどうかを返答する機会をユーザに与えます.</para> <para>また, &a.cvsall; メーリングリストでは, それぞれの変更がなされると, 起こりうる副作用に関するすべての適切な情報と一緒に commit log を読むことができます. subscribe しておきたいもう一つのメーリングリストです. </para> <para>メーリングリストに参加するには, &a.majordomo; へメッセージの本文に次のように書いたメールを送ってください:</para> <programlisting>subscribe freebsd-stable subscribe cvs-all</programlisting> <indexterm> <primary><application>majordomo</application></primary> </indexterm> <para>オプションとして本文に `help' と書けば, Majordomo はわたしたちがサポートするさまざまなメーリングリストに参加 / 脱退する方法に関する詳しいヘルプを送付します.</para> </listitem> <listitem> <para>もし, あなたが新しいシステムをインストールしようとしていて それを可能な限り安定なものにしておきたいなら, 最新のブランチの snapshot を <ulink url="ftp://releng4.freebsd.org/pub/FreeBSD"> ftp://releng4.freebsd.org/pub/FreeBSD</ulink> から取得し, これを一般のリリースのものと同様にインストールしてください.</para> <para>もし, 既に &os; の以前のリリースが動いている場合で, これをソースからアップグレードしようとするならば, <hostid role="fqdn">ftp.FreeBSD.org</hostid> より簡単に これを行う事が出来ます. これには次の 3 つの方法があります. </para> <orderedlist> <indexterm> <primary><command>CTM</command></primary> </indexterm> <indexterm> <primary>-STABLE</primary> <secondary>CTM を使った同期</secondary> </indexterm> <listitem> <para><application><link linkend="ctm">CTM</link></application> 機能を使用する. 転送レートが安定している TCP/IP 接続でない場合は, この方法が適しています.</para> </listitem> <indexterm> <primary>-STABLE</primary> <secondary>CVSup を使った同期</secondary> </indexterm> <listitem> <para><link linkend="cvsup">cvsup</link> を <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/src/share/examples/cvsup/stable-supfile">この supfile</ulink> を用いて使用する. 一度コレクション全体を入手してしまえば, 前回からの変更部分だけですむので, 2 番目に推奨される方法です. 多くの人が <command>cron</command> から <command>cvsup</command> を実行し, 自動的にソースコードを最新の状態に保っています. これを簡単に扱うには次のようにタイプしてください.</para> <blockquote><screen>&prompt.root; <userinput>pkg_add -f ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CVSup/cvsupit.tgz</userinput></screen></blockquote> </listitem> <indexterm> <primary>-STABLE</primary> <secondary>FTP を使ったダウンロード</secondary> </indexterm> <listitem> <para><command>ftp</command> を使用する. &os.stable; 用のソースツリーは 常に次のところで<quote>公開</quote>されています: <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-stable/">ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-stable/</ulink></para> <para>私たちはまた, tar/compress でツリー全体を入手できる <command>wu-ftpd</command> を使用しています. 例えば :</para> <screen>usr.bin/lex</screen> <para>に対して:</para> <screen><prompt>ftp></prompt> <userinput>cd usr.bin</userinput> <prompt>ftp></prompt> <userinput>get lex.tar</userinput></screen> <para>とすることにより, ディレクトリ全体を tar ファイルとして入手することができます.</para> </listitem> </orderedlist> </listitem> <listitem> <para>基本的には, ソースに迅速でオンデマンドなアクセスが必要で, 接続のバンド幅が問題でなければ, <command>cvsup</command> か <command>ftp</command> を使いましょう. そうで ない場合は <application>CTM</application> を使いましょう.</para> </listitem> <indexterm> <primary>-STABLE</primary> <secondary>構築, コンパイル</secondary> </indexterm> <listitem> <para>&os.stable; をコンパイルする前に, <filename>/usr/src</filename> にある Makefile をよ く読んでください. 少なくとも一回はアップグレードの処理の一部として最初に <link linkend="makeworld">make world</link> を実行するべきでしょう. &a.stable; を読めば, 次のリリースに移行する に当たって時々必要となる既存システムからの 新システムの構築手順に ついての最新情報が得られるでしょう.</para> </listitem> </orderedlist> </sect3> </sect2> </sect1> <sect1 id="synching"> <title>ソースの同期</title> <para><emphasis>訳: &a.jp.iwasaki;. 13 September 1997.</emphasis></para> <para>インターネット接続 (または電子メール) を使用して, あなたの興味の対象によって &os; プロジェクトのソースのある一部分または全体の最新を 追いかける方法は色々あります. 私たちが提供している基本的なサービスは <link linkend="anoncvs">Anonymous CVS</link>, <link linkend="cvsup">CVSup</link> と <link linkend="ctm">CTM</link> です:</para> <warning> <para>ソースツリーの一部を最新のものに更新することは可能です. ただし, サポートされているアップデート手順は, ソースツリー全体を最新のものに更新して, ユーザランド (<filename>/bin</filename> や <filename>/sbin</filename> にあるような, ユーザが実行するプログラム全体のこと) およびカーネルのソースから再構築することのみであることに注意してください. カーネルだけ, あるいはユーザランドだけというように, ソースツリーの一部を更新した場合は, 問題が生じることがよくあります. この時に発生する問題はコンパイル時のエラーからカーネルパニック, データの破壊とさまざまです.</para> </warning> <indexterm><primary>anonymous CVS</primary></indexterm> <para><application>Anonymous CVS</application> と <application>CVSup</application> は <emphasis>pull</emphasis> 同期モデルを採用しています. <application>CVSup</application> の場合, ユーザ (または <command>cron</command> スクリプト) が <command>cvsup</command> 起動し, どこかにある <command>cvsupd</command> サーバとやりとりしてファイルを 最新状態にします. 届けられる更新情報はその時点の最新のものであり, また必要な時にだけ取り寄せられます. 興味のある特定のファイルやディレクトリに 限定して更新することも簡単にできます. クライアント側のソースツリーの状態・ 設定ファイルの指定に従い, サーバによって更新情報が 素早く生成されます. <application>Anonymous CVS</application> は, このプログラムがリモートの CVS リポジトリから直接変更点を pull できるようにした &man.cvs.1; への拡張であるという点で, <application>CVSup</application> よりもずっと単純です. <application>CVSup</application> は効率の点ではるかにまさっていますが, <application>Anonymous CVS</application> の方が簡単に利用できます. </para> <indexterm> <primary><command>CTM</command></primary> </indexterm> <para>一方, <application>CTM</application> はあなたが持っているソースとマスタアーカイブ上に あるそれとの対話的な比較をおこないませんし, あるいは向こう側から変更点を pull したりもしません. そのかわりに, 前回の実行時からの変更を認識するスクリプトが マスタ CTM マシン上で一日に数回実行され, すべての変更を compress して通し番号を振り, さらに電子メールで転送できるようにエンコードします (印字可能な ASCII キャラクタのみです). 受信した後は, これらの <quote>CTM のデルタ</quote> は自動 的にデコード, 検査してユーザのソースのコピーに変更を適用する &man.ctm.rmail.1; によって処理可能となります. この処理は <application>CVSup</application> や <application>Anonymous CVS</application> よりずっと効率 的であり, <emphasis>pull</emphasis> モデルというよりむしろ <emphasis>push</emphasis> モデルで あるため, 私たちのサーバ資源の負荷は軽くなります.</para> <para>もちろん他のトレードオフもあります. うっかりアーカイブ の一部を消してしまっても, <application>CVSup</application> は壊れた部分を検出して再構築してくれます. <application>CTM</application> はこれをやってくれませんし, <application>Anonymous CVS</application> はおそらく他の何よりも深く混乱してしまうことが多いでしょう. もしソースツリーの一部を消してしまったら, (最新の CVS <quote>ベースデルタ</quote>から) 一からやり直し, CTM か anoncvs を使って悪い部分を消去し, 再同期させることによって すべてを再構築しなければなりません.</para> <para><application>Anonymous CVS</application>, <application>CTM</application>, <application>CVSup</application> についての 詳しい情報については, 以下の節を参照してください.</para> </sect1> <sect1 id="makeworld"> <title><command>make world</command> の利用</title> <indexterm> <primary><command>make world</command></primary> </indexterm> <para>FreeBSD のどれか特定のバージョン &os; (&os.stable;, &os.current; など) について, ローカルのソースツリーを同期させたら, そのソースツリーを使ってシステムを 再構築しなければなりません.</para> <warning> <title>バックアップを作成する</title> <para>システムを再構築する<emphasis>前に</emphasis>バックアップを 作成することの重要性は, いくら強調してもし過ぎると言うことはありません. システム全体の再構築とは (以降に書かれた手順に従っている限り)難しい作業ではありませんが, どんなに注意していたとしても, <!-- hrs:2000/01/12 inevitably --> あなた自身, あるいはソースツリーで作業している他の人達に手違いがあった時には, システムが起動しなくなってしまう状態になることがあるのです. </para> <para>まず, バックアップがきちんと作成されていることを確認して, fix-it フロッピーを用意してください. 多分, それを使うことはないと思いますが, あとで後悔することのないよう, 念のため用意しておきましょう.</para> </warning> <warning> <title>メーリングリストに参加する</title> <indexterm><primary>メーリングリスト</primary></indexterm> <para>もともと, &os.stable; と &os.current; のコードブランチは, <emphasis>開発中のもの</emphasis>です. &os; の作業に貢献してくださっている人達も人間ですから, 時にはミスをすることだってあるでしょう. </para> <para>そのような間違いは, 単に警告を示す見慣れない 診断メッセージをシステムが,表示するような, 全く害のないものであることもあれば, システムを起動できなくしたり, ファイルシステムを破壊してしまうような, 恐ろしい結果を招くものかも知れません. </para> <para>万が一, このような問題が生じた場合, 問題の詳細と, どのようなシステムが影響を受けるかについて書かれた <quote>注意(heads up)</quote>の記事が 適切なメーリングリストに投稿され, そして, その問題が解決されると, <quote>問題解決(all clear)</quote>のアナウンス記事が同様に 投稿されます. </para> <para>&os.stable; や &os.current; ブランチを試したり, それらに 追随していくときに <email>FreeBSD-stable@FreeBSD.ORG</email> や <email>FreeBSD-current@FreeBSD.ORG</email> を読まないというのは, 自ら災難を招くことになるでしょう. </para> <para><emphasis>訳注:</emphasis> これらのメーリングリストは英語でやりとりされているため, 日本語での投稿は歓迎されません. 英語でのやりとりができない人は, <ulink url="http://www.jp.FreeBSD.org">FreeBSD 友の会</ulink> の運営しているメーリングリストをあたってみるのがいいでしょう. </para> </warning> <sect2> <title><filename>/usr/src/UPDATING</filename> を読む</title> <para>何を始めるにしろ, まず最初に <filename>/usr/src/UPDATING</filename> (もしくはあなたがソースコードを どこにコピーしたにせよそれに相当するファイル) を読みましょう. このファイルにはあなたが遭遇するかも知れない問題に対する重要な情報を 含んでいたり, あなたが特定のコマンドを実行しなければならなくなった時 その順序を指示したりするはずです. <filename>UPDATING</filename> があなたが読んだ事柄と矛盾している時は <filename>UPDATING</filename> が優先します.</para> <important> <para><filename>UPDATING</filename> を読むということは, 前述の 適切なメーリングリストを購読する代わりにはなりません. 二つの要求は相補的なもので排他的なものではないのです.</para> </important> </sect2> <sect2> <title><filename>/etc/make.conf</filename> の確認</title> <indexterm> <primary><filename>make.conf</filename></primary> </indexterm> <para>まず, <filename>/etc/defaults/make.conf</filename> と <filename>/etc/make.conf</filename> を調べてください. そこには 最初から標準的なものが (多くのものはコメントアウトされていますが) 含まれています. ソースからシステムを再構築するときに make が <filename>/etc/make.conf</filename> に付け加えられた設定を使用します. <filename>/etc/make.conf</filename> に追加された設定は <command>make </command> を実行したときに常に使われることを覚えておいてください. そのため, システムに必要な設定を書いておくと良いでしょう.</para> <para>標準的なユーザならおそらく, <filename>/etc/defaults/make.conf</filename> の <makevar>CFLAGS</makevar> と <makevar>NOPROFILE</makevar> のコメントをはずすことを考えると思います.</para> <para>他の定義 (<makevar>COPTFLAGS</makevar>, <makevar>NOPORTDOCS</makevar> など) の定義行についても, コメントを外す必要があるかどうか調べておきましょう. </para> </sect2> <sect2> <title><filename>/etc/group</filename> の更新</title> <para> <filename>/etc</filename> ディレクトリには, システム起動時に実行されるスクリプトだけでなく, あなたのシステムの設定に関連する情報の大部分が 含まれています. そのディレクトリに含まれる スクリプトは, FreeBSD のバージョンによって多少異なります. </para> <para> また, 設定ファイルのなかには, 稼働中のシステムが日々利用している ものもあります. 実際には, <filename>/etc/group</filename> などがそれに該当します. </para> <para> <quote>make world</quote> のインストールの段階では, 特定のユーザ名, あるいはグループが存在していることを 要求する場面があります. システムのアップグレードを行なう際には, それらのグループが削除, あるいは変更されて存在していない可能性が 考えられますが, そういった場合, システムのアップグレードを 行なっている間に, 問題が発生する原因になります. </para> <para>この種の例でもっとも記憶に新しいのは, <quote/ppp/ グループ(後に <quote/network/ に変更されました)が 追加された時です. <filename>ppp</filename> サブシステムがインストールされる時, そのサブシステムが利用する <quote/ppp/ グループが存在しなかったために, それらのインストールに失敗してしまったのです. </para> <para>解決方法は, <filename>/usr/src/etc/group</filename> を調べ, 自分のシステムのグループ名リストと比較することです. 最新のファイルに含まれていて, あなたのファイルに含まれていない グループ名があれば, あなたのファイルにそのグループ名をコピーして下さい. 同様に, 名前が異なるにも関わらず, <filename>/etc/group</filename> と <filename>/usr/src/etc/group</filename> で同じ GID を持っているグループ名があれば, <filename>/etc/group</filename> に含まれる, 該当するすべてのグループ名を変更しておかなければなりません. </para> <tip> <para>もし, あなたがもっと神経質な人なら, あなたが名前を変更したり, 削除してしまったグループが所有しているファイルを, 次のようにして調べることもできます. </para> <screen>&prompt.root; <userinput>find / -group <replaceable>GID</replaceable> -print</userinput></screen> <para>これは <replaceable>GID</replaceable>(グループ名もしくは数字で示されたグループ ID)で 指定されたグループが所有するすべてのファイルを表示します. </para> </tip> </sect2> <sect2 id="makeworld-singleuser"> <title>シングルユーザモードへの移行</title> <indexterm><primary>シングルユーザモード</primary></indexterm> <para>コンパイルは, シングルユーザモードで行なった方が良いでしょう. そうすることで多少速度が向上する, というちょっとした利点が あるだけでなく, システムの再インストールは重要なシステムファイル, 標準コマンド, ライブラリ, インクルードファイルなどを操作します. 稼働中のシステムに (特に他のユーザがそのシステムにログインしている時に) そのような変更を加えることは, トラブルを引き起こす原因となります. </para> <indexterm><primary>マルチユーザモード</primary></indexterm> <para>もう一つの方法として, マルチユーザモードでシステムを再構築して, シングルユーザモードに移行してからそれをインストールする, というのがあります. もしこのような方法で行ないたい場合は, 以下の手順を構築が完了するところまで飛ばしてください.</para> <para>稼働中のシステムでシングルユーザモードに移行するには, スーパユーザ(root)権限で次のコマンドを実行します.</para> <screen>&prompt.root; <userinput/shutdown now/</screen> <para>あるいはシステムを再起動し, ブートプロンプトから <option>-s</option> フラグを設定することで, シングルユーザモードで システムを起動させることができます. 起動後, シェルプロンプトから 次のように実行して下さい. </para> <screen>&prompt.root; <userinput>fsck -p</userinput> &prompt.root; <userinput>mount -u /</userinput> &prompt.root; <userinput>mount -a -t ufs</userinput> &prompt.root; <userinput>swapon -a</userinput></screen> <para>これはファイルシステムをチェックした後, <filename>/</filename> を読み書き可能にして再マウント, <filename>/etc/fstab</filename> に指定されている, それ以外の UFS ファイルシステムをすべてマウントしてから スワップを有効にします. </para> </sect2> <sect2> <title><filename>/usr/obj</filename> の削除</title> <para>システムが再構築される時, 構築されたものは(デフォルトで) <filename>/usr/obj</filename> 以下のディレクトリに格納され, そのディレクトリの下は <filename>/usr/src</filename> と同じ構造となります. </para> <para>このディレクトリをあらかじめ削除しておくことにより, <quote>make world</quote> の行程にかかる時間を短縮させ, 依存問題に悩まされるようなトラブルを回避することができます. </para> <para><filename>/usr/obj</filename> 以下のファイルには, 変更不可(immutable)フラグ(詳細は &man.chflags.1; 参照)がセットされているものがある可能性があります. そのため, まず最初にそのフラグを変更しなければなりません. </para> <screen>&prompt.root; <userinput>cd /usr/obj</userinput> &prompt.root; <userinput>chflags -R noschg *</userinput> &prompt.root; <userinput>rm -rf *</userinput></screen> </sect2> <sect2> <title>ソースの再構築</title> <sect3> <title>出力メッセージの保存</title> <para>実行される &man.make.1; からの出力は, ファイルに保存すると良いでしょう. もし, 何か障害が発生した場合, エラーメッセージのコピーを手元に残すことができます. 何が悪かったのか, あなた自身がそれから理解することはできないかも 知れませんが, &os; メーリングリストに投稿して, 誰か他の人からの助言を得るために利用することができます.</para> <para>ファイルに保存する最も簡単な方法は, &man.script.1; コマンドを 使い, 引数に出力を保存したいファイル名を指定することです. これを make world の直前に行ない, 再構築が終了してから <userinput>exit</userinput> と入力すると, 出力を保存することができます.</para> <screen>&prompt.root; <userinput>script /var/tmp/mw.out</userinput> Script started, output file is /var/tmp/mw.out &prompt.root; <userinput>make TARGET</userinput> <emphasis>… compile, compile, compile …</emphasis> &prompt.root; <userinput>exit</userinput> Script done, …</screen> <para>出力を保存する場合, <filename>/tmp</filename> ディレクトリの中に 保存しては<emphasis>いけません</emphasis>. このディレクトリは, 次の再起動で削除されてしまう可能性があります. 出力の保存には, (上の例のように)<filename>/var/tmp</filename>や <username>root</username> のホームディレクトリが適しています.</para> </sect3> <sect3> <title>ベースシステムの構築とインストール</title> <para>まず, カレントディレクトリを <filename>/usr/src</filename> に 変更しなければなりません. 次のように実行して下さい.</para> <screen>&prompt.root; <userinput>cd /usr/src</userinput></screen> <para>(もちろん, ソースコードが他のディレクトリにある場合には, <filename>/usr/src</filename> ではなく, ソースコードのあるディレクトリに移動して下さい). </para> <indexterm><primary><command>make</command></primary></indexterm> <para> make world を行なうには, &man.make.1; コマンドを使用します. このコマンドは, <filename>Makefile</filename> というファイルから, FreeBSD を構成するプログラムの再構築方法や, どういう順番でそれらを構築すべきかといったような 指示を読み込みます. </para> <para> コマンドラインの一般的な書式は, 次のとおりです. </para> <screen>&prompt.root; <userinput>make <option>-<replaceable/x/</option> <option>-D<replaceable>VARIABLE</replaceable></option> <replaceable>target</replaceable></userinput></screen> <para> この例では, <option>-<replaceable>x</replaceable></option> が &man.make.1; に渡されるオプションになります. どのようなオプションが利用できるかについては, マニュアルページを 参照して下さい. </para> <para> <option>-D<replaceable>VARIABLE</replaceable></option> は, <filename>Makefile</filename> に渡される変数であり, この変数は <filename>Makefile</filename> の動作をコントロールします. また, <filename>/etc/make.conf</filename> で設定される変数も 同様です. これは変数を設定するもう一つの方法として用意されています. </para> <screen>&prompt.root; <userinput>make -DNOPROFILE=true <replaceable>target</replaceable></userinput></screen> <para> は, プロファイル版のライブラリを構築しないことを指定する もう一つの記法で, <filename>/etc/make.conf</filename> 中の</para> <programlisting>NOPROFILE= true # Avoid compiling profiled libraries</programlisting> <para>の行に対応します.</para> <para> <replaceable>target</replaceable> は, &man.make.1; に どのように動作するのかを指示するためのものです. 各々の <filename>Makefile</filename> には, 数多くの異なる <quote>ターゲット(target)</quote> が定義されていて, 指定されたターゲットによって, 動作が決まります. </para> <para> <filename>Makefile</filename> に書かれているターゲットには, あなたが指定しても意味を持たないものも含まれます. これらは, システムの再構築に必要な段階を, 多くの さらに細かい段階に分割するため, 構築の過程で利用されるものです. </para> <para> 大抵の場合, &man.make.1; にパラメータを指定する必要はないでしょうから, コマンドラインは次のようなものになるでしょう. </para> <screen>&prompt.root; <userinput>make <replaceable>target</replaceable></userinput></screen> <para> &os; の 2.2.5 から(実際には, &os.current; ブランチで最初に作成され, 2.2.2 と 2.2.5 の間の時点で &os.stable; に導入されたのですが), <maketarget>world</maketarget> ターゲットは <maketarget>buildworld</maketarget> と <maketarget>installworld</maketarget> の二つに分割されました. </para> <para> その名前が示すように, <maketarget>buildworld</maketarget> は <filename>/usr/obj</filename> 以下に新しい完全な ディレクトリツリーを構築し, <maketarget>installworld</maketarget> は, そのツリーを 現在のマシンにインストールします. </para> <para> これは, 二つの理由から非常に有用です. まず第一に, 稼働中のシステムに全く影響を与えることなく, 安全にシステムの構築作業を行えることです. 構築作業は<quote>何にも依存せず独立して行なわれる</quote>ため, <!-- hrs:2000/02/14: needs good phrase that means "self hosted" --> マルチユーザモードで稼働中のシステムでも, 何一つ 悪影響を与えずに <maketarget>buildworld</maketarget> を 実行することができます. ただし, <maketarget>installworld</maketarget> は シングルユーザモードで行なうことをおすすめします. </para> <para> 第二に, NFS マウントを利用することで, ネットワーク上の複数のマシンをアップグレードすることが 可能な点があげられます. 例えば三台のマシン, マシン A, マシン B, マシン C をアップグレードしたい場合には, まず マシン A で <command>make buildworld</command> と <command>make installworld</command> を実行します. それから, マシン B とマシン C で <filename>/usr/src</filename> を NFS マウントし, <command>make installworld</command> とすることで 構築済みのシステムを各マシンにインストールすることができるのです. </para> <para><maketarget>world</maketarget> ターゲットも利用可能ですが, このターゲットの利用は推奨されていません.</para> <para>次のコマンド</para> <screen>&prompt.root; <userinput>make buildworld</userinput></screen> <para>を実行してください. ここで <command>make</command> に -j オプションをつけると, 同時にいくつかのプロセスを生成させることが できます. この機能はマルチ CPU マシンで特に効果を発揮します. 構築過程の大部分では CPU 性能の限界より I/O 性能の限界の方が問題となるため, シングル CPU マシンにも効果があります.</para> <para>普通のシングル CPU マシンで以下のコマンド</para> <screen>&prompt.root; <userinput>make -j4 buildworld</userinput></screen> <para>を実行すると, &man.make.1; は最大 4 個までのプロセスを同時に実行します. メーリングリストに投稿された経験的な報告によると, 4 個という指定が最も良いパフォーマンスを示すようです.</para> <para>もし, 複数の CPU を備えたマシンで SMP 設定が行なわれたカーネルを 利用しているなら, 6 から 10 の間の値を設定し, 速度がどれくらい 向上するか確認してみて下さい.</para> <para>ただし, この機能はまだ実験段階であるということに注意してください. そのため, ソースツリーへ変更が加えられたときに これが正常に機能しなくなる可能性があります. もし, このオプションを用いてシステムの構築に失敗した場合には, 障害を報告する前に, もう一度オプションを付けずに試してみて下さい. </para> </sect3> <sect3 <title>システムの構築にかかる時間</title> <indexterm> <primary><command>make world</command></primary> <secondary>時間</secondary> </indexterm> <para>構築時間を決める要素はさまざまありますが, 現時点では Pentium 3 の 500MHz, 128MB の RAM という構成で トリックや近道を使わずに普通に構築した場合, &os.current; の構築に約 3 時間半かかります. &os.stable; の構築は, もう少し早く終わります.</para> </sect3> </sect2> <sect2> <title>新しいカーネルの構築とインストール</title> <indexterm> <primary>カーネル(kernel)</primary> <secondary>構築, コンパイル</secondary> </indexterm> <para> 新しいシステムの全機能を完全に利用できるようにするには, カーネルの再構築をする必要があります. 再構築は, ある種のメモリ構造体が変更された時には特に必須であり, &man.ps.1; や &man.top.1; のようなプログラムは, カーネルとソースコードのバージョンが一致しないと正常に動作しないでしょう.</para> <para>最も簡単で安全にカーネルの再構築を行なう方法は, <filename>GENERIC</filename> を使ったカーネルを構築・インストールすることです. <filename>GENERIC</filename> にはあなたが必要とするデバイスがすべて含まれていない かも知れませんが, あなたのシステムをシングルユーザモードで 起動させるのに必要なものはすべて入っています. これは新しいバージョンのシステムがきちんと動作するかどうか 調べる良い方法の一つです. <filename>GENERIC</filename> で起動してから, あなたがいつも使っているカーネルコンフィグレーションファイルを 使って新しいカーネルを構築することで, システムが正常に動作しているかどうか確かめることができます.</para> <para>もし &os; 4.0 以降のシステムにアップグレードする場合, (<xref linkend="kernelconfig"> に記載されている) 標準的なカーネル構築手順は使えません. 代わりに, 以下のコマンドを実行する必要があります.</para> <screen>&prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make buildkernel</userinput> &prompt.root; <userinput>make installkernel</userinput></screen> <para>&os; の 4.0 以前にアップグレードする場合は, 標準的なカーネル構築手順に従う必要があります. ただし, 以下のコマンドを使って新しいバージョンの &man.config.8; を利用することが推奨されています.</para> <screen>&prompt.root; <userinput>/usr/obj/usr/src/usr.sbin/config/config <replaceable>KERNELNAME</replaceable></userinput></screen> </sect2> <sect2> <title>シングルユーザモードで再起動する</title> <indexterm><primary>single-user mode</primary></indexterm> <para> 新しいカーネルが動作するかどうかテストするために, シングルユーザモードで再起動するべきです. シングルユーザモードでの起動は, <xref linkend="makeworld-singleuser"> に書かれている手順に従ってください.</para> </sect2> <sect2> <title>新しいシステムバイナリのインストール</title> <para>十分最近のバージョンの &os; を <command>make buildworld</command> で構築しているなら, 次にここで <maketarget>installworld</maketarget> を 使うことで新しいシステムバイナリのインストールを行ないます.</para> <para>それには, 以下のコマンドを実行してください.</para> <screen>&prompt.root; <userinput>make installworld</userinput></screen> <note> <para><command>make buildworld</command> でコマンドラインから 変数を指定した場合は, 同じ指定を <command>make installworld</command> のコマンドラインにも 指定しなければなりません. ただし, オプションについてはその限りではありません. たとえば <option>-j</option> は <maketarget>installworld</maketarget> で絶対に使ってはいけません.</para> <para>たとえば以下のように実行したなら,</para> <screen>&prompt.root; <userinput>make -DNOPROFILE=true buildworld</userinput></screen> <para>以下のようにしてインストールしなければなりません.</para> <screen>&prompt.root; <userinput>make -DNOPROFILE=true installworld</userinput></screen> <para>もしそうしなかった場合, <command>make buildworld</command> の段階で構築されていない プロファイル版ライブラリをインストールしようとしてしまうでしょう.</para> </note> </sect2> <sect2> <title><command>make world</command> で更新されないファイルの更新</title> <para> システムの再構築は, いくつかのディレクトリ ( 特に, <filename>/etc</filename>, や <filename>/var</filename> や <filename>/usr</filename>) において, 新規に導入されたり, 変更された設定ファイルによる ファイルの更新は行なわれません.</para> <indexterm><primary><command>mergemaster</command></primary></indexterm> <para> これらのファイルを更新するもっとも簡単な方法は, &man.mergemaster.8; を使うことです. これは自分でやることも可能なので, そうしても かまいません. &man.mergemaster.8; は簡単に使えるので, こちらを使うことを お勧めします. その場合には <link linkend="update-dev"> 次のセクション</link> に進んでください. まず最初にマニュアルページを読んで, <filename>/etc</filename> のバックアップを取って不測の事態に備えてください. </para> <para> 手動で更新することを選んだ場合, 単にファイルを <filename>/usr/src/etc</filename> から <filename>/etc</filename> に コピーしただけでは正常に動作させることはできません. これらのファイルには, <quote>インストールという 手順を踏まなければならないもの</quote>が含まれています. <filename>/usr/src/etc</filename> ディレクトリは <filename>/etc</filename> ディレクトリにそのまま置き換えられるような コピーでは<emphasis>ない</emphasis>からです. また, <filename>/etc</filename> にあるべきファイルのうちで <filename>/usr/src/etc</filename> にないものもあります. </para> <para> 手動で行う際の 一番簡単な方法は, ファイルを新しいディレクトリにインストールしてから, 以前のものと異なっている部分を調べて更新作業を行なうことです. </para> <warning> <title>既存の <filename>/etc</filename> をバックアップする</title> <para> 理論的に考えて, このディレクトリが自動的に 処理されることはありませんが, 念には念を入れておいて 損はありません. たとえば以下のようにして, 既存の <filename>/etc</filename> ディレクトリを どこか安全な場所にコピーしておきましょう. </para> <screen>&prompt.root; <userinput>cp -Rp /etc /etc.old</userinput></screen> <para> <option>-R</option> は再帰的なコピーを行ない, <option>-p</option> はファイルの更新時間や所有者などを保存します. </para> </warning> <para> また, 新しい <filename>/etc</filename> やその他のファイルを インストールするための, 仮のディレクトリを作っておく必要があります. 仮ディレクトリは <filename>/var/tmp/root</filename> に置くのが良いでしょう. 同様に, 必要なサブディレクトリもこの下に置きます.</para> <screen>&prompt.root; <userinput>mkdir /var/tmp/root</userinput> &prompt.root; <userinput>cd /usr/src/etc</userinput> &prompt.root; <userinput>make DESTDIR=/var/tmp/root distrib-dirs distribution</userinput></screen> <para> 上の例は, 必要なディレクトリ構造をつくり, ファイルをインストールします. <filename>/var/tmp/root</filename> 以下に作られる, たくさんの空のディレクトリは削除する必要があります. 一番簡単なやり方は, 次のとおりです. </para> <screen>&prompt.root; <userinput>cd /var/tmp/root</userinput> &prompt.root; <userinput>find -d . -type d | xargs rmdir 2>/dev/null</userinput></screen> <para> これは空ディレクトリをすべて削除します. (空でないディレクトリに関する警告を避けるために, 標準エラー出力は <filename>/dev/null</filename> に リダイレクトされます) </para> <para> この段階の <filename>/var/tmp/root</filename> には, 本来 <filename>/</filename> 以下にあるべきファイルが すべて含まれています. 各ファイルを順に見て, 既存のファイルと異なる部分を 調べて下さい. </para> <para> <filename>/var/tmp/root</filename> 以下に インストールされているファイルの中には, <quote/./ から始まっているものがあります. これを書いている時点で, それに該当するファイルは <filename>/var/tmp/root/</filename> と <filename>/var/tmp/root/root/</filename> の中にある シェルスタートアップ ファイルだけですが, 他のものがあるかも知れません. (これは, あなたがこれをどの時点で読んでいるかに依存するので, <command/ls -a/ を使って確かめてください)</para> <para> もっとも簡単な方法は, 二つのファイルを比較するコマンド &man.diff.1; を使うことです. </para> <screen>&prompt.root; <userinput>diff /etc/shells /var/tmp/root/etc/shells</userinput></screen> <para> これは, あなたの <filename>/etc/shells</filename> ファイルと 新しい <filename>/etc/shells</filename> ファイルの 異なる部分を表示します. これらを, あなたが書き換えたものに変更点をマージするか, それとも既存のファイルを新しいもので上書きするかを 判断する材料にして下さい. </para> <tip> <title>新しい root ディレクトリ (<filename>/var/tmp/root</filename>) の名前に タイムスタンプを付けておくと, 異なるバージョン間の比較を楽に行なうことができます. </title> <para> 頻繁にシステムの再構築を行なうということは, <filename>/etc</filename> の更新もまた, 頻繁に行う必要がある ということです. これはちょっと手間のかかる作業です. </para> <para> この作業は, あなたが <filename>/etc</filename> にマージした, 新しく変更されたファイルの最新のセットのコピーを保存しておくことで 素早く行なうことができます. 下の手順は, それを実現するための一つの方法です. </para> <procedure> <step> <para> 普通に make world します. <filename>/etc</filename> や 他のディレクトリを更新したくなったときは, ターゲット ディレクトリに, そのときの日付に基づく名前をつけてください. たとえば 1998 年 2 月 14 日 だとすれば, 以下のようにします. </para> <screen>&prompt.root; <userinput>mkdir /var/tmp/root-19980214</userinput> &prompt.root; <userinput>cd /usr/src/etc</userinput> &prompt.root; <userinput>make DESTDIR=/var/tmp/root-19980214 \ distrib-dirs distribution</userinput></screen> </step> <step> <para> 上に説明されているように, このディレクトリから変更点をマージします. </para> <para> その作業が終了しても, <filename>/var/tmp/root-19980214</filename> を 削除しては<emphasis>いけません</emphasis>. </para> </step> <step> <para> 最新版のソースをダウンロードして再構築したら, ステップ 1 にしたがって下さい. 今度は, <filename>/var/tmp/root-19980221</filename> (更新作業が一週間おきだった場合) のような名前の, 新しいディレクトリをつくることになるでしょう. </para> </step> <step> <para> この段階で &man.diff.1; を使用し, 二つのディレクトリを比較する再帰的 diff を作成することで, 一週間の間に行なわれたソースへの変更による相違点を調べます. </para> <screen>&prompt.root; <userinput>cd /var/tmp</userinput> &prompt.root; <userinput>diff -r root-19980214 root-19980221</userinput></screen> <para> これによって報告される相違点は, 大抵の場合, <filename>/var/tmp/root-19980221/etc</filename> と <filename>/etc</filename> との場合に比べて 非常に少ないものになります. 相違点が少ないため, 変更点を既存の <filename>/etc</filename> ディレクトリにマージすることは, 比較的容易になります. </para> </step> <step> <para> ここまで終了したら, <filename>/var/tmp/root-*</filename> の 二つのうち, 古い方のディレクトリは削除して構いません. </para> <screen>&prompt.root; <userinput>rm -rf /var/tmp/root-19980214</userinput></screen> </step> <step> <para> この工程を, <filename>/etc</filename> へ変更点をマージする 必要があるたび, 毎回繰り返します. </para> </step> </procedure> <para> ディレクトリ名の生成を自動化するには, &man.date.1; を利用することができます. </para> <screen>&prompt.root; <userinput>mkdir /var/tmp/root-`date "+%Y%m%d"`</userinput></screen> </tip> </sect2> <sect2 id="update-dev"> <title><filename>/dev</filename> の更新</title> <note> <title>DEVFS</title> <indexterm><primary>DEVFS</primary></indexterm> <para>もし DEVFS を利用しているなら, この作業は必要ありません.</para> </note> <para>ほとんどの場合, &man.mergemaster.8; は デバイスの再構築が必要であることを検出して自動的にそれを実行するのですが, ここではデバイスの再構築を手動で行なう方法について説明します.</para> <para>安全のため, これはいくつかの段階に分けて行ないます.</para> <procedure> <step> <para> <filename>/var/tmp/root/dev/MAKEDEV</filename> を <filename>/dev</filename> にコピーします. </para> <screen>&prompt.root; <userinput>cp /var/tmp/root/dev/MAKEDEV /dev</userinput></screen> <indexterm> <primary><filename>MAKEDEV</filename></primary> </indexterm> <para> <filename>/etc</filename> を更新するのに &man.mergemaster.8; を使った場合, <filename>MAKEDEV</filename> スクリプトは既に更新 されているでしょうが, (&man.diff.1; を使って) チェックすることは無駄ではありませんし, 必要なら自分でコピーしてください. </para> </step> <step> <para> ここで, <filename>/dev</filename> のファイル一覧を記録しておきます. この一覧は, 各ファイルの許可属性, 所有者, メジャー番号, マイナー番号が 含まれている必要がありますが, タイムスタンプは含まれていてはいけません. これを行なう簡単な方法は, &man.awk.1; を使って, いくつかの情報を取り除くことです. </para> <screen>&prompt.root; <userinput>cd /dev</userinput> &prompt.root; <userinput>ls -l | awk '{print $1, $2, $3, $4, $5, $6, $NF}' > /var/tmp/dev.out</userinput></screen> </step> <step> <para>デバイスファイルをつくり直します. </para> <screen>&prompt.root; <userinput/sh MAKEDEV all/</screen> </step> <step> <para> もう一度, ディレクトリのファイル一覧を記録します. 今回は <filename>/var/tmp/dev2.out</filename> です. この段階で, この二つのファイル一覧を調べて 作成に失敗したデバイスを探して下さい. 違いは一つもないはずなのですが, 安全のために一応チェックして下さい. </para> <screen>&prompt.root; <userinput>diff /var/tmp/dev.out /var/tmp/dev2.out</userinput></screen> <para> 次のようなコマンドを使用し, ディスクスライスエントリを 再作成することで, ディスクスライスの矛盾を検出することができます. <screen>&prompt.root; <userinput>sh MAKEDEV sd0s1</userinput></screen> 適当な組み合わせは, 環境によって異なります. </para> </step> </procedure> </sect2> <sect2> <title><filename>/stand</filename> の更新</title> <note> <para> この段階は, 完全な更新を行なう場合にだけ必要な内容を含んでいます. 悪影響はありませんので, 省略しても構いません. </para> </note> <para> 完全な更新を行なうために, <filename>/stand</filename> にあるファイルも同じように 更新したいと考えるかも知れません. これらのファイルは, <filename>/stand/sysinstall</filename> という バイナリファイルへのハードリンクです. このバイナリファイルは, 他のファイルシステム(特に <filename>/usr</filename>)が マウントされていない場合にも動作できるよう, 静的にリンクされていなければなりません. </para> <screen>&prompt.root; <userinput>cd /usr/src/release/sysinstall</userinput> &prompt.root; <userinput>make all install</userinput></screen> </sect2> <sect2> <title>再起動</title> <para> これで, 作業はおしまいです. すべてがあるべき正しい場所に存在することをチェックしたら, システムを再起動します. これは, 単に &man.fastboot.8; を実行するだけです. </para> <screen>&prompt.root; <userinput>fastboot</userinput></screen> </sect2> <sect2> <title>作業の完了</title> <para> ここまで来れば, &os; システムのアップグレードは成功です. おめでとうございます. </para> <para>もしちょっとした問題があった場合でも, システムの一部を再構築するのは簡単です. たとえば, アップグレードの途中で誤って <filename>/etc/magic</filename> を削除して <filename>/etc</filename> にマージしてしまい, その結果 <command>file</command> コマンドが動作しなくなってしまったような場合を考えてみてください. これを修復するには, 次のコマンドを実行すれば修復することができます.</para> <screen>&prompt.root; <userinput>cd /usr/src/usr.bin/file</userinput> &prompt.root; <userinput/make all install/</screen> </sect2> <sect2> <title>質問ですか?</title> <qandaset> <qandaentry> <question> <para>変更が行なわれたら, その度にシステムの再構築が必要になるのでしょうか?</para> </question> <answer> <para> それは変更の性質によるので, なんとも言えません. 例えば, CVSup を実行したとき, 最後に実行したときから比べて 次にあげるようなファイルが更新されていたとします.</para> <screen><filename>src/games/cribbage/instr.c</filename> <filename>src/games/sail/pl_main.c</filename> <filename>src/release/sysinstall/config.c</filename> <filename>src/release/sysinstall/media.c</filename> <filename>src/share/mk/bsd.port.mk</filename></screen> <para> このときには, 改めてシステム全体を再構築する必要はないでしょう. 適切なサブディレクトリに移って <command>make all install</command> を行うだけで更新することができます. しかし, もし何らかの大きな変更が行なわれているとき, 例えば <filename>src/lib/libc/stdlib</filename> が変更されている場合には, システム全体を再構築するか, もしくはそのうち, 少なくとも静的にリンクされているもの(と, あなたが追加した 静的にリンクされたプログラム)を作り直す必要があります.</para> <para>結局のところ, どの時点で現在のシステムをアップグレードするかは あなたが決めることです. 2 週間ごとにシステムを再構築し, その 2 週間の変更を取り込めば 幸せかもしれませんし, 変更のあった部分だけ再構築し, 依存関係を確かめたいと考えるかも知れません. <!-- hrs:2000/02/15 What's "every fortnight say"? s/say/day/? --> </para> <para> もちろん, それらはどのくらいの頻度でアップグレードしたいか, そして &os.stable; か &os.current; のどちらを追いかけているのかによります. </para> </answer> </qandaentry> <qandaentry> <question> <para>signal 11(もしくは他のシグナル番号)のエラーがたくさん出て コンパイルが失敗します. 何が起こっているんでしょうか?</para> </question> <indexterm><primary>signal 11</primary></indexterm> <answer> <para>これは通常, ハードウェアに問題があることを示しています. システムの再構築は, ハードウェアに対する負荷耐久試験を行なうための 有効な手段の一つで, メモリに関係する問題がよく報告されます. その大部分は, コンパイラが奇妙なシグナルを受け取り, 不可解な異常終了となることで発見されます.</para> <para>本当にこの問題によるものかどうかは, 再構築をもう一度実行し, 異なる段階で異常終了が発生するか, ということから確認できます.</para> <para>この場合には, マシンの部品を交換して, どの部分が悪いのかを 調べてみることくらいしかできることはありません.</para> </answer> </qandaentry> <qandaentry> <question> <para>終了したら <filename>/usr/obj</filename> を削除しても かまいませんか?</para> </question> <answer> <para>一言で答えるなら「削除しても構わない」です.</para> <para><filename>/usr/obj</filename> には, コンパイルの段階で生成された すべてのオブジェクトファイルが含まれています. 通常 <quote/make world/ の最初の段階では, このディレクトリを削除して新しくつくり直すようになっています. その場合には, 構築終了後の <filename>/usr/obj</filename> を保存しておいても, あまり意味はありません. 削除すれば, 大きなディスクスペースを (現在はだいたい 340MB あります) 解放することができます. </para> <para> しかし, もしあなたが何を行なおうとしているのか理解しているなら, この段階を省略して <quote/make world/ を行なうことができます. こうすると, ほとんどのソースは再コンパイルされないため, 構築はかなり高速化されます. これは裏をかえせば, デリケートな依存関係の問題によって, システムの構築が奇妙な失敗に終わる可能性があるということです. &os; メーリングリストではしばしば, 構築の失敗が, この段階の省略によるものだということを理解せずに 不満の声をあげる人がいます.</para> <para>もし, このような危険を承知した上でシステムの再構築を行なう場合には, 次のように変数 <makevar>NOCLEAN</makevar> を定義して構築します.</para> <screen>&prompt.root; <userinput>make -DNOCLEAN world</userinput></screen> </answer> </qandaentry> <qandaentry> <question> <para>構築を中断した場合, その構築を途中から再開することはできますか?</para> </question> <answer> <para>それは, あなたが問題に気付く前に, どれだけの作業を終えているかによって変わります.</para> <para><emphasis>一般的に</emphasis> (そしてこれは確実でしっかりした 規則ではありませんが), <quote>make world</quote> の過程では, 基本的なツール ( &man.gcc.1;, や &man.make.1; のようなもの) や, システムライブラリの新しいコピーが作成されます. その後まず, これらのツールやライブラリはインストールされてから 自分自身の再構築に使われ, もう一度, インストールされます. 全体のシステム (ここでは &man.ls.1; や &man.grep.1; といった 標準的なユーザプログラムを含みます) は, その新しいシステムファイルを用いて作り直されることになります.</para> <para>もし, 再構築が最終段階に入っていること が(記録しておいた出力を見たりすることで)わかっていたら, (全く悪影響を与えることなく)次のようにすることができます.</para> <screen><emphasis>… fix the problem …</emphasis> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make -DNOCLEAN all</userinput></screen> <para> これは, 前回の <quote>make world</quote> の作業をやり直しません. </para> <para>次のメッセージ <screen>-------------------------------------------------------------- Building everything.. --------------------------------------------------------------</screen> が <quote>make world</quote> の出力にある場合には, 上のようにしてもほとんど悪影響が現れることはありません. </para> <para> もしこのメッセージがないとか, よく分からないという場合には, 安全を確保し, 後悔するようなことがないよう, システムの再構築を最初からやり直しましょう. </para> </answer> </qandaentry> <qandaentry> <question> <indexterm><primary>NFS</primary></indexterm> <para>あるマシンを <emphasis/マスタ/ として, 他の多くのマシンを (NFSで) アップグレードできますか?</para> </question> <answer> <para>この作業を行なうのは簡単で, たくさんのマシンをアップグレードする場合に時間を節約することができます. これには, 中心となるマシンで <maketarget>buildworld</maketarget> を実行し, 終了後にリモートマシンで <filename>/usr/src</filename> と <filename>/usr/obj</filename> を NFS マウントしてから, そこで <maketarget>installworld</maketarget> します.</para> </answer> </qandaentry> <qandaentry> <question> <para>どのようにすれば make world を高速化できますか?</para> </question> <answer> <itemizedlist> <listitem> <para>シングルユーザモードで動かしてください.</para> </listitem> <listitem> <para><filename>/usr/src</filename> と <filename>/usr/obj</filename> ディレクトリを, 異なるディスク上の別のファイルシステムに置いてください. また可能ならば, 異なるディスクコントローラに接続された ディスクを使って下さい. </para> </listitem> <listitem> <para>さらに高速化するには, これらのファイルシステムを &man.ccd.4; (連結ディスクドライバ) デバイスを 使って, 複数のディスク上に置いてください.</para> </listitem> <listitem> <para>プロファイル版の作成を無効化して下さい. (<filename>/etc/make.conf</filename> で <quote>NOPROFILE=true</quote> をセットします) 普通, それが必要になることはありません. </para> </listitem> <listitem> <para>また, <filename>/etc/make.conf</filename> の中の <makevar>CFLAGS</makevar> を, <quote>-O -pipe</quote> のように指定しましょう. <quote>-O2</quote> の最適化はさらに多くの時間を必要とし, しかも <quote>-O</quote> と <quote>-O2</quote> の 最適化には, ほとんど差はありません. <quote>-pipe</quote> を指定することで, コンパイラはテンポラリファイルの代わりにパイプを利用します. その結果, (メモリの利用は増えますが)ディスクアクセスが減ります. </para> </listitem> <listitem> <para>make に <option>-j<n></option> オプションを指定して, 複数のプロセスを並列に実行させてください. これはプロセッサが単一か複数かによらず, どちらも同様に恩恵を得ることができます.</para> </listitem> <listitem><para><filename>/usr/src</filename> のある ファイルシステムを, <option>noatime</option> オプションを付けてマウント(もしくは再マウント)してください. これは, そのファイルシステムにおいて, 最後にアクセスされた時刻の書き込みを抑制します. おそらく, この情報が必要になることはないでしょう.</para> <screen>&prompt.root; <userinput>mount -u -o noatime /usr/src</userinput></screen> <warning> <para>上の例は, <filename>/usr/src</filename> 自身が独立したファイルシステムで あることを想定しています. もしそうでないときには (例えば <filename>/usr</filename> の 一部である場合には), <filename>/usr/src</filename> ではなく 適切なマウントポイントを指定する必要があります. </para> </warning> </listitem> <listitem> <para><filename>/usr/obj</filename> のあるファイルシステムを, <quote>async</quote> オプションをつけてマウント (もしくは 再マウント) してください. これによって, ディスクへの書き込みが非同期になります. つまり, 書き込み命令はすぐに完了するのに対し, 実際にデータがディスクに書き込まれるのは, その数秒後になります. これによって, 書き込み処理の一括化が可能になるため, 劇的なパフォーマンスの向上が期待できます. <!-- hrs:2000/02/15 (for ja-translators) "be clusterd togather" is translated into "clusterization" --> </para> <warning> <para> このオプションを指定すると, ファイルシステムは 壊れやすくなってしまうことに注意してください. このオプションを付けていて, 突然電源が落ちた場合には, 再起動後にファイルシステムが復旧不能になる可能性が 非常に高くなります. </para> <para>もし, <filename>/usr/obj</filename> 自身が独立した ファイルシステムであるならば, これは問題になりません. しかし, 同じファイルシステムに, 他の貴重なデータを置いているときには, このオプションを有効にする前に, バックアップをきちんと取っておきましょう.</para> </warning> <screen>&prompt.root; <userinput>mount -u -o async /usr/obj</userinput></screen> <warning> <para>もし <filename>/usr/obj</filename> 自身が ファイルシステムでない場合には, 適切なマウントポイントを指すように, 上の例の名前を置き換えて下さい. </para> </warning> </listitem> </itemizedlist> </answer> </qandaentry> </qandaset> </sect2> </sect1> </chapter> <!-- Local Variables: mode: sgml sgml-declaration: "../chapter.decl" sgml-indent-data: t sgml-omittag: nil sgml-always-quote-attributes: t sgml-parent-document: ("../book.sgml" "part" "chapter") End: -->