一部のCentOS5サーバーに Ceph FSをマウント したい。 ceph-Fuse
が以下のエラーで失敗したため:
# ceph-Fuse --no-Fuse-big-writes -m 192.168.2.15:6789 /mnt/ceph/
ceph-Fuse[7528]: starting ceph client
ceph-Fuse[7528]: starting Fuse
fuse: unknown option `atomic_o_trunc'
2013-04-04 13:51:21.128506 2b82d6e9e8f0 -1 Fuse_lowlevel_new failed
ceph-Fuse[7528]: Fuse finished with error 33
ceph-Fuse[7526]: mount failed: (33) Numerical argument out of domain
Googleは this を指摘しましたが、CentOS 5.xはカーネル2.6.18に同梱されているので、Cephをサポートする新しいカーネルをコンパイルします。
.config
は、実行中のカーネルから2つの追加設定でコピーされました。
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_CEPH_FS=m
しかし、どちらも次のエラーが発生します。
最初の警告は、カーネルイメージを抽出して2行を削除した後、initスクリプトを編集することで取り除くことができます。
echo "Loading dm-region-hash.ko module"
insmod /lib/dm-region-hash.ko
http://funky-dennis.livejournal.com/3290.html
2番目のエラーはどうですか:
device-mapper: table: 253:0: mirror: Error creating mirror dirty log
RAID set "ddf1_bar" was not activated
次のモジュールが新しいカーネルにロードされないことを除いて、これらはほとんど同じです。
echo "Loading dm-mem-cache.ko module"
insmod /lib/dm-mem-cache.ko
echo "Loading dm-message.ko module"
insmod /lib/dm-message.ko
echo "Loading dm-raid45.ko module"
insmod /lib/dm-raid45.ko
これがRAID set "ddf1_foo" was not activated
の理由ですか?
UPDATE Thu Apr 4 21:40:32 ICT 2013
http://alistairphipps.com/wiki/index.php?title=Notes#LVM
「ミラーログ:ミラーログへの認識されない同期引数:2」、「テーブル:ミラー:ミラーダーティログの作成エラー」に似た奇妙なエラーメッセージは、カーネルデバイスマッパーとユーザースペースツールのバージョンが一致していないことを意味します:おそらくカーネルがお使いのバージョンのlvmツール。ソースから最新のデバイスマッパーとlvm2をインストールすると、機能するはずです。
最新バージョンの LVM2 をコンパイルしようとしました:
# /usr/sbin/lvm version
LVM version: 2.02.98(2) (2012-10-15)
Library version: 1.02.67-RHEL5 (2011-10-14)
Driver version: 4.11.6
しかし、何も変わりません。
UPDATE Sat Apr 6 18:51:31 ICT 2013
/ lib/modules/2.6.18-274.el5/kernel/drivers/md /
|-- dm-crypt.ko
|-- dm-emc.ko
|-- dm-hp-sw.ko
|-- dm-log.ko
|-- dm-mem-cache.ko
|-- dm-message.ko
|-- dm-mirror.ko
|-- dm-mod.ko
|-- dm-multipath.ko
|-- dm-raid45.ko
|-- dm-rdac.ko
|-- dm-region_hash.ko
|-- dm-round-robin.ko
|-- dm-snapshot.ko
|-- dm-zero.ko
|-- faulty.ko
|-- linear.ko
|-- multipath.ko
|-- raid0.ko
|-- raid1.ko
|-- raid10.ko
|-- raid456.ko
`-- xor.ko
/ lib/modules/2.6.34.14/kernel/drivers/md /
|-- dm-crypt.ko
|-- dm-log.ko
|-- dm-mirror.ko
|-- dm-mod.ko
|-- dm-multipath.ko
|-- dm-region-hash.ko
|-- dm-round-robin.ko
|-- dm-snapshot.ko
|-- dm-zero.ko
|-- faulty.ko
|-- linear.ko
|-- multipath.ko
|-- raid0.ko
|-- raid1.ko
|-- raid10.ko
|-- raid456.ko
`-- raid6_pq.ko
UPDATE Wed Apr 10 11:22:54 ICT 2013
ソースフォルダで検索してください、私はこれを見つけました:
# grep -lr 'Error creating mirror dirty log' /usr/src/linux-2.6.34.14
/usr/src/linux-2.6.34.14/drivers/md/dm-raid1.c
dm-raid1.c
:
static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
unsigned argc, char **argv,
unsigned *args_used)
{
unsigned param_count;
struct dm_dirty_log *dl;
if (argc < 2) {
ti->error = "Insufficient mirror log arguments";
return NULL;
}
if (sscanf(argv[1], "%u", ¶m_count) != 1) {
ti->error = "Invalid mirror log argument count";
return NULL;
}
*args_used = 2 + param_count;
if (argc < *args_used) {
ti->error = "Insufficient mirror log arguments";
return NULL;
}
dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
argv + 2);
if (!dl) {
ti->error = "Error creating mirror dirty log";
return NULL;
}
return dl;
}
dm-log.c
:
struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
struct dm_target *ti,
int (*flush_callback_fn)(struct dm_target *ti),
unsigned int argc, char **argv)
{
struct dm_dirty_log_type *type;
struct dm_dirty_log *log;
log = kmalloc(sizeof(*log), GFP_KERNEL);
if (!log)
return NULL;
type = get_type(type_name);
if (!type) {
kfree(log);
return NULL;
}
log->flush_callback_fn = flush_callback_fn;
log->type = type;
if (type->ctr(log, ti, argc, argv)) {
kfree(log);
put_type(type);
return NULL;
}
return log;
}
私の友人のすべての助けのおかげで、問題は解決されました。
最初の試みで、彼はti->error = "Error creating mirror dirty log";
の行dm-raid1.c
をコメントアウトし、いくつかのデバッグ行をdm-log.c
に挿入して、上記のエラーの原因を特定しました。
log = kmalloc(sizeof(*log), GFP_KERNEL);
if (!log)
ti->error = "kmalloc error";
return NULL;
type = get_type(type_name);
if (!type) {
kfree(log);
ti->error = "get_type error";
return NULL;
}
log->flush_callback_fn = flush_callback_fn;
log->type = type;
if (type->ctr(log, ti, argc, argv)) {
kfree(log);
put_type(type);
ti->error = "ctr error";
return NULL;
}
次に、カーネルを再コンパイルすると、次のようになります。
2回目の試行で、彼はtype_name
の値を取得したいと考えています。
if (type->ctr(log, ti, argc, argv)) {
kfree(log);
put_type(type);
char* typeN = kmalloc(1000, GFP_KERNEL);
char* pTypeN = typeN;
char* ptype_name = type_name;
while (*ptype_name != '\0') {
*pTypeN = *ptype_name;
++pTypeN;
++ptype_name;
}
ti->error = typeN;
return NULL;
}
上記の方法を使用して、core_ctr
およびcreate_log_context
へのトレースを続行します。
static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
unsigned int argc, char **argv,
struct dm_dev *dev)
{
enum sync sync = DEFAULTSYNC;
struct log_c *lc;
uint32_t region_size;
unsigned int region_count;
size_t bitset_size, buf_size;
int r;
if (argc < 1 || argc > 2) {
DMWARN("wrong number of arguments to dirty region log");
ti->error = "argc < 1 or > 2";
return -EINVAL;
}
if (argc > 1) {
if (!strcmp(argv[1], "sync"))
sync = FORCESYNC;
else if (!strcmp(argv[1], "nosync"))
sync = NOSYNC;
else {
DMWARN("unrecognised sync argument to "
"dirty region log: %s", argv[1]);
ti->error = "unrecognised sync argument to";
return -EINVAL;
}
}
if (argc < 1 || argc > 2) {
DMWARN("wrong number of arguments to dirty region log");
char* argcStr = kmalloc(1000, GFP_KERNEL);
char* pArgc = argcStr;
unsigned int temp = argc;
do {
*pArgc = temp % 10;
++pArgc;
temp = temp / 10;
} while (temp > 0);
*pArgc = ' ';
++pArgc;
//copy argv;
int i = 0;
for (i; i < argc; ++i) {
char* pArgv = argv[i];
while (*pArgv != '\0') {
*pArgc = *pArgv;
++pArgc;
++pArgv;
}
*pArgc = ' ';
++pArgc;
}
*pArgc = '\0';
ti->error = argcStr;
return -EINVAL;
}
黒のハート記号のASCIIコードは... 3であることに注意してください。
作者がcore_ctr
とdisk_ctr
を混同している理由がわかりません。 type_name
はcore
ですが、引数の数は3なので、block_on_error
構造体に以下を挿入して、最後の引数(dm_dirty_log_create
)をトリミングします。
struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
struct dm_target *ti,
int (*flush_callback_fn)(struct dm_target *ti),
unsigned int argc, char **argv)
{
struct dm_dirty_log_type *type;
struct dm_dirty_log *log;
log = kmalloc(sizeof(*log), GFP_KERNEL);
if (!log) {
ti->error = "kmalloc error";
return NULL;
}
char* core = "core";
char* pCore = core;
int is_core = 1;
char* ptype_name = type_name;
while (*ptype_name != '\0') {
if (*pCore != *ptype_name) {
is_core = 0;
}
++pCore;
++ptype_name;
}
if (is_core && *pCore == *ptype_name && argc == 3) {
--argc;
}
type = get_type(type_name);
しばらく様子を見てみましょう:
# uname -r
2.6.34.14
# dmraid -s
*** Group superset .ddf1_disks
--> Active Subset
name : ddf1_VCBOOT
size : 489971712
stride : 128
type : mirror
status : ok
subsets: 0
devs : 2
spares : 0
# modprobe ceph
# lsmod | grep ceph
ceph 176676 0
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ddf1_VCBOOTp3
219G 17G 191G 8% /
/dev/mapper/ddf1_VCBOOTp1
99M 64M 30M 69% /boot
tmpfs 48G 16M 48G 1% /dev/shm
192.168.2.13:6789,192.168.2.14:6789,192.168.2.15:6789:/
72T 28T 45T 39% /mnt/ceph
そもそもなぜddfフォーマットのRAIDアレイを使用しているのですか? dmraid
でアクティブ化しようとしているようですが、これは数年間開発が見られず、多かれ少なかれ減価償却されています。 mdadm
のサポートははるかに優れており、最近のバージョンではddf形式がサポートされていますが、ネイティブ形式が推奨されます。
Dm-logモジュールがロードされていることを確認してください。
Cephのバグ 4286 によると、Fuseはatomic_o_truncに少なくともカーネル2.6.24が必要です。 2.6.25のRPM を見つけました。このカーネルは、HPCクラスター用のようです。
上記の問題は、RedHatがカーネルリリースに対して行った大幅な変更が原因だと思います。ハードウェア構成とソフトウェア要件によっては、新しいカーネルを試すのがはるかに難しくなります。