2013.11.17
nvidia-driverで無駄にoptionsダイアログ画面が再表示される問題を追加。
Please read English summary if you need.
何かご質問がありましたら、
英語必須ですが、
The FreeBSD Forumsで私が立てるか投稿しているスレッドで、
私の投稿にReply下さい。
そちらにはT-Aokiで登録しています。
公開できるメールアドレスは対処しても対処してもコンスタントにSPAMで埋まっていますし、
ここの掲示板は一時期しつこい不正投稿が続いた関係で極度な広範囲の規制をかけざるを得ず、
巻き添えで書き込めない方が多い筈ですので...。
現在私のところでは発生していない問題がメインのPR(ports/186465)で事のついでに触れられている関係か、
絶賛放置中の問題ですね。
この問題、
1/31付のr342050とr342061より前には起きていなかったのですが、
地味〜に煩わしいため、
観念してPorter's Handbookのoptions関連部分とMakefileで読み込まれている*.mkを読んで対策してみました。
お困りの場合、
下記のリンク先からパッチなりMakefileなりをダウンロードして使用して下さい。
パッチの方は/usr/portsでsvnlite diff x11/nvidia-driver/Makefileした出力です。
修正済のMakefileもアップロードしてあるので無くて困るものではないと思いますが、
どう修正してあるかの覚えも兼ねて。
自分ではパッチ当てのテストはしていませんが、
もしbaseのpatchやportsのdevel/patchでダメなら、
10系以降ならsvnlite patch、
9系以前ならportsのdevel/subversionが入っていればsvn patchで行けるかと。
日常の運用ならportsnapでportsツリーを更新するのが楽なのかもしれませんが、
こういうトラブルがあった場合に特定ファイルだけ旧版に戻したり失敗した変更を無かったことにしたりと
試行錯誤するには本家へのコミット権限が無くてもsubversionを使って同期している方が楽。
特に10系以降では標準でsvnliteが入っているし、
FreeBSDのbaseやportsを扱うのに必要な機能は揃っているので便利です。
自分の覚えも兼ねて、
今回の修正点の要旨を。
というのが必須条件のようだったため、
違反していたbsd.port.options.mkの行とBROKEN判定のブロックをOK範囲へ移動。
一応、
私の環境ではこれで無駄なoptionsダイアログは出なくなりましたし、
意図的に/var/db/ports/x11_nvidia-driver/を削除したらその直後はきちんと
ダイアログが出ます。 ビルド・インストールも動作もOK。
但し、
前述のports/186465ではbuildkernel時に一緒にビルドし、
installkernel時に一緒にインストールするportsを/etc/src.confで指定する
"PORTS_MODULES="でnvidia-driverを設定した時のインストール失敗がメインのようですが、
私は問題が出た時に切り分けが面倒になりそうなので使っていないため、
そちらが直るかは一切検証していません。
この問題が直っていないからといってクレームを頂いても、
故障者の体力ではこれ以上は対応できませんのであしからず。
PR kern/182963に添付しておいたパッチがheadにはr257841としてFri Nov 8 08:44:10 UTC 2013付で、
stable/10にはr258123としてThu Nov 14 09:19:50 UTC 2013付で各々コミットされ、
PRもクローズされました。
現時点(Sun Nov 17 2013 JST)でreleng/10はまだできていないので、
この修正は無事10.0-RELEASEに取り込まれることになります。
少なくともstable/9以前で得られていた程度の安定性は期待できます。
よかった。
但し、
今日、
r258230でWITH_LIBICONV_COMPATオプションがstable/10からも削除されてしまいました。
元の更新がheadに入った当初はMFC時期が示されていなかったので、
stable/10には来ないと思って気にしていなかったのですが、
少なくとも、japanese/mozc-toolsのようにlibiconv.so.3が必要なportは、
headのみならずstable/10でもビルド不能に陥ります。
この問題についてはREチームメンバも認識しており、
freebsd-stable MLに投げたrevert要請に対して解決策を進めているとの回答がありましたが、
それが形になる(10.0-RELEASEに間に合うことを期待します...)までの間、
影響を受けるportをビルドするには、
src.confにWITHOUT_ICONV=YESを設定してbaseのiconvをビルドさせないようにした上でworld更新後に関連のヘッダとライブラリを削除してportsのlibiconvをインストールするしかありません。
portsのlibiconvでは/usr/include/iconv.hの有無でチェックしているだけなので、
これを削除して騙す手も無いわけではありませんが、
混在させるとどういう不具合が発生するか分かったものではありませんので...。
また、
この方法だと、
Dominic Fandrey氏がsend-prしているmount_smbfsのlibiconv問題対策ではWITHOUT_ICONV=YESに対応できない事への対策としてWITHOUT_ICONV=YESの場合にはmount_smbfsの-Eオプションそのものを無効にしてしまうという荒業とセットでMFCされてしまったため、
smb共有のマウント時のファイル名の文字コード変換が設定できなくなります。
そうするくらいなら、
「良いことより害のほうが多い」という「害」にハマらないことを期待しつつ、
r258230の直前版に留め置くか、
svnliteで更新を追いかけているのが前提ですが、
/usr/srcで
#svnlite diff -r 258212:258230
で見られる直前版ソースツリーとの差分をファイルに落としておいてsvnlite patch --reverse-diffに食わせて自力でrevertするかで何とかするしか無いでしょう。
但し、
ObsoleteFiles.incのように比較的頻繁に更新されるファイルはパッチ当てに失敗する事もありがちなので、
一部は手作業が必要になるかもしれませんので要注意。
なお、
どうやら現状iconv関係の問題は実質的なShow Stopper扱いで対策が進められているようで、
必要な情報をfreebsd-stable MLに投げると、
特定portsのビルド不能等、
分かっている人なら簡単に直せる問題だと速攻でパッチとともにテスト要請が出てきて、
1人のOK報告だけでも速攻でコミットされたりもします。
japanese/mozc-toolの件は物凄く早くて驚いた...。
一方、
回答と同報のiconv無関係の分は華麗にスルーされていますが。
iconvとlibc++については既にどう見ても「前進あるのみ」な状況ですので、
何かiconv絡み・libc++絡みの問題に遭遇した方は、
リリース後に後悔しないためにもfreebsd-stable MLかfreebsd-current MLに報告してあげて下さい。
ベストはsend-prで詳細(と、
もし分かっていれば対策も)を登録して履歴を残しつつ概要と付与されたPR番号(例えばkern/182963)をMLに報告、
という形ですが、
どちらか一方ならMLの方が気づいて貰い易いかと。
以下、
前回更新時までの内容。
まずは最終結論から。
私の手許で発生した挙動不審の根本原因は、
headのr255138でのsockbuf構造体のタイムアウト値sb_timeoが
calloutng絡みでsys/sys/time.hに導入されたsbintimeベース(sbintime_t型)に変わったことに、
sys/netsmb/smb_trantcp.cが追従しておらず、
hzを基準にした不正な値を設定してしまっていることでした。
64bits幅ビットフィールドの上32bitsを秒数,
下32bitsを1秒未満の端数に使って絶対値で時間を表現するデータ型に1/kern.hz秒
(つまり、
起動時点のkern.hzの設定次第で変わってしまう)
の整数倍で表現される時間を代入しようものならおかしくなって当然。
既にsend-prはしてあり、
kern/182963として登録はされていますが、
headではr257205、
stable/10ではr257187の時点では未だ動きがないため、
修正が取り込まれるまでは、
srcとworldが整合している前提で、
の「いずれか一方のみ」を行って、
buildkernel/installkernelしましょう。
両方やると逆の不整合を起こします。
前者は原因となった変更の切り戻し、
後者は変更への追従ですので。
影響範囲を考えると、
後者の対応が無難です。
もうひとつ。
stable/10とheadではデフォルトでiconvが入っていますが、
libiconvは入っていません。
そのため、
mount_smbfsで-Eオプションを使うなり.nsmbrcで設定するなりで文字コード変換をさせる場合、
マウント時に警告が出て(マウント自体はできる)、
コード変換も機能しません。
対策は、
/etc/src.confに以下の行を追加し、
buildworld/installworldすること。
WITH_LIBICONV_COMPAT=YES
これで、
あとは従来9系以前で使っていた設定を行えばファイル名の変換は機能するかと思います。
2013.10.23付でconverters/libiconvに修正が入り、
worldがWITHOUT_ICONVを設定して再構築されていればインストールできるようになったので、
その方法でも機能するかもしれませんが、
私は既に先述の方法で対処してしまっていたので試していません。
こちらの方法は、
9系以前からソースベースで更新する場合にはベストかもしれませんが、
新規での10系インストールの場合、
恐らく手作業でiconv系のライブラリを削除する必要があるでしょう。
libiconv問題については、
Dominic Fandrey氏が別の対応法をsend-prしていますが、
こちらも試していません。
これも未だ動きなし。
さて。
それでは上記結論に至った経緯を。
既に当初発表から一部変更されていますが、
10.0-RELEASEのスケジュールが出ています。
となれば、
「最新のstableブランチを使う」ポリシーの私は遅かれ早かれ移行することになる訳ですが、
メジャーバージョンが上がる場合のパターンで遅れて
11月下旬〜12月上旬あたりになれば本家のSubversionリポジトリにstable/10ができるだろうから、
年末年始辺りで移行かな、
と思っていました。
当初は。
が、
その後続々とALPHAが出てくるので、
試しにALPHA5のmemstickイメージをダウンロード・書込して起動してみたら、
とりあえずThinkPad T420での起動は問題なさ気。
と。
ここで、
どういう訳か突然、
headでNon-MPSAFEなファイルシステム切り捨てで、
smbfsが一時的に切られて復活した経緯があるのを思い出してしまい、
HDD起動後にマウントしてしまえば/etcやら/rootやら弄れるのをいいことに、
常用の環境から最低限のfstabやら.nsmbrcやらを移植して試してみたら...
ファイル数個のディレクトリの表示やその中の1kB程度のファイルの表示なら問題ないものの、
ファイル数/ディレクトリ数の合計100個程度のディレクトリのlsですらトラブル発生。
なにせ、
という有り様。
その時点ではまだstable/10はブランチしていなかったのでsvnwebでheadの
sys/fs/smbfs以下と/sys/netsmb以下の最新更新を調べたら、
各々
なので、
どちらかが原因だろうと軽く考えて、
r254627の前後とr255219の前後の挙動を見れば特定できるだろ、
とVirtualBoxの仮想マシンに10-ALPHA5をsrc抜きでインストールし、
ネットワーク設定はブリッジにしておいて手持ちのNASに接続するための最少設定。
問題の再発を確認した上で既にheadでは標準で入っているsvnliteでsrc取得、
まずはr254627の直前から順次トライ。
CPUとメモリのリソースを限定しても物理的に1台しか無いHDDのI/Oでホスト側まで重くなりはするものの、
基本的にホスト側を使いながらトライできるので、
OSの蟲探しにVMは楽なのを実感。
こんな日が来ることになるとは思ってもいなかった...。
そこまででの結論。
をや?
想定と違う。
どっちもシロだ!
とはいえ、
能力的にもぶっ壊れている体力的にも、
その間のあらゆる変更をチェックするなんて無理。
というわけで、
vfsかvmかsocketの変更に当たりをつけ、
svn-src-head MLのアーカイブで両リビジョンの間の変更から臭そうなのをピックアップ、
直前とズバリでの地道な挟み撃ちテストの結果、
冒頭のリビジョンにぶち当たったという訳。
なにしろビルド中は寝込んでいてもOKだし、
確実に症状の出るディレクトリは分かっているから、
NGのテストはNASをマウント(これは再発時でもほぼ確実に成功)してそこをlsするだけの簡単なお仕事。
で、
冒頭のリビジョンを特定するに至った訳です。
PC任せでビルドしている時間が圧倒的に長く、
地味〜に日数がかかっている間にstable/10がブランチしてしまう、
という想定外の事態があったため、
RELEASEで直ってなかったらマズイよな、
という訳で急遽そちらでも再発することを確認し、
同じ修正で機能することをポカよけで確認し、
誰か確認してsend-prしてくれろ、
とThe FreeBSD Forumsにスレッドを作成したら、
wblock@に振り返されてしまったので初めてのsend-pr。
ちなみに、 sb_timeoをsrc全体でgrepすると、 例えばusb_timeout_tのような明らかな過剰検出とドキュメントを除けば引っかかるのは
だけで、
最初の4つはr255138での変更箇所、
5つ目は私のdiffでの修正対象の箇所なので、
他に直接影響を受けるのは最後の1つだけ。
で、
これは単純なコピーをしているだけなので、
どちらの修正方法を採っても実質的な影響は無さげ。
但し、
どうやらkernel内部の時間関係はsbintime系に移行する方向のようだし、
r255138での変更の趣旨はタイムアウトの精度向上
(Fix socket buffer timeouts precision)
ということなので、
そこを戻すよりは未対応の部分を直す方が建設的ではあります。
なお、
私のdiffで使っているSBT_1Sというのは
sys/sys/time.hで定義されているマクロで、
sbintime形式での1秒です。
そんなのsys/netsmb/smb_trantcp.cでは#includeされてないぞ、
という方、
ちゃんとビルドは通って動作もしていますし、
sys/sys/param.hかsys/sys/proc.hのどちらか経由で#includeされているようです。
元のコードで使われているhzは「1秒間にhz回」のclock frequency周期が設定される変数なので、
時間単位としてhzを使うのは1秒という単位を設定する目的の筈、
ということで、
係数の是非は別として実態を新しい形式に合わせただけです。
せっかくVMを仕立てたのでportsからいくつかインストールしてみましたが、
現状で試した範囲内でダメだったのは、
がビルドに失敗、
がインストールまで可能なもののpkgng非対応で機能しません。
これ、
dialogベースで対象を選択できる上に、
削除で新たに末端になったものも連鎖的に削除できて楽チンなんですが...。
ports-mgmt/pkg_cutleavesはpkgng対応ですが、
1個々々対応を聞いてきて面倒で。
逆に大丈夫だったのが
です。
xfce4は最少限の構成で、
xorgのビデオドライバはVESAだけでのインストールですが。
2013.11.03追記
security/clamavについてはports/183331のRainer Hurling氏のパッチで問題解決を確認。
但し、
メンテナにassignされてはいるものの、
これを書いている時点ではまだportsツリーに入っていません。
security/clamav-develでは試していませんが、
発生するエラーは同じだったので、
同じ修正でいけると思います。
japanese/mozc-*については、
エラーメッセージから当たりをつけてjapanese/mozc-server/files/patch-base_compiler_specific.hを削除したらOK。
正確には、
このファイルの中の以下の行が致命的に悪さをしているため、
この行をその次の行と同様に直してしまえばビルドは通って動作もOKです。
+#define unique_ptr auto_ptr
但し、
9系以前では必要なパッチなので、
portsツリーに修正を取り込むためには、
ビルド時の環境によってこのパッチの適用要否を判定する必要があります。
テスト環境を構築していないので確認はしていませんが、
10系以降でもgcc4.2.1 + libstdc++の環境ではこのパッチが必要な可能性が濃厚だと思いますので、
clang + libc++の環境がデフォルトになった${OSVERSION}の1000054を境界値として判定するのは恐らく不適切です。
この部分の適切な対応が分からないため、
現時点ではsend-prしていません。
The FreeBSD Forumsにスレッド立てても結局send-prよろ、
となるんだろうな...。
上記を書いてアップロードした数時間後、
japanese/mozc-serverに更新(r332611)が入り、
STAGEサポートと同時に上記不具合の対策もされました。
stable/10環境のVMで私が使っている範囲のものは直っているのを確認。
見たところ、
MakefileはSTAGEサポートの更新だけで、
パッチの方で条件判断を入れて対応してあるようです。
今回問題の原因になったunique_ptrの定義は完全に削除され、
もう一方(残っていてもwarningが出るだけ)のstatic_assert(a,b)だけ未定義なら定義するようになっています。
japanese/mozc-serverは他のmozc-*のマスターになっているので、
本家が現在のmozcに対応していないfcitx-mozc以外は大丈夫と思います。
他、
新たに確認したものとして、
www/chromiumがビルドは通ってインポートしたブックマークからブラウズする分には正常なのですが、
検索バーに何か入力しようとするとコア吐いて落ちます。
試しにgcc46でのビルドに切り替えてみたら、
こちらは起動途中でコア吐いて落ちるので状況悪化。
原因は...どこから手を付けていいやら分からないので追求する気力も体力もありません。
誰かお願い...
...と書いていたのですが、
たまたまFirefoxのブックマークをインポートしていない状態だとこの問題が発生しないのを発見。
一旦インポートしてしまっていても、
ブックマークバーのFirefoxブックマークのアイコン右クリックから削除してしまえば直ります。
gccでのビルドはやり直していないのでテストしていませんし、
鬱陶しい対処法ではありますが、
本家なりports側なりで修正されるまでは、
ブックマークからのアクセスをしたい時だけインポートして使ったら即外す、
という運用で緊急対応はできそうです。
Chromiumはアドレスバー(検索バーというべきか?)に何かタイプすると履歴やらブックマークやらを参照して補完しようとするので、
この機能からインポートしたFirefoxブックマークにアクセスする部分に問題があるのだと思いますが、
多少は慣れもあるFreeBSDのbaseならともかく、
巨大で構造を理解できていない(しかもportsの依存関係まである)Chromiumのソースを調べるのは体力的にも能力的にも無理...。
ビルド不能ならエラーメッセージを手がかりに対策を発見できることもありますが、
coreからトレースなんて...。
2013.11.24更新
Mon Nov 18 16:02:34 2013 UTC付でwww/chromiumが31.0.1650.57に更新されました。
私はheadをWed Nov 20 12:48:34 2013 UTC付のUSES=compiler絡みの追加更新が入る前の段階で、
stable/10はその後の段階で更新しましたが、
いずれも試した範囲では直っているようです。
これで面倒な対処法は不要。
buildworld中は寝ていられるとはいえ、
体調の大崩れしたタイミングでこれは勘弁してほしい。
stableブランチなのに...というのは置いといて。
この問題、
問題の範囲のリビジョンに更新する時点では気づきようがありません。
なにせ、
buildworld後、
インストールされていない作りたてのtoolchainを使う筈のbuildkernelが成功してしまうので。
が。
installworldした後、
次のソース更新・buildworldの時、
そいつが牙を剥きます。
有り体に言うと原因はr254626でのyacc更新なのですが、
上記期間のソースツリーで構築されたworldではbuildworldが不可能です。
この問題にハマってしまったら、
とりあえずソースツリーをr254649以降に更新し、
buildworldの前に
/usr/src/usr.bin/yacc
で
make ; make install clean
しましょう。
後は通常どおり/usr/srcでbuildworld以降の処理を進めればOK。
なお、
私は/usr/src/usr.bin/yaccを
svn update -r 225736 /usr/src/usr.bin/yacc
で前のリビジョンに戻して
make ; make install clean
してから改めて
svn update /usr/src
でソースツリーを最新に更新しなおしてbuildworldしましたが、
後でsvnwebでログを見てみたら、
r254649では単純にr254626での変更を元に戻しているだけでしたので、
先に書いた方法で充分な筈ですし、
ソースツリーの更新をsvnでなくsvnupでやっていても大丈夫。
2013.09.01追記
Thu Aug 29 09:33:12 UTC 2013付のr255017で、
stable/9に、
PMBR上のGPTスライス(Partition ID=0xEE)にへのactiveフラグ設定をデフォルトで無しとし、
後からgpartコマンドで設定/解除できる仕組みがMFCされました。
コミットログ記載の方法だけでは使用中のドライブの設定を変更することはできませんが、
sysctlコマンドでとあるgeomデバッグ用のtunableにそのための値を設定して制限を解除すればOK。
解除したままだと
(FreeBSDで感染動作が可能かどうかは別として)
ブートセクタ感染型ウィルスへの感染リスクが無くはないし、
何をしているかがよく分かっていないままでブートセクタを操作出来てしまうのも危険なので、
具体的なやり方は自分で探してよく理解して頂くとして、
たぶん、
似たような問題を抱えていた機種の多くで問題が解消できることでしょう。
しかし、
残念ながら、
私のThinkPad T420 (UEFI BIOSバージョン1.36)では、
Chris Torek氏の方法でのProtectiveMBR上でGPTの位置移動をしないと起動できないことを、
例によってのUSBメモリで9.0-BETA3のmemstick.imgを使っての実験で検証しました。 残念。
なお、
ダミーにする1個目のスライスはactiveでもactiveでなくても支障ありませんでしたので、
(or実績の報告されていないバージョンのUEFI BIOSでインストールしたくない等)
何らかの事情でこのバグ持ちバージョンのUEFI BIOSでThu Aug 29 09:33:12 UTC 2013以降のstable/9のスナップショットを新規インストールする場合、
わざわざactiveフラグを設定する必要もありません。
これまで、
The FreeBSD Forumsの投稿(October 7th, 2011, 04:31付の#2)の情報を基に、
ProtectiveMBRでのPartition IDを変更する方法をご紹介してきましたが、
別法としてfreebsd-i386 MLへのChris Torek氏の投稿でトリッキーながらパッチ不要なやり方が紹介されているのを見つけました。
例によってUSBメモリで9.0-BETA3のmemstick.imgを使って実験してみたところ、
ジオメトリ関係の数字を実態に合わせる以外【完全に指示どおり】に作業すれば成功します。
作業内容自体が合っていれば、
警告は無視。
但し、
この作業をしてしまったUSBメモリをsysutils/gdiskのcgdiskで見ようとすると、
エラーで拒否されました。
となると、
他のOSの標準パーティション管理ソフトでダメなものがあっても不思議ではありません。
FreeBSD標準のfdiskやgpartは大丈夫なようですし、
Gnome3なりMateなりがPortsに入った時用に確保してあった新品HDDにvermaden氏の方法をベースにZFS Root環境を作って試してみたところ、
zpoolでのpool作成もzfsでのパーティション操作もできました。
仮設とはいえSwapはZFS pool内でなく独立して作った等、微妙な違いはありますが...。
今どきのドライブで本番ZFS環境を作るなら、
例えば佐藤広生氏の2011年9月3日付記事にあるgnopを使った方法でアライメント合わせをしておいた方がいいかと。
さて。
話を戻すと、
実働マシンでのパーティション操作は危険なので、
具体的な方法は原文(英語)をよ〜〜〜く読んで充分理解して頂くとして、
読んでみると「これじゃダメなの?」と思うような部分を補足しておきます。
例えば原文の例ズバリのドライブで全く同じ作業を行ったとすると、
作業後に再びfdisk -p $diskを実行したら、
# /dev/ada0
g c969021 h16 s63
p 2 0xee 1 976773167
のように表示されるからといって、
gの行を調整しないまま書き込むと、
同様に作業後にfdisk -p $diskを実行したら、
# /dev/ada0
g c969021 h16 s63
p 2 0xee 64 976773167
のように、
開始セクタがズレて悲惨なことになります。
また、
p 1の行が表示されないことから
(元々存在しない)
2つ目のパーティションをID 0のActiveにすればいいようにも思えますが、
試したところこれではダメでした。
fdisk $diskで見ると、
ここだけは都合上/dev/da0として見えるUSBメモリに9.0-BETA3のmemstick.imgを書き込んだものを使った例ですが、
******* Working on device /dev/da0 *******
parameters extracted from in-core disklabel are:
cylinders=243 heads=255 sectors/track=63 (16065 blks/cyl)
parameters to be used for BIOS calculations are:
cylinders=243 heads=255 sectors/track=63 (16065 blks/cyl)
Media sector size is 512
Warning: BIOS sector numbering starts with sector 1
Information from DOS bootblock is:
The data for partition 1 is:
sysid 238 (0xee),(EFI GPT)
start 1, size 1096244 (535 Meg), flag 0
beg: cyl 0/ head 1/ sector 1;
end: cyl 202/ head 254/ sector 1
The data for partition 2 is:
sysid 0 (0000),(unused)
start 0, size 0 (0 Meg), flag 80 (active)
beg: cyl 0/ head 0/ sector 0;
end: cyl 0/ head 0/ sector 0
The data for partition 3 is:
The data for partition 4 is:
となっており、
狙いどおり2つめの未使用エントリがActiveになっているのですが...。
これでうまくいってくれれば弊害も出難くなりそうですが。
また、
別途、
The FreeBSD Forumsの投稿(March 31st, 2013, 15:23付の#12)で、
darcsis氏からT430だとOKという報告が出ており、
freebsd-fs MLへのAlexandr氏のJul 4 10:42:32 UTC 2013付投稿でも、
ThinkPad E530で半年前のBIOSではダメだったが2.52 from 04/23/2013で大丈夫になったという報告があり、
T420用でも既に数バージョンの更新があったため、
最新のBIOSでは問題が解消されているかもしれません。
ただ、
BIOS更新にはそれまで起動できていたものが起動できなくなるリスクがつきまとうため、
次の1台を買う算段が付いていない現状で踏み切る覚悟が...。
なお、
Chris Torek氏の方法のメリットはFreeBSD自体には全く手を加える必要がないことですが、
その一方で、
技術的には【あえて異常なProtectiveMBRを作る】ものですので、
最悪の場合もFreeBSDのfdiskで復旧させることは可能なものの、
OSやパーティション管理ツールによってはMBR形式・GPT形式のどちらとしても操作不能になるリスクがあります。
対して、
私の方法はその逆で、
ProtectiveMBRもGPTも【構造は】正常なままですが、
少なくともFreeBSDではloaderの改造が必須です。
FreeBSDだけで使う上ではChris Torek氏の方法がベターとは思いますが、
FreeBSDで使っていた起動ドライブを他のマシン・OSに流用したい場合等に対処不能になる恐れがあること、
(私は試していませんしFreeBSD標準ではGPTだと非対応ですが)
マルチOS環境を構築したい場合の他OSとの相性でどちらがいいかがケースバイケースであることより、
私の方法も下にそのまま残しておきます。
2013.02.18付でstable/9ブランチにApple Boot Campサポートがr246938としてMFCされ、
/usr/src/sys/boot/common/part.cが更新されました。
とはいえ、
変更箇所は下記のパッチに影響ない箇所なので問題なく当たりますし、
正常にブートできますので、
慌てる必要はありません。
少なくともソースツリーの更新にsvnを使っているなら、
既に下記のパッチを当ててあっても、自動で善きに計らってマージしてくれる筈です。
単に該当ファイルの更新時、
更新表示の行頭が通常の「U」でなく「G」になるだけです。
2013.02.24更新: loader関係の記述について、重要な追加情報
私が私物のメーカ製PC (ThinkPad等、
Windozeがプレインストールされていない選択肢が無いもの)
を購入して何より最初にやるのは、
WindozeがプレインストールされたHDDを交換することです。
ということは、
過去に色々なOSをインストールして味見していた初号機を除き、
Windozeがインストールされた環境が存在しない訳で、
その初号機も現状ハードウェア障害を直すために分解する体力が無いため不稼働状態です。
何が言いたいかといえば、
GPTでのテスト環境になっている2.5inch HDDはFreeBSDオンリーの状態のため、
GPTスライス全体のダミーパーティションIDを変えた場合に他のOSが起動できるかどうかは、
私は全くテストしていないということです。
GPTスライス全体のダミーパーティションIDを変えた場合、
そのHDDから他のOSを起動できなくなる恐れがありますので、
マルチOS環境でトライする場合はその点もくれぐれもご注意下さい。
まずは、
同じLenovo UEFI BIOS機でも、
MBR形式で分割されたドライブのBSDスライスから起動するのであれば、
下記の修正は不要です。
下記に沿ってProtective MBR上のGPTスライスのパーティションIDを
変更し、
普通ではないGPT形式になったドライブでも、
一旦FreeBSDカーネルが動き出してしまえば
(少なくとも私の環境では)
GEOM階層で何食わぬ顔で認識してくれ、
例えば/dev/ada1p3のようにデバイスノードが生えて、
マウントもできます。
現時点で問題があるのは、
あくまでGPT形式で分割されたドライブから起動する時だけです。
その問題のある状況に(少なくとも以前私がダウンロードして試した9.0-BETA3の場合)
公式memstick.imgで作ったUSBメモリ版インストールメディアが含まれるのが問題ですが。
結局、
Lenovo UEFI-BIOS搭載機でクリーンインストールする場合に無難なのは、
isoファイルから焼いたCDなりDVDなりのインストールディスクを使い、
(9系のインストーラではデフォルトでありませんが)
容量やスライス数等の問題が無ければMBR形式を選んでおくことです。
下記の修正はFreeBSD 9-STABLE(時期により9.x-PRERELEASE)を前提としています。
8.xやそれ以前、
及びCurrentブランチでは一切確認していませんので、
ご注意下さい。
2012.11.18付のr243243で、9-STABLEブランチのローダ周りに一括大量MFCがあり、
これを境にGPTパーティションの探し方が変わってしまいました。
これ以降は【r243243以降の場合】を、
それより前の場合は【従来の方法(既報)】をご参照下さい。
なお、
2012.11.30付で9.1-Releaseのビルド準備が整ったようですが、
svnwebで見たところ問題の変更は取り込まれていないため、
9.1-Releaseでは【従来の方法(既報)】でご対応下さい。
いずれの場合も、
「現時点で正常に起動できているloader」がある方は、
下記対応を行う前に修正前の/boot/loaderをバックアップしておいて下さい。
ルートパーティション内のどこかでinstallworldで上書きされないところがお薦め。
例えば、
rootのホームディレクトリがルートパーティション内だったらその中など。
何はさておき、
まずはコードの修正箇所。
svn diff /usr/src/sys/boot/common/part.c
Index: sys/boot/common/part.c
===================================================================
--- sys/boot/common/part.c (revision 243669)
+++ sys/boot/common/part.c (working copy)
@@ -634,7 +634,16 @@
break;
}
#ifdef LOADER_GPT_SUPPORT
- if (dp[i].dp_typ == DOSPTYP_PMBR) {
+
+/*
+ * Quick hack for Lenovo UEFI BIOS because it cannot boot from freebsd-boot
+ * partition in GPT slice having partition ID 0xee, but 0xef.
+ * Intentionally put magic No. here, because defining symbol in sys/diskmbr.h
+ * could have possibility of side effect to sbin/fdisk, usr/sbin/boot0cfg,
+ * usr/lib/libdisk.a, lib/geom/part.so because they include it.
+ */
+
+ if (dp[i].dp_typ == DOSPTYP_PMBR || dp[i].dp_typ == 0xef) {
table->type = PTABLE_GPT;
DEBUG("PMBR detected");
}
何故こんな小細工が必要か、
等の細かな情報は【従来の方法(既報)】の方をご覧頂くとして、
この節ではFreeBSDソースコードの修正箇所について記載します。
r243243の一括MFCで、
loaderでのスライス/パーティション認識方法が変更されました。
従来は3つのファイルで各1箇所、
Protective MBR上でのパーティションID(本来0xee)をマジックナンバとして決め打ちして
GPTスライス
(GPTパーティションを収容するブロック全体)
を認識するコードを含んでいたのですが、
この変更でパーティション関係の処理が/usr/src/sys/boot/common/part.cに集約されました。
で、
このpart.cの中では問題のマジックナンバが出て来ず、
それどころか、
このMFCで更新されたどのファイルにも出て来ません。
かといって、
体を壊している現状ではincludeしているファイルまで含めて丹念に読み込むなんて無理。
自分で開発する訳ではないからと統合開発環境の類は避けて通っていましたが、
軽くググってなるべく依存物の少なそうでportsにあるのを探し、
devel/sourcenavを使ってみることに。
/usr/src/sys/boot以下をホームディレクトリにコピーして取り込ませ、
関数名からいくつか当たりをつけて該当部分に飛んでみつつ、
眺めてみたら上記の部分を発見。
DOSPTYP_PMBRを定義している部分は見当たらなかったので、
どう見てもヘッダファイルだろ、
と取り込んでいない/usr/src/includeと/usr/src/sys/sysでgrepしてみたら、
/usr/src/sys/sys/diskmbr.hに
#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */
を発見。
本来ならこのあたりに例えば
#define DOSPTYP_PMBR_L 0xef /* quirks: GPT Protective MBR for Lenovo UEFI*/
のように定義を追加して、
それを使うべきところですが、
たぶん大丈夫とはいえ、
他にもincludeしているファイルのあるヘッダファイルを弄って副作用が出ても困るし、
かといってあえてpart.c内で定義して万一後から本家との名前のバッティングが出るのも困るし、
他の名前の長さを見るとDOSTYP_PMBR_LENOVO_UEFIだと
(FreeBSDでのコーディング規則は確認していませんが)長すぎるようだし、
という訳で、
あえてpart.c内部でマジックナンバを使っての修正に逃げるヘタレな私。
ここまでが私のフォローできる限界です。
もしどなたかsendprして頂けるなら、
diskmbr.hに定義を追加するパターンでpart.cでのマジックナンバ使用を避け、
少なくともbaseの中でdiskmbr.hをincludeしている他のコードで問題が出ないことを確認してから
送らないと無視or拒絶されそうな気が。
なにせ、
ただでさえLenovoのUEFI-BIOSの異常な仕様に対応するためのquirksなので...。
使う立場としては、
gpartで実際にドライブにGPT関係の情報を書き込む直前、
「Lenovo UEFI BIOSはGPT領域のIDに異常なものを要求する。
対応するか?[no]」
のような趣旨のデフォルト「no」の警告を出して、
あえて「yes」の回答をした場合には0xeeのかわりに0xefを使ってくれるようになると嬉しい。
私はそこまで直す根性も体力もありませんが...。
ちなみに、
installworldでloaderだけ入れ替わった状態でも、
pmbrとgptboot
(私の環境ではgptzfsbootは試せません) を新しいものに書き換えた状態でも、
いずれにせよGPTパーティションからは起動せず、
念のため残してあった後述の9.0-BETA3実験用のUSBメモリで起動しなおして
loaderだけバックアップから上書きしたら起動するようになったので、
pmbrやgptbootは更新してもしなくても影響無さそうです。
但し、
少なくともgpartで更新するとせっかくfdiskで強制的に0xefに変更して
Lenovo UEFI-BIOSに見つけて貰えるようにしたProtective MBR上の
GPTスライスのパーティションIDが0xeeに戻されてしまうのでご注意を。
図らずも、
今回の件で、
pmbrやgptbootは素のままでも問題無さそうな
(私の修正の影響範囲がloaderだけなのかgptbootやgptzfsbootまで及ぶのかを
追いかけていなかったのですが、
loader限定だったらしい)ことが判明しました。
普通にgpartでパーティショニングしてインストールしても、
少なくともThinkPad T420(4177-CTO)ではFreeBSDを起動できない。
9.0-ReleaseのDisk1でインストーラ経由だろうと、
8-STABLE環境等でgpartのman等を見ながら手作業でパーティショニングし、
インストーラでそこを選んでやっても同じこと。
原因は、
FreeBSD側ではなく、
ThinkPadのUEFI BIOS側にあります。
何らかの理由でMBR形式しかサポートしていないマシンにGPT形式で
パーティショニングされたドライブを接続された時に空っぽだと誤認されないため、
GPT形式のパーティションを収めた領域全体にはダミーで
MBR形式互換でパーティションID 0xEEを設定することになっており、
FreeBSDのgpartもそれに従っている訳ですが、
ThinkPadのUEFI BIOSはパーティションIDが0xEEのパーティションを始動可能な
ものとして認識してくれないようです。
BIOS設定でUEFIにしようがLegacyにしようがダメ。
でもDisk1 CDからのブートは可能。
今のところ2.5"ドライブではMBR形式でも困らない容量しか無いし、
MBR形式ならLegacyでなら始動できるのは先代T61のDisk to DiskバックアップのHDDを
繋いでのテストで確認できたので、
この問題は放置してMBRで仕切りなおしてもよかったのですが、
問題のT420納品前から休日に少しずつ環境構築し、
届いたらWindozeのプリインストールされたHDDに通電することなく入れ替えて
すぐ使えるようにしてあったつもりのHDDが半ばお遊びでGPTにしてあり、
T61では問題なく始動できていたので、
いろいろ探ってみたところ、The FreeBSD Forumsの投稿に重要なヒント を発見。
リンク先のスレッドでOctober 7th, 2011, 04:31付の#2。
もちろん、
そのままではFreeBSDのGPT用ローダは本来あるべきパーティションIDが0xEEの
パーティションしかGPT用として認識してくれません。
挫折しかけましたが、
考えてみればローダのサイズは限られているし、
関係するソースも全部/usr/src/sys/boot以下に揃っている。
アセンブリ言語やC++の部分だとキツいが、
要修正箇所がC言語部分だけなら何とかなるかも。
試しにパーティションIDを1つずらして0xEFにしてみようとローダ関係のソース内の
0xeeをgrepで探し、
それっぽい箇所を特定したら、
幸いi386に関係しそうなのはC言語部分だけで、
しかも3箇所のみ。
ここを下記のように0xefも取り扱うように修正してリビルド、
gpartのmanに従ってpmbrとgptbootをあるべきところに書き込んだ上でfdiskで
強制的にパーティションIDを0xeeから0xefに書換え。
これで無事ローダのメニューに辿り着けた。
ウチはPC Doctor等、
Lenovo提供のツール類が必要になる状況があり、
展開にONLY_FOR_ARCHS= i386なWineが必要になることがあるのでi386環境のため、
pc98やia64等特有の部分はノーチェックなのであしからず。
amd64はkernelに制御を移す瀬戸際まではi386と共通の筈。
たぶん、
GPTを扱う各アーキティクチャ用に同じような部分があると思います。
diff /usr/src/sys/boot/common/disk.c.orig /usr/src/sys/boot/common/disk.c
536a537,538
> else if (dp[i].dp_typ == 0xef)
> part++;
diff /usr/src/sys/boot/i386/libi386/biosdisk.c.orig /usr/src/sys/boot/i386/libi386/biosdisk.c
885a886,887
> else if (dp[i].dp_typ == 0xef)
> part++;
diff /usr/src/sys/boot/uboot/lib/disk.c.orig /usr/src/sys/boot/uboot/lib/disk.c
275a276,277
> else if (dp[i].dp_typ == 0xef)
> part += 1;
3つめはUSB始動用っぽいので、HDD用では当てなくても大丈夫かもしれません。
USBメモリでは試してもいないのでこの変更で機能するのかどうかも不明。
MLはWebのアーカイブで気になる分を拾い読みしているだけですが、
未だに今どきのThinkPadで起動できないという悲鳴が上がっていて的はずれな回答しか出ていないのを見ると、
(何をどう直せばいいかが書かれていないからかもしれませんが)
英語圏でさえせっかくThe FreeBSD Forumsにあるヒントが活かされていない模様。
現状、
MLもForumも登録していないし、
体を壊したままだし、
質問を貰ってもやり取りしている余裕がない可能性大のため、
誰かこれ見て分かる人が情報提供してあげてくれることを期待しつつ...。
2012.4.29追記:
ダウンロードだけして放置してあった9.0-BETA3のmemstick.imgをUSBメモリに書き込んで
試してみました。
そのままでは内蔵HDD同様始動できませんが、
上記の修正を加えてビルドした9-STABLEのpmbr,
gptbootをgpartで上書きし、
パーティションIDで書き換えた...だけではloaderのメニューに辿りつけない。
ふと気がついて、
マウントしてloaderを上書きしてやったら無事USBメモリからも起動できるように。
今まではT61でHDDを差し替え、
installworldしていたので、
その過程で(ドライブ先頭やパーティション先頭のpmbrやgptbootと違って)
loaderは毎度入れ替わっていたから意識していませんでした。
2012.12.15追記:
2012.11.18付のr243243の一件で、
パーティションID変更とloaderの対策版への入替えだけで対策できてしまう
(PMBRやgptbootの入替えは不要な)
ことが判明したため、
アナウンスは未だ出ていないものの9.1-RELEASEのISO各種がアップロードされたこともあり、
早速試そうと思ったら...。
FreeBSD-9.1-RELEASE-i386-memstick.imgを書き込んだUSBメモリはGPTでなくなっている!
おや?
と思って手許にダウンロードだけはしてあった9.0-RC3と9.0-RELEASEでも試したら、
いずれもGPTでない。
9.0-BETA1〜BETA2, 9.0-RC1〜RC2は手許に無いので不明なものの、
FreeBSD-9.0-BETA3-i386-memstick.imgはテストベッドとして貴重かもしれません。
改めてこれを書き込み、
そのままでは起動できないのを再確認した上で、
/boot/loaderだけをビルド済の対策版に入替え、
パーティションIDをfdiskで強制的に0xef(239)に書換え。
くどいようですが、
自分がやっている操作が何を意味するのかが充分理解できていないと非常に危険なため、
具体的なfdiskの操作方法は記載しません。
r243243前のloaderでも以後のloaderでも、
私のThinkPad T420は起動できました。
UEFIなThinkPadへのGPTパーティションでの始動をクリアしたとしても、
罠がもうひとつ。
開発者は別として、
普通にユーザとして使う分には、
今どきのPCのメモリ容量ならGENERICカーネルに組み込まれているドライバを
削る必要性は薄いものの、
種々デバッグ機能はCPU負荷まで増えてしまい、
何かと重量化していくブラウザその他アプリケーションにも影響しがち。
上述の環境構築時点では9.0もRelease前だったためGENERICでもデバッグ機能が
ほぼ全部有効な状態で、
ウチでもデバッグ機能を無効化したカーネルを構築して使っていた訳です。
通常はそれでも何の問題もなく、
T61では「.0リリース」とは思えない安定性で問題なく機能していたの、
です、
が。
上述の問題を解決し、
普通に起動しようとしたら、
カーネルの初期化途中でハングアップ。
initに辿り着くどころかpanicも起こさずハング。
試しにローダのメニューからACPIを無効にして起動すると、
起動はする。
但し、
CPUコアの認識すらACPI経由の模様で、
デュアルコア(HTTを有効にすれば見かけ上クアッドコア)のi7なのに、
常に全開稼働するシングルコアCPUとしてしか機能しない。orz
上述のThe FreeBSD ForumsのスレッドでOctober 7th, 2011, 06:27付の#4を参考に下記の修正を加えてリビルドしたカーネルを試すも変わらず。orz
diff /usr/src/sys/dev/acpi_support/acpi_ibm.c.orig /usr/src/sys/dev/acpi_support/acpi_ibm.c
293c293
< static char *ibm_ids[] = {"IBM0068", NULL};
---
> static char *ibm_ids[] = {"IBM0068", "LEN0068", "TP-83", NULL};
ふと、
Disk1のCDを使った始動ではACPIを無効にした記憶が無いことに気が付き、
kernelをGENERICでリビルドしてみたら。
をや?
acpi_ibm.cへの修正も戻してあるのにスルッと立ち上がるじゃないか。
コアもちゃんと2つ認識しているし、
試しにBIOS設定でHTTを有効にしてみたら4つ認識するし。
結局、
acpi_ibm.cへの修正があっても無くてもX環境では多くのFnキーが機能しなかったり
問題は残るものの、
電源ボタンでのシャットダウンは機能するし、
スピーカのミュートとボリュームは機能するし、
powerdでのクロック制御も効くからまぁ妥協範囲。
最終的に、
そこそこ環境整備が進んだらDisk to Diskでバックアップを取る予定で確保してあった
HDDにMBR形式でパーティショニングした環境を作りなおしてしまいましたとさ。
最小限だけインストールして/usr/localやら/usr/srcやら/usr/portsやら
/homeやら/var/dbやらの配下はシングルユーザモードでcp -aしといて
最少限の辻褄合わせだけという無茶で(^^;。
カーネルを再構築したら、
カーネルモジュールを作るportsやカーネル内部に依存するportsは再構築する
必要がある訳ですが、
なぜか、
r233099のMFCでカーネルモジュールを作るportsが素直に再構築できなくなりました。
具体的には、
csup → make buildworld → make buildkernel → mergemaster -p → make installkernelした上で少なくともloader.confで読み込むカーネルモジュールを作る portを再構築・インストールしてrebootし、 シングルユーザモードで起動してinstallworldし、 mergemasterの残り(ウチだとmergemaster -UFiP)してreboot、 最後に残りのカーネルソース依存のportsを再構築してrebootという流れを やる訳ですが、 installkernel後の再構築に失敗。 エラーメッセージを見ながら試行錯誤したところ、 /etc/src.confに以下の2行が必要でした。
WITH_CLANG_IS_CC=no
MK_CLANG_IS_CC=no
但し、
2行目があるとreboot後のinstallworldがエラーになり、
1行目があるとinstallworld後のデフォルトコンパイラがgcc系からclang系に
変わってしまって未対応のportsのビルドに失敗することになるため、
この副作用が嫌ならinstallworld前にこの2行をコメントアウトするか、
/etc/src.confがこの2行だけならファイルごと削除してしまう必要あり。
一旦installworldしてしまえば以後この問題は再発しないため、
これで対応終わり。
但し、
この回避策に従って再構築されたportsはclangでビルドされている筈なので、
それが気持ち悪い、
という人は該当分をinstallworld以後に再構築しといて下さい。
既にデフォルトコンパイラをclangに移行してしまっている人や、
万一loader.confで読み込むモジュールの不整合で起動中にフリーズしても
電源入れなおしてboot:プロンプト段階(短時間でタイミングがシビアだけど)
で止めてアンロードするからいいや、
という人は問題に気がつくこと無くやり過ごせているのかも。
base由来のgccとports由来のgccがテレコになると、
何かトラブった時の切り分けが面倒。
それに、
はっきり言って、
buildworldする時のgccやclangの再構築はクソ重い。
できればそこそこ更新の入るportsのgccまでは面倒見たくない。
という訳で、
その時点で使っている-STABLEなり-Releaseなりでbaseのデフォルトがclangに切り替わり、
baseからgccが関連toolchain込みで削除されるまでは、
portsのgccはインストールしたくない。
従来、
FORTRANが必要等の理由でports由来のgccを要求するのは小物が多く、
それほど間をおかずpackages-stableが更新されるので、
portupgrade依存の当騎は、
該当のものをpkgtools.confのUSE_PKGS_ONLYに追加して対処してきました。
しかし、
FirefoxやChromiumやLibreOfficeのような大物はなかなかそうもいかず、
特にブラウザはOS本体よりメジャーかつセキュリティ関連での更新も多く、
待ったなしと考えるべき。
ChromiumではOPTIONSにCLANGがあり、
19系に更新されて暫くはi386でCPUTYPE=core2だと、
世代的に大丈夫な筈なのにSSSE3が無いものと看做されてビルドできない
(9-STABLEのbaseのgccではダメでもclangではOKのCPUTYPE=corei7なら無問題)
問題があったものの2012/06/03付でビルドは通るように修正されました。
一方、
Firefoxはというと、
Firefox13系に更新されると同時にFreeBSD 9-STABLEではgcc4.6が必須にされてしまい、
もしやと思ってChromimでCLANG有効化したときのMakefile変更点を手作業で移植してみたら、
途中でアウト。
念のためLibreOfficeの方を見たらChromiumでは指定していないCXXFLAGSが追加されていたので、
LibreOfficeでのやり方を手作業で移植してみたらビルド完走。
動作も正常っぽい。
その後、
2012/06/07にMakefileがclangがあれば使うように修正されたというので、
portupgrade -fしてみるとgcc4.6のソースをダウンロードし始めたので慌てて中断。
Makefileでの判定の仕方の記述(empty(CXX:M*clang++*))はDOSのmake程度で済むくらいの
使い方しかしてこなかった身では理解できませんが、
結果を見る限り、
pathの通っている範囲内での実行可能なclang++有無を見ているのではなさげ。
デフォルトをclangに移行するのはSTABLEブランチのデフォルト追従にしたいし、
できれば毎度Makefileを手修正するのも避けたい。
かといって、
pkgtools.confのMAKE_ARGSやMAKE_ENVでCCやCXXを設定してもうまくいかないのは経験済。
お馴染みのOPTIONSやKNOBで指定されたCLANGを処理する形式とは明らかに書き方が違う。
やむなく
env CC=clang CXX=clang++ CXXCPP=clang-cpp CPP=clang-cpp portupgrade -f
で一時的に環境変数を設定する方法を試すと、
とりあえず期待どおりclang++を使ったビルドが進行するものの途中でアウト。
http://www.freebsd.org/cgi/cvsweb.cgi/ports/www/firefox/Makefile
で更新箇所を見たら上述の理解できない判定の記述が増えただけだったので、
もしかして...と思ってenvで設定する環境変数に上述のLibreOfficeのケース由来の
CXXFLAGS="-std=gnu++98 -Qunused-arguments"
を追加(コマンドラインに書く都合でダブルクォートを付加)したら無問題。
できれば、
portsに入れるものは、
baseにあるもので何とかする方法がない場合だけ他のportsに頼るようにして欲しい...。
メンテナが匙投げて無理かな?
clangを使おうという動きが無い訳ではなさげなので、
特定メーカ依存という訳ではないこの問題は、
とりあえずの備忘録で済んでくれることを期待しつつ...。
なお、
LibreOfficeは、
現状devel/boost-jamかdevel/boost-libsの一方でも入っているとビルドに失敗するため、
先にpkgdb -Ffして依存情報を正常化してから一時的にこれらを強制的にアンインストールし、
LibreOfficeのビルド&インストール後に入れなおすようにしないと、
確実にLibreOfficeのビルドに失敗します。
抜本的対策こそ今後の3.5.4への更新まで持ち越されそうなものの、
これに注意すればChromium同様OPTIONSでCLANGを有効にしてあればportsのgcc不要。
2012.9.16追記:
タイムリーに更新できていませんでしたが...
既にLibreOfficeのboost問題は修正されていますね。
メンテナ各位に更新感謝。
2013.02.24追記:
いつの間にか、
stable/9のclangでビルドしたLibreOfficeが起動直後にsegfaultするようになってしまっていましたが、
これはLibreOffice自体の更新に伴う問題というわけではなく、
前回の問題が直った後のbase側でのclang関係の更新のどれかに原因があったようです。
Firefox 19.0も、
baseのgcc、clangどちらでビルドしても起動して画面表示が出てから僅かの時間でsegfaultする問題が発生していたのですが、
ヒントを探していたらfreebsd-portsメーリングリストのFlorian Smeets氏の投稿を発見。
その時点ではまだMFCされていなかったので自前でパッチを当てて試したところ、
clangでのビルドなら問題なし。
ふと「これでLibreOfficeも直るんじゃね?」と思いついて、
この更新版clangでビルドしなおしてみたら、
大当たり!
が。
LibreOfficeのビルドを仕掛けて寝たら、
起きてからその間に問題の更新がr247156としてMFCされているのに気づいてがっくり。
ちなみに、
その後Firefoxのportには現時点で2回修正が入り、
1回目はPGOオプション設定時のgcc使用強制(clangではダメらしい)、
2回目はさらにその場合のbase gcc除外(既にサポート外)とのこと。
ウチではPGOオプション非設定かつportsのgccはどれも入れてないのだが、
gccでビルドするとダメってことは、
baseのgccじゃPGO設定如何によらずダメになってるんでは?という気もするのだが...。
せっかくMozcが1.10.1390.2に更新されましたが、
がまだインストールされていない,
その他
(実際のところどれが肝なのかは把握できていませんが)
__stack_chk_fail_local()
の含まれるライブラリがあるといった、
素のままの9.0-RELEASEなり9.1-RELEASEから普通に9-STABLEに移行して新規環境構築中、
かつ真っ先にMozcのインストールに突入といった一風変わった状況でなければ多分ビルドに失敗。
ご多聞に漏れず、
私の環境でも失敗。
とりあえず細かい話は後にして、
この修正が本質的に正しいかどうかも別にして、
ビルド可能にするための修正版ファイルを置いておきます。
下のリンクからダウンロードし、
対応するファイルと差し替えて下さい。
japanese/mozc-server/Makefile
japanese/mozc-server/files/patch-gyp_common.gypi
emacsやfcitxは使っていないので、
japanese/mozc-elやjapanese/fcitx-mozcが大丈夫かは確認していませんが、
私の環境ではこれでjapanese/ibus-mozcが正常に使えています。
具体的には、
japanese/mozc-serverでは
===> ja-mozc-server-1.10.1390.102_2 depends on executable: glib - not found
となって、glibという存在しない実行形式ファイル、
japanese/mozc-toolでは
===> ja-mozc-tool-1.10.1390.102_2 depends on executable: gtk - not found
となってgtkという存在しない実行形式ファイルを探しに行って、
現実にはインストール済のportsがインストールされていないと誤認て依存物としてビルドし、
そのインストール段階でインストール済エラーで失敗。
portupgradeに-kを付けずに作業しているので、
japanese/ibus-mozcは依存物のjapanese/mozc-serverが失敗してスキップされますが、
-k付で作業していたらこれもコケる筈。
/mozc-toolもjapanese/ibus-mozcも、
japanese/mozc-serverがマスターになっているスレーブportなので、
japanese/mozc-serverのMakefileを見ると、
BUILD_DEPENDS+= glib:${PORTSDIR}/devel/glib20 \
gtk:${PORTSDIR}/x11-toolkits/gtk20
のように、devel/glib20やx11-toolkits/gtk20がBUILD_DEPENDSに。
通常ならgtkやglibはLIB_DEPENDSで指定するものだし、
記憶違いかもしれないが、
RUN_DEPENDSは普通ビルド中にpythonを使うものの実行時には必要ない、
というような場合に使うものでは?
実際、
他にglibやgtkを指定している箇所全部でBUILD_DEPENTSになっていて、
エラーメッセージでも実行形式のファイルを探して見つからない、
というものだし。
ということで、
gtkとglibのBUILD_DEPENDSを全部LIB_DEPENDSに直してトライすると、
今度は別の問題が。
japanese/mozc-serverでは
undefined reference to `__stack_chk_fail_local'
というエラーが大量に出てLinker Errorに、
japanese/mozc-toolでは
===> ja-mozc-tool-1.10.1390.102_2 depends on file: /libQtCore.so - not found
となって、
何故か入っている筈のdevel/qt4-corelibを見失っている。
こちらはMakefileでも
USE_QT4+= corelib gui
の行があるだけで問題無さげなのだが、
エラーメッセージをよく見るとルートディレクトリ直下を探している!
ということは、
どこかで何らかの理由でデフォルトのQt4の在り処の指定を見失っているのでは?
ということで、
上記の行の直前にMk/bsd.qt.mkからフォルダ指定と思しき部分を移植してみたら、
次はjapanese/mozc-serverと同じ状況に。
こちらは何が何だか分からなかったため、
stack_chk_fail_local
でググってみると、
どうやらgccで
-fstack-protector
を指定してコンパイルしたものをリンクする際に、
リンクされる相手のどれにもエラーハンドラが無いと発生するものらしい。
念のため、
portupgrade -Rfでmozc-serverの依存物一式をリビルドさせても変化なかったので、
どれかのデフォルト設定が変わったことでハンドラが含まれるようになったという訳ではなさげ。
で、
ググった際によく見かけた対策を参考に、
Makefileに
CFLAGS+= -fno-stack-protector
CXXFLAGS+= -fno-stack-protector
を入れたりコマンドラインにenvで指定したり強制的にclangを使うようにしてみてもダメ。
japanese/mozc-server/work以下のビルド失敗の残骸にmozcmakeといういかにもそれっぽい実行属性付のファイルがあるので見てみたら、
実体はシェルスクリプトでCFLAGS等も反映されているため訳がわからなくなった。
最後に、
ふと
「どこかで強制的にgccを使いつつ-fstack-protectorを設定するようなところがあるのでは?」
と思いついて、
残骸の中をgrep -rしてみると、
gyp/common.gypiにありました。
このファイルはjapanese/mozc-server/files/patch-gyp_common.gypiでパッチが当てられるのですが、
問題の行はノータッチ。
で、
パッチの中でコメントアウトはシェルスクリプトと同様でOKっぽいと見て取れたので、
これをケアするようにパッチを修正し、
念のためMakefileからは追加したCFLAGSやCXXFLAGSを外してトライしてみたら、
これでようやく成功。
...と、
ここまで来て、
この文章を纏めるためにMakefileをざっと見直していたら、
bsd.port.mkではなく、
bsd.port.pre.mkとbsd.port.post.mkに分割して呼び出しているのに気がついた。
そのへんの仕組みを把握できていませんが、
もしかして、
この場合、
自前でbsd.qt.mkを呼び出さないといけない?
とは思いつつ、
自分のところでは既にうまく行ってしまっているので、
そこまでは追いかけませんでした。
一応、
この文章の執筆時点でのjapanese/mozc-server/Makefileとjapanese/mozc-server/files/patch-gyp_common.gypiと修正版とのdiff -uも下に記載しておきます。
%cd /usr/ports/japanese/mozc-server
%diff -u Makefile.orig Makefile
--- Makefile.orig 2013-04-24 18:51:05.000000000 +0900
+++ Makefile 2013-04-27 16:10:45.000000000 +0900
@@ -100,7 +100,7 @@
# mozc_server
.if ${BUILD_MOZC_LIST:Mmozc_server} == "mozc_server"
-BUILD_DEPENDS+= glib:${PORTSDIR}/devel/glib20 \
+LIB_DEPENDS+= glib:${PORTSDIR}/devel/glib20 \
gtk:${PORTSDIR}/x11-toolkits/gtk20
PLIST_FILES+= bin/mozc_server
@@ -117,7 +117,10 @@
# mozc_tool
.if ${BUILD_MOZC_LIST:Mmozc_tool} == "mozc_tool"
LIB_DEPENDS+= zinnia.0:${PORTSDIR}/japanese/zinnia
-BUILD_DEPENDS+= gtk:${PORTSDIR}/x11-toolkits/gtk20
+LIB_DEPENDS+= gtk:${PORTSDIR}/x11-toolkits/gtk20
+QT_LIBDIR_REL= lib/qt4
+QT_PREFIX= ${LOCALBASE}
+QT_LIBDIR= ${QT_PREFIX}/${QT_LIBDIR_REL}
USE_QT4+= corelib gui
RUN_DEPENDS+= ${LOCALBASE}/share/tegaki/models/zinnia/handwriting-ja.model:${PORTSDIR}/japanese/tegaki-zinnia-japanese
@@ -203,7 +206,7 @@
LIB_DEPENDS+= fcitx-config.4:${PORTSDIR}/chinese/fcitx \
zinnia.0:${PORTSDIR}/japanese/zinnia
-BUILD_DEPENDS+= glib:${PORTSDIR}/devel/glib20
+LIB_DEPENDS+= glib:${PORTSDIR}/devel/glib20
RUN_DEPENDS+= mozc_server:${PORTSDIR}/japanese/mozc-server \
mozc_tool:${PORTSDIR}/japanese/mozc-tool \
mozc_server_start:${PORTSDIR}/japanese/mozc-additions
@@ -264,8 +267,8 @@
# mozc_el
.if ${BUILD_MOZC_LIST:Mmozc_el} == "mozc_el"
LIB_DEPENDS+= zinnia.0:${PORTSDIR}/japanese/zinnia
-BUILD_DEPENDS+= emacs:${PORTSDIR}/editors/emacs \
- glib:${PORTSDIR}/devel/glib20 \
+BUILD_DEPENDS+= emacs:${PORTSDIR}/editors/emacs
+LIB_DEPENDS+= glib:${PORTSDIR}/devel/glib20 \
gtk:${PORTSDIR}/x11-toolkits/gtk20
RUN_DEPENDS+= mozc_server:${PORTSDIR}/japanese/mozc-server \
mozc_server_start:${PORTSDIR}/japanese/mozc-additions
%cd /usr/ports/japanese/mozc-server
%diff -u files/patch-gyp_common.gypi.orig files/patch-gyp_common.gypi
--- files/patch-gyp_common.gypi.orig 2013-04-24 15:15:01.000000000 +0900
+++ files/patch-gyp_common.gypi 2013-04-27 15:51:23.000000000 +0900
@@ -9,6 +9,15 @@
'-Wno-char-subscripts',
'-Wno-sign-compare',
'-Wno-deprecated-declarations',
+@@ -71,7 +71,7 @@
+ '-fno-strict-aliasing',
+ '-funsigned-char',
+ '-include base/namespace.h',
+- '-fstack-protector',
++# '-fstack-protector',
+ '--param=ssp-buffer-size=4',
+ '-pipe',
+ '-pthread',
@@ -194,7 +194,7 @@
# - http://code.google.com/p/protobuf/issues/detail?id=128
# - http://code.google.com/p/protobuf/issues/detail?id=370
なお、
体力の都合で、
バージョンアップされてなお問題が残っていても、
パッチを差し替えていく保証はできないのであしからず。
日本語インプットメソッド関係だしメンテナも日本人だから、
英語のページの更新は要らないよね?
OS/2のサポートがセキュリティFixも含めて終了し、
開発元を移しての後継たるeComStationの日本語版が出てこない現状、
主に初号機をテストベンチとして
超漢字,
BeOS,
数種のLinuxディストリビューションも含めて味見程度に触ってきた中で、
ということでFreeBSDを選択して今に至ります。
その後、
FreeBSD/Linux用のVJEディスコン,
Radeon系のアーキティクチャ変更とその後のAGP→PCI-Expressへの潮流変化で
安定して性能の出ていたradeonドライバが使えなくなって実質的にNVIDIA一択に
なったりとショッキングな出来事はあったものの、
IMEはcanna,
Anthyを中継ぎに、
現在はPortsからインストールしたMozcがそれなりに快適に使えるようになり、
ディスプレイアダプタもインターフェースのデジタル化でアナログ的画質が全面的に
モニタ側要因になったこともあって、
NVIDIAの1世代古い程度のを選んでおけば、
大変有難いことに、
少なくとも2012年3月現在、
プロプライエタリながら性能の出るNVIDIA謹製のドライバが正式かつ継続的に
FreeBSD用に提供されています。
カーネル側サポートモジュールも含めての提供なので、
カーネルを再構築する度にNVIDIAドライバも再構築が必要ですが...