diff options
-rw-r--r-- | Documentation/filesystems/proc.txt | 24 | ||||
-rw-r--r-- | fs/proc/Makefile | 1 | ||||
-rw-r--r-- | fs/proc/proc_console.c | 114 |
3 files changed, 139 insertions, 0 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index e73df2722ff3..9471225212c4 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -1181,6 +1181,30 @@ Table 1-12: Files in /proc/fs/ext4/<devname> | |||
1181 | mb_groups details of multiblock allocator buddy cache of free blocks | 1181 | mb_groups details of multiblock allocator buddy cache of free blocks |
1182 | .............................................................................. | 1182 | .............................................................................. |
1183 | 1183 | ||
1184 | 2.0 /proc/consoles | ||
1185 | ------------------ | ||
1186 | Shows registered system console lines. | ||
1187 | |||
1188 | To see which character device lines are currently used for the system console | ||
1189 | /dev/console, you may simply look into the file /proc/consoles: | ||
1190 | |||
1191 | > cat /proc/consoles | ||
1192 | tty0 -WU (ECp) 4:7 | ||
1193 | ttyS0 -W- (Ep) 4:64 | ||
1194 | |||
1195 | The columns are: | ||
1196 | |||
1197 | device name of the device | ||
1198 | operations R = can do read operations | ||
1199 | W = can do write operations | ||
1200 | U = can do unblank | ||
1201 | flags E = it is enabled | ||
1202 | C = it is prefered console | ||
1203 | B = it is primary boot console | ||
1204 | p = it is used for printk buffer | ||
1205 | b = it is not a TTY but a Braille device | ||
1206 | a = it is safe to use when cpu is offline | ||
1207 | major:minor major and minor number of the device separated by a colon | ||
1184 | 1208 | ||
1185 | ------------------------------------------------------------------------------ | 1209 | ------------------------------------------------------------------------------ |
1186 | Summary | 1210 | Summary |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 2758e2afc518..288a49e098bf 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -15,6 +15,7 @@ proc-y += devices.o | |||
15 | proc-y += interrupts.o | 15 | proc-y += interrupts.o |
16 | proc-y += loadavg.o | 16 | proc-y += loadavg.o |
17 | proc-y += meminfo.o | 17 | proc-y += meminfo.o |
18 | proc-y += proc_console.o | ||
18 | proc-y += stat.o | 19 | proc-y += stat.o |
19 | proc-y += uptime.o | 20 | proc-y += uptime.o |
20 | proc-y += version.o | 21 | proc-y += version.o |
diff --git a/fs/proc/proc_console.c b/fs/proc/proc_console.c new file mode 100644 index 000000000000..8a707609f528 --- /dev/null +++ b/fs/proc/proc_console.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Werner Fink, Jiri Slaby | ||
3 | * | ||
4 | * Licensed under GPLv2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/console.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/proc_fs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | #include <linux/tty_driver.h> | ||
12 | |||
13 | /* | ||
14 | * This is handler for /proc/consoles | ||
15 | */ | ||
16 | static int show_console_dev(struct seq_file *m, void *v) | ||
17 | { | ||
18 | static const struct { | ||
19 | short flag; | ||
20 | char name; | ||
21 | } con_flags[] = { | ||
22 | { CON_ENABLED, 'E' }, | ||
23 | { CON_CONSDEV, 'C' }, | ||
24 | { CON_BOOT, 'B' }, | ||
25 | { CON_PRINTBUFFER, 'p' }, | ||
26 | { CON_BRL, 'b' }, | ||
27 | { CON_ANYTIME, 'a' }, | ||
28 | }; | ||
29 | char flags[ARRAY_SIZE(con_flags) + 1]; | ||
30 | struct console *con = v; | ||
31 | unsigned int a; | ||
32 | int len; | ||
33 | dev_t dev = 0; | ||
34 | |||
35 | if (con->device) { | ||
36 | const struct tty_driver *driver; | ||
37 | int index; | ||
38 | driver = con->device(con, &index); | ||
39 | if (driver) { | ||
40 | dev = MKDEV(driver->major, driver->minor_start); | ||
41 | dev += index; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | for (a = 0; a < ARRAY_SIZE(con_flags); a++) | ||
46 | flags[a] = (con->flags & con_flags[a].flag) ? | ||
47 | con_flags[a].name : ' '; | ||
48 | flags[a] = 0; | ||
49 | |||
50 | seq_printf(m, "%s%d%n", con->name, con->index, &len); | ||
51 | len = 21 - len; | ||
52 | if (len < 1) | ||
53 | len = 1; | ||
54 | seq_printf(m, "%*c%c%c%c (%s)", len, ' ', con->read ? 'R' : '-', | ||
55 | con->write ? 'W' : '-', con->unblank ? 'U' : '-', | ||
56 | flags); | ||
57 | if (dev) | ||
58 | seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); | ||
59 | |||
60 | seq_printf(m, "\n"); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
66 | { | ||
67 | struct console *con; | ||
68 | loff_t off = 0; | ||
69 | |||
70 | acquire_console_sem(); | ||
71 | for_each_console(con) | ||
72 | if (off++ == *pos) | ||
73 | break; | ||
74 | |||
75 | return con; | ||
76 | } | ||
77 | |||
78 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
79 | { | ||
80 | struct console *con = v; | ||
81 | ++*pos; | ||
82 | return con->next; | ||
83 | } | ||
84 | |||
85 | static void c_stop(struct seq_file *m, void *v) | ||
86 | { | ||
87 | release_console_sem(); | ||
88 | } | ||
89 | |||
90 | static const struct seq_operations consoles_op = { | ||
91 | .start = c_start, | ||
92 | .next = c_next, | ||
93 | .stop = c_stop, | ||
94 | .show = show_console_dev | ||
95 | }; | ||
96 | |||
97 | static int consoles_open(struct inode *inode, struct file *file) | ||
98 | { | ||
99 | return seq_open(file, &consoles_op); | ||
100 | } | ||
101 | |||
102 | static const struct file_operations proc_consoles_operations = { | ||
103 | .open = consoles_open, | ||
104 | .read = seq_read, | ||
105 | .llseek = seq_lseek, | ||
106 | .release = seq_release, | ||
107 | }; | ||
108 | |||
109 | static int register_proc_consoles(void) | ||
110 | { | ||
111 | proc_create("consoles", 0, NULL, &proc_consoles_operations); | ||
112 | return 0; | ||
113 | } | ||
114 | module_init(register_proc_consoles); | ||