首页 > 解决方案 > 从 ftrace 原始文件读取时 splice(2) 返回“无效参数”

问题描述

我想尝试 splice syscall,trace-cmd 使用它来零复制 off ftrace 的原始文件。

以下是 splice 无法读取的 ftrace 原始文件的部分列表:

/sys/kernel/debug/tracing/per_cpu/cpo0/trace_pipe_raw

/sys/kernel/debug/tracing/per_cpu/cpo0/snapshot_raw

/sys/kernel/debug/tracing/per_cpu/cpo1/trace_pipe_raw

/sys/kernel/debug/tracing/per_cpu/cpo1/snapshot_raw

这里还有一些其他文件(拼接处理得很好):

/sys/kernel/debug/tracing/per_cpu/cpo0/trace_pipe

/sys/kernel/debug/tracing/per_cpu/cpo0/snapshot

/sys/kernel/debug/tracing/per_cpu/cpo1/trace_pipe

/sys/kernel/debug/tracing/per_cpu/cpo1/snapshot

什么有效:

这是我的代码:

static void unit_test_x(void)
{  
    int buffer_pipe[2];
    pipe(buffer_pipe);

    std::string source_path = "/sys/kernel/debug/tracing/per_cpu/cpu1/trace_pipe_raw";
    int trace_fd = open(source_path.c_str(), O_RDONLY);

    std::string destination_path = "foo";
    int dest_fd = open (destination_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);

    int actually_read = splice(trace_fd,
                               NULL,
                               buffer_pipe[1],
                               NULL,
                               1000,
                               SPLICE_F_MORE | SPLICE_F_MOVE );

    if (0 > actually_read )
    {   
        printf("Oh dear, something went wrong %s\n", s  trerror(errno));
        throw std::runtime_error("writing from source to pipe failed");
    }

    actually_read = splice(buffer_pipe[0],
                           NULL,
                           dest_fd,
                           NULL,
                           actually_read,
                           SPLICE_F_MORE | SPLICE_F_MOVE);

}

笔记:

对 /sys/kernel/debug/tracing 的所有访问都是使用 sudo 完成的

标签: linuxlinux-kernelspliceftracezero-copy

解决方案


经过大量故障排除后,我已经解决了问题。Splice 不会从作为二进制数据流的“原始”文件中读取小于页面大小(4096 字节)的内容。提供小于页面大小将导致“无效参数”错误。


推荐阅读