sys-apps/groff-1.20.1-r1(man)の日本語の文字化けを解消する(on Gentoo)

sys-apps/groff-1.20.1-r1を使用して日本語の文字化けを解消する方法のメモ。
UTF-8な環境だと日本語が化けてしまうのですが、EUC-JPからUTF-8に明示的に変換するとこで日本語の表示ができました。

手順

/etc/man.confのJNROFF行を下記のように変更します。

JNROFF          /usr/bin/groff -DeucJP -mandoc -Tutf8

これで終わりです。

備考

引数

参考

  • man
$LANG=c man groff

Linux(Gentoo)をサーバにしてMac OS X 10.6(Snow Leopard)とファイル共有してみた(AFP over TCP)

LinuxMac間でファイルのやりとり出きるようにしていないことに気がついたので、AFPデーモンをLinuxに立ててファイル共有することにしました。

NFSも考えましたが設定がいろいろと面倒くさいのでやめてAFPにしました。AFPというのはAppleが開発したファイル共有プロトコルです。Mac OS X以前はAppleTalkの一部でしたが、現状はTCP/IP上で動くプロトコル(AFP over TCP)となっています。

ゴール

AFP経由でLinuxのhomeのユーザディレクトリにアクセスする。

細かいうんちくは備考にまとめてあります。

環境

手順

  1. netatalkを導入する
  2. /etc/netatalk/nettatalk.confを変更する
  3. /etc/netatalk/afpd.confを変更する
  4. /etc/netatalk/AppleVolumes.defaultを変更する
  5. netatalkデーモンを起動する
  6. netatalkデーモンをrcに登録する
  7. Macでマウントする

netatalkを導入する

LinuxでAFPを使用する場合はnetatalkを使用します。入れるだけなので簡単です。

$sudo emerge netatalk

/etc/netatalk/nettatalk.confを変更する

下記のように設定します。netatalk.confから変更が必要な部分だけを抽出しています。

ATALKD_RUN=no
PAPD_RUN=no
CNID_METAD_RUN=yes
AFPD_RUN=yes
TIMELORD_RUN=no
A2BOOT_RUN=no

Apple Talkが不要なのでATALKD_RUNはnoとなります。

/etc/netatalk/afpd.confを変更する

下記の行をファイルに追加してください。それぞれの引数の意味は備考にまとめてあります。

- -noddp -uamlist uams_dhx2.so

/etc/netatalk/AppleVolumes.defaultを変更する

ここは設定できるボリュームの設定をします。ユーザのホームディレクトリやビデオやオーディオ、TimeMachineのバックアップ先の指定などが可能です。

ユーザのホームディレクトリの共有を行うのが目的なのでファイルに"~"を挿入します。というか、元々"~"は入っていました。

~

その他のオプションは備考で簡単に紹介します。

netatalkデーモンを起動する

特に何も考えることもなく

$sudo /etc/init.d/atalk start

netatalkデーモンをrcに登録する

何も考えることも無く

sudo rc-update add atalk default

Macでマウントする

Finderの「サーバに接続」機能を使用します。下記で接続できます。

[ユーザ名]はサーバ側と同じであれば特に指定不要です。

# ユーザ名を指定する場合
afp://[ユーザ名]@[アドレス]

# ユーザ名を指定しない場合
afp://アドレス

備考

AppleTalkはなくなりました

AppleTalkMacに搭載されている辞書だと下記の用に紹介されています。

アップルが提供していた、コンピュータネットワークのためのソフトウェアツールのセットです。AppleTalk ネットワークシステムは、Mac OS X を使用する Macintosh コンピュータでは TCP/IP ネットワークにその役割が引き継がれました。

もともとAFPはAppleTalkプロトコル上で動いていた分けですが、AppleTalkプロトコルが廃止されるとともにAFP over TCP/IPとなりました。

CNIDとは

Catelog Node ID(CNID)の略称でファイルやディレクトリに割り当てられたIDです。AFPではこのIDを用いてファイルへの要求を行います(パスを用いては行いません)。例えばファイルの指定はファイルの指定に文字列使用し、ディレクトリの指定にCNIDを使用すると言った具合です。

netatalk.confの設定について
  • unixcodepage
  • maccodepage

