2010年12月28日

vvfat、もしくはおっさんの死語的知識

qemu-img とか実行すると、最近無闇にオプションが増えてtftpやらhttpやらあるのはともかく、vvfat ってあるのが割と謎に見えるとおもうのですがあまり触れてる人をみたことがないので読んでみた。

qemu-img を実行したら最後の行にサポートするフォーマット一覧がこんな感じででてくる:
Supported formats: cow qcow vdi vmdk cloop dmg bochs vpc vvfat qcow2 parallels nbd host_cdrom host_floppy host_device raw tftp ftps ftp https http


まあここで他のはファイルフォーマットだったり通信プロトコルだったりするのですぐわかるわけですが、vvfatってなにかよくわからない。

よくわからない時の行動として反射的にapt-get source qemu とかやっちゃう。FTTHバンザイ!日本人でよかったよ!そしてdebianで生活してる幸せをかみしめ…… とか思ってるあいだに手元にソースが展開される。


snake:~/Job/20101228$ cd qemu-0.12.5+dfsg
snake:~/Job/20101228/qemu-0.12.5+dfsg$ find | grep vvfat
./block/vvfat.c


vvfat.c キタコレ。

lessで見ると不穏なコメントが最初にある。

* QEMU Block driver for virtual VFAT (shadows a local directory)

仮想的なブロックデバイスで、VFATでフォーマットされている風に、ローカルのディレクトリを見せる。と書いている。ヤバい匂いがプンプンするyo! でもちゃんと動くならホストからゲストにちょちょいとファイル送るのにつかえるかも。最近ブロックデバイスの動的attach/detachもできるようになったしね。 ということでもうちょっと読んでみる。

ソースをななめ読みするとFATのベースになる線型リスト定義をしたあと
目につくのがこれ。


