是否有一个linux命令(沿着cat或dd的行)允许我指定读取系统调用的偏移量?

时间:2014-07-27 20:36:17

标签: linux shell command-line filesystems fuse

我正在为操作系统类完成一项家庭作业,我们正在使用FUSE实现某些文件系统操作的基本版本。

我们正在实施的唯一一项我无法测试的操作是read()系统调用。我无法找到一种方法来使用0以外的偏移量来调用read()系统调用。

我尝试了this question的答案中提到的一些命令(如dd,head和tail),但是当它们到达我的read()系统调用的实现时,偏移量为0。当我调用这些命令时,我收到(在调用终端上)调用中指定的文件中的字节,但是在显示由FUSE处理的系统调用的另一个终端中,因此我的实现,它显示了我的read()系统调用的实现总是被调用偏移0(通常大小为4096,我认为是我正在使用的真正的linux文件系统的块大小)。我假设这些命令以4096字节为单位进行read()系统调用,然后在内部(即在dd,head或tail命令的代码内,而不是通过系统调用)将输出修改为在呼叫终端。

我是否可以运行任何命令(或脚本)(或者在脚本的情况下编写然后运行),这将允许我使用不同的偏移值测试此系统调用?

1 个答案:

答案 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;
 }