上記の文字コード指定の項目がありますがUTF-8で運用していれば変更の必要はありません。
Mac OSのバージョンが古い(AFP2.2まで)場合などはクライアントの文字コードを正しく指定する必要がある場合があるので注意が必要です。詳しくはhttp://netatalk.sourceforge.net/2.0/htmldocs/configuration.html を参照ください。

afpd.confの設定について
- -noddp -uamlist uams_dhx2.so

下記に引数の意味をまとめました。

  • noddp:AFPをAppleTalk上で扱うかどうかを設定しています。AppleTalkは使用しないので[no]を付加しています
  • uamlist:使用するUAM(User Authentication Modules)を指定します
    • uams_dhx2.so:パスワードが最大256文字までサポートされたモジュールです。MacOS X 10.2から導入されています

もし、AppleShare client 3.8.4〜Mac OS X 10.2より前のバージョンとでやり取りを行いたい場合は"uams_dhx.so"を指定します。
全てのMac OSを対象にしたい場合は"uams_randnumo.so"を指定することで可能になります。
モジュールは複数指定することも可能です(','で区切ることにより)。

AppleVolumes.defaultsの設定について

この記事ではホームディレクトリにアクセスするのが目的だったので"~"で終わらせてしまったので、ざっくり紹介。詳しくはmanをどうぞ。

下記が基本となる記述になっています。

path [ volume name ] [ options ]
  • path:ボリュームへのパスを指定します。"/home/ktomoya/xx"といったパスや"/var/afpd/timemachine/$u"といった$[a-z]の記述でユーザ名など動的要素も指定できます。
  • [ volume name ]:ボリュームの名称を指定します。"Music"といった名称や"Music for $g group"のようにパスと同様に動的要素も指定できます。
  • [ options ]:allow,denyユーザやtimemachine対応か否か

感想

特に何もとらぶるなく終わってしまうと何のノウハウも蓄積されないので微妙。

今後

TimeMachineとか試しに使ってみようかなぁ。

参考

更なる情報は参考元をどうぞ。
manは日本語もありますが、古いので"LANG=c"で英語を見るのをお勧めします。

LSI Logic 3ware 9750-4iを導入する(Gentoo Linux)

LSI Logic 3ware 9750-4iを購入したのでGentooLinuxに突っ込んだときのログです。カーネルモジュールの有効〜ユニットの作成までをまとめてみました。
中で触れていませんが、ユニットの作成は3BM(BIOSベース)や3DM2(ブラウザベース)でやった方が簡単です。

環境

流れ

  1. カーネルモジュールを有効にする
  2. tw_cliの導入
  3. ユニット(とボリューム)の作成
    1. コントローラオブジェクトの番号確認とフォーカスの移動
    2. ディスクの確認
    3. ユニット作成
    4. ユニットの確認

カーネルモジュールを有効にする

下記、モジュール各々を有効にします。

Device Drivers
  SCSI device support
    <*> SCSI disk support
    [*] SCSI low-level drivers  --->
      <M>   3ware 97xx SAS/SATA-RAID support
      # 起動ディスクにする場合は、 initrdにモジュールを含めるか、*にする

tw_cliの導入

tw_cliを導入します。tw_cliは3ware向けのコンフィギュレーションツールです。9750シリーズは、バージョン10以降が必要になります。

インストールパッケージのダウンロード

自分でパッケージのダウロードが必要です(ダウンロード時にライセンスに同意しないといけないから?)。また、ダウンロード先は変更される可能性があるので注意です。
ダウンロード後"/usr/portage/distfiles/"にコピーします。

http://www.lsi.com/DistributionSystem/AssetDocument/cli_linux_10.1.zip

package.keywordsへの追加
$sudo sh -c "echo 'sys-block/tw_cli' >> /etc/portage/package.keywords"
tw_cliのインストール

準備が整ったのでインストールします。

$sudo emerge tw_cli

以上で完了です。以降はtw_cliを使ってディスクの設定を行います。

ユニット(とボリューム)の作成

ユニット/ボリュームの作成を行います。ユニットとボリュームの詳細は備考欄をご覧ください。
まずは、tw_cliを起動します。

