会社で仕事をするのに、メインマシンはMacを使っているのだけれど、どうしてもWindowsも使う必要があるので、VMware FusionにWindows 7を入れて使っている。
vmwareにはホストのディレクトリをゲストからアクセスするためのhgfsと言う仕組みがあるのだが、こいつがいまいち使えないのでMacのファイル共有を有効にして、Windowsからマウントして使っていた。
が、どうもこの OS X 標準のファイル共有には問題があるらしく、svn checkoutがうまくいかないとか、PowerPointのファイルが開けないとか変な動作をしていた。
そこで、ファイル共有を捨てて、sambaを使ってみることに。
参考にしたのは、スタジオとぅえいん アーカイブス | Lion/Mountain Lion環境下でSambaを起動するための手順メモ
参考手順だと、netbiosdとsmbdを止めることになっているが、Macの設定でファイル共有をoffにするとsmbdは死んでくれる。netbiosdは生き続けるようだ。
で、brewからsambaをインストール。本日時点では samba-3.6.20がインストールされた。/usr/local/Celler/samba/3.6.20ディレクトリに入る。
他のサイトとかを見ていると、古いFormulaだとprivateディレクトリが作られない問題があったらしいが、現時点のものだとprivateディレクトリは作成された。
/usr/local/Celler/samba/3.6.20/etc/smb.confも作成されるようだが、中身は空だった。
そこで、/Library/Caches/Homebrew/samba-3.6.20.tar.gz を展開し、中からexamples/smb.conf.default を取り出して/usr/local/Celler/samba/3.6.20/etc/smb.confにコピー。
smb.confの中身を適宜修正。
  • workgroupを適当に修正
  • server stringを適当に修正
  • load printers を no に修正(プリンタは別で共有していたので)
  • [global]セクションに以下を追加
    unix charset = UTF-8-MAC
    
  • [printers]セクションを全部コメントアウト
気になったのは、log file のところで /usr/local/samba/var を指定していたこと。brewでインストールすると /usr/local/samba ディレクトリは存在しない。
ここを/usr/local/Celler...に修正しても良いのだが、将来バージョンが変わった時のことを考えて、/usr/local/Celler/samba/3.6.20 から /usr/local/samba にシンボリックリンクを張った。
この状態で、手でnmbdとsmbdを起動してみる。
# /usr/local/sbin/nmbd -D
# /usr/local/sbin/smbd -D
で、psコマンドで見てみるとsmbdはいるがnmbdがいない。/usr/local/Celler/samba/3.6.20/var/log.nmbdを見ると、
[2014/01/10 14:18:52,  0] nmbd/nmbd.c:861(main)
  nmbd version 3.6.20 started.
  Copyright Andrew Tridgell and the Samba Team 1992-2011
[2014/01/10 14:18:52,  0] lib/util_sock.c:667(open_socket_in)
  bind failed on port 137 socket_addr = 0.0.0.0.
  Error = Address already in use
とか出てる。ポート137がLISTENできないらしい。
おそらく、nmbdの役目をnetbiosdがやっているのだろう。
参考サイトの手順通りにnetbiosdを止めても良かったのだが、ここはnetbiosdにまかせてみることにする。
後は、smbpasswd -a でアクセスしたいユーザを追加し、パスワードを設定してやると、無事にWindowsからアクセスできた。
特に文字コード系の設定はsmb.confには入っていないのだが、日本語のファイル名もちゃんと見えている。「が」みたいなMac特有のNFD/NFCの問題も大丈夫そうだ。(実は、最初unix charset=UTF-8-MACを書かなかったら、見た目は問題なかったがブリーフケースによるファイルの同期で問題があった)
後は、OSの起動時に起動して欲しいので、参考サイトに従ってsmbd用のplistファイルを作成し、一度smbdを殺した後、launchctl load でlaunchdから起動できるようにした。
一応plistファイルとコマンドラインを転載しておく。
org.samba.smbd.plist

上記ファイルを /Library/LaunchDaemons/に置き、
# launchctl load -w /Library/LaunchDaemons/org.samba.smbd.plist
で有効化。
参考サイトだと、smbdの起動オプションが-Dになっていたけど、それだとlaunchdがsambaが死んだと思って10秒置きに再起動してくれる。
2014/01/10 16:29:55.831 com.apple.launchd[1]: (org.samba.smbd) Throttling respawn: Will start in 10 seconds
んで、samba側は死んでいないので、ERROR: smbd is already running. とか言い続ける。
-Dオプションの代わりに、-Fオプションを使うようにすれば、launchdに死んだと誤解されないようになった。
さらにlog.smbdを見ていると、以下のログが出ている。
[2014/01/10 18:41:25,  0] smbd/server.c:1072(main)
  smbd version 3.6.20 started.
  Copyright Andrew Tridgell and the Samba Team 1992-2011
