Re: cannot release a UDP kernel socket - why ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Here is the full code:

#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/proc_fs.h>
#include <linux/compiler.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/byteorder/generic.h>
#include <linux/inet.h>
#include <linux/udp.h>
#include <linux/netdevice.h>
#include <linux/time.h>
#include <linux/spinlock.h>
#include <net/ip.h>
#include <net/checksum.h>
#include <linux/vmalloc.h>
#include <linux/net.h>
#include <linux/in_route.h>
#include <net/route.h>
#include <linux/kthread.h>
static struct socket *udpInserversocket=NULL;
static struct task_struct *p;

static int createUdpInSocket(void)
{
	int res;
	struct sockaddr_in server;
	int servererror;
	unsigned char *buf;
	printk( KERN_ERR "createUdpInSocket\n" );

	if( sock_create( PF_INET,SOCK_DGRAM,IPPROTO_UDP,&udpInserversocket)<0 ) {
		printk(KERN_ERR "server: Error creating udpserversocket.\n" );
		return -EIO;
	}
	server.sin_family      = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons((unsigned short)4000);
	servererror = udpInserversocket->ops->bind(udpInserversocket,
			(struct sockaddr *) &server, sizeof(server) );
		{
		struct msghdr msg;
		struct iovec iov;
		mm_segment_t oldfs;
		int size = 0;
		int len = 160;
		iov.iov_base = buf;
		msg.msg_flags = 0;
		//msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL;
		msg.msg_name = &server;
		msg.msg_namelen  = sizeof(struct sockaddr_in);
		msg.msg_control = NULL;
		msg.msg_controllen = 0;
		msg.msg_iov = &iov;
		msg.msg_iovlen = 1;
		msg.msg_control = NULL;

		oldfs = get_fs();
		set_fs(KERNEL_DS);
		printk("before sock_recvmsg in %s %s\n",__FUNCTION__,__FILE__);
		size = sock_recvmsg(udpInserversocket,&msg,len,msg.msg_flags);
		printk("after sock_recvmsg in %s %s\n",__FUNCTION__,__FILE__);
		set_fs(oldfs);
		}

		
}


static int kernThread(void *arg)
{
	allow_signal(SIGKILL);

  createUdpInSocket();

	return 0;
}


static int __init nic_init(void)
	{
	int ret;	
	void *kdata;
	p = kthread_run(kernThread,kdata,"myKernThread");
		
	return 0;	
	}

//////////////////////////////////////////////////////////////////////////////

static void __exit nic_exit(void)
	{
	printk("in nic_exit\n");

  if (p)
	  kthread_stop(p);


	if (udpInserversocket) {
		//udpInserversocket->ops->shutdown(udpInserversocket,2);
		sock_release(udpInserversocket);
		udpInserversocket=NULL;		
	}
	}

	
//////////////////////////////////////////////////////////////////////////////

module_init(nic_init)
module_exit(nic_exit)

MODULE_DESCRIPTION("test");
MODULE_LICENSE("GPL");

Mark