#tw_cli
コントローラオブジェクトの番号確認とフォーカスの移動

追加したRAIDカードが何番目のコントローラーオブジェクトに割り当てられているかを調べます。
実行すると下記のようになります。

//xx>show
Ctl   Model        (V)Ports  Drives   Units   NotOpt  RRate   VRate  BBU
------------------------------------------------------------------------
c6    9750-4i      3         3        1       0       1       1      -     

c6に割り当てられているのでフォーカスを変更します。

//xx>focus /c6
ディスクの確認

RAIDカードに接続しているディスクのポートを確認します。
VPort 0-2にディスクが接続されていることが確認できます。今回は0-2のディスクを用いてRaid5を構築します。

//xx>show
Unit  UnitType  Status         %RCmpl  %V/I/M  Stripe  Size(GB)  Cache  AVrfy
------------------------------------------------------------------------------  

VPort Status         Unit Size      Type  Phy Encl-Slot    Model
------------------------------------------------------------------------------
p0    OK             u0   1.82 TB   SATA  0   -            ST32000542AS        
p1    OK             u0   1.82 TB   SATA  1   -            ST32000542AS        
p2    OK             u0   1.82 TB   SATA  2   -            ST32000542AS        
ユニット作成

ユニットの作成はaddコマンドを用いて行います。

//xx>/c6 add type=raid5 disk=0-2
  • type:raidの種類(raid0,1....)を指定します。今回はraid5を指定しています。
  • diskに使用するディスクのポート番号を指定します。今回はp0-2を指定しています。

また、下記項目は任意設定項目です。変更する必要がないので変更していません。他の設定値は備考やマニュアルをご覧ください。

  • Read Cache:標準で有効
  • Write Cache:標準で有効
  • 先読み処理:標準で有効
  • ストリップサイズ:256kb
ユニットの確認

作成したユニットを確認します。まずはコントローラオブジェクトレベルからです。
u0が作成されています。

//xx>/c6 show

Unit  UnitType  Status         %RCmpl  %V/I/M  Stripe  Size(GB)  Cache  AVrfy
------------------------------------------------------------------------------
u0    RAID-5    OK             -       -       256K    3725.27   RiW    ON     

VPort Status         Unit Size      Type  Phy Encl-Slot    Model
------------------------------------------------------------------------------
p0    OK             u0   1.82 TB   SATA  0   -            ST32000542AS        
p1    OK             u0   1.82 TB   SATA  1   -            ST32000542AS        
p2    OK             u0   1.82 TB   SATA  2   -            ST32000542AS    

次にユニットレベルで確認します。u0/v0というボリュームが作成されています。
このボリュームが実際にカーネルからディスクとして認識されます。(ボリュームの詳細は備考をご覧ください)。

//xx>/c6/u0 show

Unit     UnitType  Status         %RCmpl  %V/I/M  VPort Stripe  Size(GB)
------------------------------------------------------------------------
u0       RAID-5    OK             -       -       -     256K    3725.27   
u0-0     DISK      OK             -       -       p0    -       1862.63   
u0-1     DISK      OK             -       -       p1    -       1862.63   
u0-2     DISK      OK             -       -       p2    -       1862.63   
u0/v0    Volume    -              -       -       -     -       3725.27  

以上で作成完了です。dmesgからディスクが認識されていることが分かります。

$dmesg
 scsi 6:0:0:0: Direct-Access     LSI      9750-4i    DISK  5.12 PQ: 0 ANSI: 5
 sd 6:0:0:0: [sdc] 7812456448 512-byte logical blocks: (3.99 TB/3.63 TiB)
 sd 6:0:0:0: Attached scsi generic sg4 type 0
 sd 6:0:0:0: [sdc] Write Protect is off
 sd 6:0:0:0: [sdc] Mode Sense: 23 00 10 00
 sd 6:0:0:0: [sdc] Write cache: disabled, read cache: enabled, supports DPO and FUA
 sdc1
 sd 6:0:0:0: [sdc] Attached SCSI disk

今回は約3.7TBのディスクを作成しました。2Tバイト以上のパーティションMBR(現行PC/ATで使用されているパーティションテーブル)で扱えないのでGPTを必要とします。GPTの扱いについては http://d.hatena.ne.jp/ktomoya/20100912/1284256525 を参照ください。

