aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/kernel/module.c b/kernel/module.c
index dcb8a2cbf75e..1bb4c5e0d56e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -496,6 +496,8 @@ static struct module_attribute modinfo_##field = { \
496MODINFO_ATTR(version); 496MODINFO_ATTR(version);
497MODINFO_ATTR(srcversion); 497MODINFO_ATTR(srcversion);
498 498
499static char last_unloaded_module[MODULE_NAME_LEN+1];
500
499#ifdef CONFIG_MODULE_UNLOAD 501#ifdef CONFIG_MODULE_UNLOAD
500/* Init the unload section of the module. */ 502/* Init the unload section of the module. */
501static void module_unload_init(struct module *mod) 503static void module_unload_init(struct module *mod)
@@ -719,6 +721,8 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
719 mod->exit(); 721 mod->exit();
720 mutex_lock(&module_mutex); 722 mutex_lock(&module_mutex);
721 } 723 }
724 /* Store the name of the last unloaded module for diagnostic purposes */
725 sprintf(last_unloaded_module, mod->name);
722 free_module(mod); 726 free_module(mod);
723 727
724 out: 728 out:
@@ -2357,21 +2361,30 @@ static void m_stop(struct seq_file *m, void *p)
2357 mutex_unlock(&module_mutex); 2361 mutex_unlock(&module_mutex);
2358} 2362}
2359 2363
2360static char *taint_flags(unsigned int taints, char *buf) 2364static char *module_flags(struct module *mod, char *buf)
2361{ 2365{
2362 int bx = 0; 2366 int bx = 0;
2363 2367
2364 if (taints) { 2368 if (mod->taints ||
2369 mod->state == MODULE_STATE_GOING ||
2370 mod->state == MODULE_STATE_COMING) {
2365 buf[bx++] = '('; 2371 buf[bx++] = '(';
2366 if (taints & TAINT_PROPRIETARY_MODULE) 2372 if (mod->taints & TAINT_PROPRIETARY_MODULE)
2367 buf[bx++] = 'P'; 2373 buf[bx++] = 'P';
2368 if (taints & TAINT_FORCED_MODULE) 2374 if (mod->taints & TAINT_FORCED_MODULE)
2369 buf[bx++] = 'F'; 2375 buf[bx++] = 'F';
2370 /* 2376 /*
2371 * TAINT_FORCED_RMMOD: could be added. 2377 * TAINT_FORCED_RMMOD: could be added.
2372 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't 2378 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
2373 * apply to modules. 2379 * apply to modules.
2374 */ 2380 */
2381
2382 /* Show a - for module-is-being-unloaded */
2383 if (mod->state == MODULE_STATE_GOING)
2384 buf[bx++] = '-';
2385 /* Show a + for module-is-being-loaded */
2386 if (mod->state == MODULE_STATE_COMING)
2387 buf[bx++] = '+';
2375 buf[bx++] = ')'; 2388 buf[bx++] = ')';
2376 } 2389 }
2377 buf[bx] = '\0'; 2390 buf[bx] = '\0';
@@ -2398,7 +2411,7 @@ static int m_show(struct seq_file *m, void *p)
2398 2411
2399 /* Taints info */ 2412 /* Taints info */
2400 if (mod->taints) 2413 if (mod->taints)
2401 seq_printf(m, " %s", taint_flags(mod->taints, buf)); 2414 seq_printf(m, " %s", module_flags(mod, buf));
2402 2415
2403 seq_printf(m, "\n"); 2416 seq_printf(m, "\n");
2404 return 0; 2417 return 0;
@@ -2493,7 +2506,9 @@ void print_modules(void)
2493 2506
2494 printk("Modules linked in:"); 2507 printk("Modules linked in:");
2495 list_for_each_entry(mod, &modules, list) 2508 list_for_each_entry(mod, &modules, list)
2496 printk(" %s%s", mod->name, taint_flags(mod->taints, buf)); 2509 printk(" %s%s", mod->name, module_flags(mod, buf));
2510 if (last_unloaded_module[0])
2511 printk(" [last unloaded: %s]", last_unloaded_module);
2497 printk("\n"); 2512 printk("\n");
2498} 2513}
2499 2514