Tag: linux kernel

使用带有inotify的read

我一直在研究inotify调用,但是当涉及到读取接口时,我仍然有点不稳定。 这些是关于如何使用read(2)正确连接inotify的最相关的资源: http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/index.html http://www.linuxjournal.com/article/8478 它们都以相同的方式实现它们,它们首先定义以下大小: #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) 然后他们以这种方式使用它们: length = read( fd, buffer, BUF_LEN ); if ( length < 0 ) { perror( "read" ); } while ( i len; } 现在,我们知道name是struct inotify_event一部分,并且它具有可变长度。 那么,缓冲区中的最后一个inotify_event是否会被截断? 假设有1023个inotify_events,路径为16个字节,另一个路径为32个字节。 那会发生什么? 后来会被截断吗? 或者内核是否会看到它不适合缓冲区并完全放弃?

Linux内核调试打印输出?

有没有更好的方法来调试Linux内核中的打印输出? 现在乱丢代码: printk(KERN_DBG “%s:%d – %s() “, __FILE__, __LINE__, __FUNCTION__ ); 哪个不是很干净。 应该有一种方式让整行成为#ifdef :ed以一种不错的方式。

使用sk_buff添加以太网帧头

我有一个内核模块,可以捕获传出的Internet流量(Netfilter hook:LOCAL_OUT)在这个钩子上,仍然没有以太网头。 我构建了以太网头,它已经可以使用了,但是如何将它附加到skb以便我可以将整个skb结构发送到dev_queue_xmit() ? 是否有关于如何操作sk_buff数据的指南,您可以提供给我以获取更多信息? 作为样本,我尝试在所有ECHO ICMP流量上做我想做的事情; 这是我的代码。 但是当在另一台机器上检查Wireshark时,我得到了一个工作的以太网头但是一个EMPTY IP数据包……为什么会这样? static unsigned int post_icmp_check(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct iphdr *iph; struct icmphdr *icmph; struct sk_buff *sb; struct ethhdr *ethh; unsigned char *frame = NULL; //Used just to copy the skb->data […]

如何在Linux中使用内核空间的ioctl()?

是否可以从Linux内核模块调用ioctl ? 任何人都可以举例说明它是如何使用的吗?

跟踪数据包通过内核(linux)

我有两台机器设置为使用Ip-Security和机器A(让我们称之为A和B)有一个套接字,它绑定到本地机器上的特定UDP端口,并经常轮询它以查看是否有任何接收在上面。 当我禁用Ip-security时,两台机器之间的数据运行良好,我发送和接收数据包很好。 但是当启用Ip-Security时,数据包不会到达机器B发送的机器A上的那个套接字。 我在这两台机器上都做了一个tcpdump ,我可以看到(加密的)数据包从机器B发出并在机器A上接收。但是之后,数据包进入内核,在某个地方要么解密数据包,要么在某个其他阶段,数据包被丢弃。 我希望能够在数据包通过内核时跟踪数据包并查看它被丢弃的位置。 是否有一些/proc可以用于此目的? 我能想到的另一种方法是在整个内核中插入调试语句并重新编译它,然后再次尝试发送数据包并进行调试。 感谢和抱歉长信息,但这是必要的。

在Linux内核源代码中实现系统调用/陷阱

我目前正在学习操作系统使用陷阱来促进Linux内核中的系统调用。 我在traps.c中找到了陷阱表,并在entry.S中实现了许多陷阱。 但是,我被指示在Linux内核中找到两个系统调用的实现,它使用陷阱来实现系统调用。 虽然我可以找到陷阱本身的定义,但我不确定内核中的其中一个陷阱的“调用”是什么样的。 因此,我正在努力寻找这种行为的一个例子。 在有人问之前,是的,这是家庭作业。 作为一个注释,我正在使用Github浏览内核源代码,因为kernel.org已关闭: https : //github.com/torvalds/linux/

在Linux内核源代码中遇到Abstruse #define宏

get_cpu_var marcro,定义如下 29 #define get_cpu_var(var) (*({ \ 30 extern int simple_identifier_##var(void); \ 31 preempt_disable(); \ 32 &__get_cpu_var(var); })) 似乎是不可理解的。我假设它是一种函数宏,它返回一个变量指针(基于星号)或者它是某种函数指针。我甚至接近它?有人能启发我吗?

从内核模块内发送原始以太网数据包

我发现我需要在内核模块中构建一个新的sk_buff结构并将其传递给我的网络设备,但我无法弄清楚的是如何为简单的原始以太网数据包设置结构变量。 这一定很容易,但我真的很感激,如果有人能给我一个如何将sk_buff放在一起的示例代码。

CLFLUSH如何处理尚未缓存的地址?

我们正在尝试使用Intel CLFLUSH指令在用户空间中刷新Linux中进程的缓存内容。 我们创建了一个非常简单的C程序,它首先访问一个大型数组,然后调用CLFLUSH来刷新整个数组的虚拟地址空间。 我们测量CLFLUSH刷新整个arrays所需的延迟。 程序中arrays的大小是一个输入,我们将输入从1MB变为40MB,步长为2MB。 根据我们的理解,CLFLUSH应该刷新缓存中的内容。 所以我们期望看到整个arrays的刷新延迟首先在arrays大小方面线性增加,然后在arrays大小大于20MB(这是我们程序的LLC的大小)之后延迟应该停止增加。 然而,实验结果非常令人惊讶,如图所示。 数组大小超过20MB后,延迟不会停止增加。 我们想知道如果地址不在缓存中,CLFLUSH是否可能在CLFLUSH将地址刷出缓存之前引入地址? 我们还尝试在英特尔软件开发人员手册中进行搜索,但没有找到任何解释,如果地址不在缓存中,CLFLUSH会做什么。 以下是我们用于绘制图形的数据。 第一列是以KB为单位的数组大小,第二列是以秒为单位刷新整个数组的延迟。 任何建议/建议都不仅仅是值得赞赏的。 [改性] 以前的代码是不必要的。 尽管CLFLUSH具有相似的性能,但它可以更容易地在用户空间中完成。 所以我删除了凌乱的代码以避免混淆。 SCENARIO=Read Only 1024,.00158601000000000000 3072,.00299244000000000000 5120,.00464945000000000000 7168,.00630479000000000000 9216,.00796194000000000000 11264,.00961576000000000000 13312,.01126760000000000000 15360,.01300500000000000000 17408,.01480760000000000000 19456,.01696180000000000000 21504,.01968410000000000000 23552,.02300760000000000000 25600,.02634970000000000000 27648,.02990350000000000000 29696,.03403090000000000000 31744,.03749210000000000000 33792,.04092470000000000000 35840,.04438390000000000000 37888,.04780050000000000000 39936,.05163220000000000000 SCENARIO=Read and Write 1024,.00200558000000000000 3072,.00488687000000000000 5120,.00775943000000000000 7168,.01064760000000000000 9216,.01352920000000000000 11264,.01641430000000000000 13312,.01929260000000000000 15360,.02217750000000000000 17408,.02516330000000000000 19456,.02837180000000000000 21504,.03183180000000000000 23552,.03509240000000000000 […]

Linux内核:为什么’子类’结构将基类信息放在最后?

我正在阅读Linux内核上的Beautiful Code中的章节,作者讨论了Linux内核如何在C语言中实现inheritance(以及其他主题)。 简而言之,定义了一个“基础”结构,为了从中inheritance,“子类”结构将基类的副本放在子类结构定义的末尾 。 然后,作者花了几页来解释一个聪明而复杂的宏,以确定要从对象的基本部分转换为对象的子类部分要返回多少字节。 我的问题:在子类struct中,为什么不将struct struct声明为struct中的第一个东西,而不是最后一个 ? 首先放置基础结构的主要优点是从基类转换到子类时根本不需要移动指针 – 本质上,执行转换只是告诉编译器让代码使用’额外’子类struct在基类定义的东西之后放置的字段。 只是为了澄清我的问题,让我抛出一些代码: struct device { // this is the ‘base class’ struct int a; int b; //etc } struct usb_device { // this is the ‘subclass’ struct int usb_a; int usb_b; struct device dev; // This is what confuses me – // why put this […]