[2014/01/10 18:41:25.999537,  0] smbd/server.c:1128(main)
  standard input is not a socket, assuming -D option
[2014/01/10 18:41:26.005124,  0] lib/util.c:1723(set_maxfiles)
  set_maxfiles: setrlimit for RLIMIT_NOFILE for 16404 files failed with error Invalid argument
最初の standard input is not a socket, assuming -D option の方は、launchdが標準入力を与えてくれないせいだと思うので、ほっておいて良いと思われる。
次の、set_maxfilesの方は、一度に開けるファイルの上限を16404にしようとして失敗したよ?というもので、実際にWindowsで大量のファイルをコピーしようとしたら失敗した。
調べてみると、MacでHomeBrewのSambaは使えました(ちょっと面倒)。:毎回サブタイトル考えるの面倒いなぁ:So-net blogと言うページがヒット。
ここから(とか他のところを見て)わかったことは、
  • smb.confにmax open filesと言うパラメータがあるが、16404より小さくできないこと。
  • macの場合、setrlimitでRLIMIT_NOFILEに設定できる値の上限はkern.maxfilesperprocになっていること
そして、実際に試してみてわかったことは、kern.maxfilesperprocはkern.maxfilesに依存していること。(これは、ulimit -nが失敗するかどうかで判断したので、本当はmaxfilesの方は不要かもしれない)
と、言うわけで、以下を実行してからsmbdを再起動したら、このメッセージは出なくなった。
sysctl -w kern.maxfiles=16404
sysctl -w kern.maxfilesperproc=16404
sysctl -w で設定した内容は、再起動したら消えてしまうので、/etc/sysctl.confに以下を書いておいた。(Macの場合、デフォルトではこのファイルは存在していないが、あれば読んでくれるらしい。試してないけど)
kern.maxfiles=16404
kern.maxfilesperproc=16404

しっかし、この16404って言う数字、Windows 7から来てるらしいけど、なんでそんなに大きくしたかねえ。(ちなみに、macのデフォルトは12288/10240だった。)
サーバが新しくなってから放置状態だったasteriskを復活させてみる。以前のエントリはasteriskの導入 (1) - PC日記
まずは、portsからnet/asteriskをインストール。現在のバージョンは1.8系になっている。(ちなみに、最新版はasterisk11系らしい)
configのオプションはSPANDSPを追加(後でfax系をやるため)
インストールが終わったら、続いてjapanese/asterisk-soundsをインストール。
=============================================================================
[FYI]

 To get natural word order in Japanese sentences
 you can patch to /usr/ports/net/asterisk and reinstall it as below.

 For example,
 1. Download app_voicemail.c.yymmdd-01.patch and say.c.yymmdd-01.patch from
    ftp://ftp.voip-info.jp/asterisk/patch/1.8.X.Y/
    where 1.8.X.Y is corresponding to PORTVERSION in
    /usr/ports/net/asterisk/Makefile.
 2. Put them to /usr/ports/net/asterisk/files as
    patch-apps::app_voicemail.c and patch-main::say.c, respectively.
 3. Reinstall /usr/ports/net/asterisk.
 4. Add the following options section to
    /usr/local/etc/asterisk/asterisk.conf.

     [options]
     languageprefix=yes

=============================================================================
インストールされたのは1.8.25.0だが、ftp://ftp.voip-info.jp/asterisk/patch/ には 1.8.20.1までしかない。しかし、1.8系はすべて1.8.0へのシンボリックリンクのようなので、1.8.0から2つのファイルを持って来る。
このとき、何故かfetchコマンド等だとtimeoutで失敗するので、ブラウザで表示させてファイルに保存した。
これを指示通りにリネームして/usr/ports/net/asterisk/filesに置き、asteriskを再インストール。
昔の環境から設定ファイルをコピーしてきて起動したところ、エラーが出てうまく動かない。
ぷちぷち潰したので、違いについて記述していく。

asterisk.conf
asterisk-soundsの指示に従ってlanguageprefix = yes を有効に。(何故昔のが無効だったのか謎)
live_dangerously = no を有効化。(Privilege Escalations with Dialplan Functions - Asterisk Project - Asterisk Project Wikiには、asterisk12からはデフォルトがnoって書いてあるけど、コメントをはずさないと文句を言われた)
sip.conf
language=jpをjaに変更。
username=の行を全てdefaultuser=に変更
insecure=veryの行をinsecure=invite,portに変更。これをやらないと、ひかり電話の着信でasteriskが応答しない。(Asterisk Forums • View topic - insecure=very Unknown insecure mode 'very')
modules.conf
エラーではないのだが、起動時にログにずらずらとWARNINGが出るので、未使用のモジュールの内警告が出るものをnoload指定
noload => pbx_ael.so
noload => chan_dahdi.so
noload => codec_dahdi.so
noload => res_config_sqlite.so
noload => res_smdi.so
noload => cel_tds.so
noload => cel_custom.so
noload => cel_pgsql.so
noload => cdr_sqlite.so
noload => cdr_radius.so
noload => chan_skinny.so
noload => chan_unistim.so
cdr_pgsql.conf
Encoding not specified.とか言われたので、encoding=UTF-8を追加。

