]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: add debugfs for debug control
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 17 Mar 2009 00:03:35 +0000 (17:03 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 17 Mar 2009 00:04:04 +0000 (17:04 -0700)
src/kernel/Makefile
src/kernel/debugfs.c [new file with mode: 0644]
src/kernel/inode.c
src/kernel/super.c
src/kernel/super.h

index d9b2a40db856c6f05bdb0827e83a3058d5781ca3..2266829a3fc7e344abc4488510cd7dbbdd0914d8 100644 (file)
@@ -12,7 +12,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \
        mds_client.o mdsmap.o \
        mon_client.o \
        osd_client.o osdmap.o crush/crush.o crush/mapper.o \
-       sysfs.o bookkeeper.o
+       sysfs.o debugfs.o bookkeeper.o
 
 else
 #Otherwise we were called directly from the command
diff --git a/src/kernel/debugfs.c b/src/kernel/debugfs.c
new file mode 100644 (file)
index 0000000..b887177
--- /dev/null
@@ -0,0 +1,195 @@
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include "super.h"
+
+static struct dentry *ceph_debugfs_dir = NULL;
+static struct dentry *ceph_debugfs_debug = NULL;
+static struct dentry *ceph_debugfs_debug_msgr = NULL;
+static struct dentry *ceph_debugfs_debug_console = NULL;
+static struct dentry *ceph_debugfs_debug_mask = NULL;
+
+/*
+ * ceph_debug_mask
+ */
+struct _debug_mask_name {
+       int mask;
+       char *name;
+};
+
+static struct _debug_mask_name _debug_mask_names[] = {
+               {DOUT_MASK_ADDR, "addr"},
+               {DOUT_MASK_CAPS, "caps"},
+               {DOUT_MASK_DIR, "dir"},
+               {DOUT_MASK_EXPORT, "export"},
+               {DOUT_MASK_FILE, "file"},
+               {DOUT_MASK_INODE, "inode"},
+               {DOUT_MASK_IOCTL, "ioctl"},
+               {DOUT_MASK_MDSC, "mdsc"},
+               {DOUT_MASK_MDSMAP, "mdsmap"},
+               {DOUT_MASK_MSGR, "msgr"},
+               {DOUT_MASK_MON, "mon"},
+               {DOUT_MASK_OSDC, "osdc"},
+               {DOUT_MASK_OSDMAP, "osdmap"},
+               {DOUT_MASK_SNAP, "snap"},
+               {DOUT_MASK_SUPER, "super"},
+               {DOUT_MASK_PROTOCOL, "protocol"},
+               {DOUT_MASK_PROC, "proc"},
+               {DOUT_MASK_TOOLS, "tools"},
+               {0, NULL}
+};
+
+static int debug_mask_show(struct seq_file *s, void *p)
+{
+       int i = 0;
+       seq_printf(s, "0x%x", ceph_debug_mask);
+
+       while (_debug_mask_names[i].mask) {
+               if (ceph_debug_mask & _debug_mask_names[i].mask)
+                       seq_printf(s, " %s",
+                                      _debug_mask_names[i].name);
+               i++;
+       }
+       seq_printf(s, "\n");
+       return 0;
+}
+
+static int get_debug_mask(const char *name, int len)
+{
+       int i = 0;
+
+       while (_debug_mask_names[i].name) {
+               if (strncmp(_debug_mask_names[i].name, name, len) == 0)
+                       return _debug_mask_names[i].mask;
+               i++;
+       }
+       return 0;
+}
+
+static ssize_t debug_mask_store(struct file *file,
+               const char __user *buffer, size_t count, loff_t *data)
+{
+       char *next, *tok;
+       char *buf;
+
+       if (count > PAGE_SIZE)
+               return -EINVAL;
+
+       buf = kmalloc(count + 1, GFP_KERNEL);
+
+       if (copy_from_user(buf, buffer, count))
+               return -EFAULT;
+
+       buf[count] = '\0';
+
+       next = buf;
+
+       while (1) {
+               tok = next;
+               next = strpbrk(tok, " \t\r\n");
+               if (!next)
+                       break;
+               if (isdigit(*tok)) {
+                       ceph_debug_mask = simple_strtol(tok, NULL, 0);
+               } else {
+                       int remove = 0;
+                       int mask;
+
+                       if (*tok == '-') {
+                               remove = 1;
+                               tok++;
+                       } else if (*tok == '+')
+                               tok++;
+                       mask = get_debug_mask(tok, next-tok);
+                       if (mask) {
+                               if (remove)
+                                       ceph_debug_mask &= ~mask;
+                               else
+                                       ceph_debug_mask |= mask;
+                       }
+               }
+               next++;
+       }
+
+       kfree(buf);
+
+       return count;
+}
+
+static int debug_mask_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, debug_mask_show, NULL);
+}
+
+static const struct file_operations ceph_debug_mask_fops = {
+       .open           = debug_mask_open,
+       .read           = seq_read,
+       .write          = debug_mask_store,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+int ceph_debugfs_init(void)
+{
+       int ret = 0;
+
+       ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
+
+       if (!ceph_debugfs_dir)
+               goto out;
+
+       ceph_debugfs_debug = debugfs_create_u32("debug",
+                                       0600,
+                                       ceph_debugfs_dir,
+                                       &ceph_debug);
+       if (!ceph_debugfs_debug)
+               goto out;
+
+       ceph_debugfs_debug_msgr = debugfs_create_u32("msgr",
+                                       0600,
+                                       ceph_debugfs_dir,
+                                       &ceph_debug_msgr);
+       if (!ceph_debugfs_debug_msgr)
+               goto out;
+
+       ceph_debugfs_debug_console = debugfs_create_u32("console",
+                                       0600,
+                                       ceph_debugfs_dir,
+                                       &ceph_debug_console);
+       if (!ceph_debugfs_debug_console)
+               goto out;
+
+       ceph_debugfs_debug_mask = debugfs_create_file("mask",
+                                       0600,
+                                       ceph_debugfs_dir,
+                                       NULL,
+                                       &ceph_debug_mask_fops);
+       if (!ceph_debugfs_debug_mask)
+               goto out;
+
+       return 0;
+
+out:
+       if (ceph_debugfs_debug_mask)
+               debugfs_remove(ceph_debugfs_debug_console);
+       if (ceph_debugfs_debug_console)
+               debugfs_remove(ceph_debugfs_debug_console);
+       if (ceph_debugfs_debug_msgr)
+               debugfs_remove(ceph_debugfs_debug_msgr);
+       if (ceph_debugfs_debug)
+               debugfs_remove(ceph_debugfs_debug);
+       if (ceph_debugfs_dir)
+               debugfs_remove(ceph_debugfs_dir);
+
+       return ret;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+       debugfs_remove(ceph_debugfs_debug_mask);
+       debugfs_remove(ceph_debugfs_debug_console);
+       debugfs_remove(ceph_debugfs_debug_msgr);
+       debugfs_remove(ceph_debugfs_debug);
+       debugfs_remove(ceph_debugfs_dir);
+}
index 0754f274e87f99ea7d87208154c267e552378b85..6e78cb942af458df36178c94b2a0b519f7953f6e 100644 (file)
@@ -815,7 +815,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                dn = d_find_alias(in);
                if (IS_ERR(dn))
                        return PTR_ERR(dn);
-               iput(in);
+               iput(in); /* dn still references in */
        } else {
                /* first reply (i.e. we just mounted) */
                dn = d_alloc_root(in);
index a15790e1c2bbce609a17f44d16e217bcda9ec90a..a161c46740f28dd88a5f1e513518ed5f8c331434 100644 (file)
@@ -1071,10 +1071,14 @@ static int __init init_ceph(void)
        ceph_bookkeeper_init();
 #endif
 
-       ret = ceph_sysfs_init();
+       ret = ceph_debugfs_init();
        if (ret < 0)
                goto out;
 
+       ret = ceph_sysfs_init();
+       if (ret < 0)
+               goto out_debugfs;
+
        ret = ceph_msgr_init();
        if (ret < 0)
                goto out_sysfs;
@@ -1094,6 +1098,8 @@ out_msgr:
        ceph_msgr_exit();
 out_sysfs:
        ceph_sysfs_cleanup();
+out_debugfs:
+       ceph_debugfs_cleanup();
 out:
        return ret;
 }
@@ -1105,6 +1111,7 @@ static void __exit exit_ceph(void)
        destroy_inodecache();
        ceph_msgr_exit();
        ceph_sysfs_cleanup();
+       ceph_debugfs_cleanup();
 #ifdef CONFIG_CEPH_BOOKKEEPER
        ceph_bookkeeper_finalize();
 #endif
index 403f83a65545bc53e11f39cbeb66621a68871646..7f5686fa5e9df6a5af722547d1e097fd609e87d2 100644 (file)
@@ -809,6 +809,9 @@ extern int ceph_sysfs_mon_statfs_req_init(struct ceph_mon_client *monc, struct c
                                          struct ceph_msg *msg);
 extern void ceph_sysfs_mon_statfs_req_cleanup(struct ceph_mon_statfs_request *req);
 
+/* debugfs.c */
+extern int ceph_debugfs_init(void);
+extern void ceph_debugfs_cleanup(void);
 
 static inline struct inode *get_dentry_parent_inode(struct dentry *dentry)
 {