aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r--fs/pstore/platform.c31
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 @@
37static DEFINE_SPINLOCK(pstore_lock); 37static DEFINE_SPINLOCK(pstore_lock);
38static struct pstore_info *psinfo; 38static 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 */
41static unsigned long kmsg_bytes = 10240; 41static unsigned long kmsg_bytes = 10240;
42 42
43static ssize_t b_show(struct kobject *kobj, 43void 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
49static 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
55struct 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 */
59static int oopscount; 49static int oopscount;
60 50
51static 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);