ここまでで、以前と同じように使えるようになった。以前はSIPクライアントにWindowsのExpress Talkを使っていたのだが、今はMacなのでLinphoneと言うアプリを入れてみた。(設定がわかりにくい)
続いて、voicemail機能を使ってみようと思いたち、voicemail.confを眺める。
こちらは、前回の記事で内容を晒していないので、有効な行だけ掲載する。
[general]
format=wav49
serveremail=asterisk@wizard-limit.net
attach=yes
skipms=3000
maxsilence=10
silencethreshold=128
maxlogins=3
emaildateformat=%Y/%m/%d(%a) %H:%M:%S
sendvoicemail=yes
[zonemessages]
eastern=America/New_York|'vm-received' Q 'digits/at' IMp
central=America/Chicago|'vm-received' Q 'digits/at' IMp
central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'
military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
japan=Asia/Tokyo|Q PHM 'jp-ni' 'vm-received'
[default]
1234 => password,mailbox,to address,,tz=japan
注意点は以下。
  • serveremailは、デフォルトのasteriskだけだと、正しいホスト名がつかなかったので、ドメインまで含めるようにした。
  • emaildateformatは、メールに含まれる日時のフォーマットが気に入らなかったので修正した
  • zonemessagesのjapan=の後は、Asterisk サンプル設定ファイル voicemail.conf - VOIP-Info.jp Wikiの通りにJapanだとタイムゾーンが正しくならない。/usr/share/zoneinfoにあるものでないといけないらしいので、FreeBSDの場合はAsia/Tokyoとする
  • defaultの1234はメールボックス名。変えても良いが、数字でないといけないらしい。/var/spool/asterisk/voicemail/default/にディレクトリが存在する必要があるので、面倒だからデフォルトのまま1234とした
後は、extensions.confでVoicemail()アプリを呼んであげれば良いのだが、voip-info.jpのサンプルだと内線毎のメールボックスなので、外線着信で使えるように以下のようにした。
exten => 200,1,Dial(SIP/201&SIP/202&SIP/203&SIP/204,30,tT)
exten => 200,n,NoOp(${DIALSTATUS})
exten => 200,n,GotoIf($["${DIALSTATUS}"!="CHANUNAVAIL"]?vm-rec)
exten => 200,n,Ringing()
exten => 200,n,Wait(30)
exten => 200,n(vm-rec),Answer()
exten => 200,n,Wait(1)
exten => 200,n,Voicemail(1234)
exten => 200,n,Hangup
200は、ひかり電話の外線が着信したときに呼び出されるextenで、最初の行で201〜204を30秒間呼び出す。この間にひかり電話の子機を含むどれかの端末が応答すればそれで終わり。
30秒間誰も応答しなかった場合は、次の行のNoOpが実行されるが、これはログにDIALSTATUSを出すためだけで、何もしない。
次のGotoIfで、DIALSTATUSがCHANUNAVAIL以外のときは、vm_recの行に飛ぶ。
これは、MacのLinphoneが起動していないときなど、SIPクライアントが一つもいないときは、30秒呼び出す前にCHANUNAVAILでDialが終了してしまうため、ひかり電話の子機が電話に出られないのを防ぐため。
CHANUNAVAILのときは、Ringing()で相手に着信を知らせ、次の行のWait(30)で30秒待つ。(Ringing()がないと、Wait()が異常終了してしまう)
それでも誰も電話に出ない時は、Answer()で着信する。
Wait(1)で1秒待つ。
Voicemail(1234)で、voicemail.confで設定したメールボックス1234に録音される。
これだと、例えばSIPの子機が一台だけで、それが内線通話中のときにもWait(30)に行かずにいきなりAnswer()に行ってしまうので、もう少し調整が必要かもしれない。
とりあえずこの設定で、asteriskのvoicemailが留守電として機能し、録音されると指定した宛先にメールが飛ぶ。
私の場合はiPhoneに届くようにしているので、iPhoneのメールアプリから添付ファイルをタッチすればそのまま録音内容を聞くことができる。iPhone自体の留守電は、ソフトバンクの「留守番電話プラス」を契約していないので、いちいち留守番電話センターに電話しないと聞けないのと比べると非常に良い。

