我正在为操作系统类完成一项家庭作业,我们正在使用FUSE实现某些文件系统操作的基本版本。
我们正在实施的唯一一项我无法测试的操作是read()系统调用。我无法找到一种方法来使用0以外的偏移量来调用read()系统调用。
我尝试了this question的答案中提到的一些命令(如dd,head和tail),但是当它们到达我的read()系统调用的实现时,偏移量为0。当我调用这些命令时,我收到(在调用终端上)调用中指定的文件中的字节,但是在显示由FUSE处理的系统调用的另一个终端中,因此我的实现,它显示了我的read()系统调用的实现总是被调用偏移0(通常大小为4096,我认为是我正在使用的真正的linux文件系统的块大小)。我假设这些命令以4096字节为单位进行read()系统调用,然后在内部(即在dd,head或tail命令的代码内,而不是通过系统调用)将输出修改为在呼叫终端。
我是否可以运行任何命令(或脚本)(或者在脚本的情况下编写然后运行),这将允许我使用不同的偏移值测试此系统调用?
答案 0 :(得分:0)
我想出了我遇到的问题。对于后代,我会记录答案,而不仅仅是删除我的问题,因为答案不一定容易找到。
基本上,问题发生在FUSE中。 FUSE默认不使用直接I / O(这绝对是正确的默认值,不要误解我),这导致读取大小为4096 (these are the result of FUSE using a page cache of file contents [AKA a file content cache] in the kernel)的块。对于我想测试的内容(如问题中所述),我需要启用直接I / O.有一个few ways of doing this,但我这样做的最简单方法是将-o direct_io
作为命令行参数传递。这对我有用,因为我在我的程序的fuse_main
函数中使用main
调用。
所以我的main
函数看起来像这样:
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &my_operations_structure, NULL);
}
我能够像这样调用我的程序(我在-d
选项中添加了-o direct_io
选项,以显示FUSE正在处理的系统调用以及来自的输出/调试信息我的节目):
./prog_name -d -o direct_io test_directory
然后,我使用以下简单的测试程序测试了我的程序(我知道我没有做太多的错误检查,但是这个程序仅用于一些快速和脏的测试):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
FILE * file;
char buf[4096];
int fd;
memset(&buf[0], 0, sizeof(buf));
if (argc != 4)
{
printf("usage: ./readTest [size] [offset] [filename]\n");
return 0;
}
file = fopen(argv[3], "r");
if (file == NULL)
{
printf("Couldn't open file\n");
return -1;
}
fd = fileno(file);
pread(fd, (void *) buf, atoi(argv[1]), (off_t) atoi(argv[2]));
printf("%s\n", buf);
return 0;
}