在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指出了这一点,但是内核2.6.18附带的CentOS 5.x,我要编译一个支持Ceph的更新的内核。

  • 我第一次尝试使用ELRepo的kernel-lt 3.0.71
  • 第二个是kernel.org的2.6.34.14

.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's: 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日星期四21:40:32 ICT 2013

http://alistairphipps.com/wiki/index.php?title=Notes#LVM

类似于“镜像日志:镜像日志:2的无法识别的同步参数”,“表:镜像:创build镜像脏日志时出错”的奇怪的错误消息意味着您的内核设备映射器和用户空间工具版本不匹配:可能是您的内核太近你的版本的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 

但没有什么变化。


更新6月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 

更新周四4月10 11:22:54 ICT 2013

在源文件夹中search,我发现这个:

 # 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", &param_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; } 

为什么你首先使用ddf格式的raid数组? 你似乎试图用dmraid激活它,这几年没有任何发展,并且或多或less的折旧。 mdadm支持得更好,最近的版本也支持ddf格式,不过它的本地格式是首选。

确保你已经加载了dm-log模块。

感谢我朋友的帮助,问题解决了。

在第一次尝试时,他注释掉了行 – ti->error = "Error creating mirror dirty log";dm-raid1.c ,并在dm-raid1.c插入一些debugging行来确定是什么导致了上述错误:

  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_ctrcreate_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_ctrdisk_ctr混合disk_ctrtype_namecore但参数的数量是3,所以他通过将以下内容插入到dm_dirty_log_create结构中来修剪最后一个参数( block_on_error ):

 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 

根据Ceph bug 4286 ,FUSE至less需要核心2.6.24 for atomic_o_trunc。 我发现2.6.25的RPM 。 该内核似乎是用于HPC群集的。

我认为你的上述问题是由于Red Hat对内核版本的重大修改所致。 这使得根据您的硬件configuration和软件要求尝试更新的内核要困难得多。