Re: kernel dynamic references
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
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
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]"