pstore: use mount option instead sysfs to tweak kmsg_bytes

/sys/fs is a somewhat strange way to tweak what could more
obviously be tuned with a mount option.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Luck, Tony 2011-03-18 15:33:43 -07:00 committed by Linus Torvalds
parent 10effcb548
commit 366f7e7a79
5 changed files with 59 additions and 47 deletions

View file

@ -1,6 +1,6 @@
Where: /dev/pstore/... Where: /dev/pstore/...
Date: January 2011 Date: March 2011
Kernel Version: 2.6.38 Kernel Version: 2.6.39
Contact: tony.luck@intel.com Contact: tony.luck@intel.com
Description: Generic interface to platform dependent persistent storage. Description: Generic interface to platform dependent persistent storage.
@ -11,7 +11,7 @@ Description: Generic interface to platform dependent persistent storage.
of the console log is captured, but other interesting of the console log is captured, but other interesting
data can also be saved. data can also be saved.
# mount -t pstore - /dev/pstore # mount -t pstore -o kmsg_bytes=8000 - /dev/pstore
$ ls -l /dev/pstore $ ls -l /dev/pstore
total 0 total 0
@ -33,3 +33,9 @@ Description: Generic interface to platform dependent persistent storage.
will be saved elsewhere and erased from persistent store will be saved elsewhere and erased from persistent store
soon after boot to free up space ready for the next soon after boot to free up space ready for the next
catastrophe. catastrophe.
The 'kmsg_bytes' mount option changes the target amount of
data saved on each oops/panic. Pstore saves (possibly
multiple) files based on the record size of the underlying
persistent storage until at least this amount is reached.
Default is 10 Kbytes.

View file

@ -1,7 +0,0 @@
What: /sys/fs/pstore/kmsg_bytes
Date: January 2011
Kernel Version: 2.6.38
Contact: "Tony Luck" <tony.luck@intel.com>
Description:
Controls amount of console log that will be saved
to persistent store on oops/panic.

View file

@ -27,6 +27,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/ramfs.h> #include <linux/ramfs.h>
#include <linux/parser.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/pstore.h> #include <linux/pstore.h>
@ -112,10 +113,52 @@ static struct inode *pstore_get_inode(struct super_block *sb,
return inode; return inode;
} }
enum {
Opt_kmsg_bytes, Opt_err
};
static const match_table_t tokens = {
{Opt_kmsg_bytes, "kmsg_bytes=%u"},
{Opt_err, NULL}
};
static void parse_options(char *options)
{
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
if (!options)
return;
while ((p = strsep(&options, ",")) != NULL) {
int token;
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_kmsg_bytes:
if (!match_int(&args[0], &option))
pstore_set_kmsg_bytes(option);
break;
}
}
}
static int pstore_remount(struct super_block *sb, int *flags, char *data)
{
parse_options(data);
return 0;
}
static const struct super_operations pstore_ops = { static const struct super_operations pstore_ops = {
.statfs = simple_statfs, .statfs = simple_statfs,
.drop_inode = generic_delete_inode, .drop_inode = generic_delete_inode,
.evict_inode = pstore_evict_inode, .evict_inode = pstore_evict_inode,
.remount_fs = pstore_remount,
.show_options = generic_show_options, .show_options = generic_show_options,
}; };
@ -215,6 +258,8 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent)
sb->s_op = &pstore_ops; sb->s_op = &pstore_ops;
sb->s_time_gran = 1; sb->s_time_gran = 1;
parse_options(data);
inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0); inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0);
if (!inode) { if (!inode) {
err = -ENOMEM; err = -ENOMEM;
@ -258,28 +303,7 @@ static struct file_system_type pstore_fs_type = {
static int __init init_pstore_fs(void) static int __init init_pstore_fs(void)
{ {
int rc = 0; return register_filesystem(&pstore_fs_type);
struct kobject *pstorefs_kobj;
pstorefs_kobj = kobject_create_and_add("pstore", fs_kobj);
if (!pstorefs_kobj) {
rc = -ENOMEM;
goto done;
}
rc = sysfs_create_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
if (rc)
goto done1;
rc = register_filesystem(&pstore_fs_type);
if (rc == 0)
goto done;
sysfs_remove_file(pstorefs_kobj, &pstore_kmsg_bytes_attr.attr);
done1:
kobject_put(pstorefs_kobj);
done:
return rc;
} }
module_init(init_pstore_fs) module_init(init_pstore_fs)

View file

@ -1,7 +1,6 @@
extern void pstore_set_kmsg_bytes(int);
extern void pstore_get_records(void); extern void pstore_get_records(void);
extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
char *data, size_t size, char *data, size_t size,
struct timespec time, int (*erase)(u64)); struct timespec time, int (*erase)(u64));
extern int pstore_is_mounted(void); extern int pstore_is_mounted(void);
extern struct kobj_attribute pstore_kmsg_bytes_attr;

View file

@ -37,24 +37,14 @@
static DEFINE_SPINLOCK(pstore_lock); static DEFINE_SPINLOCK(pstore_lock);
static struct pstore_info *psinfo; static struct pstore_info *psinfo;
/* How much of the console log to snapshot. /sys/fs/pstore/kmsg_bytes */ /* How much of the console log to snapshot */
static unsigned long kmsg_bytes = 10240; static unsigned long kmsg_bytes = 10240;
static ssize_t b_show(struct kobject *kobj, void pstore_set_kmsg_bytes(int bytes)
struct kobj_attribute *attr, char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%lu\n", kmsg_bytes); kmsg_bytes = bytes;
} }
static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
return (sscanf(buf, "%lu", &kmsg_bytes) > 0) ? count : 0;
}
struct kobj_attribute pstore_kmsg_bytes_attr =
__ATTR(kmsg_bytes, S_IRUGO | S_IWUSR, b_show, b_store);
/* Tag each group of saved records with a sequence number */ /* Tag each group of saved records with a sequence number */
static int oopscount; static int oopscount;