voip-info.jpのサンプルだと、録音がある状態で内線から298にかけるとVoicemailMain()が呼ばれるので、ガイダンスに従ってメールボックス番号とパスワードを入れると、録音を聞くことができる。
しかし、ひかり電話の子機からは操作できないし、いちいちガイダンスを聞きながら操作をするのもだるいので、webインターフェイスを使うことにする。参考にしたのはAsteriskによるIP-PBXの構築(CentOS4.2編)
portsから入れた場合、vmail.cgiはどこにもインストールされないので、ソースから持って来る必要がある。/usr/port/net/asteriskでmakeした後、cleanしなければworkの下にソースが残っているので、そこから必要なファイルを取り出すことにする。
まずは、cgiを入れる先を決める必要がある。私の場合は、過去のしがらみ等の関係で /var/www/docs/lan/asteriskとした。以下の説明はそのつもりで読んで欲しい。
# mkdir /var/www/docs/lan/asterisk
# cd /usr/ports/net/asterisk/work/asterisk-1.8.25.0
# cp contrib/scripts/vmail.cgi /var/www/docs/lan/asterisk/
# cp images/*.gif /var/www/docs/lan/asterisk/
次に、vmail.cgiを編集する。

変更点は、以下。
  • 設定ファイル系が、/etc/asteriskになっているので、/usr/local/etc/asteriskに変更
  • 日時が、UTCで送られてしまうので、Asia/Tokyoのタイムゾーンで、かつ日本人に馴染みのあるフォーマットで表示するようにしてみた
後は、apacheの設定でvmail.cgiをブラウザからアクセスできるようにすれば良いのだが、メールボックス名、パスワード共に電話で入力できるように数字なので、プライバシーを大事にしたい場合は別の方法で認証するようにすると良い。私の場合は、httpsのクライアント証明書がないとアクセスできないページに配置した。
ここまでで、録音の一覧の参照と再生ができるようになる。
始めて再生するときは、コーデックを選択する画面が出るが、GSM Compressed WAV を選べば voicemail.confで指定した wav49 を指定したことになる。
Macのfirefoxだとこれで再生できたが、iPhoneのSafariだと再生できなかった。

ここまでだと、削除ができないので、なんとかする必要がある。
voicemailの録音データは/var/spool/asterisk/voicemail/default/1234/INBOXにある(新規の録音の場合)
このディレクトリは、asteriskユーザしか書き込みができないので、cgiを動かすユーザが書き込みできるようにしてやる必要がある。
  1. cgiを動かすユーザ(FreeBSD/apacheの場合はwww)を、/etc/groupでasteriskグループに追加する
  2. メールボックスディレクトリを、グループ権限で書けるようにする
    # cd /var/spool/asterisk/voicemail/default/1234
    # chmod g+ws INBOX
    
    ※ setgidしているのは、BSDのファイルシステムではディレクトリにsetgidすると中に作られるファイルのグループがディレクトリと一致するようになるため。別に不要だが。
    ※ 中の録音データは、0644だが、ディレクトリに書き込み権があれば削除、移動はできる。
    ※ vmail.cgiでは、削除だけでなくフォルダの移動もできるので、この機能を使いたい場合はINBOX以外のフォルダも用意し、chmod g+wsする必要がある
