diff options
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r-- | fs/pstore/platform.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 705fdf8abf6e..f835a25625ff 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -37,27 +37,21 @@ | |||
37 | static DEFINE_SPINLOCK(pstore_lock); | 37 | static DEFINE_SPINLOCK(pstore_lock); |
38 | static struct pstore_info *psinfo; | 38 | static struct pstore_info *psinfo; |
39 | 39 | ||
40 | /* How much of the console log to snapshot. /sys/fs/pstore/kmsg_bytes */ | 40 | /* How much of the console log to snapshot */ |
41 | static unsigned long kmsg_bytes = 10240; | 41 | static unsigned long kmsg_bytes = 10240; |
42 | 42 | ||
43 | static ssize_t b_show(struct kobject *kobj, | 43 | void pstore_set_kmsg_bytes(int bytes) |
44 | struct kobj_attribute *attr, char *buf) | ||
45 | { | 44 | { |
46 | return snprintf(buf, PAGE_SIZE, "%lu\n", kmsg_bytes); | 45 | kmsg_bytes = bytes; |
47 | } | 46 | } |
48 | 47 | ||
49 | static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr, | ||
50 | const char *buf, size_t count) | ||
51 | { | ||
52 | return (sscanf(buf, "%lu", &kmsg_bytes) > 0) ? count : 0; | ||
53 | } | ||
54 | |||
55 | struct kobj_attribute pstore_kmsg_bytes_attr = | ||
56 | __ATTR(kmsg_bytes, S_IRUGO | S_IWUSR, b_show, b_store); | ||
57 | |||
58 | /* Tag each group of saved records with a sequence number */ | 48 | /* Tag each group of saved records with a sequence number */ |
59 | static int oopscount; | 49 | static int oopscount; |
60 | 50 | ||
51 | static char *reason_str[] = { | ||
52 | "Oops", "Panic", "Kexec", "Restart", "Halt", "Poweroff", "Emergency" | ||
53 | }; | ||
54 | |||
61 | /* | 55 | /* |
62 | * callback from kmsg_dump. (s2,l2) has the most recently | 56 | * callback from kmsg_dump. (s2,l2) has the most recently |
63 | * written bytes, older bytes are in (s1,l1). Save as much | 57 | * written bytes, older bytes are in (s1,l1). Save as much |
@@ -71,15 +65,20 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
71 | unsigned long s1_start, s2_start; | 65 | unsigned long s1_start, s2_start; |
72 | unsigned long l1_cpy, l2_cpy; | 66 | unsigned long l1_cpy, l2_cpy; |
73 | unsigned long size, total = 0; | 67 | unsigned long size, total = 0; |
74 | char *dst; | 68 | char *dst, *why; |
75 | u64 id; | 69 | u64 id; |
76 | int hsize, part = 1; | 70 | int hsize, part = 1; |
77 | 71 | ||
72 | if (reason < ARRAY_SIZE(reason_str)) | ||
73 | why = reason_str[reason]; | ||
74 | else | ||
75 | why = "Unknown"; | ||
76 | |||
78 | mutex_lock(&psinfo->buf_mutex); | 77 | mutex_lock(&psinfo->buf_mutex); |
79 | oopscount++; | 78 | oopscount++; |
80 | while (total < kmsg_bytes) { | 79 | while (total < kmsg_bytes) { |
81 | dst = psinfo->buf; | 80 | dst = psinfo->buf; |
82 | hsize = sprintf(dst, "Oops#%d Part%d\n", oopscount, part++); | 81 | hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part++); |
83 | size = psinfo->bufsize - hsize; | 82 | size = psinfo->bufsize - hsize; |
84 | dst += hsize; | 83 | dst += hsize; |
85 | 84 | ||
@@ -96,7 +95,7 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
96 | memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); | 95 | memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); |
97 | 96 | ||
98 | id = psinfo->write(PSTORE_TYPE_DMESG, hsize + l1_cpy + l2_cpy); | 97 | id = psinfo->write(PSTORE_TYPE_DMESG, hsize + l1_cpy + l2_cpy); |
99 | if (pstore_is_mounted()) | 98 | if (reason == KMSG_DUMP_OOPS && pstore_is_mounted()) |
100 | pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id, | 99 | pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id, |
101 | psinfo->buf, hsize + l1_cpy + l2_cpy, | 100 | psinfo->buf, hsize + l1_cpy + l2_cpy, |
102 | CURRENT_TIME, psinfo->erase); | 101 | CURRENT_TIME, psinfo->erase); |