在 CentOS 5 上编译内核版本 >= 2.6.34:RAID 集“ddf1_foo”未激活?

在 CentOS 5 上编译内核版本 >= 2.6.34:RAID 集“ddf1_foo”未激活?

我想要挂载 Ceph FS在某些 CentOS 5 服务器上。由于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

谷歌指出但是 CentOS 5.x 附带内核 2.6.18,我将编译一个支持 Ceph 的新内核。

.config从正在运行的内核复制而来,并带有 2 个附加设置:

CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_CEPH_FS=m

但它们都给了我以下错误:

在此处输入图片描述

提取内核映像后,通过编辑初始化脚本并删除两行,可以消除第一个警告:

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

除了以下模块未加载到较新的内核之外,它们大部分是相同的:

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


更新时间:2013 年 4 月 4 日星期四 21:40:32 ICT

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

出现类似于“镜像日志:无法识别镜像日志的同步参数:2”、“表:镜像:创建镜像脏日志时出错”的奇怪错误消息,表示内核设备映射器和用户空间工具版本不匹配:可能内核对于 lvm 工具版本来说太新了。从源安装最新的设备映射器和 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

但没有什么变化。


更新时间:2013 年 4 月 6 日星期六 18:51:31 ICT

/lib/modules/2.6.18-274.el5/内核/驱动程序/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/内核/驱动程序/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", &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;
}

答案1

为什么首先要使用 ddf 格式的 raid 阵列?您似乎试图使用 来激活它dmraid,它已经好几年没有开发了,而且或多或少已经贬值了。 mdadm得到了更好的支持,而且最近的版本确实支持 ddf 格式,尽管它的原生格式是首选。

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

答案2

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

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_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_ctr和混为一谈disk_ctr。 是type_namecore但参数数量是 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

答案3

根据 Ceph bug4286,FUSE 至少需要内核 2.6.24 才能使用 atomic_o_trunc。我找到了一个2.6.25 的 RPM。该内核似乎是用于 HPC 集群的。

我认为上述问题是由于 Red Hat 对其内核版本进行了大量修改造成的。根据您的硬件配置和软件要求,尝试较新的内核会变得更加困难。

相关内容