次回は、iaxmodem + hylafaxでfax関連をやってみようと思う。
# どうせ、電話もFAXも全然使わないんだけどさ。
FreeBSDで日本語のマニュアルを読むには、ports/japanese/man でインストールされるjmanを使う。
のだが、そろそろ jman が使っている groff が古い(FreeBSD9に入っている英語のマニュアルが正しく清書できない)とか、UTF-8 の環境だと使いにくい(LANG=ja_JP.eucJP jman する必要がある)とか問題があるので、別の手段を検討する。
参考にしたのは、FreeBSD 9.0RELASEで日本語manを使う - akira_youの私見
当初、/usr/doc/ja_JP.eucJP/man/Makefile.inc を書き換えて、/usr/share/man/ja_JP.UTF-8 にutf-8のマニュアルソースを入れたりしてみたのだが、それだと ports/japanese/* 等でインストールされる /usr/local/man/ja が見られないので、結局マニュアルソースは今まで通り euc-jpでインストールして、manコマンドでのフォーマット時に utf-8 に変換することにした。
以下、試行錯誤の末の最終手順。

  1. ports/japanese/nkf をインストールする
  2. ports/textpfoc/groff をインストールする
    このとき、ports/textproc/groff/Makefileを修正して、依存関係の ghostscript8をghostscript9にしておく
  3. 日本語のマニュアルページをインストールする。
    ports/japanese/man-doc をインストールしても良いし、/usr/doc/ja_JP.eucJP/man でmake installしても良い
  4. man/ja から man/ja_JP.UTF-8 にシンボリックリンクを張る
    # ln -s /usr/share/man/ja /usr/share/man/ja_JP.UTF-8
    # ln -s /usr/local/man/ja /usr/local/man/ja_JP.UTF-8
    
  5. /usr/bin/man を /usr/local/bin/man にコピーする
  6. /usr/local/bin/man を編集する
PAGERは私の場合はlvを使っているが、jmanが入れるjlessでも良いと思う。
これで、/usr/local/bin/man を使えば日本語のマニュアルも見られるようになる。
日本語のマニュアルは内容が古かったりするので、そう言う時は man -oを使えば英語のマニュアルが読める。
以前のPentium Mのサーバは、FreeBSD9にすると起動してすぐにカーネルパニックを起こしてリブートループしてしまうため、8-STABLEを使用していた。
今回、サーバマシンが死んでCore i7マシンに変わったので、FreeBSD9にすることを検討する。
で、どうせ9系にするのならば、i386版ではなくamd64版にしたい。
一応、二つのスライスを利用した FreeBSD i386 から amd64 への移行: uyota 匠の一手と言うサイトを見て、stable/9をチェックアウトして、TARGET_ARCH=amd64をつけてやればアップグレードもできそうだと思ったんだけど、i386のライブラリが残るだとか、portsも全部ビルドし直した方が良さそうとかあるので、クリーンインストールすることに。
2TのHDDを購入して、新しいディスクをATA0に、古いディスクをATA1に繋いで、9.2-RELEASEのインストーラを起動。
現在のデフォルトはMBRではなくGPTらしいので、GPTでfreebsd-bootに128k、freebsd-ufs(/)に512G、freebsd-swapに8Gの領域を確保して、インストール実行。
あっという間に終わるので、再起動・・・・。
起動しません。
マシンを交換したときと同じ、
Reboot and Select proper Boot device
or Insert Boot Media in selected Boot device and press a key 
が出るだけ。
何か間違えたかと思って、インストールDVDから起動し直してgpart show とかやっても正しそうに見える。
パーティションの切り方が悪いのかと思って、全部デフォルトでインストールし直しても同じ。
この時気になったのが、ATA1に繋いでいるはずの古いディスクがgpart showで正しく見えない。 dmesgを見ると、
GEOM_RAID: Promise: Array Promise created.
GEOM_RAID: Promise: Disk ada1 state changed from NONE to ACTIVE.
GEOM_RAID: Promise: Subdisk PROMISE Array 1:0-ada1 state changed from NONE to ACTIVE.
GEOM_RAID: Promise: Volume started.
GEOM_RAID: Promise: Volume PROMISE Array 1 state changed from STARTING to OPTIMAL.
GEOM_RAID: Promise: Provider raid/r0 for volume PROMISE Array 1 created.  
とか言って、promiseのraidコントローラと勘違いしている?
この時点で、OSが起動しない、古いディスクが読めない、と言う2つの大きな問題を抱えてしまった。
GPTとFreeBSDのbootシーケンス等についていろいろ調べたりして、pmbrを書いてみたり、gptbootを書いてみたりしたけど状況は変わらず。
面白いことに、古いHDDにあるmbrからブートすると、ブートメニューでF5を押して別のディスクを選択すると、GPTの新しいFreeBSDが起動する。
しかし、古いディスクをブートシーケンスに含むのは変だし、先々困りそうである。
ここで一度諦めて古いHDDからブートし、一晩頭を冷やすことにする。
頭を冷やしている間に、古いHDDがraidに見えてしまう問題について調べてみたところ、freebsd-stable - GEOM_RAID in GENERIC is harmful と言うのを発見。
FreeBSD 9-STABLEのどこかのタイミングで、GENERICカーネルにGEOM_RAIDオプションがデフォルト化され、それが原因で古いHDDを繋ぐとおかしいことが起きるよ、的な話らしい。
そこで、最初のサイトをヒントに、古い環境にstable/9のソースをチェックアウトし、amd64用のカーネルコンフィグを作成して、TARGET=amd64でbuildkernelし、新しいHDDに入れてみた。
include GENERIC

ident           FALSE

device crypto

options         IPSEC
#options                IPSEC_ESP
options         IPSEC_DEBUG
options         IPSEC_NAT_T
options         IPFILTER
options         IPFILTER_LOG
options         IPFILTER_DEFAULT_BLOCK
#options                TCP_DROP_SYNFIN
options         SHMMAXPGS=10000
options         SHMMNI=100
options         SHMSEG=10
options         SEMMNS=200
options         SEMMNI=70
options         SEMMSL=61

nooptions       GEOM_RAID
変更点は、最後のnooptions GEOM_RAID
これで、新しいHDDから起動してみると、無事に古いHDDをマウントして見ることができた。
その後、GPTのブートについていろいろ調べたがどうにも解決しなかったので、諦めてMBRでパーティションを作成してOSをインストール。
これで起動することができた。
再度古いHDDからinstallkernelして、今度は新しいHDDでbuildworld/installworldもやり直した。

今回のディスクも、以前のディスクも、AFT(物理セクタが4kiB)なので、パーティションも4KiB境界にあるのが望ましいらしい。(clicklog: FreeBSD 9.0-RELEASE インストールの練習)
gpartを使うと、勝手にやってくれそうな感じだけど、MBRでインストールした場合は勝手にやってくれなかったようだ。
# diskinfo -v /dev/ada0s1a
/dev/ada0s1a
        512             # sectorsize
        541165879296    # mediasize in bytes (504G)
        1056964608      # mediasize in sectors
        4096            # stripesize
        3072            # stripeoffset
        1048576         # Cylinders according to firmware.
        16              # Heads according to firmware.
        63              # Sectors according to firmware.
        WD-WMC4M1940446 # Disk ident.
diskinfo -v して、stripeoffsetが0か、4096の倍数であれば良いらしいのだが、見事に3072である。
そこで、FreeBSDでWD10EARSをMBRで使う際に本来の性能を出す方法 - mteramotoの日記を参考に504(63と8の最小公倍数)の倍数をstart sectorとするパーティションを作成し、上記ada0s1aとシーケンシャルread/writeでの速度比較を行ってみた。
結果としては、新しくアラインメントを合わせて作った ada0s2 の方が、アライメントがあっていないada0s1よりも気持ち遅い、と言う結果になった。(以下で、/varがインストーラが作ったパーティションで、/mntが自分でアライメントを合わせて作ったパーティション)
実験1: /dev/randomからHDDにddで約40Gコピー
# dd if=/dev/random of=/var/test.dd bs=4k count=10000000
10000000+0 records in
10000000+0 records out
40960000000 bytes transferred in 453.281270 secs (90363319 bytes/sec)
# dd if=/dev/random of=/mnt/test.dd bs=4k count=10000000 
10000000+0 records in
10000000+0 records out
40960000000 bytes transferred in 419.405037 secs (97662156 bytes/sec)
実験2: HDDからHDDにddで約40Gコピー
# dd if=/var/test.dd of=/var/test2.dd bs=4k
10000000+0 records in
10000000+0 records out
40960000000 bytes transferred in 905.631041 secs (45228132 bytes/sec)
# dd if=/mnt/test.dd of=/mnt/test2.dd bs=4k
10000000+0 records in
10000000+0 records out
40960000000 bytes transferred in 1377.528304 secs (29734416 bytes/sec)
稼働中のサーバなのである程度の誤差はあるが、アライメントを合わせた方がread/writeでは明らかに遅い。
これは、実験1では純粋なシーケンシャルwriteなのに対し、実験2はread/writeで間にシークが入るので、ディスクの場所(内周/外周)による差が出やすいのではないかと思ったりしている。
結局、実運用では気にするようなパフォーマンスの差はないのではないかと結論し、パーティションを作りなおして再インストールはしないことにする。(実験1はアライメントを合わせた方が速いので、今から入れる人は504の倍数に合わせた方が良いかも)

この後いろいろインストールして、rrdがアーキテクチャの違いで読めないとか、pptpが繋がらないとかあったけど、それはまた気がむいたら別の機会に。
艦これをiPhoneから快適にできるようにしようと思っていろいろやっているのだけれど、なかなか実用レベルにならない。すでに手段が目的化している感はありつつ、これから何回かにわたってやったことを書こうと思う。

艦これをiPhoneでやりたくて、FreeBSDに艦メモを入れてみたりしたんだけど、flashplayerが常駐していると無駄にCPUがぶん回るのと、スクリーンショットが取れないのが嫌だったので、やはりMacをサーバにしたい。
そのためには、出先からMacにアクセスする必要があるのだが、ノート型のMacは蓋が閉まっているとWake On Demandが使えない。
いろいろ調べたり試したりしたんけど、最終的にはDownload InsomniaX for Mac - Disable sleep mode on an Apple Laptop. MacUpdate.comに落ち着いた。
こいつを常駐させて「Disable Lid Sleep」にチェックを入れておくと、蓋を閉じてもsleepしなくなるので、出先からアクセスできるわけだ。
ちなみに、「CPU Safety」と言う設定があって、これにチェックが入っているとCPU温度が80℃を超えるとsleepするようになるんだけど、あっと言う間に80℃を超えてしまって使い物にならなかった。
なので、冬の間だけと割りきって運用することにする。(やはり母艦としてのMac miniが欲しいかな・・・)

さて、これで出先でiPhoneからiSSHとかで繋げるようになったのだけれど、OS Xの画面共有のサーバは8bit colorのクライアントから接続しようとすると切ってしまう。
また、MacBook Proは解像度もそれなりなので、VNCでの転送量が多く 3G 回線ではあまり快適にプレイできない。iPhoneの場合は通信量がある程度行くと速度制限がかかる問題もあり、通信量を減らしたい。
となると、OSの画面共有を使うのではなく、ゲーム画面だけを8bit color で転送できれば良いのだ。
艦メモはQtのQWebView上に艦これのページを表示しているけれど、画面キャプチャを取る機能がある。と言うことは、Qtでゲーム画面がキャプチャできると言うことなので、ならばそのままクライアントに転送することもできるはず、と考えた。
VNCのプロトコルとかもちょっと読んだりしたんだけど、自分で一から実装したらそれなりに大変そうである。QtにVNC Serverの機能がないかと思って調べてみたところ、Qt Embedded にはそんな機能があったっぽいが、今の最新のQtのデスクトップ版には見当たらない。QPAにあっても良いのに。
さらに調べていくと、LibVNCServer/LibVNCClient と言うものを発見。
C/C++から使えるVNC Serverの実装があるじゃないですか。
と、言うわけでこいつを使って艦メモの画面が飛ばせているわけだけど、まだ公開できるところまで行っていないので、前段としてLibVNCServerのMacへのインストールについて。

MacPortsを使う場合
MacPortsにはLibVNCServerのportがあるので、port install LibVNCServer 一発で・・・入らない。
エラーログを見ると、libintl.la が見つからない的なエラー。libintl.laについて調べると、gettextに入っているらしい。
と思って良く見ると、gettextはインストール済みだし、/opt/local/lib/libintl.dylibは存在している。
さらに調べていくと、delete_la_files yes for Mavericksから始まるスレッドを発見。
イマイチどう言うことだか理解していないんだけど、MacPortsのdelete_la_filesと言うオプションがデフォルトでyesになって、laファイルが消されるようになったように見える。
しょうがないので、/opt/local/etc/macports/macports.conf の最後に delete_la_files no と書いて、gettextを再インストールしてみたところ、今度はlibiconv.laがないと言われたので、iconvも入れなおした。
これで、LibVNCServerが入った。

Homebrewを使う場合
HomebrewにはLibVNCServerのFormulaがなかった。
ので、とりあえずソースからビルドすることにして、公式サイトのDonwloadから最新のソースを持ってくる。
configureすると、
==========================================================================
*** The libjpeg compression library was not found. ***
This may lead to reduced performance, especially over slow links.
If libjpeg is in a non-standard location use --with-jpeg=DIR to
indicate the header file is in DIR/include/jpeglib.h and the library
in DIR/lib/libjpeg.a.  You can also set the JPEG_LDFLAGS variable to
specify more detailed linker flags.  A copy of libjpeg-turbo may be
obtained from:  https://sourceforge.net/projects/libjpeg-turbo/files/
A copy of libjpeg may be obtained from:  http://ijg.org/files/
==========================================================================
とか言われる。(言われると言っても、ずらずらと流れるconfigureのlogの途中に出ているので、気をつけて見ていないと気が付かない)
そこで、brew install libjpegして再度configureすると、
==========================================================================
*** The libjpeg library you are building against is not libjpeg-turbo.
Performance will be reduced.  You can obtain libjpeg-turbo from:
https://sourceforge.net/projects/libjpeg-turbo/files/ ***
==========================================================================
とか言われる。そこで、brew uninstall libjpegして、brew install libjpeg-turboして、試してみると、また見つからないと言う。
そう言えば、libjpeg-turboをインストールしたときに、libjpegと喧嘩するから/usr/local/opt/jpeg-turboに入れるね♪とか言っていた気がする(ログ取ってない)
そこで、configureのオプションに--with-jpeg=/usr/local/opt/jpeg-turbo を付けて上げたら、無事に行けたような気がする。
homebrewは/usr/local/のオーナーが自分なので、sudoせずにmake installまで行ける。
ここまでやって、portsはどうなってるんだろう?と思ってみたところ、portsにはlibjpegはなくlibjpeg-turboしかない。(でもjpegとかopenjpegとかある)
そして、LibVNCServerのportの依存関係にあったのはjpegだった。
さて、せっかくビルドできたので、また野良Formulaを作ってみる。
Formula Cookbook · mxcl/homebrew Wikiに従い、brew createすると、
% brew create http://sourceforge.net/projects/libvncserver/files/libvncserver/0.9.9/LibVNCServer-0.9.9.tar.gz/download
Formula name [download]: 
Formula nameを聞かれた。これは、LibVNCServerのダウンロードURLが、ファイル名ではなくdownloadで終わっているせいだろう。そこで、LibVNCServer と入れてenterを押すと、勝手にファイルが作られてviが起動した。
後は、作られたファイルの中身とにらめっこしながら、消せって書いてあるコメントを消したり、homepageを埋めたり、依存関係を埋めたりして進めていく。
test のところが、デフォルトの実装だと受け入れないよ?とか書いてあるんだけど、ライブラリの場合に何を書けば良いのかわからなかったので放置した。本家にpull reqする度胸ないし。(良く考えたら、他のライブラリのFormulaを参考にすれば良かった)
動作確認をしたら、githubに"homebrew-"で始まるリポジトリを作り、そこにFormulaを置いておくと、brew tap で使えるようになる。
私の場合は、homebrew-local にしてみたので、false-git/homebrew-localになる。
これを他の人が使いたい場合は、以下のようにする。
% brew tap false-git/local
% brew install libvncserver

Qtのプロジェクトから使えるようにする
LibVNCServerが入ったので、こいつをQtから使えるようにする。
LibVNCServerはpkg-configに対応しているので、pkg-config --cflags libvncserver とすればコンパイル時に必要なオプションが得られるし、pkg-config --libs libvncserver とすればリンク時に必要なオプションが得られる。MacPortsで入れた人もHomebrewで入れた人も同じMakefileが使えるわけだ。
と言うわけで最初に書いたバージョン。
QMAKE_CXXFLAGS += `pkg-config --cflags libvncserver`
LIBS += `pkg-config --libs libvncserver`
これでも動くんだけど、みんながVNC Serverを使うわけでもないだろうから使うかどうかを外から指定できるようにしたくていろいろ調べていたら、そもそもQtがpkg-configに対応してそうなことがわかってきた。
そこで書いたバージョン2。
!isEmpty(WITH_VNC) {
    DEFINES += WITH_VNCSERVER
    CONFIG += link_pkgconfig
    PKGCONFIG += libvncserver
}
これで、qmakeを実行するときにqmake WITH_VNC=1とか書くと、libvncserverをリンクしてくれるはずだったんだけど、libvncserverが見つからないって言われる。
なんでだろー、と調べていくと、Using pkg-config with Qt Creator/qmake on Mac OSX - Stack Overflowと言うページを発見。OS Xの場合は、QT_CONFIGにno-pkg-configが指定されてしまっているので、わざわざそれを外してやる必要があると。
そこで最終形。
!isEmpty(WITH_VNC) {
    DEFINES += WITH_VNCSERVER
    QT_CONFIG -= no-pkg-config
    CONFIG += link_pkgconfig
    PKGCONFIG += libvncserver
    SOURCES += vncserver.cpp
    HEADERS += vncserver.h
    message("with VNCServer")
}
SOURCES += と HEADERS += については先の回で説明するとして、とりあえずこんな感じで書いて上げると、もしlibvncserverがインストールされていない状態で qmake WITH_VNC=1 すると、qmake時にエラーが出て教えてくれる。
さて、これでコマンドラインからビルドする分には困らなくなったんだけど、Qt Creatorからビルドしようとするとpkg-configが見つからなくてエラーになる。
なんでだろー、と(こればっかり)・・・。osx - Environment variables in Mac OS X - Stack Overflow
Macの場合は、DockとかSpotlightから起動するアプリはユーザのシェルじゃなくてlaunchdから起動される。このため、.zshrcとかに環境変数を書いておいても、Qt Creatorには影響しないのだ。
  • 「launchctl setenv 変数名 値」で環境変数が設定できる
  • でもログアウトしたら忘れるよ
  • ~/.launchd.conf に書いたらおk
  • 最近のOS Xだと効かないよ
  • ワークアラウンドとして、~/Library/LaunchAgents/local.launchd.conf.plist ってファイル作って、以下の内容書いとけ
みたいな流れかな。system wideのpathだったら、/etc/paths.d/ に書くって言う手もあるけど、rootに影響する環境には書きたくないのよね。

と、言うわけでここまでが準備編。次回は、LibVNCServerの使い方について触れていこうと思いますが、いつになるかわかりません。
2014年3月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
[New] [Admin]

最近のコメント

FreeBSDで日本語マニュアル by false: コメントありがとうご
FreeBSDで日本語マニュアル by satoumc: いろいろ検討した上で
841SHとAperture by false: 試してみたところ、デ
841SHとAperture by false: なんと、今度親の携帯
841SHとAperture by 匿名: 841SHで撮るとき

Photos

  • zabbix_3.png
  • zabbix_2.png
  • zabbix_1.png
  • Lhaplus-1.png
  • mt-error.jpg
  • lisp-type.png
  • graph_47_5.png
  • items.jpg
  • feeds.jpg
  • false.jpg

アーカイブ

コンタクト

広告

Powered by Movable Type 5.2