typedef struct bootsector_t {


これはFATの1セクタ目ですね……。 中にあるunionでfat16とfat32の両方に対応しようとしているのがわかります。同じデータ構造が2回並んでバックアップになるんですよね。PC98の頃に1GBのHDDをneco98で復旧したトラウマが蘇ります。


typedef struct partition_t {
typedef struct mbr_t {

まんまですね。このへんはBIOSに縛られて30年ほど生き延び中のPCの代名詞的構造体です。


typedef struct direntry_t {

FATのディレクトリエントリキタ。これが大活躍するはず。みなさまはlong filenameが導入された時の衝撃を覚えているでしょうか……。

/* this structure are used to transparently access the files */

typedef struct mapping_t {
/* begin is the first cluster, end is the last+1 */
uint32_t begin,end;
/* as s->directory is growable, no pointer may be used here */
unsigned int dir_index;
/* the clusters of a file may be in any order; this points to the first */
int first_mapping_index;
union {
/* offset is
* - the offset in the file (in clusters) for a file, or
* - the next cluster of the directory for a directory, and
* - the address of the buffer for a faked entry
*/
struct {
uint32_t offset;
} file;
struct {
int parent_mapping_index;
int first_dir_index;
} dir;
} info;
/* path contains the full path, i.e. it always starts with s->path */
char* path;

enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
MODE_DIRECTORY = 4, MODE_FAKED = 8,
MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
int read_only;
} mapping_t;

さてやっとvvfat.c に独特っぽいのがでてきました。ファイルやディレクトリに対応してサイズ情報ももって、ホスト側ファイルのパス名も持ってますね。
このデータ構造をVM内からクラックできたら1秒でprocfsつつかれてVM全滅コースです。

コメントの中の s-> ってなに? とおもったら次の構造体のStateのsのようです。

typedef struct BDRVVVFATState {
BlockDriverState* bs; /* pointer to parent */
unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a d
isk with partition table */
unsigned char first_sectors[0x40*0x200];

int fat_type; /* 16 or 32 */
array_t fat,directory,mapping;

unsigned int cluster_size;
unsigned int sectors_per_cluster;
unsigned int sectors_per_fat;
unsigned int sectors_of_root_directory;
uint32_t last_cluster_of_root_directory;
unsigned int faked_sectors; /* how many sectors are faked before file data *
/
uint32_t sector_count; /* total number of sectors of the partition */
uint32_t cluster_count; /* total number of clusters of this partition */
uint32_t max_fat_value;

int current_fd;
mapping_t* current_mapping;
unsigned char* cluster; /* points to current cluster */
unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
unsigned int current_cluster;

/* write support */
BlockDriverState* write_target;
char* qcow_filename;
BlockDriverState* qcow;
void* fat2;
char* used_clusters;
array_t commits;
const char* path;
int downcase_short_names;
} BDRVVVFATState;

FAT16,32に対応してて、セクタやFATのブロックサイズの他にclusterという管理のためのサイズがあること、書き込みサポートまでしようとしてること、qcowという名前から書き込みはファイルに反映するのではなくqcowファイルに差分を書き出す形で反映するのかな??、というあたりが読めます……。だいぶ感じがわかってきたかも。

array_t fat,directory,mapping; となっているのでこの構造体からディレクトリやマッピングをアクセスできる。名前的にもこいつが元締めで正解のよう。

さてデータ構造はだいたい眺めました。どうやらFAT12/16/32あたりのフォーマットを割とまじめに生成してそうです。そのあとつらつら眺めると create_short_and_long_name とかで1995年あたりに苦労させられたような気がするvfatのlong filename生成コードが。

vfatでのlong filenameは複数の8.3ファイル名のディレクトリエントリを組み合わせて1つのエントリを作るというアクロバットを行っていました。ドットの扱いや先に作ったファイルのshort filenameが後から作られるファイルによって変わってしまう悪夢については近くのおっさんに聞いてください。またこのあたりにエンコードがらみの記述がないので日本語ファイル名の利用は絶望的だということもわかります。

基本的なデータ構造とFAT用の関数群がそろったところで read_directory関数がでてきます。これが元となるディレクトリ1つを読んで、対応するVVFATのディレクトリ構造とmappingを作ります。mappingはファイル1つまたはディレクトリ1つに対応するようです。

子ディレクトリを見つけると新しいmappingを作って追加してるので、read_directoryの呼びだし元、init_directory関数の
for (i = 0, cluster = 0; i < s->mapping.next; i++) {
となっているループでうまいこと回りそうです。

なんとなくうまく動きそうな気がして落ちついてきました。

このvvfatディスクの諸元がどうやって決まるのかちょっと探索してみましょう。
ファイルの一番最後にいくと static BlockDriver bdrv_vvfat = { というような行があってバックエンド各種のオペレーションが定義されています。.brdv_open に対応するvvfat_open関数で諸元は設定されるはず。

まずはfat12が16か32か。これはコマンドライン引数から生成されています。
  fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");

テストされてない宣言きました。ここでサクッとexFAT対応とかFAT32対応のテストとかやるとモテそうですね。おっさんに。

さてサイズはどうなってるでしょうか。以下のような即値で入ってました。これはFAT16BIOSのCHSアドレッシング上限にあわせたディスクですね。
bs->cyls=1024; bs->heads=16; bs->secs=63;


あとフロッピーの定義もはいっています。
bs->cyls = 80; bs->heads = 2; bs->secs = 36;


今手元のソースを見るとこの3つを掛けたものにパーティションテーブルやFATの分のオフセットを足した値でディスク容量が決まります。
特に指定がなければ504MB, フロッピーの指定があれば2.88MB。シリンダ数などの指定はできず、自動的に拡張する仕組みもないので今のところここが限界。むむ。

ちょっとしたドライバとかを渡すには便利ですが最初に期待した汎用のホスト→ゲストファイル渡し経路としてはちょっと苦しいなあ。

尻すぼみになって御免!

2010年8月17日

RHELサポートと動作確認済みの動作環境、特に仮想化環境について

現状RHELが認証されている仮想化環境はRHELのXen, RHELのKVM,
MSのHyper-V, VMwareの ESX, GSX(RHEL3のみ), Workstation(RHEL3のみ)です。
最新の認証状況については https://hardware.redhat.com/ で確認できます。

CitrixのXenServerおよびxen.orgのxen、OracleVMは現在RHELの動作環境として認証されていません。
サポート時に問題が実機(または他の認証された仮想化環境)で再現することの確認を
お願いする場合があります。

以下は蛇足かもしれませんが念の為。

CitrixはXenServer用に変更されたカーネルパッケージを提供しています。
# このあたり http://updates.xensource.com/XenServer/5.0.0/

これはレッドハットが公開しているソースコードを元にしていますが、
レッドハットではこのパッケージについては何もサポートを提供できません。
カーネルを入れ替えて使うこと自体は契約上何も問題ありませんが、サポートご利用時に
レッドハットのカーネルパッケージを利用した環境での再現をお願いする場合があります。

xen.orgで提供されているlinux-2.6.18-xenツリーをお客様でビルドして利用する場合なども同様です。

# カーネルや環境に関係しない内容であれば特に上記のようなお願いはしませんが、
# 切り分けが難しい場合などに早い段階でお願いする可能性はあります。

2010年7月17日

daily bookmarks 07/17/2010


Posted from Diigo. The rest of my favorite links are here.

2010年5月18日

HDDをデータ復活できないように完全に消去したいとき

HDD消去のためには、RHELに
同梱されておりますコマンド shred をご利用いただくことで、0によるfill、
1によるfill、乱数によるfillを行うことができます。

shredは以下の25パターンを持っていて、デフォルトでは3回の乱数による上書き

行います。

shredの利用するパターンについて、ソースより引用:

* First, all possible 1-bit patterns. There are two of them.
* Then, all possible 2-bit patterns. There are four, but the two
* which are also 1-bit patterns can be omitted.
* Then, all possible 3-bit patterns. Likewise, 8-2 = 6.
* Then, all possible 4-bit patterns. 16-4 = 12.
*
* The basic passes are:
* 1-bit: 0x000, 0xFFF
* 2-bit: 0x555, 0xAAA
* 3-bit: 0x249, 0x492, 0x924, 0x6DB, 0xB6D, 0xDB6 (+ 1-bit)
* 100100100100 110110110110
* 9 2 4 D B 6
* 4-bit: 0x111, 0x222, 0x333, 0x444, 0x666, 0x777,
* 0x888, 0x999, 0xBBB, 0xCCC, 0xDDD, 0xEEE (+ 1-bit, 2-bit)
* Adding three random passes at the beginning, middle and end
* produces the default 25-pass structure.


パターン毎の指定はできません。
オプションで5回を指定することで
以下のように 乱数、0、乱数、1、乱数 の順で上書きを行います。

$ shred -v -n 5 hoge
shred: hoge: 経過 1/5 (random)...
shred: hoge: 経過 2/5 (000000)...
shred: hoge: 経過 3/5 (random)...
shred: hoge: 経過 4/5 (ffffff)...
shred: hoge: 経過 5/5 (random)...

daily bookmarks 05/18/2010


Posted from Diigo. The rest of my favorite links are here.

2010年5月7日

daily bookmarks 05/07/2010


Posted from Diigo. The rest of my favorite links are here.

2010年5月5日

daily bookmarks 05/05/2010


Posted from Diigo. The rest of my favorite links are here.

2010年5月4日

daily bookmarks 05/04/2010


Posted from Diigo. The rest of my favorite links are here.

2010年3月28日

新PS3へ

新型PS3を購入、500GBHDDにさしかえて旧PS3のデータを移行…。
半分こわれたPS3でデータは無事か? と心配したものの無事移行できた。よかったー。

旧PS3は友達に譲る予定。

2010年3月23日

Core i7に対応したRHELはいつ出荷されますか? というFAQ

レッドハット製品はパーツ単位での動作認定をしていません。
そのため「CPUごとの動作認定はしていません。」というのが第一の回答になります。


次にCore i7はブランド名なのでCPUのマイクロアーキテクチャとしては
NehalemとWestmereが対応します。"Core i7"はデスクトップ向けブランドなので
直接に対応するハードウェアがHCLに載る可能性は低いかと思います。


Nehalem-EPを利用する場合はRHEL4.7および5.3以降を利用することを
強く推奨しています。事実上の対応宣言です。この中でも記載されていますが
5.2以前を利用の
場合にはサポートにて5.3以降へアップグレードをお願いする場合があります。http://kbase.redhat.com/faq/docs/DOC-15262


同様にWestmere-EPを利用する場合はRHEL4.8および5.3以降を利用することを
推奨しています。
http://kbase.redhat.com/faq/docs/DOC-27818


nehalem, westmere, core i7については以下のwikipediaのページがわかりやすいです:
http://en.wikipedia.org/wiki/Nehalem_(microarchitecture)

http://en.wikipedia.org/wiki/Intel_Core_i7

PS3こわれた orz

前回の故障から3ヶ月と3日でPS3が壊れた。。。。
めんどくさーーーーい!

2010年1月26日

RHCS+仮想化

Red Hat Cluster Suite 、RHEL5.4時点では仮想化との組み合わせでサポートされるのは今のところRHEL5のXenのみ
VMwareもRHEVもXenServerもHyper-VもRHEL5のKVMさえもサポートされないから気をつけろ

RHEL5のKVMとVMwareはTechnology Previewなのでたぶんそのうちサポート対象になる予定のはず……。

2010年1月25日

rhelで1ユーザあたりのプロセス数制限はできますか?

直接的な制限はPIDの個数になり、40億以上のプロセスが同時に実行可能です。
実際的にはメモリ使用量が問題になり、たとえば1つのプロセスで4MB消費すると
仮定すると128GB搭載でも32768個のプロセスが同時に実行可能です。

個別のユーザへのlimitについては、ulimitという仕組みにより可能です。
ulimitはシェルの組み込みコマンドで
ulimit -H -u 100

のような指定をすることで、そのユーザが同時に動作させることができる
プロセスの数を制限できます。(この例では100個に制限しています)

この設定をログイン時に強制したい場合は、
/etc/security/limits.conf ファイルに設定を記述します。
同時にopenできるファイルの数の制限を変更する例が以下のknowledge base
エントリで紹介されています。
http://kbase.redhat.com/faq/docs/DOC-2062

上記例の中で nofile(number of file)となって
いるものを nproc (number of process) に置換し、適切な
数を指定することで、一人のユーザあたりのプロセス数を制限することができま
す。


この時に利用されるのは pam_limits とよばれるPAMのモジュールです。
記述方法の詳細については man limits.conf をごらんください。