Skip to content

Commit

Permalink
pstore: add pstore unregister
Browse files Browse the repository at this point in the history
pstore doesn't support unregistering yet. It was marked as TODO.
This patch adds some code to fix it:
 1) Add functions to unregister kmsg/console/ftrace/pmsg.
 2) Add a function to free compression buffer.
 3) Unmap the memory and free it.
 4) Add a function to unregister pstore filesystem.

Signed-off-by: Geliang Tang <[email protected]>
Acked-by: Kees Cook <[email protected]>
[Removed __exit annotation from ramoops_remove(). Reported by Arnd Bergmann]
Signed-off-by: Tony Luck <[email protected]>
  • Loading branch information
geliangtang authored and aegl committed Oct 22, 2015
1 parent 1873041 commit ee1d267
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 34 deletions.
2 changes: 1 addition & 1 deletion fs/pstore/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
config PSTORE
bool "Persistent store support"
tristate "Persistent store support"
default n
select ZLIB_DEFLATE
select ZLIB_INFLATE
Expand Down
6 changes: 3 additions & 3 deletions fs/pstore/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# Makefile for the linux pstorefs routines.
#

obj-y += pstore.o
obj-$(CONFIG_PSTORE) += pstore.o

pstore-objs += inode.o platform.o
obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o
pstore-$(CONFIG_PSTORE_FTRACE) += ftrace.o

obj-$(CONFIG_PSTORE_PMSG) += pmsg.o
pstore-$(CONFIG_PSTORE_PMSG) += pmsg.o

ramoops-objs += ram.o ram_core.o
obj-$(CONFIG_PSTORE_RAM) += ramoops.o
25 changes: 19 additions & 6 deletions fs/pstore/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,41 @@ static const struct file_operations pstore_knob_fops = {
.write = pstore_ftrace_knob_write,
};

static struct dentry *pstore_ftrace_dir;

void pstore_register_ftrace(void)
{
struct dentry *dir;
struct dentry *file;

if (!psinfo->write_buf)
return;

dir = debugfs_create_dir("pstore", NULL);
if (!dir) {
pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
if (!pstore_ftrace_dir) {
pr_err("%s: unable to create pstore directory\n", __func__);
return;
}

file = debugfs_create_file("record_ftrace", 0600, dir, NULL,
&pstore_knob_fops);
file = debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir,
NULL, &pstore_knob_fops);
if (!file) {
pr_err("%s: unable to create record_ftrace file\n", __func__);
goto err_file;
}

return;
err_file:
debugfs_remove(dir);
debugfs_remove(pstore_ftrace_dir);
}

void pstore_unregister_ftrace(void)
{
mutex_lock(&pstore_ftrace_lock);
if (pstore_ftrace_enabled) {
unregister_ftrace_function(&pstore_ftrace_ops);
pstore_ftrace_enabled = 0;
}
mutex_unlock(&pstore_ftrace_lock);

debugfs_remove_recursive(pstore_ftrace_dir);
}
9 changes: 9 additions & 0 deletions fs/pstore/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ static loff_t pstore_file_llseek(struct file *file, loff_t off, int whence)
}

static const struct file_operations pstore_file_operations = {
.owner = THIS_MODULE,
.open = pstore_file_open,
.read = pstore_file_read,
.llseek = pstore_file_llseek,
Expand Down Expand Up @@ -456,6 +457,7 @@ static void pstore_kill_sb(struct super_block *sb)
}

static struct file_system_type pstore_fs_type = {
.owner = THIS_MODULE,
.name = "pstore",
.mount = pstore_mount,
.kill_sb = pstore_kill_sb,
Expand All @@ -479,5 +481,12 @@ static int __init init_pstore_fs(void)
}
module_init(init_pstore_fs)

static void __exit exit_pstore_fs(void)
{
unregister_filesystem(&pstore_fs_type);
sysfs_remove_mount_point(fs_kobj, "pstore");
}
module_exit(exit_pstore_fs)

MODULE_AUTHOR("Tony Luck <[email protected]>");
MODULE_LICENSE("GPL");
4 changes: 4 additions & 0 deletions fs/pstore/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)

#ifdef CONFIG_PSTORE_FTRACE
extern void pstore_register_ftrace(void);
extern void pstore_unregister_ftrace(void);
#else
static inline void pstore_register_ftrace(void) {}
static inline void pstore_unregister_ftrace(void) {}
#endif

#ifdef CONFIG_PSTORE_PMSG
extern void pstore_register_pmsg(void);
extern void pstore_unregister_pmsg(void);
#else
static inline void pstore_register_pmsg(void) {}
static inline void pstore_unregister_pmsg(void) {}
#endif