On Tue, Apr 28, 2009 at 9:42 AM, Pei Lin <telent997@xxxxxxxxx> wrote:
> sorry,i make a mistake,plz upload your code fully...where your "p"
> come from...
>
> BRs
>
> lin
>
> 2009/4/28 Mark Ryden <markryde@xxxxxxxxx>:
>> Hello,
>>  I don't think there is any misuse using the kthread_run; indeed it
>> is a macro not a function. This does not say that I cannot use it. It
>> is used widely:
>> for example, in pdflush.c:
>>
>> http://lxr.linux.no/linux+v2.6.29/mm/pdflush.c#L178
>> or here:
>> http://lxr.linux.no/linux+v2.6.29/fs/ocfs2/journal.c#L1353
>>
>> And if you will grep in the kernel tree, there are more
>> places.
>>
>> regards,
>> Mark
>>
>>
>>
>> On Tue, Apr 28, 2009 at 8:58 AM, Pei Lin <telent997@xxxxxxxxx> wrote:
>>> hi,
>>> i think you misuse the kthread_run,this a macro not a function.
>>>
>>> reference the define(linux-2.6.30-rc3):
>>> /**
>>>  13  * kthread_run - create and wake a thread.
>>>  14  * @threadfn: the function to run until signal_pending(current).
>>>  15  * @data: data ptr for @threadfn.
>>>  16  * @namefmt: printf-style name for the thread.
>>>  17  *
>>>  18  * Description: Convenient wrapper for kthread_create() followed by
>>>  19  * wake_up_process().  Returns the kthread or ERR_PTR(-ENOMEM).
>>>  20  */
>>>  21 #define kthread_run(threadfn, data, namefmt, ...)                          \
>>>  22 ({                                                                         \
>>>  23         struct task_struct *__k                                            \
>>>  24                 = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
>>>  25         if (!IS_ERR(__k))                                                  \
>>>  26                 wake_up_process(__k);                                      \
>>>  27         __k;                                                               \
>>>  28 })
>>>
>>> BRs
>>>
>>> Lin
>>>
>>>
>>>
>>>
>>> 2009/4/27 Mark Ryden <markryde@xxxxxxxxx>:
>>>> Hello,
>>>>  The following module creates a UDP kernel socket which calls sock_recvms.
>>>> after insmoding the module ,
>>>> netstat -nl | grep 4000 shows that indeed a socket was created and that it
>>>> listens on port 4000.
>>>> However, after running rmmod  on the module, it does **not** close the socket.
>>>> netstat -nl | grep 4000 shows that it **does** exist; the "rmmod"
>>>> itself hangs, and
>>>> there are no kernel messages.
>>>> Any ideas?
>>>>
>>>> The code of the module is below:
>>>>
>>>> static int createUdpInSocket(void)
>>>> {
>>>>        int res;
>>>>        struct sockaddr_in server;
>>>>        int servererror;
>>>>        unsigned char *buf;
>>>>        printk( KERN_ERR "createUdpInSocket\n" );
>>>>
>>>>        if( sock_create( PF_INET,SOCK_DGRAM,IPPROTO_UDP,&udpInserversocket)<0 ) {
>>>>                printk(KERN_ERR "server: Error creating udpserversocket.\n" );
>>>>                return -EIO;
>>>>        }
>>>>        server.sin_family      = AF_INET;
>>>>        server.sin_addr.s_addr = INADDR_ANY;
>>>>        server.sin_port = htons((unsigned short)4000);
>>>>        servererror = udpInserversocket->ops->bind(udpInserversocket,
>>>>                        (struct sockaddr *) &server, sizeof(server) );
>>>>                {
>>>>                struct msghdr msg;
>>>>                struct iovec iov;
>>>>                mm_segment_t oldfs;
>>>>                int size = 0;
>>>>                int len = 160;
>>>>                iov.iov_base = buf;
>>>>                msg.msg_flags = 0;
>>>>                msg.msg_name = &server;
>>>>                msg.msg_namelen  = sizeof(struct sockaddr_in);
>>>>                msg.msg_control = NULL;
>>>>                msg.msg_controllen = 0;
>>>>                msg.msg_iov = &iov;
>>>>                msg.msg_iovlen = 1;
>>>>                msg.msg_control = NULL;
>>>>
>>>>                oldfs = get_fs();
>>>>                set_fs(KERNEL_DS);
>>>>                printk("before sock_recvmsg in %s %s\n",__FUNCTION__,__FILE__);
>>>>                size = sock_recvmsg(udpInserversocket,&msg,len,msg.msg_flags);
>>>>                printk("after sock_recvmsg in %s %s\n",__FUNCTION__,__FILE__);
>>>>                set_fs(oldfs);
>>>>
>>>>                }
>>>> }
>>>>
>>>>
>>>> static int kernThread(void *arg)
>>>> {
>>>>        allow_signal(SIGKILL);
>>>>
>>>>  createUdpInSocket();
>>>>
>>>>        return 0;
>>>> }
>>>>
>>>>
>>>> static int __init nic_init(void)
>>>>        {
>>>>        int ret;
>>>>        void *kdata;
>>>>        p = kthread_run(kernThread,kdata,"myKernThread");
>>>>
>>>>        return 0;
>>>>        }
>>>>
>>>> //////////////////////////////////////////////////////////////////////////////
>>>>
>>>> static void __exit nic_exit(void)
>>>>        {
>>>>        printk("in nic_exit\n");
>>>>  if (p)
>>>>          kthread_stop(p);
>>>>
>>>>        if (udpInserversocket)
>>>>                sock_release(udpInserversocket);
>>>>
>>>>        }
>>>>
>>>>
>>>> //////////////////////////////////////////////////////////////////////////////
>>>>
>>>> module_init(nic_init)
>>>> module_exit(nic_exit)
>>>>
>>>> Regards,
>>>> Mark Ryden
>>>>
>>>> --
>>>> To unsubscribe from this list: send an email with
>>>> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
>>>> Please read the FAQ at http://kernelnewbies.org/FAQ
>>>>
>>>>
>>>
>>
>

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux