如何使用mount(2)挂载使用mkfs创建的常规文件系统?

4

这是我创建“普通”文件系统的方法:

$ touch container
$ mkfs.ext4 container 20000

如何使用 C 函数mount(2) 挂载它?

实际上,mount 告诉我:

需要块设备

是否有一种方法可以在 C 中创建文件系统?


你需要创建一个回环设备,但这取决于你使用的UNIX系统。你使用的是哪个UNIX系统? - fuz
@FUZxxl:由于要使用mkfs.ext4,所以基本上必须是Linux系统。 - Joshua
据我所知,FreeBSD也有这个功能。 - fuz
2个回答

1
问题在于mount库调用不设置一个循环设备。为了挂载您的容器,您需要传递-o loopmount命令,这 effectively 包含了losetup所做的事情(即使/dev/loopN指向您的文件并将其挂载)。使用库调用时,您需要模拟它,即首先需要设置一个循环设备。
要确定您要做的确切操作,请尝试:
strace mount -t ext4 -o loop container /mnt

请看系统调用。你可以看到,首先它使用与losetup等效的系统调用创建一个循环设备(例如/dev/loop0),然后挂载该循环设备。

以下是strace输出中的关键行:

首先分配循环设备:

stat("/dev/loop", 0x7fffe90b00b0)       = -1 ENOENT (No such file or directory)
open("/dev/loop0", O_RDONLY)            = 3
fstat(3, {st_mode=S_IFBLK|0660, st_rdev=makedev(7, 0), ...}) = 0
ioctl(3, LOOP_GET_STATUS, {number=39736224, offset=0x6f726763, encrypt_type=0x732f7075 /* LO_CRYPT_??? */, encrypt_key_size=1702130553, flags=LO_FLAGS_READ_ONLY|LO_FLAGS_AUTOCLEAR|LO_FLAGS_PARTSCAN|0x63206460, name="group rw,noexec,nosuid,nodev,none,name=systemd 0 0", encrypt_key="s 0 0\0\0e-agent.devices 0 0\0\0\320\177\0\0", ...}) = -1 ENXIO (No such device or address)
close(3)                                = 0
open("/home/amb/so/container", O_RDWR)  = 3
open("/dev/loop0", O_RDWR)              = 4
readlink("/home", 0x7fffe90adfa0, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/amb", 0x7fffe90adfa0, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/amb/so", 0x7fffe90adfa0, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/amb/so/container", 0x7fffe90adfa0, 4096) = -1 EINVAL (Invalid argument)
ioctl(4, LOOP_SET_FD, 0x3)              = 0
close(3)                                = 0
ioctl(4, LOOP_SET_STATUS64, {offset=0, number=0, flags=LO_FLAGS_AUTOCLEAR, file_name="/home/amb/so/container", ...}) = 0
ioctl(4, LOOP_GET_STATUS64, {offset=0, number=0, flags=LO_FLAGS_AUTOCLEAR, file_name="/home/amb/so/container", ...}) = 0

然后才执行mount操作:
mount("/dev/loop0", "/mnt", "ext4", MS_MGC_VAL, NULL) = 0

我建议您使用mount命令,除非您有充分的理由不这样做。这可以确保/etc/mtab等文件得到维护。


1
作为abligh答案的后续,设置循环设备的代码如下:
int device = open(device_path, O_RDWR);
/* omitting error checking on device for clarity */
char buf[20];
int success = 0;
for (i = 0; i < 999999999) {
    sprintf(buf, "/dev/loop%d", i);
    int h = open(buf, O_RDWR);
    if (h > -1) {
        int r= ioctl(h, LOOP_SET_FD, device);
        close(h);
        if (!r) {
           success = 1;
           break;
        }
    } else if (errno == ENOENT)
        break;
}
if (!success) {
     /* no more free loop devices or you're not root */
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接