【问题标题】:Examples for reading text files in FreeBSD kernel module在 FreeBSD 内核模块中读取文本文件的示例
【发布时间】:2015-04-15 06:27:39
【问题描述】:

谁能给出一些简单的例子(函数名很好),以便在 FreeBSD 内核模块中从给定目录逐行读取文本文件(如果文本真的很难,则二进制也可以)?

非常感谢您的帮助。

【问题讨论】:

    标签: unix filesystems kernel freebsd kernel-module


    【解决方案1】:

    这是一个示例内核模块,它将在您的 /etc/motd 加载时进行监控:

    // kernel module motd catter.
    // Doug Luce doug@forephypodia.con.com
    
    #include <sys/param.h>
    #include <sys/vnode.h>
    #include <sys/fcntl.h>
    #include <sys/module.h>
    #include <sys/kernel.h>
    #include <sys/namei.h>
    #include <sys/proc.h>
    #include <sys/sbuf.h>
    
    static int catfile(const char *filename) {
      struct sbuf *sb;
      static char buf[128];
      struct nameidata nd;
      off_t ofs;
      ssize_t resid;
      int error, flags, len;
    
      NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, curthread);
      flags = FREAD;
      error = vn_open(&nd, &flags, 0, NULL);
      if (error)
        return (error);
    
      NDFREE(&nd, NDF_ONLY_PNBUF);
    
      ofs = 0;
      len = sizeof(buf) - 1;
      sb = sbuf_new_auto();
      while (1) {
        error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
                        UIO_SYSSPACE, IO_NODELOCKED, curthread->td_ucred,
                        NOCRED, &resid, curthread);
        if (error)
          break;
        if (resid == len)
          break;
        buf[len - resid] = 0;
        sbuf_printf(sb, "%s", buf);
        ofs += len - resid;
      }
    
      VOP_UNLOCK(nd.ni_vp, 0);
      vn_close(nd.ni_vp, FREAD, curthread->td_ucred, curthread);
      uprintf("%s", sbuf_data(sb));
      return 0;
    }
    
    static int EventHandler(struct module *inModule, int inEvent, void *inArg) {
      switch (inEvent) {
      case MOD_LOAD:
        uprintf("MOTD module loading.\n");
        if (catfile("/etc/motd") != 0)
          uprintf("Error reading MOTD.\n");
        return 0;
      case MOD_UNLOAD:
        uprintf("MOTD module unloading.\n");
        return 0;
      default:
        return EOPNOTSUPP;
      }
    }
    
    static moduledata_t  moduleData = {
      "motd_kmod",
      EventHandler,
      NULL
    };
    
    DECLARE_MODULE(motd_kmod, moduleData, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
    

    这主要是由https://svnweb.freebsd.org/base/release/10.1.0/sys/kern/vfs_mountroot.c?revision=274417&view=markup 的一些片段拼凑而成的

    本地内核端没有很好的扫描/解析工具,所以 这通常很难做到。

    【讨论】:

    • 当我在内核模块中直接使用它时,内核崩溃。页面错误发生在vn_open()。也许我错误地使用了NDINIT()?如何将struct thread *td 提供给该函数?还是UIO_SYSSPACE 正确而不是UIO_USERSPACE
    • 我的内核模块前几行代码:struct sbuf *sb; static char buf[128]; struct nameidata nd; off_t ofs; ssize_t resid; int error, flags, len; NDINIT(&amp;nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/test.txt", curthread); flags = FREAD; error = vn_open(&amp;nd, &amp;flags, 0, NULL); 错误发生在vn_open_cred() ->namei() -> vref()。我相信是NDINIT()问题没有正确初始化nd
    • 和你粘贴的代码差不多。我猜这个故障最有可能发生在vn_open()。 (我用内核DDB调试,故障回溯是vn_open_cred() -&gt;namei() -&gt; vref()
    • vref() 中的页面错误是它写入页面0xb0,即supervisor write data, page not presentlock comxchgq %r15, 0xb0(%rbx) 处的故障。可能这里%rbx 为0,所以出现故障。
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 2016-01-16
    • 2021-11-20
    • 1970-01-01
    • 2014-08-05
    相关资源
    最近更新 更多