将存储在静态变量中的文件系统映像挂载

3
可以将包含文件系统镜像的二进制文件进行循环挂载。我想将该二进制文件放入C语言的静态变量中,然后挂载该静态变量。这是可能的吗?如果可以,我需要使用什么 C API 魔法呢?

当然可以。为了澄清,您想要在二进制文件内部完成所有操作,并避免使用外部的“losetup”和“mount”命令吗? - Employed Russian
花钱买工具也可以(在脚本中可能会这样做?),但我对C API调用很感兴趣。 - bobbogo
“但我对C API调用很感兴趣”——抱歉,我不明白。如果您知道如何通过外部命令执行此操作,则可以查找这些命令使用的API。那么,您已经知道如何执行此操作,但无法发现API,还是卡在早期的“我该如何执行此操作?”阶段? - Employed Russian
不完全正确。我知道如何挂载文件。当然,我可以将我的静态变量写入文件,并以此方式完成。我希望有一些魔法可以让我直接在内存中挂载缓冲区。 - bobbogo
1个回答

1

我们需要采取几个步骤:

  1. 创建文件系统映像
  2. 将此映像嵌入二进制文件中
  3. 将嵌入的映像作为只读文件系统挂载。

听起来你已经知道如何执行步骤1和2,但不知道如何执行步骤3。

我准备了ab.sqfs映像和a.out,其中包含该映像在偏移量0x3010处。以下是挂载此文件系统的命令:

# optional, look at the bytes of the filesystem from step 1 
xxd -l 16 -g1 ab.sqfs
00000000: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# optional: confirm that we have the correct file offset to the start of FS image
xxd -l 16 -g1 -s 0x3010 a.out
00003010: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# create a loop device which "points" into the file:
sudo losetup -r -o 0x3010 loop0 a.out 
losetup: a.out: Warning: file does not fit into a 512-byte sector; the end of the file will be ignored.

# optional: confirm that (just created) /dev/loop0 contains expected bytes
sudo xxd -l 16 -g1 /dev/loop0
00000000: 68 73 71 73 07 00 00 00 6c 61 ce 60 00 00 02 00  hsqs....la.`....

# create directory on which the FS will be mounted
mkdir /tmp/mnt         

# finally mount the FS:
sudo mount -oro /dev/loop0 /tmp/mnt

# optional: verify contents of /tmp/mnt
ls -lR /tmp/mnt
... has exactly the files I've put into it.

我需要哪些 C API 魔法?

您可以在 strace 下运行 losetupmount 命令以观察它们的操作。对于 losetup 的关键步骤如下:

openat(AT_FDCWD, "/tmp/a.out", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/loop0", O_RDONLY|O_CLOEXEC) = 4
ioctl(4, LOOP_SET_FD, 3)                = 0
ioctl(4, LOOP_SET_STATUS64, {lo_offset=0x3010, lo_number=0, lo_flags=LO_FLAGS_READ_ONLY, lo_file_name="/tmp/a.out", ...}) = 0

而对于 mount

mount("/dev/loop0", "/tmp/mnt", "squashfs", MS_RDONLY, NULL) = 0

这些调用可以由应用程序本身执行,也可以通过“外壳”到外部losetupmount命令来执行。


谢谢您的回复。不幸的是,您只是将静态缓冲区写入标准文件,然后循环挂载该文件。这是相当标准的做法。难道没有办法以某种方式共享缓冲区,使得内存中的数据出现为一个文件,然后可以直接进行循环挂载吗? - bobbogo
@bobbogo 不,我不这样做。 - Employed Russian

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