Re: kernel dynamic references

2007-07-04 Thread Abdullah Ibn Hamad Al-Marri

On 7/4/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:

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."



David, this is really great thank you!

I hope it will be reviewed soon and committed :)


--
Regards,

-Abdullah Ibn Hamad Al-Marri
Arab Portal
http://www.WeArab.Net/
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


kernel dynamic references

2007-07-04 Thread [EMAIL PROTECTED]
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.hWed Jul  4 10:21:40 2007
@@ -147,7 +147,8 @@
 intmodule_getid(module_t);
 module_t   module_getfnext(module_t);
 void   module_setspecific(module_t, modspecific_t *);
-
+intmodule_add_dynrefs(const char *);
+intmodule_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.


___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


kernel dynamic references

2007-07-04 Thread [EMAIL PROTECTED]

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_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;



 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 comment 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.
--- module.h.orig   Wed Jul  4 10:29:53 2007
+++ module.hWed Jul  4 10:21:40 2007
@@ -147,7 +147,8 @@
 intmodule_getid(module_t);
 module_t   module_getfnext(module_t);
 void   module_setspecific(module_t, modspecific_t *);
-
+intmodule_add_dynrefs(const char *);
+intmodule_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));
 }
 
 /* 
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"