【发布时间】:2015-04-15 06:27:39
【问题描述】:
谁能给出一些简单的例子(函数名很好),以便在 FreeBSD 内核模块中从给定目录逐行读取文本文件(如果文本真的很难,则二进制也可以)?
非常感谢您的帮助。
【问题讨论】:
标签: unix filesystems kernel freebsd kernel-module
谁能给出一些简单的例子(函数名很好),以便在 FreeBSD 内核模块中从给定目录逐行读取文本文件(如果文本真的很难,则二进制也可以)?
非常感谢您的帮助。
【问题讨论】:
标签: unix filesystems kernel freebsd kernel-module
这是一个示例内核模块,它将在您的 /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(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/test.txt", curthread); flags = FREAD; error = vn_open(&nd, &flags, 0, NULL); 错误发生在vn_open_cred() ->namei() -> vref()。我相信是NDINIT()问题没有正确初始化nd。
vn_open()。 (我用内核DDB调试,故障回溯是vn_open_cred() ->namei() -> vref())
vref() 中的页面错误是它写入页面0xb0,即supervisor write data, page not present。 lock comxchgq %r15, 0xb0(%rbx) 处的故障。可能这里%rbx 为0,所以出现故障。