sockets - 在自定义模块中调用 sock_release() 后内核卡住了

标签 sockets linux-kernel kernel-module

我写了一个内核模块来处理基于套接字的 TCP 连接。除了一个特定的用异常(exception),一切都很好。如果有人建议我如何解决下面描述的问题,我将不胜感激。

我有:

  • 内核模块,它是使用注册的设备
    misc_register ()。
  • 使用标准文件 i/o 函数与此模块通信的用户空间应用程序:打开 ,
    关闭 , ioctl

  • 确切的场景如下所示:
  • 使用 insmod 加载模块。
  • 使用标准 从用户应用程序打开相关设备打开 () 函数
  • 调用 ioctl () 在内核模块中执行以下操作(忽略无关紧要的代码行):

  • `
    ...
    sock_create(PF_INET, SOCK_STREAM, 0, sock);
    ...
    flags = O_NONBLOCK;
    sock_map_fd(*sock, flags);
    ...
    kernel_connect (sock, (struct sockaddr *)server_addr, sizeof(struct sockaddr_in), sock->file->f_flags);
    ...
    

    `

    所有函数都成功返回。 TCP 连接建立成功。之后,也可以在此连接上进行读/写,但这不会影响问题。

    如果应用程序自然完成或者我通过发送 SIGINT 来中断它,则连接会很好地关闭 - 使用 FIN 交换等。在 SIGKILL 上,它会按我的预期发出 TCP。到目前为止没有问题。

    现在我想在没有停止应用程序的情况下关闭这个套接字。我尝试调用 socks 释放 () 通过另一个 ioctl 调用在我的内核模块中。在这个调用上,TCP 连接也很好地关闭了。但是,现在当我的应用程序完成或中断时,内核会卡住!

    我怀疑内核不知何故没有“通知”套接字已关闭。它会尝试再次关闭它,一旦套接字内存结构被解除分配,它就会失败。

    有人使用内核模块中的套接字并遇到类似问题吗?
    您能否推荐一种使用内核模块中的 TCP 套接字的替代方法?
    从内核中关闭套接字的替代方法?

    非常感谢您提前。

    最佳答案

    经过内核代码调查,我发现如果您使用 将套接字映射到文件sock_map_fd () 函数调用 是不够的 socks 释放 ()。此函数不会释放与套接字关联的文件描述符。如果您确实需要将内核套接字映射到文件,请保留 返回的文件描述符。 sock_map_fd () 并使用 系统关闭 () 函数关闭套接字并清理相关文件。请注意,当设备文件描述符关闭时,模块中创建并与文件关联的所有套接字也会自动关闭。

    或者,您可以避免将套接字映射到文件描述符。即使没有映射,套接字的基本功能也将保持正常。在这种情况下 socks 释放 () 完美运行。

    关于sockets - 在自定义模块中调用 sock_release() 后内核卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25552224/

    相关文章:

    linux - 在操作系统中,为什么可加载内核模块(LKM)不需要调用消息传递来进行通信?

    android - 制作 Android 内核 - 模块准备

    c - 系统调用未定义!编译内核模块

    assembly - 如何读取特定内核的(性能计数器)寄存器?

    c - 如何使用 ioctl 将负整数作为有效结果返回?

    linux - 如何修改linux内核中的kvm模块?

    java - 通过 TCP 连接发送文件时缺少字节

    c# - 即使我的服务器套接字已收到所有字节,为什么 SendAsync 不会在 SocketAsyncEventArgs 上引发 Completed 事件?

    c# - UWP - 通过套接字将网络摄像头流式传输到 MediaElement - 图片损坏?

    c++ - 如何检查 TCP 连接是否是本地的?