extern struct pstore_info *psinfo;
Expand Down
35 changes: 35 additions & 0 deletions fs/pstore/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ static void allocate_buf_for_compression(void)

}

static void free_buf_for_compression(void)
{
kfree(stream.workspace);
stream.workspace = NULL;
kfree(big_oops_buf);
big_oops_buf = NULL;
}

/*
* Called when compression fails, since the printk buffer
* would be fetched for compression calling it again when
Expand Down Expand Up @@ -358,6 +366,11 @@ static void pstore_register_kmsg(void)
kmsg_dump_register(&pstore_dumper);
}

static void pstore_unregister_kmsg(void)
{
kmsg_dump_unregister(&pstore_dumper);
}

#ifdef CONFIG_PSTORE_CONSOLE
static void pstore_console_write(struct console *con, const char *s, unsigned c)
{
Expand Down Expand Up @@ -395,8 +408,14 @@ static void pstore_register_console(void)
{
register_console(&pstore_console);
}

static void pstore_unregister_console(void)
{
unregister_console(&pstore_console);
}
#else
static void pstore_register_console(void) {}
static void pstore_unregister_console(void) {}
#endif

static int pstore_write_compat(enum pstore_type_id type,
Expand Down Expand Up @@ -467,12 +486,28 @@ int pstore_register(struct pstore_info *psi)
*/
backend = psi->name;

module_put(owner);

pr_info("Registered %s as persistent store backend\n", psi->name);

return 0;
}
EXPORT_SYMBOL_GPL(pstore_register);

void pstore_unregister(struct pstore_info *psi)
{
pstore_unregister_pmsg();
pstore_unregister_ftrace();
pstore_unregister_console();
pstore_unregister_kmsg();

free_buf_for_compression();

psinfo = NULL;
backend = NULL;
}
EXPORT_SYMBOL_GPL(pstore_unregister);

/*
* Read all the records from the persistent store. Create
* files in our filesystem. Don't warn about -EEXIST errors
Expand Down
7 changes: 7 additions & 0 deletions fs/pstore/pmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,10 @@ void pstore_register_pmsg(void)
err:
return;
}

void pstore_unregister_pmsg(void)
{
device_destroy(pmsg_class, MKDEV(pmsg_major, 0));
class_destroy(pmsg_class);
unregister_chrdev(pmsg_major, PMSG_NAME);
}
19 changes: 8 additions & 11 deletions fs/pstore/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,30 +578,27 @@ static int ramoops_probe(struct platform_device *pdev)
return err;
}

static int __exit ramoops_remove(struct platform_device *pdev)
static int ramoops_remove(struct platform_device *pdev)
{
#if 0
/* TODO(kees): We cannot unload ramoops since pstore doesn't support
* unregistering yet.
*/
struct ramoops_context *cxt = &oops_cxt;

iounmap(cxt->virt_addr);
release_mem_region(cxt->phys_addr, cxt->size);
pstore_unregister(&cxt->pstore);
cxt->max_dump_cnt = 0;

/* TODO(kees): When pstore supports unregistering, call it here. */
kfree(cxt->pstore.buf);
cxt->pstore.bufsize = 0;

persistent_ram_free(cxt->mprz);
persistent_ram_free(cxt->fprz);
persistent_ram_free(cxt->cprz);
ramoops_free_przs(cxt);

return 0;
#endif
return -EBUSY;
}

static struct platform_driver ramoops_driver = {
.probe = ramoops_probe,
.remove = __exit_p(ramoops_remove),
.remove = ramoops_remove,
.driver = {
.name = "ramoops",
},
Expand Down
14 changes: 1 addition & 13 deletions include/linux/pstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,8 @@ struct pstore_info {

#define PSTORE_FLAGS_FRAGILE 1

#ifdef CONFIG_PSTORE
extern int pstore_register(struct pstore_info *);
extern void pstore_unregister(struct pstore_info *);
extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
#else
static inline int
pstore_register(struct pstore_info *psi)
{
return -ENODEV;
}
static inline bool
pstore_cannot_block_path(enum kmsg_dump_reason reason)
{
return false;
}
#endif

#endif /*_LINUX_PSTORE_H*/
1 change: 1 addition & 0 deletions kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ int check_syslog_permissions(int type, int source)
ok:
return security_syslog(type);
}
EXPORT_SYMBOL_GPL(check_syslog_permissions);

static void append_char(char **pp, char *e, char c)
{
Expand Down

0 comments on commit ee1d267

Please sign in to comment.