郵便番号データは自分で加工しない
結論を先に。
- 細かい要件がない場合,zipcloud さんの提供している加工済データを使う (日本郵便さんの提供している原本ではなく)
- ライセンスが不明だけど Web API の利用規約とかみると商用利用等も OK と思われる
- わりきって Web API を使う (よそにまかせる) というのも手かも
- いろいろあるし。前述の zipcloud さん自身も検索 API を提供している。
以下各論。
- いわゆる ken_all.csv を (必要フィールドだけ) そのままデータベースにつっこむなんてのは (わかってやってる場合はともかく) やってはいけない
- 複数行に分割されているレコードがあるため,マージする必要がある
- 明文化されていない仕様などがありマージやクリーニングを自力でおこなうのは大変 (バッドノウハウのかたまり)
- さまざまなバッドノウハウを適用済の「きれいなデータ*1」を zipcloud さんが提供している
- しかも Web API やメールによる更新通知サービスも提供なさっている
- ただし,「郵便番号から住所を検索するサービスにまともなものがない - ぐるぐる~」の要望に完全に沿ったデータというわけではない
- 地番や丁目を括弧内で「〜」等表記してある場合などはその部分を削除してある
- 同一郵便番号で複数の町域名が対応する場合,複数レコードに分解してある (郵便番号ユニークではない)
- 事業所の個別郵便番号*2についてはマージされていない
- 仕様があわない場合は自力でがんばる必要がある
- 地名→郵便番号変換したいときとか,GIS 情報をからめたいときとかも
- 自力でがんばるとき参考になるサイト
- ろっきーさんの関連記事 (郵便番号検索 – my-hobby カテゴリ)
- あと再掲だけど 郵便番号から住所を検索するサービスにまともなものがない - ぐるぐる~
Compiz を Python からあやつる
タイトルは大袈裟。
ここ半年ほど Compiz のワークスペース切替器にキューブではなくデスクトップの壁(wall)を使っています。こっちのほうがキビキビ動くし。
んでこの wall plugin ですが,システム起動直後だと,ワークスペース切替時に壁紙がスクロールしないんです。まぁそんな仕様だと思えばいいんですけど,CompizConfig 設定マネージャを立ち上げて,「デスクトップの壁」プラグインを一度無効化して有効にすると,壁紙もスクロールするようになります。じゃあそういう仕様じゃないじゃん。
いままでいちいち起動後に CompizConfig 設定マネージャを立ち上げて修正していたんですけど,めんどくさい。CompizConfig 設定マネージャ*1が Python で書かれているっぽいので Python から Compiz の挙動を操作できるんじゃね,と思ってやってみました。
import time import compizconfig ccs = compizconfig context = ccs.Context() wall = ccs.Plugin(context, 'wall') wall.Enabled = False time.sleep(1) wall.Enabled = True
いちいち compizconfig.Context()
って書いてもいいんだけど長ったらしいので ccs = compizconfig
ってしてます((まぁ本気で短く書こうと思ったら compizconfig
のままやったほうが今回は短いと思う。Context
オブジェクトもわざわざ変数に代入する必要ないし。))。って実は CompizConfig 設定マネージャのソースの真似。Python ってこういう書き方もできるのねと勉強になりました。
time.sleep()
なしでもうまく動くかなと思ったけど,ムリだったので入れてる。1秒も待たされるのはアレだけど,まぁ実害ないというか設定マネージャ立ち上げるより百倍はやいので。
ソース見ると相当たいしたことないでしょ。でも API ドキュメントとかが全然なくて結構苦労しました。
Compiz の Git レポジトリは Compiz Git repository browser とかで見られるんだけど,libcompizconfig のソースから[http://cgit.compiz.org/compiz/compizconfig/libcompizconfig/tree/include/ccs.h:title=include/ccs.h]
とか Python バインディングのソースから[http://cgit.compiz.org/compiz/compizconfig/compizconfig-python/tree/src/compizconfig.pyx:title=compizconfig.pyx]
とか見ながら書いた。
*1:よくよく考えたら変な名前ですよね。まぁ英語でももともと CompizConfig Setting Manager ですけど。
電源連動 USB HDD の切断・再接続を CLI で
さいきんの外付けハードディスクは電源連動機能とかついてたりしますね。んで,たとえば REGZA とかにつなぐと,テレビの電源を on にしたときだけハードディスクの電源が on になったりします。
同じようなことを Linux からもやってみたい。
といっても PC の電源を切ったらハードディスクの電源が切れるのは当たり前。PC の電源を入れっぱなし HDD 接続しっぱなしで,ソフトウェア的に HDD の電源を入れたり切ったりできたらいいなぁと思いやってみました。
もしうまくできれば,たとえば定時バックアップの際だけハードディスクの電源を入れて,バックアップが終わったら電源を切るとかできそう。かえって寿命が落ちるかもしんないけど。
調べてみたら,またたびりなっくす UbuntuでのUSBメディアの安全な取り外し とかその元ネタの Yan Li's Words: Safely remove an USB hard drive in Linux とかですでにやられてました。再接続までコミでやってるのはなかったので一応記事におこしておきます。
実験環境は下記の通り。
- OS: Ubuntu 10.04 (Lucid Lynx) Kernel 2.6.32(-23) i386 pae
- PC: Dell Inspiron mini10v
- USB HDD: IO-DATA HDCR-U シリーズ
切断編
前提として,アンマウント済みになってるとする。
1. 下調べ
いくつか知っておく必要のある ID がある。
udevadm
というコマンドを使うと,デバイスノードパスからこれらの情報を取得することができる。今回の例だと HDD が /dev/sdc
にぶらさがっているとする。
$ sudo udevadm info --query=path --name=/dev/sdc /devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host3/target3:0:0/3:0:0:0/block/sdc
出力結果のうち
1-8
ってところが,USB のバス ID = 1, デバイス ID = 8 であることを示している3:0:0:0
ってところが SCSI のホスト ID = 3, チャネル = 0, デバイス ID = 0, LUN = 0 であることを示している
ちなみに,SCSI デバイスとしての各種 ID を知りたいだけなら /proc/scsi/scsi
の中身を見てもわかる。
$ cat /proc/scsi/scsi Attached devices: Host: scsi0 Channel: 00 Id: 00 Lun: 00 Vendor: ATA Model: WDC WD1600BEVT-7 Rev: 11.0 Type: Direct-Access ANSI SCSI revision: 05 Host: scsi2 Channel: 00 Id: 00 Lun: 00 Vendor: Generic- Model: Multi-Card Rev: 1.00 Type: Direct-Access ANSI SCSI revision: 00 Host: scsi3 Channel: 00 Id: 00 Lun: 00 Vendor: I-O DATA Model: HDCR-U Rev: Type: Direct-Access ANSI SCSI revision: 02
2. HDD へのフラッシュ(強制書込)
OS 側がアンマウントしていても,HDD 内部のキャッシュ内容がフラッシュされていない可能性がある(らしい)ので強制的にフラッシュする。非標準コマンドの sdparm
というコマンドを使うので apt-get などでインストールしておくこと。
$ sudo sdparm --command=sync /dev/sdc /dev/sdc: I-O DATA HDCR-U
んー。非同期で実行されている気もする。フラッシュが終了してるという確証はどうやったら得られるのだろう。
ちなみにたいていのディストリビューションで標準的にインストールされてる hdparm
の -f
コマンドも同じようなことができそうだけど,man 読んだ感じだと,あれは OS 側のバッファキャッシュをフラッシュするためのコマンドのような気がする。
さらに,同じコマンドを使ってデバイス(HDD)のスピンダウンを行うこともできるらしい。
$ sudo sdparm --command=stop /dev/sdc
だけど,手持ちの IO-DATA の HDCR-U だと,一度スピンダウンするもののそのあと再びすぐにスピンアップしてしまい意味がなかった。逆に壊れるんじゃないかと怖くなった。
3. SCSI サブシステムから切り離し
んで,いままでのコマンドはデバイスノードパス対象のコマンドだったんだけど,もう必要ない,というかデバイスノード経由でアクセスできると危ないので,切り離す。
切り離す前。
$ ls /dev/sd* /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb /dev/sdc /dev/sdc1
いままでの実行例でわかるとおり,USB HDD のデバイス名は /dev/sdc*
。
さきほど調べた SCSI デバイスとしてのホスト ID 等をパラメータとして指定しつつ /proc
ファイルシステムに下記のようなテキストを書き込む。
$ echo 'scsi remove-single-device 3 0 0 0' | sudo tee /proc/scsi/scsi
あ,tee
コマンドを使っているのは,今回の環境例が Ubuntu であり root 権限でコマンドを実行するには sudo 使うから。簡単に言うと,root 権限で
# echo 'scsi remove-single-device 3 0 0 0' > /proc/scsi/scsi
というのを実行しているのとほぼ同義。これをそのまま sudo でラップしてもリダイレクトしているのは一般ユーザ権限になってしまいうまくいかないので,tee コマンドを利用して root 権限でパイプ書込をしている。
ともかく,このようにすると,
$ ls /dev/sd* /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb
見事 /dev/sdc*
のデバイスノードが消えた。
4. USB パワーを落とす
いよいよ USB デバイスのパワーを落とす。
$ echo 'suspend' | sudo tee /sys/bus/usb/devices/1-8/power/level
これを実行したしばらくのち((IO-DATA の USB HDD の場合,だからかと思ったんだけど,ひょっとすると /sys/bus/usb/devices/*/power/autosuspend
のデフォルト値 2 が影響したのかもしれない。ちょっと未検証でわからん。see Manual driver binding and unbinding [LWN.net]))に実際にパワーが切れた。感動。
一番最初にあげた文献の例だとこれを行うまえに次で例示してある「USB サブシステムからの切り離し」をおこなっているんだけど,実際にはこの順序にしないと,後述する再接続ができなかった。
あと,この suspend
というコマンドトークンで USB 電源を切るのは,カーネルバージョン 2.6.32(つまり Ubuntu Lucid のカーネルバージョンだ)以下でしか使えないらしい。
2.6.33 以上だと /sys/bus/usb/devices/*/remove
というノードが新設されたのかな*1。ちょっとよくわからんです。
5. USB サブシステムから切り離し
OS の USB サブシステムから切り離す(ってこういう表現で合っているかもわかんないけど)。
$ echo -n '1-8' | sudo tee /sys/bus/usb/drivers/usb/unbind
再接続編
以上のようにして切断した USB HDD をつないだまま再接続(パワー on)するには,いままでの過程の逆をおこなえばよい。
まず USB サブシステムへの再接続(再登録)を行う。
$ echo -n '1-8' | sudo tee /sys/bus/usb/drivers/usb/bind
このとき以下のようなカーネルメッセージを吐くことがある。
usb 1-8: configuration #1 chosen from 1 choice usb 1-8: can't set config #1, error -1
対処方法がわかんないので無視する。IO-DATA の USB HDD だから出たってこともないみたい。たしか USB メモリスティックでも出力された気がする。
次に USB パワーを上げる。
$ echo 'on' | sudo tee /sys/bus/usb/devices/1-8/power/level
なおいままでのシーケンスの順序(USB サブシステムからの切断とパワーオフの順序とか)がよくないと下記のようなカーネルメッセージを吐いてうまくいかないことがある。
/sys/bus/usb/devices/1-8/power/level: Transport endpoint is not connected
そんなときは物理的に USB から外して再接続してやり直してみること。
SCSI サブシステムへ再接続する。
$ echo 'scsi add-single-device 3 0 0 0' | sudo tee /proc/scsi/scsi
すると(通常 HDD を USB で接続したときのように)下記のようなカーネルメッセージが表示される。
scsi 3:0:0:0: Direct-Access I-O DATA HDCR-U PQ: 0 ANSI: 2 CCS sd 3:0:0:0: Attached scsi generic sg2 type 0 sd 3:0:0:0: [sdc] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB) sd 3:0:0:0: [sdc] Write Protect is off sd 3:0:0:0: [sdc] Mode Sense: 3c 00 00 00 sd 3:0:0:0: [sdc] Assuming drive cache: write through sd 3:0:0:0: [sdc] Assuming drive cache: write through sdc: sdc1 sd 3:0:0:0: [sdc] Assuming drive cache: write through sd 3:0:0:0: [sdc] Attached SCSI disk
で,実際にデバイスノードも生成される。
$ ls /dev/sd* /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb /dev/sdc /dev/sdc1
あとはマウントするなりなんなり。めでたしめでたし。
課題
再接続編を見ればわかるとおり,再接続時においてもともと接続されていたときの SCSI サブシステム上のバス ID や USB サブシステム上のバス ID とかがわかっていることが前提となっている。これらをなんとか sysfs や procfs 経由で取得できればなぁと思う。
今回使った USB HDD。ファンレスなのはうれしいけど,電源投入後スピンアップするまでがちょっと遅いのとうるさい(ゴゴゴゴっていう)気がする。採用ドライブの個性で個体差ありそうだけど。
本文と関係ないけど,センチュリーの裸族のお立ち台って電源連動機能なかったなぁ(実際にはクーリングファンつきの eSATA プラスには電源連動機能がついてる),電源連動機能つきのああいうのがあれば REGZA 用に使いたいなぁ,と思ってたら,玄人志向のやつは電源連動があるっぽい。レビューがほとんどないのが不安。あと,HDD にアダプタつける形になるのかな?よくわからん。
SHDocVw で表示中のページをファイルに保存
せめて月イチくらいでは何かかきたいので書く。
んで,ブラウザコンポーネント(SHDocVw)で,表示中のページをファイルに保存する方法。ただし画像等のリソースファイルの保存(Web ページ、完全)や Web アーカイブとしての保存はできない。「Web ページ、HTML のみ」のイメージ。リソース込みで保存したい場合の方策はあるのかな。
ほぼ how to save html file in VC++ で引用されているサンプルのまま。
ほんとはフォームの pas ファイルからの切り出しなので FWebBrowser
が外在化してたりおかしいけど,サンプルなので。
uses OleCtrls, ActiveX, SHDocVw; var FWebBrowser: TWebBrowser; procedure SaveWebPage(AFileName: string); var PFile: IPersistentFile; WFileName: PWideChar; begin PFile := FWebBrowser.Document as IPersistFile; WFileName := StringToOleStr(AFileName); try PFile.Save(WFileName, False); finally SysFreeString(WFileName); end; end;
独立したプロシジャになってるけど,ほんとは NavigateComplete2 イベントが発火したあとに実行するなど,いろいろ考えなくてはいけない。
メリット
- Cookie 等について考える必要がない
デメリット
- エンコードミスマッチで文字化けしていた場合はどうなる?
- Excel や Word などが内部で開かれた場合はどうなる?
- エラー(5xx や 4xx 系)がおきた場合のハンドリングがめんどう(イベントドリブンなので)
つまり。
すでに SHDocVw コンポーネントを(オートパイロット的に)使っている場合には使ってもいい(価値がある)。そうでなくて wget 的ことがしたいときにわざわざ SHDocVw を使うのは意味がない。そのような場合たとえば WinInet などを使えばよい(.Net だと webClient を使うほうがお気楽かな)。WinInet で Cookie 込みで使うノウハウはまだもってないので,暇ができたらやってみたい。
Ubuntu 10.04 (Lucid) でスプラッシュスクリーンをなんとかする
なんとかするってなんだ。
わたしが使っているマシンの VGA は NVIDIA の GeForce 7600 GS です。結構古いですね。んで Ubuntu Lucid から NVIDIA のカードのデフォルトグラフィックドライバが nouveau というのにかわったんだけど,これから nvidia プロプラドライバに変更したら,起動時のスプラッシュスクリーンの表示が解像度が低くなってしまった。
実害はないんだけど,なんとなく気持ち悪いので直してみました。
[Lucid][Ubuntu 10.04] High resolution Plymouth & Virtual Terminal for ATI/NVIDIA cards with proprietary/restricted driver | Tux's idyllic life. がとても参考になった。英語に抵抗感のないひとはこちらを読んだらいいと思う。とてもわかりやすい構造で書いているので。
概要だけいうと,カーネルフレームバッファを uvesafb というドライバモジュール*1を利用するように変更する。なおスプラッシュスクリーンは Plymouth という機構にかわったらしいんだけど,そのへんのカスタマイズとかには興味ないので触れません。
まず,必要となるソフトをインストールする。uvesafb カーネルモジュール自体はもともと入ってるが,uvesafb には v86d
というコンポーネントが必要になるのでインストールする。また,使っているグラフィックカードの BIOS レベルで利用可能な画面解像度を調べるために hwinfo
というパッケージもインストールする(こちらは必ずしも必要ない)。
$ sudo aptitude install v86d hwinfo
さっそく hwinfo
コマンドを使って,使っているグラフィックカードでサポートされている VESA BIOS ビデオモードを確認する。sudo
つけなくても怒られないけど,下記のような結果を得ることができないのでつける。
$ sudo hwinfo --framebuffer 02: None 00.0: 11001 VESA Framebuffer [Created at bios.464] Unique ID: rdCR.XJVGY3Zr0S5 Hardware Class: framebuffer Model: "NVIDIA G73 Board - p345h0b " Vendor: "NVIDIA Corporation" Device: "G73 Board - p345h0b " SubVendor: "NVIDIA" SubDevice: Revision: "Chip Rev" Memory Size: 256 MB Memory Range: 0xd0000000-0xdfffffff (rw) Mode 0x0300: 640x400 (+640), 8 bits Mode 0x0301: 640x480 (+640), 8 bits Mode 0x0303: 800x600 (+800), 8 bits Mode 0x0305: 1024x768 (+1024), 8 bits Mode 0x0307: 1280x1024 (+1280), 8 bits Mode 0x030e: 320x200 (+640), 16 bits Mode 0x030f: 320x200 (+1280), 24 bits Mode 0x0311: 640x480 (+1280), 16 bits Mode 0x0312: 640x480 (+2560), 24 bits Mode 0x0314: 800x600 (+1600), 16 bits Mode 0x0315: 800x600 (+3200), 24 bits Mode 0x0317: 1024x768 (+2048), 16 bits Mode 0x0318: 1024x768 (+4096), 24 bits Mode 0x031a: 1280x1024 (+2560), 16 bits Mode 0x031b: 1280x1024 (+5120), 24 bits Mode 0x0330: 320x200 (+320), 8 bits Mode 0x0331: 320x400 (+320), 8 bits Mode 0x0332: 320x400 (+640), 16 bits Mode 0x0333: 320x400 (+1280), 24 bits Mode 0x0334: 320x240 (+320), 8 bits Mode 0x0335: 320x240 (+640), 16 bits Mode 0x0336: 320x240 (+1280), 24 bits Mode 0x033d: 640x400 (+1280), 16 bits Mode 0x033e: 640x400 (+2560), 24 bits Config Status: cfg=new, avail=yes, need=no, active=unknown
このカードでは BIOS レベルでは 1920x1080 とかサポートされてない。がーん。
以上で下準備おわり。
早速設定をしていく。GRUB2 の場合,/etc/default/grub
の該当部分を下記のように変更する。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset video=uvesafb:mode_option=1280x1024-24,mtrr=2,scroll=ywrap" GRUB_GFXMODE=1280x1024
GRUB_GFXMODE
のほうは別に指定しなくてもいいと思う。
キモは GRUB_CMDLINE_LINUX_DEFAULT
のほうなんだけど,quiet splash
はもともと設定されていると思う。
nomodeset
は KMS (Kernel Mode Setting) を無効にするという意味。今回のようにカーネルフレームバッファドライバとしては uvesafb を使うばあい,Kernel Mode Setting は使えない(フレームバッファドライバと X.Org ドライバが一致しないからね)んで指定しているみたい。たぶんわざわざ書かなくても自動的に KMS は無効になると思うんだけど。
で,video=uvesafb
がフレームバッファドライバとして uvesafb を使うという意味で以降その設定が続く。どんなオプションを指定できるのかは fb/uvesafb.txt 参照。
mode_option=1280x1024-24
というのは,さきほど hwinit
で調べた指定しうる解像度(と色深度)を指定する。
mtrr=2
というのは,MTRR レジスタ*2に設定する内容。わたしの環境では 2 を指定しているけど,とりあえず 3 を指定しておくとよい。後述。
scroll=ywrap
は,端的に言うと仮想ターミナル画面でのスクロールの実現方法を設定している。ywrap
, ypan
, redraw
を指定することができて,頭のほうから順にパフォーマンスがいい((わたしの GeForce 7600 GS だと scroll=ywrap
でひととおり問題なく動くんだけど,デュアルスクリーンの場合にセカンダリモニタの表示内容がスクロール時におかしくなる。実害ないのでそのままにしてるけど。))。
んで,カーネル起動時に uvesafb モジュールを読み込んでもらうために initramfs のほうにも指定しておく必要があるみたい。具体的には /etc/initramfs-tools/modules
に,
uvesafb mode_option=1280x1024-24 mtrr=2 scroll=ywrap
のように追記する。書式がちょっと違うけど,指定している内容はさきほどと同じ。
あと,/etc/initramfs-tools/conf.d/splash
というファイルを作成して
FRAMEBUFFER=y
という内容にする(もしすでにあれば追記する)。
以上のプロセスで GRUB2 や initramfs の設定を更新する準備ができたので,順次更新していく。
$ sudo update-grub2 $ sudo update-initramfs -u
これでうまくいったら Plymouth の解像度があがる。わたしはあがった。でも黒ブランク画面の時間が短くなった気はしなかった(そもそも KMS disabled だから nouveau より不利だけど)。
あと,関係ないけど Lucid になって起動ちょっぱやになったっていう報告をいくつかみるけど,自分の環境ではそんな感じでもないですね。たんにマシンパワーのおかげで Karmic の時点でもはやかっただけかもだけど。
んで,副作用?で,仮想ターミナルの解像度もあがりました。やったね。jfbterm とかいれると仮想ターミナルもなかなか快適。jfbterm 抜ける時に画面がフリーズしちゃうけど。
MTRR について
fb/uvesafb.txt によると
mtrr:n Setup memory type range registers for the framebuffer where n: 0 - disabled (equivalent to nomtrr) (default) 1 - uncachable 2 - write-back 3 - write-combining 4 - write-through If you see the following in dmesg, choose the type that matches the old one. In this example, use "mtrr:2". ... mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining ... nomtrr Do not use memory type range registers.fb/uvesafb.txt
のように設定できる。
で,たぶん write-combining > write-back > write-through > uncachable の順にパフォーマンスがよくなる。パフォーマンスといっても今回の例では uvesafb ドライバ部分の話であって,X.Org が立ち上がったあとは話が別(たぶん nvidia プロプラドライバがよしなに設定してくれる)。
どのモードをサポートしているかはグラフィックチップやグラフィックカードによって異なるみたい。だけど,どれを指定すればいいかはやってみなきゃわかんなさそう((X.Org が立ち上がっている状態で /proc/mtrr
とかみてみたけどわかんなかった。uncachable になってたし。))。指定してみて間違っていると起動時の dmesg で教えてくれる。
以下は write-back
(2) しかサポートしていないグラフィックカードで mtrr=3
(write-combining
) を指定した時の dmesg の例。
mtrr: type mismatch for d0000000,800000 old: write-back new: write-combining mtrr: type mismatch for d0000000,400000 old: write-back new: write-combining mtrr: type mismatch for d0000000,200000 old: write-back new: write-combining mtrr: type mismatch for d0000000,100000 old: write-back new: write-combining mtrr: type mismatch for d0000000,80000 old: write-back new: write-combining mtrr: type mismatch for d0000000,40000 old: write-back new: write-combining mtrr: type mismatch for d0000000,20000 old: write-back new: write-combining mtrr: type mismatch for d0000000,10000 old: write-back new: write-combining mtrr: type mismatch for d0000000,8000 old: write-back new: write-combining mtrr: type mismatch for d0000000,4000 old: write-back new: write-combining mtrr: type mismatch for d0000000,2000 old: write-back new: write-combining mtrr: type mismatch for d0000000,1000 old: write-back new: write-combining
このようにいわれるので mtrr=2
に設定をかえた。
かえたあとの dmesg は以下のとおり。
uvesafb: NVIDIA Corporation, G73 Board - p345h0b , Chip Rev , OEM: NVIDIA, VBE v3.0 uvesafb: protected mode interface info at c000:c2e0 uvesafb: pmi: set display start = c00cc316, set palette = c00cc380 uvesafb: pmi: ports = 3b4 3b5 3ba 3c0 3c1 3c4 3c5 3c6 3c7 3c8 3c9 3cc 3ce 3cf 3d0 3d1 3d2 3d3 3d4 3d5 3da uvesafb: VBIOS/hardware supports DDC2 transfers uvesafb: monitor limits: vf = 76 Hz, hf = 83 kHz, clk = 210 MHz uvesafb: scrolling: ywrap using protected mode interface, yres_virtual=2048 uvesafb: framebuffer at 0xd0000000, mapped to 0xf8700000, using 10240k, total 262144k
MTRR まわりで文句はいわれなくなった。
用語など
あとで書くかも。
collectd のフロントエンドとして Cacti を使う
- リソースデータ収集は collectd がとてもいい
- だが collectd にはプレゼンテーション層が欠けている
- いくつかフロントエンドもでていますが気に入ったものはありませんでした。
- Cacti のデータ閲覧 UI は(この手のフリーのもののなかでは)かなり良い
- でも Cacti のデータソース管理 UI をいじるのは相当面倒
端的に言うと「Cacti の UI で collectd のデータを閲覧できたらなぁ」
collectdのデータをKDEデスクトップ上に表示したい場合は、kcollectdの利用を検討するとよい。誕生して間もないプロジェクトだが、すでに有用性が認められている。また、生成されたRRDtoolファイルはCactiでも利用できる。ただし、非常に長々とした設定をグラフ別に行う必要がある。
Webインタフェースでマシンを監視する4つの方法 (2/5) - ITmedia エンタープライズ
collectd は膨大な rrd ファイルを生成するので、これを手作業で Cacti にインポートしてってやるのも面倒だよなぁと思っていました。
すると Cacti のフォーラム Cacti • View topic - Cacti as a frontend for collecd? にて、collectd のデータを Cacti から閲覧できるようにするスクリプトがあったので、やってみました。Python 2.6 が必要と書いてあったけど、CentOS 5 に付属の Python 2.4.3 でもうまく動きました。
ただ、このスクリプトにもいいところもあればわるいところもあります。
良い点
イマイチな点
- すべてのグラフの縦軸の項目名が「vertical_label」になってしまう(これは RRD ファイルに値の単位が記載されていないというしくみ上どうしようもないか; Cacti の管理画面で変更していけばいい)
- collectd のデータ上、同じディレクトリに存在する rrd ファイルの値がまとめられてしまう(たとえば cpu の場合、idle, interrupt, nice, softirq, steal, system, user, wait)
- このため、たとえば vmem のように vmpage_number-file_pages の値だけ突出しているグラフの場合、その他の値がグラフの下にべったり張り付いてしまい傾向をみることができなくなってしまう
- 全部線グラフとなり、(適宜項目数におうじて色を変えてくれる*3が)塗りつぶし表現などなく平板な印象になってしまう
- あとからある項目を追加したり、あるホストを追加したり、ということができない(もちろんスクリプトを書き換えればいけると思うけど)
とはいえ、これ一つで collectd のデータを簡単に見ることができるようになるのは事実。
Python で書かれているのが個人的にはちょっとつらいのだけれど、がんばって読み込んでみようかなぁ。
Linux で 4096 バイトセクタ HDD を fdisk
Linux でも 4096 バイトセクタのハードディスクを使うときには注意が必要らしいということを 4096 バイトセクタの HDD と Linux - daily dayflower で書きました。でも fdisk のエキスパートモードってどんなんだろうと思いつつ実際に触っていなかったので、今回はちゃんと触ってみました(でもベンチマークはとってないよ)。
今回のおはなしは(前回と同様)、物理セクタサイズ 4096 バイトの 512 バイトセクタエミュレーションモードのハードディスク、つまり 2010 年現在において 4K セクタとして売られている HDD がターゲット*1です。
CentOS 5.4 で動作確認を行いました。fdisk のバージョンはこんな感じです。
# fdisk -v fdisk (util-linux 2.13-pre7)
以降の例では 1TB のディスクを3つのパーティションにわけます。
- 128GB
- 256GB
- 残り全部
を、全部基本パーティションとして切ってみました。
方法 1. エキスパートモードを使って開始セクタを微調整する
エキスパートモードと銘打っていますが、後述する方法 2 より簡単です。ただし、複数パーティションを切る場合、(最終パーティション以外の)パーティション末尾のセクタがいくらか無駄になります。
ですが単一パーティションで使う場合は無駄が発生しないので、こちらの方法のほうが楽*2でしょう。
fdisk の起動
# fdisk /dev/sdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. The number of cylinders for this disk is set to 121601. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help):
現在パーティションテーブルが存在しないため、いろいろいわれていますが無視してください。
立ち上げ当初の基本コマンドモードでは以下のコマンドが使えます。
Command action a toggle a bootable flag b edit bsd disklabel c toggle the dos compatibility flag d delete a partition l list known partition types m print this menu n add a new partition o create a new empty DOS partition table p print the partition table q quit without saving changes s create a new empty Sun disklabel t change a partition's system id u change display/entry units v verify the partition table w write table to disk and exit x extra functionality (experts only)
いろいろありますが、今回の例で使うのはおもに下記のコマンドだけです。
d delete a partition n add a new partition p print the partition table q quit without saving changes w write table to disk and exit
fdisk の場合、いろいろパーティション情報等をいじっても w
で書き込まない限り、q
コマンドや Ctrl+C
で抜けてしまえばディスクには反映されないので気楽に試すことができます。
ざっくりとパーティションを切っていく
現在のパーティションテーブルを見てみます。
Command (m for help): p Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System
空っぽです。
まずは n
コマンドで第1パーティションを作成します。
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-121601, default 1): <CR> Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-121601, default 121601): +128G
開始シリンダ(≠セクタ)は、デフォルトにしておきます。エンターを押すだけでデフォルト値の 1 が採用されます。
終了シリンダを絶対値で指定するか、サイズを与えることができます。例示ではメガバイト(+sizeM
)やキロバイト(+sizeK
)しかありませんが、ギガバイト(+sizeG
)でも指定することができます。
同様にして第2、第3パーティションも切っていきます。
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (15564-121601, default 15564): <CR> Using default value 15564 Last cylinder or +size or +sizeM or +sizeK (15564-121601, default 121601): +256G Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First cylinder (46689-121601, default 46689): <CR> Using default value 46689 Last cylinder or +size or +sizeM or +sizeK (46689-121601, default 121601): <CR> Using default value 121601
第3パーティションはディスクを最後まで使い切るので、終了シリンダをデフォルト値(末尾シリンダ)のままにしています。
どのようなパーティションテーブルになったのか、p
コマンドで見てみます。
Command (m for help): p Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 1 15563 125009766 83 Linux /dev/sdb2 15564 46688 250011562+ 83 Linux /dev/sdb3 46689 121601 601738672+ 83 Linux
ご覧のとおり、単位がシリンダ単位なので、セクタ単位ではどのようになっているかわかりません。
セクタ単位の微調整を行うために、エキスパートモードに入ることにします。
エキスパートモードで開始セクタを調整する
x
コマンドをもちいるとエキスパートモードに入ることができます。
Command (m for help): x Expert command (m for help):
エキスパートモードのコマンドは下記のとおりです。
Command action b move beginning of data in a partition c change number of cylinders d print the raw data in the partition table e list extended partitions f fix partition order g create an IRIX (SGI) partition table h change number of heads m print this menu p print the partition table q quit without saving changes r return to main menu s change number of sectors/track v verify the partition table w write table to disk and exit
ディスクの CHS(シリンダ/ヘッド/セクタ数)を変更することもできますが、BigDrive の現在ほとんど意味がありません(し危険です)。なので、今回使うコマンドは、
b move beginning of data in a partition p print the partition table
だけです。
まずはエキスパートモードでパーティションテーブルを確認してみましょう。
Expert command (m for help): p Disk /dev/sdb: 255 heads, 63 sectors, 121601 cylinders Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID 1 00 1 1 0 254 63 1023 63 250019532 83 2 00 254 63 1023 254 63 1023 250019595 500023125 83 3 00 254 63 1023 254 63 1023 750042720 1203477345 83 4 00 0 0 0 0 0 0 0 0 00
ノーマルモードにくらべて、いろいろ複雑な情報がでてきました。
実は DOS パーティションテーブルは、各パーティションの開始位置・終了位置を、CHS と LBA(セクタインデックス)の両者でもっています。テーブル左側にかいてあるのが CHS による開始・終了位置です*3。右側が LBA による位置(とサイズ)情報です。
これを見ると第1・第2パーティションについては残念ながら、開始セクタ番号が 8 の倍数になっていないことがわかります。第3パーティションはラッキーにも 8 の倍数になっています。
さきほどあげた b
コマンドを使うと、この開始セクタ番号をいじることができます。
Expert command (m for help): b Partition number (1-4): 1 New beginning of data (63-500023124, default 63): 64
もともと 63 だったところを 64 にしました。
パーティションテーブルを見てみます。
Expert command (m for help): p Disk /dev/sdb: 255 heads, 63 sectors, 121601 cylinders Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID 1 00 1 1 0 254 63 1023 64 250019531 83 2 00 254 63 1023 254 63 1023 250019595 500023125 83 3 00 254 63 1023 254 63 1023 750042720 1203477345 83 4 00 0 0 0 0 0 0 0 0 00
第1パーティションの開始セクタ番号が 8 の倍数である 64 になったこと、(終了セクタ番号をいじれないために)サイズが 1 セクタ分少なくなったことがわかります。
シングルパーティションで使う場合なら、ここまでの作業で OK です。あとは w
コマンドで今回編集したパーティションテーブルをディスクに書き込みます。
今回は3つパーティションを切ったので、同様にして第2パーティションの開始セクタについてもいじっていきます。
Expert command (m for help): b Partition number (1-4): 2 New beginning of data (250019595-750042719, default 250019595): 250019600
8 の倍数にアラインするには、下 3 桁が 8 で割りきれるようにします。
第 3 パーティションについてはもともと 8 の倍数だったのでそのままで大丈夫です。さて、最終的にどのようなパーティションテーブルになったのかを確認します。
Expert command (m for help): p Disk /dev/sdb: 255 heads, 63 sectors, 121601 cylinders Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID 1 00 1 1 0 254 63 1023 64 250019531 83 2 00 254 63 1023 254 63 1023 250019600 500023120 83 3 00 254 63 1023 254 63 1023 750042720 1203477345 83 4 00 0 0 0 0 0 0 0 0 00
無事、各パーティションの開始セクタ番号が 8 の倍数になりました。
なおさきほど述べたように、エキスパートモードにおいてすら終了セクタ番号を編集することはできません。ですので、今回の場合、第 1 パーティションの末尾が 5 セクタほど使えない状態になっています。これはこの方法 1 ではどうしようもありません。
方法 2. セクタモードを使って開始セクタ・終了セクタを設定する
一番最初のノーマルモードでパーティションを切った際、パーティション開始位置等はシリンダ番号単位で与えていました。だからエキスパートモードにわざわざ入って開始セクタの位置を調整することになりました。
ですが、実は fdisk はパーティションの開始・終了位置を最初からセクタ単位で指定することもできます。そこで、方法 2 ではエキスパートモードを使わず、セクタ単位で一から指定してみます。
セクタ単位モードに切り替える
u
コマンドを使うと、単位系をシリンダ単位とセクタ単位の両者で切り替えることができます。
# fdisk /dev/sdb ...... Command (m for help): u Changing display/entry units to sectors
なにもコマンドラインオプションをつけない場合、デフォルトではシリンダ単位になっています。ですので、u
コマンドを一度実行すると、セクタ単位モードになります。
また、起動時に -u
オプションをつけて fdisk を実行すると、最初からセクタ単位モードになります。
パーティションをざっくり切る
自力で全パーティション境界を計算してもいいのですが、桁数も多くめんどくさいので、まずはパーティション境界にこだわらずざっくりと切ってみます。
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First sector (63-1953525167, default 63): <CR> Using default value 63 Last sector or +size or +sizeM or +sizeK (63-1953525167, default 1953525167): +128G Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First sector (250000064-1953525167, default 250000064): <CR> Using default value 250000064 Last sector or +size or +sizeM or +sizeK (250000064-1953525167, default 1953525167): +256G Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First sector (750000065-1953525167, default 750000065): <CR> Using default value 750000065 Last sector or +size or +sizeM or +sizeK (750000065-1953525167, default 1953525167): <CR> Using default value 1953525167
ではパーティションテーブルを確認してみましょう。
Command (m for help): p Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors Units = sectors of 1 * 512 = 512 bytes Device Boot Start End Blocks Id System /dev/sdb1 63 250000063 125000000+ 83 Linux /dev/sdb2 250000064 750000064 250000000+ 83 Linux /dev/sdb3 750000065 1953525167 601762551+ 83 Linux
残念ながら今回は第1・3パーティションの開始セクタが 8 の倍数ではありません。そもそもなぜか終了セクタが指定した容量 + 1セクタになっているのが不可解です。まあいずれにせよ今回の情報をもとにパーティションを切り直すのであまり深く考えないようにします。
きちんとパーティションを切る
さきほどのパーティションテーブルをもとに、開始セクタを 8 の倍数にしつつ容量もきちんとするなら下記のようになるでしょう。
/dev/sdb1 64 250000063 /dev/sdb2 250000064 750000063 /dev/sdb3 750000064 1953525167
この方針でパーティションを手動できっていきます。
といっても、いままで開始セクタ番号をおまかせで決めさせたり、終了セクタ番号を容量で指定していたところを絶対セクタ番号で指定するように変更するだけです。
まず、o
コマンドでパーティションテーブルを初期化します。
Command (m for help): o Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. The number of cylinders for this disk is set to 121601. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
あとはパーティションを切っていきます。
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First sector (63-1953525167, default 63): 64 Last sector or +size or +sizeM or +sizeK (64-1953525167, default 1953525167): 250000063 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First sector (63-1953525167, default 63): 250000064 Last sector or +size or +sizeM or +sizeK (250000064-1953525167, default 1953525167): 750000063 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First sector (63-1953525167, default 63): 750000064 Last sector or +size or +sizeM or +sizeK (750000064-1953525167, default 1953525167): <CR> Using default value 1953525167
最初の開始セクタを 64 にしたせいで、あとあとのパーティションの開始位置のデフォルト値が 63 になってしまい、いちいち手入力しないといけないのがめんどうですが、メモをもとに作業すればまあ間違わないでしょう。
パーティションテーブルを確認します。
Command (m for help): p Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors Units = sectors of 1 * 512 = 512 bytes Device Boot Start End Blocks Id System /dev/sdb1 64 250000063 125000000 83 Linux /dev/sdb2 250000064 750000063 250000000 83 Linux /dev/sdb3 750000064 1953525167 601762552 83 Linux
無事開始セクタが 8 の倍数になりました。
雑多な話題
方法 1 と方法 2 でパーティションの開始位置などが異なる
方法 1 の場合は(大枠で)シリンダ境界に沿うようにパーティションが自動的に切られていたのに対して、方法 2 ではシリンダ境界にとらわれることなくパーティションを切ることができるからです。
本来シリンダ境界に沿うようにしたほうが旧来のシステムとの互換性が高いのですが、開始セクタ番号をずらしている(シリンダ境界でなくなっている)時点で互換は保たれていないので方法 2 の切り方でも問題はないでしょう。そもそもさきほどみたように CHS ではとっくにオーバーフローしてますしね。
第 1 パーティションの開始位置は 64 じゃないといけないのか
方法 2 で、さらに c
コマンドによって DOS コンパチビリティをオフにすると、開始セクタの位置を 63 より前に設定することができます(セクタ番号 0 は MBR およびパーティションテーブル自体なので、設定できない)。
ですが、古典的に第 1 パーティションは(シリンダ境界から)第 63 セクタから開始することになっていました。で、ブートローダーによってはこの 1〜62 セクタの間にコードや情報をおくことがあります。たとえば GRUB の場合(パーティションに置くのでなければ)、stage 1.5 のローダーはこの部分におかれます。
なので、少なくともシステムディスクの場合、開始セクタは 64 としたほうがよいでしょう。データとしてしか使わないのなら開始セクタを 8 としてもいいかもしれませんが、増やせる容量はたかだか 32K bytes 程度です。
他のパーティションツールではどうすればいいか
面倒なので調べていません。
cfdisk はもう使っている人はいないと思います。
sfdisk でもセクタ単位で設定できそうですが、あれを操れる人は自力でなんとでもできるでしょう。
parted はコマンドを実行した瞬間にパーティションテーブルが変更されそうで怖くてためしていません。マニュアルを読む限りセクタ単位で編集することもできそうですが、今回の方法 2 のように一度(容量や割合で)サイズを指定しておまかせで切ったあとに手動で切り直す必要がありそうです。
gparted もためしていません。基本的に容量単位でパーティションを生成するので細かいセクタ単位の指定はできなさそうです。一応、シリンダ単位にパーティション境界をもってくるかどうかというフラグはあるみたいですが。