1

在 Linux(比如 Ubuntu/Debian)上,我想创建一个虚拟块设备(比如 /dev/mapper/myvbd ),它由用户家中的一堆文件(比如 /home/myuser/myvbdfiles/file [1...100])。

如果它是单个文件,我可以使用 losttup 轻松完成,但我想做的是编写一个应用程序或内核模块,在执行时创建虚拟块设备并映射用户发出的 I/O 请求在该设备上到磁盘上任何文件的任意位置(根据我想编写的算法,可能由库提供)。

我已经使用 FUSE 和 Python 编写了一个概念测试证明,但我想用 C 来做。你认为最好的方法是什么?我可以查看任何提示或资源吗?

4

1 回答 1

0

如果映射是固定的,即 512 字节扇区i始终在文件f i扇区b i中,那么您可以使用设备映射表设备 via dmsetup

表文件中的每一行都指定一个映射。在您的情况下,它们可能只是

    i   1 线性   f i   b i


创建dm-switch的派生类,比如 dm-chunkmap,重新定义region_table为每块映射(具有可配置的数量,每块 2 n 512 字节扇区)可能会很有趣:低位指定设备/文件,和高位该设备上的目标扇区。

每个表条目使用 32 位,最大大小为 2 TB(但映射需要每 GB 8 MiB 的内核 RAM);使用 16 TiB 的 8 个扇区组(并且每 GB 块设备只需要 1 MB 的内核 RAM)。

类似的东西

/* Each chunk has device index in low bits,
   and target sector number in upper bits. */
typedef unsigned chunk_t;

/*
 * Context block for a dm chunk-mapping device.
 */
struct chunkmap_ctx {
    struct dm_target *ti;
    unsigned nr_paths;        /* Number of paths (devices) in path_list. */
    unsigned dev_shift;      /* nr_paths <= 1 << dev_shift */
    unsigned dev_mask;       /* (1 << dev_shift) - 1 */
    unsigned chunk_shift;    /* 1 << chunk_shift sectors per region */
    unsigned chunk_mask;     /* (1 << chunk_shift) - 1 */
    unsigned long nr_chunks; /* Number of regions making up the device */
    chunk_t *chunk_table;
    struct dm_dev *dev_list[]; /* Devices */
};

static int chunkmap_map(struct dm_target *ti, struct bio *bio)
{
    struct chunkmap_ctx *rctx = ti->private;
    sector_t offset = dm_target_offset(ti, bio->bi_iter.bi_sector);
    chunk_t chunk = READ_ONCE(rctx->chunk_table[offset >> rctx->chunk_shift]);
    bio_set_dev(bio, rctx->dev_list[chunk & rctx->dev_mask]);
    bio->bi_iter.bi_sector = (sector_t)(chunk >> rctx->dev_shift) << rctx->chunk_mask
                           + (offset & rctx->chunk_mask);
}

static struct target_type chunkmap_target = {
    .name = "chunkmap",
    .version = {1, 1, 0},
    .module = THIS_MODULE,
    .ctr = /* chunkmap_ctr */,
    .dtr = /* chunkmap_dtr */,
    .map = chunkmap_map,
    .message = /* chunkmap_message */,
    .status = /* chunkmap_status */,
    .prepare_ioctl = /* chunkmap_prepare_ioctl */,
    .iterate_devices = /* chunkmap_iterate_devices */,
};

它允许每个块使用 2 个chunk_shift扇区(2 9 + chunk_shift字节)的块,以及最多 2 个dev_shift目标设备/路径,这些块在目标设备上完全任意排序。

应该注意的是,该结构确实允许将不同的扇区映射到同一个目标设备扇区,但这应该被视为错误,因为它可能导致错误。换句话说,只允许唯一chunk_table条目是个好主意。

如果有这样的用例,在一次性实验之外,我很确定它可以通过dm-devel邮件列表推送到主线内核中。

于 2020-07-08T16:02:46.767 回答