Skip site navigation (1)Skip section navigation (2)
Date:      Wed,  4 Jul 2007 17:41:34 +0200
From:      "=?iso-8859-1?Q?david.chosrova@libertysurf.fr?=" <david.chosrova@libertysurf.fr>
To:        "=?iso-8859-1?Q?freebsd-hackers?=" <freebsd-hackers@freebsd.org>
Subject:   kernel  dynamic references
Message-ID:  <JKNVLA$9473598C09CB973FF45B769C24DFF664@aliceadsl.fr>

next in thread | raw e-mail | index | archive | help

Hi,



 I'm new to Freebsd and interested in system programming. So I'have picked up a task from the project ideas list to start with.

 (part of) the subject is : "This task is to define and implement a general mechanism for tracking these references and use them in handling module unload requests."



So, to do that, I'have added an "int dynrefs" in struct module (kern_module.c), and functions to increase or decrease this count (module_add/remove_dynrefs(const char * modname) and module_updatedynrefs(const char * modname, int action) ) in kern_module.c.





 To avoid unload of a module which has a dynrefs count != 0  , I have modified module_unload(), so that unload is process only if dynrefs=0 or flag=LINKER_UNLOAD_FORCE.







--- module.h.orig	Wed Jul  4 10:29:53 2007

+++ module.h	Wed Jul  4 10:21:40 2007

@@ -147,7 +147,8 @@

 int	module_getid(module_t);

 module_t	module_getfnext(module_t);

 void	module_setspecific(module_t, modspecific_t *);

-

+int	module_add_dynrefs(const char *);

+int	module_remove_dynrefs(const char *);

 

 #ifdef	MOD_DEBUG

 extern int mod_debug;



--- kern_module.c.orig	Wed Jul  4 10:33:06 2007

+++ kern_module.c	Wed Jul  4 10:21:28 2007

@@ -52,6 +52,7 @@

 	TAILQ_ENTRY(module)	flink;	/* all modules in a file */

 	struct linker_file	*file;	/* file which contains this module */

 	int			refs;	/* reference count */

+	int			dynrefs;        /* dynamic reference count */

 	int 			id;	/* unique id number */

 	char 			*name;	/* module name */

 	modeventhand_t 		handler;	/* event handler */

@@ -65,6 +66,7 @@

 struct sx modules_sx;

 static int nextid = 1;

 static void module_shutdown(void *, int);

+static int module_updatedynrefs(const char* , int );

 

 static int

 modevent_nop(module_t mod, int what, void *arg)

@@ -152,6 +154,7 @@

 	}

 	newmod->refs = 1;

 	newmod->id = nextid++;

+	newmod->dynrefs = 0;

 	newmod->name = (char *)(newmod + 1);

 	strcpy(newmod->name, data->name);

 	newmod->handler = data->evhand ? data->evhand : modevent_nop;

@@ -231,7 +234,9 @@

 module_unload(module_t mod, int flags)

 {

 	int error;

-	error = MOD_EVENT(mod, MOD_QUIESCE);

+	MOD_SLOCK;

+	(mod->dynrefs == 0) ? (error = MOD_EVENT(mod, MOD_QUIESCE)) : (error = EPERM);

+	MOD_SUNLOCK;

 	if (error == EOPNOTSUPP || error == EINVAL)

 		error = 0;

 	if (flags == LINKER_UNLOAD_NORMAL && error != 0)

@@ -261,6 +266,37 @@

 

 	MOD_XLOCK_ASSERT;

 	mod->data = *datap;

+}

+

+static int

+module_updatedynrefs(const char* modname, int action)

+{

+	module_t mod;

+	

+	MOD_XLOCK;

+	mod = module_lookupbyname(modname);

+

+	if(mod == 0) {

+		MOD_XUNLOCK;

+		return(-1);

+	}

+

+	(action == 1) ? mod->dynrefs++ : mod->dynrefs--;

+	MOD_XUNLOCK;

+	return (0);

+}

+

+int

+module_add_dynrefs(const char *modname)

+{

+

+	return (module_updatedynrefs(modname,1));

+}

+

+int

+module_remove_dynrefs(const char * modname)

+{

+	return (module_updatedynrefs(modname,0));

 }

 

 /*	









 I have compiled and tested. with a 6-2 RELEASE. For the test I'have used two dummy module, one adding a dynrefs on the other.



 Any comments are welcome.



 David chosrova 









------------------------ ALICE C'EST ENCORE MIEUX AVEC CANAL+ LE BOUQUET ! ---------------
Découvrez vite l'offre exclusive ALICEBOX et CANAL+ LE BOUQUET, en cliquant ici http://alicebox.fr
Soumis à conditions.





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?JKNVLA$9473598C09CB973FF45B769C24DFF664>