備考

LSI Logic 3ware 9750-4iについて

選択した理由は単純に3wareが枯れているからという理由です。。。あとは、メモリキャッシュが欲しかったけです。

  • 4ポートSATA+SAS 6Gb/s
  • ロープロファイル対応
  • x8 PCI Express® 2.0 インターフェース
  • 512MB DDRII ECC cache (800MHz)
  • バッテリーバックアップオプション対応
  • 最大96ディスク接続可能
  • RAIDレベル0, 1, 5, 6, 10, 50,Single Disk対応
  • リビルドにおけるオートリジュー
  • 再編成におけるオートリジュー
  • 動作中にディスクのサイズ変更可能
  • 動作中にRAIDレベルの変更可能
  • Global hot spare with revertible hot spare support
  • 自動リビルド対応
  • Single controller multipathing (failover)
  • I/Oロードバランシング
  • 広範囲に渡るRAID管理スイート
ユニットについて

ユニットは複数のディスクを束ねたオブジェクトを指します。束ね方はraidtypeで指定します。

ボリュームについて

ユニットを任意の容量で切り出し、実際にディスクとして認識されるオブジェクトです。

ユニット作成コマンド引数詳細

ユニット作成コマンドの引数について少し細かく説明します。

# 全体
/cx add type=<RaidType> disk=<p:-p> [stripe=size] [noscan] [group=<3|4|5|6|7|8|9|10|11|12|13|14|15|16>] [nowrcache] [nordcache| rdcachebasic] [autoverify] [noqpolicy] [ignoreECC] [name=string] [storsave=<protect|balance|perform>] [rapidrecovery=all|rebuild|disable] [v0=n|vol=a:b:c:d]
  • type:作成するユニットのタイプを設定します。 タイプにはraid0,raid1,raid5,raid6,raid10,raid50,single(ディスク1つでユニットを作成するときに選択する), spare(スペアディスクとして設定) と多数あります。
# RAID0を選択した場合(diskは0と1)
//xx>/cx add type=raid0 disk=0:1
  • disk:ユニットに割り当てるディスクを選択する
# p0〜p2とp4を選択した場合
//xx>/cx add type=raid6 disk=0-1:4 
  • stripe(任意):RAIDカードがデータを管理する際のブロックサイズの設定です。16KB,64KB,256KBから選択可能です(RaidTypeによって選択可能なサイズはことなりますのでマニュアル参照)。
# Stripサイズに64Kを指定した場合
//xx>/cx add type=raid1 disk=1:2 stripe=64
  • v0,vol(任意):ボリュームのサイズを指定します。
      • v0:1つ目のボリュームのサイズを指定します。残り領域はもう一つのボリュームが作成されます
      • vol:先頭から4つまでの任意のボリュームサイズを指定できます。4つで全て使い切らなかった場合には、carveサイズ単位でボリュームを作成します(標準:1TB, 最大:32TB)。carveサイズは変更可能です。
# v0で1つ目のボリュームサイズ(1024GB)のみを指定する。
//xx>/cx add type=raid5 disk=0-2 v0=1024

# volで複数のボリュームを作成します。10GB,5GB,200GB,5GBで切っています。
# ディスクの残りはcarveサイズ単位となります。
//xx>/cx add type raid5 disk=0-3 vol=10:5:200:5

下記以降はマニュアルをどぞ。

  • group=3,4,5,6,7,8,9,10,11,12,13,14,15,16
  • noscan(任意)
  • nocache,nowrcache(任意):ライトバックキャッシュを無効にするとパフォーマンスが非常に落ちるのでおすすめしません。(10MB/sとかになりました。。。)
  • nordcache,rdcachebasic(任意)
  • autoverify(任意)
  • noqpolicy(任意)
  • ignorECC(任意)
  • name=string(任意)
  • rapidrecovery=all,rebuild,disable(任意)
  • storsave=protect,balance,perform(任意)
その他のコマンド
  • /cx/ux del:ユニットを削除します
  • /cx/ux migrate:作成済みのユニットの構成を変更します(RAIDレベルの変更やstripeサイズの変更など)
今後
  • 3DM2入れてみる
  • ベンチとってみる(ストリップサイズの違いで)

2TBより大きいパーティション扱う(Linux)+HDDのアライメントについて

最近はHDDだと、2TBの製品もだいぶ安くなったので人によってはRAID5やRAID6と組み合わせて、4TBや6TBの容量のパーティションを作成する機会も増えてきたかと思います。

私のメインPCも2TB * 3なRAID5を導入したので、そのときに行った手順のログです。

// 気がついたらHDDのアライメントについての記事になってしまいました。。

やること

  1. kernelの GPTを有効にする
  2. partedの導入
  3. partedでパーティションを作成する
  4. 備考

GPTを有効にする

カーネルのGPTのコンフィグを有効にします。自前でカーネルのコンフィグを変更してたら行ってください。
下記を有効にします。

File System -> Partition type -> Advanced partition selection -> EFI GUID Partition support

また、上記付近にある"PC BIOS (MSDOS partition tables) support"は消さないように注意です。既存のパーティションをマウントできなくなります。

partedの導入

partedとはディスクのパーティション作成及びパーティションのリサイズを行うためのプログラムです。

$sudo emerge parted

partedでパーティションを作成する

partedでパーティションを作成します。下記が手順になります。

$sudo parted /dev/[ブロックデバイス]
>mklabel gpt
>mkpart p [ファイルシステム名] 1M -1
>q
  • mklabel gpt

GPTの作成を行います。これは、MBRにかわるパーティション管理領域形式です。

備考

  • GPT(GUID Partition Table)について

2TB以上の容量を認識するためにはMBRではなく、GPTでテーブルを作成する必要があります。GPTはIntelの提唱するEFIのサブセットです。

  • MBRで2TBまでの理由

MBRではディスクの総セクタ数を4バイト(32ビット)で表しているので、単純に計算すると、下記になります!ちなみに、開始セクタ位置も4バイトです。

512Bytes/セクタ * 2^32セクタ * ( 1 / (1024 *1024 * 1024 * 1024))T = 2TB
  • fdiskを使用しない理由

GPTに対応していないためです。GPT対応のfdiskもあったりします。

  • mkpartfsについて

このコマンドは、パーティションの作成と一緒にファイルシステムの作成も行うコマンドです。ただし、manの注意書きにもありますが、このコマンドは使わないことを推奨されています。理由はext2progs等の公式の外部ツールを用いてファイルシステムを作成していないためです。

最近のHDDは物理1セクタ4KB(従来は512バイト)になっていて、それをHDD内で論理1セクタ512バイト(1物理セクタ=8論理セクタ)に置き換えて互換性を実現しています。
HDDの第一パーティションは懐かしのCHSで位置を表していた頃の名残で1シリンダ目からという制限がMSDOSの時代からありました(WindowsVistaでこの歴史がソフトウェアレベルでは終わりました。Vistaは第1パーティションを1MBで始めます)。これだけだと、あぁそうなんだって感じなのですが、シリンダの単位に問題がありました。

1シリンダ = 63LBA(LBA=512バイト)

なのですが、これ8で割れないんですよね。なので、書き込み時、読み込み時に2つ分の物理セクタにアクセスすることになります。どういうことかというと、4KBは8*512バイトで構成されています。ここで1パーティション目を63LBAで開始すると、

C0:[8+8+...+8+7] C1:[1+8+....] )

というように、C1の先頭512バイト分だけ余分に別の物理セクタから調達してくる必要が出てきます。で、さらにここでファイルシステムのブロックファイルは4KBです。なのでHDDへのアクセスは4KBで8論理LBA単位です。
先ほど63LBAでパーティションを切ったので、8の倍数分(4KB)アクセスされると毎回2物理LBAの領域を書き換える必要があります。つまり、データの読み書きを行う度に余分なセクタへのアクセスが発生することになり、IOのパフォーマンスに影響します(特にランダムアクセス)。

この問題を避けるために、HDDでは1シリンダ目のアライメントとして、無効な論理セクタ領域を割り当てて、物理セクタがはみ出ないようにしています。1シリンダ目の問題をパスすれば後はLBA単位で考えればいいのでアライメントの問題は回避できます。

無効[1] C0[7+8+8+...+8] C1[8+8+8+...]

で、1シリンダ目からパーティションを作る場合はこれで平気なんですが、1MBから作るとどうなるの?って問題になります。8で割り切れないのを回避するためにアライメントしているので、逆に8の倍数で切られると半端が出てしまうということです。

ただ、この辺はメーカやHDDのモデルごとに事情が変わってくるので、一概に1MBはだめってことにならないです。またWindowsが1MBでやり始めたのでメーカは追従してくると考えるととりあえず1MBでいいと考えるのが妥当です。

  • Performance測定

時間見つけて、どの程度性能差が出るのか調べてみます。(2TBのディスクやRAIDカードで)

後書き

GPTのコンフィグを有効にしていないことに気がつくのに2週間かかりました。。。

EXT4のゼロレングス問題(zero-length problem)に対処したマウントを行う

ext4で問題となっているゼロレングス問題に対処するためのマウント方法です。

方法は、noauto_da_allocオプションを追加してマウントするだけです。

マウント方法

$sudo mount デバイス ターゲット -t ext4 -o noauto_da_alloc

ゼロレングス問題(zero-length problem)とは

特定のファイル操作によりファイル置換が行われたのちに、システムが強制終了したなどが原因でsyncが完了していない状態で終了した場合に0バイトファイルになってしまうというものです。

特定のファイル操作とは、

  1. fd = open("foo.new")
  2. write(fd,..)
  3. close(fd)
  4. rename("foo.new", "foo")

などのパターン、あるいは

  1. fd = open("foo", O_TRUNC)
  2. write(fd,..)
  3. close(fd)

パターンで、fsync() を使わないで既存のファイルを入れ替えることです。

原因は、アプリのファイル操作に問題があり、EXT4から追加されたファイルブロックの遅延アロケーションで問題が発生するためです。

fd = open("foo.new")/write(fd,..)/close(fd)/rename("foo.new", "foo") の場合
  1. ファイル生成
  2. リネーム処理
  3. 遅延アロケーション

の順番に処理が行われる。ファイル生成ー>リネーム処理の流れで行うため、2で電源断が発生すると、ファイルを生成してリネーム処理を行ったという操作がファイルシステム上で有効になり、データの書き込みは行われていないため0バイトとなってしまいます。

fd = open("foo", O_TRUNC)/write(fd,..)/close(fd)パターンの場合
  1. fooファイルを0バイトにする
  2. 遅延アロケーション

これも原理は同じで、1.が完了して電源断が発生すると、0バイトファイルになってしまいます。

noauto_da_allocがやっていること

やっていることは単純で、上記のような処理の流れをファイルシステム側で検知して処理の順番を変更し、データの書き込みが完了してからリネームを行うようにします。

  1. ファイルの生成
  2. データの書き込み
  3. リネーム処理

備考

EXT4をSSD向けにマウントする

EXT4を用いて、SSDで用いられているTrimコマンドを使用するためのオプションです。

Trimコマンドを有効にする

方法は非常に簡単で、discardオプションをマウント時に渡すだけです。

  • mountコマンドでマウントする場合
$sudo mount /dev/sd[0-9]+ /mnt -t ext4 -o discard

他のオプションと組み合わせる

他、SSDに有効なオプションとして relatimeがあります。これは、必要な場合を除いてアクセス時間(ファイルを最後にオープンした時間)を更新しないものです。

  • mountコマンドでマウントする場合
$sudo mount /dev/sd[0-9]+ /mnt -t ext4 -o discard,relatime

備考

Trimコマンドとは、SSDに対して使用していた領域が不要になったことを明示するものです。
SSDはウェアリングという、1つのブロックが使い続けられて寿命が一部だけ寿命が縮まるのを防ぐ技術で、ある、ブロックへの書き込み指示が発生した場合、使用回数が少ない空き領域を割り当てて使用回数を平均化します。このときに、空き領域である必要があるのすが、通常のファイルシステムの場合、ファイルを削除するとディレクトリツリーからの切り離しだけを行います。
つまり、SSDにとっては不要になったのかどうかを判断できない訳です。それをTrimコマンドで明示することで、ウェアリングの効率を向上させることができます。