Skip to content

Commit

Permalink
Fix init ordering of /dev/console vs callers of modprobe
Browse files Browse the repository at this point in the history
Make /dev/console get initialised before any initialisation routine that
invokes modprobe because if modprobe fails, it's going to want to open
/dev/console, presumably to write an error message to.

The problem with that is that if the /dev/console driver is not yet
initialised, the chardev handler will call request_module() to invoke
modprobe, which will fail, because we never compile /dev/console as a
module.

This will lead to a modprobe loop, showing the following in the kernel
log:

	request_module: runaway loop modprobe char-major-5-1
	request_module: runaway loop modprobe char-major-5-1
	request_module: runaway loop modprobe char-major-5-1
	request_module: runaway loop modprobe char-major-5-1
	request_module: runaway loop modprobe char-major-5-1

This can happen, for example, when the built in md5 module can't find
the built in cryptomgr module (because the latter fails to initialise).
The md5 module comes before the call to tty_init(), presumably because
'crypto' comes before 'drivers' alphabetically.

Fix this by calling tty_init() from chrdev_init().

Signed-off-by: David Howells <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
dhowells authored and torvalds committed Aug 6, 2010
1 parent 1e456a1 commit 31d1d48
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 3 deletions.
2 changes: 1 addition & 1 deletion drivers/char/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ static int __init chr_dev_init(void)
NULL, devlist[minor].name);
}

return 0;
return tty_init();
}

fs_initcall(chr_dev_init);
4 changes: 2 additions & 2 deletions drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3128,7 +3128,7 @@ static struct cdev tty_cdev, console_cdev;
* Ok, now we can initialize the rest of the tty devices and can count
* on memory allocations, interrupts etc..
*/
static int __init tty_init(void)
int __init tty_init(void)
{
cdev_init(&tty_cdev, &tty_fops);
if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
Expand All @@ -3149,4 +3149,4 @@ static int __init tty_init(void)
#endif
return 0;
}
module_init(tty_init);

1 change: 1 addition & 0 deletions fs/char_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/tty.h>

#include "internal.h"

Expand Down
3 changes: 3 additions & 0 deletions include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,9 @@ static inline void tty_audit_push_task(struct task_struct *tsk,
}
#endif

/* tty_io.c */
extern int __init tty_init(void);

/* tty_ioctl.c */
extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
Expand Down

0 comments on commit 31d1d48

Please sign in to comment.