linux/net/ceph/debugfs.c
<<
>>
Prefs
   1#include <linux/ceph/ceph_debug.h>
   2
   3#include <linux/device.h>
   4#include <linux/slab.h>
   5#include <linux/module.h>
   6#include <linux/ctype.h>
   7#include <linux/debugfs.h>
   8#include <linux/seq_file.h>
   9
  10#include <linux/ceph/libceph.h>
  11#include <linux/ceph/mon_client.h>
  12#include <linux/ceph/auth.h>
  13#include <linux/ceph/debugfs.h>
  14
  15#ifdef CONFIG_DEBUG_FS
  16
  17/*
  18 * Implement /sys/kernel/debug/ceph fun
  19 *
  20 * /sys/kernel/debug/ceph/client*  - an instance of the ceph client
  21 *      .../osdmap      - current osdmap
  22 *      .../monmap      - current monmap
  23 *      .../osdc        - active osd requests
  24 *      .../monc        - mon client state
  25 *      .../dentry_lru  - dump contents of dentry lru
  26 *      .../caps        - expose cap (reservation) stats
  27 *      .../bdi         - symlink to ../../bdi/something
  28 */
  29
  30static struct dentry *ceph_debugfs_dir;
  31
  32static int monmap_show(struct seq_file *s, void *p)
  33{
  34        int i;
  35        struct ceph_client *client = s->private;
  36
  37        if (client->monc.monmap == NULL)
  38                return 0;
  39
  40        seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
  41        for (i = 0; i < client->monc.monmap->num_mon; i++) {
  42                struct ceph_entity_inst *inst =
  43                        &client->monc.monmap->mon_inst[i];
  44
  45                seq_printf(s, "\t%s%lld\t%s\n",
  46                           ENTITY_NAME(inst->name),
  47                           ceph_pr_addr(&inst->addr.in_addr));
  48        }
  49        return 0;
  50}
  51
  52static int osdmap_show(struct seq_file *s, void *p)
  53{
  54        int i;
  55        struct ceph_client *client = s->private;
  56        struct rb_node *n;
  57
  58        if (client->osdc.osdmap == NULL)
  59                return 0;
  60        seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch);
  61        seq_printf(s, "flags%s%s\n",
  62                   (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ?
  63                   " NEARFULL" : "",
  64                   (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ?
  65                   " FULL" : "");
  66        for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) {
  67                struct ceph_pg_pool_info *pool =
  68                        rb_entry(n, struct ceph_pg_pool_info, node);
  69                seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n",
  70                           pool->id, pool->v.pg_num, pool->pg_num_mask,
  71                           pool->v.lpg_num, pool->lpg_num_mask);
  72        }
  73        for (i = 0; i < client->osdc.osdmap->max_osd; i++) {
  74                struct ceph_entity_addr *addr =
  75                        &client->osdc.osdmap->osd_addr[i];
  76                int state = client->osdc.osdmap->osd_state[i];
  77                char sb[64];
  78
  79                seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n",
  80                           i, ceph_pr_addr(&addr->in_addr),
  81                           ((client->osdc.osdmap->osd_weight[i]*100) >> 16),
  82                           ceph_osdmap_state_str(sb, sizeof(sb), state));
  83        }
  84        return 0;
  85}
  86
  87static int monc_show(struct seq_file *s, void *p)
  88{
  89        struct ceph_client *client = s->private;
  90        struct ceph_mon_generic_request *req;
  91        struct ceph_mon_client *monc = &client->monc;
  92        struct rb_node *rp;
  93
  94        mutex_lock(&monc->mutex);
  95
  96        if (monc->have_mdsmap)
  97                seq_printf(s, "have mdsmap %u\n", (unsigned int)monc->have_mdsmap);
  98        if (monc->have_osdmap)
  99                seq_printf(s, "have osdmap %u\n", (unsigned int)monc->have_osdmap);
 100        if (monc->want_next_osdmap)
 101                seq_printf(s, "want next osdmap\n");
 102
 103        for (rp = rb_first(&monc->generic_request_tree); rp; rp = rb_next(rp)) {
 104                __u16 op;
 105                req = rb_entry(rp, struct ceph_mon_generic_request, node);
 106                op = le16_to_cpu(req->request->hdr.type);
 107                if (op == CEPH_MSG_STATFS)
 108                        seq_printf(s, "%lld statfs\n", req->tid);
 109                else
 110                        seq_printf(s, "%lld unknown\n", req->tid);
 111        }
 112
 113        mutex_unlock(&monc->mutex);
 114        return 0;
 115}
 116
 117static int osdc_show(struct seq_file *s, void *pp)
 118{
 119        struct ceph_client *client = s->private;
 120        struct ceph_osd_client *osdc = &client->osdc;
 121        struct rb_node *p;
 122
 123        mutex_lock(&osdc->request_mutex);
 124        for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
 125                struct ceph_osd_request *req;
 126                struct ceph_osd_request_head *head;
 127                struct ceph_osd_op *op;
 128                int num_ops;
 129                int opcode, olen;
 130                int i;
 131
 132                req = rb_entry(p, struct ceph_osd_request, r_node);
 133
 134                seq_printf(s, "%lld\tosd%d\t%d.%x\t", req->r_tid,
 135                           req->r_osd ? req->r_osd->o_osd : -1,
 136                           le32_to_cpu(req->r_pgid.pool),
 137                           le16_to_cpu(req->r_pgid.ps));
 138
 139                head = req->r_request->front.iov_base;
 140                op = (void *)(head + 1);
 141
 142                num_ops = le16_to_cpu(head->num_ops);
 143                olen = le32_to_cpu(head->object_len);
 144                seq_printf(s, "%.*s", olen,
 145                           (const char *)(head->ops + num_ops));
 146
 147                if (req->r_reassert_version.epoch)
 148                        seq_printf(s, "\t%u'%llu",
 149                           (unsigned int)le32_to_cpu(req->r_reassert_version.epoch),
 150                           le64_to_cpu(req->r_reassert_version.version));
 151                else
 152                        seq_printf(s, "\t");
 153
 154                for (i = 0; i < num_ops; i++) {
 155                        opcode = le16_to_cpu(op->op);
 156                        seq_printf(s, "\t%s", ceph_osd_op_name(opcode));
 157                        op++;
 158                }
 159
 160                seq_printf(s, "\n");
 161        }
 162        mutex_unlock(&osdc->request_mutex);
 163        return 0;
 164}
 165
 166CEPH_DEFINE_SHOW_FUNC(monmap_show)
 167CEPH_DEFINE_SHOW_FUNC(osdmap_show)
 168CEPH_DEFINE_SHOW_FUNC(monc_show)
 169CEPH_DEFINE_SHOW_FUNC(osdc_show)
 170
 171int ceph_debugfs_init(void)
 172{
 173        ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
 174        if (!ceph_debugfs_dir)
 175                return -ENOMEM;
 176        return 0;
 177}
 178
 179void ceph_debugfs_cleanup(void)
 180{
 181        debugfs_remove(ceph_debugfs_dir);
 182}
 183
 184int ceph_debugfs_client_init(struct ceph_client *client)
 185{
 186        int ret = -ENOMEM;
 187        char name[80];
 188
 189        snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid,
 190                 client->monc.auth->global_id);
 191
 192        dout("ceph_debugfs_client_init %p %s\n", client, name);
 193
 194        BUG_ON(client->debugfs_dir);
 195        client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
 196        if (!client->debugfs_dir)
 197                goto out;
 198
 199        client->monc.debugfs_file = debugfs_create_file("monc",
 200                                                      0600,
 201                                                      client->debugfs_dir,
 202                                                      client,
 203                                                      &monc_show_fops);
 204        if (!client->monc.debugfs_file)
 205                goto out;
 206
 207        client->osdc.debugfs_file = debugfs_create_file("osdc",
 208                                                      0600,
 209                                                      client->debugfs_dir,
 210                                                      client,
 211                                                      &osdc_show_fops);
 212        if (!client->osdc.debugfs_file)
 213                goto out;
 214
 215        client->debugfs_monmap = debugfs_create_file("monmap",
 216                                        0600,
 217                                        client->debugfs_dir,
 218                                        client,
 219                                        &monmap_show_fops);
 220        if (!client->debugfs_monmap)
 221                goto out;
 222
 223        client->debugfs_osdmap = debugfs_create_file("osdmap",
 224                                        0600,
 225                                        client->debugfs_dir,
 226                                        client,
 227                                        &osdmap_show_fops);
 228        if (!client->debugfs_osdmap)
 229                goto out;
 230
 231        return 0;
 232
 233out:
 234        ceph_debugfs_client_cleanup(client);
 235        return ret;
 236}
 237
 238void ceph_debugfs_client_cleanup(struct ceph_client *client)
 239{
 240        dout("ceph_debugfs_client_cleanup %p\n", client);
 241        debugfs_remove(client->debugfs_osdmap);
 242        debugfs_remove(client->debugfs_monmap);
 243        debugfs_remove(client->osdc.debugfs_file);
 244        debugfs_remove(client->monc.debugfs_file);
 245        debugfs_remove(client->debugfs_dir);
 246}
 247
 248#else  /* CONFIG_DEBUG_FS */
 249
 250int ceph_debugfs_init(void)
 251{
 252        return 0;
 253}
 254
 255void ceph_debugfs_cleanup(void)
 256{
 257}
 258
 259int ceph_debugfs_client_init(struct ceph_client *client)
 260{
 261        return 0;
 262}
 263
 264void ceph_debugfs_client_cleanup(struct ceph_client *client)
 265{
 266}
 267
 268#endif  /* CONFIG_DEBUG_FS */
 269
 270EXPORT_SYMBOL(ceph_debugfs_init);
 271EXPORT_SYMBOL(ceph_debugfs_cleanup);
 272