summaryrefslogtreecommitdiff
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 163e5c00e74c..f37abf4c1e1b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -31,6 +31,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/vermagic.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/pgalloc.h>
@@ -59,6 +60,29 @@ static spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
static DECLARE_MUTEX(module_mutex);
static LIST_HEAD(modules);
+static DECLARE_MUTEX(notify_mutex);
+static struct notifier_block * module_notify_list;
+
+int register_module_notifier(struct notifier_block * nb)
+{
+ int err;
+ down(&notify_mutex);
+ err = notifier_chain_register(&module_notify_list, nb);
+ up(&notify_mutex);
+ return err;
+}
+EXPORT_SYMBOL(register_module_notifier);
+
+int unregister_module_notifier(struct notifier_block * nb)
+{
+ int err;
+ down(&notify_mutex);
+ err = notifier_chain_unregister(&module_notify_list, nb);
+ up(&notify_mutex);
+ return err;
+}
+EXPORT_SYMBOL(unregister_module_notifier);
+
/* We require a truly strong try_module_get() */
static inline int strong_try_module_get(struct module *mod)
{
@@ -1373,6 +1397,10 @@ sys_init_module(void *umod,
/* Drop lock so they can recurse */
up(&module_mutex);
+ down(&notify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod);
+ up(&notify_mutex);
+
/* Start the module */
ret = mod->init();
if (ret < 0) {