在 CentOS 5 上編譯核心版本 >= 2.6.34:RAID 集“ddf1_foo”未啟動?
我想在一些 CentOS 5 伺服器上掛載一個 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 指出了這一點,但 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
第二個錯誤怎麼樣:
device-mapper: table: 253:0: mirror: Error creating mirror dirty log RAID set "ddf1_bar" was not activated
- 2.6.18的初始化腳本: http: //fpaste.org/byZ3/
- 2.6.34.14 的:http ://fpaste.org/8COr/
除了以下模組未載入到較新的核心中之外,它們幾乎相同:
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
嗎?更新星期四 4 月 4 日 21:40:32 ICT 2013
http://alistairphipps.com/wiki/index.php?title=Notes#LVM
類似“mirror log: unrecognized sync argument to mirror log: 2”, “table: mirror: Error Creating mirror dirty log”的奇怪錯誤消息意味著您的核心設備映射器和使用者空間工具版本不匹配:可能您的核心太新了您的 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
但沒有任何改變。
更新星期六 4 月 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
更新 2013 年 4 月 10 日星期三 11:22:54 ICT
在源文件夾中搜尋,我發現了這個:
# 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; }
然後重新編譯核心,我們得到:
在第二次嘗試時,他想獲得 的值
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 模組。