Linux Audio

Check our new training course

Loading...
v3.5.6
 
  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	client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
193	if (!client->debugfs_dir)
194		goto out;
195
196	client->monc.debugfs_file = debugfs_create_file("monc",
197						      0600,
198						      client->debugfs_dir,
199						      client,
200						      &monc_show_fops);
201	if (!client->monc.debugfs_file)
202		goto out;
203
204	client->osdc.debugfs_file = debugfs_create_file("osdc",
205						      0600,
206						      client->debugfs_dir,
207						      client,
208						      &osdc_show_fops);
209	if (!client->osdc.debugfs_file)
210		goto out;
211
212	client->debugfs_monmap = debugfs_create_file("monmap",
213					0600,
214					client->debugfs_dir,
215					client,
216					&monmap_show_fops);
217	if (!client->debugfs_monmap)
218		goto out;
219
220	client->debugfs_osdmap = debugfs_create_file("osdmap",
221					0600,
222					client->debugfs_dir,
223					client,
224					&osdmap_show_fops);
225	if (!client->debugfs_osdmap)
226		goto out;
227
 
 
 
 
 
 
 
 
228	return 0;
229
230out:
231	ceph_debugfs_client_cleanup(client);
232	return ret;
233}
234
235void ceph_debugfs_client_cleanup(struct ceph_client *client)
236{
 
 
237	debugfs_remove(client->debugfs_osdmap);
238	debugfs_remove(client->debugfs_monmap);
239	debugfs_remove(client->osdc.debugfs_file);
240	debugfs_remove(client->monc.debugfs_file);
241	debugfs_remove(client->debugfs_dir);
242}
243
244#else  /* CONFIG_DEBUG_FS */
245
246int ceph_debugfs_init(void)
247{
248	return 0;
249}
250
251void ceph_debugfs_cleanup(void)
252{
253}
254
255int ceph_debugfs_client_init(struct ceph_client *client)
256{
257	return 0;
258}
259
260void ceph_debugfs_client_cleanup(struct ceph_client *client)
261{
262}
263
264#endif  /* CONFIG_DEBUG_FS */
265
266EXPORT_SYMBOL(ceph_debugfs_init);
267EXPORT_SYMBOL(ceph_debugfs_cleanup);
v4.17
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/ceph/ceph_debug.h>
  3
  4#include <linux/device.h>
  5#include <linux/slab.h>
  6#include <linux/module.h>
  7#include <linux/ctype.h>
  8#include <linux/debugfs.h>
  9#include <linux/seq_file.h>
 10
 11#include <linux/ceph/libceph.h>
 12#include <linux/ceph/mon_client.h>
 13#include <linux/ceph/auth.h>
 14#include <linux/ceph/debugfs.h>
 15
 16#ifdef CONFIG_DEBUG_FS
 17
 18/*
 19 * Implement /sys/kernel/debug/ceph fun
 20 *
 21 * /sys/kernel/debug/ceph/client*  - an instance of the ceph client
 22 *      .../osdmap      - current osdmap
 23 *      .../monmap      - current monmap
 24 *      .../osdc        - active osd requests
 25 *      .../monc        - mon client state
 26 *      .../client_options - libceph-only (i.e. not rbd or cephfs) options
 27 *      .../dentry_lru  - dump contents of dentry lru
 28 *      .../caps        - expose cap (reservation) stats
 29 *      .../bdi         - symlink to ../../bdi/something
 30 */
 31
 32static struct dentry *ceph_debugfs_dir;
 33
 34static int monmap_show(struct seq_file *s, void *p)
 35{
 36	int i;
 37	struct ceph_client *client = s->private;
 38
 39	if (client->monc.monmap == NULL)
 40		return 0;
 41
 42	seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
 43	for (i = 0; i < client->monc.monmap->num_mon; i++) {
 44		struct ceph_entity_inst *inst =
 45			&client->monc.monmap->mon_inst[i];
 46
 47		seq_printf(s, "\t%s%lld\t%s\n",
 48			   ENTITY_NAME(inst->name),
 49			   ceph_pr_addr(&inst->addr.in_addr));
 50	}
 51	return 0;
 52}
 53
 54static int osdmap_show(struct seq_file *s, void *p)
 55{
 56	int i;
 57	struct ceph_client *client = s->private;
 58	struct ceph_osd_client *osdc = &client->osdc;
 59	struct ceph_osdmap *map = osdc->osdmap;
 60	struct rb_node *n;
 61
 62	if (map == NULL)
 63		return 0;
 64
 65	down_read(&osdc->lock);
 66	seq_printf(s, "epoch %u barrier %u flags 0x%x\n", map->epoch,
 67			osdc->epoch_barrier, map->flags);
 68
 69	for (n = rb_first(&map->pg_pools); n; n = rb_next(n)) {
 70		struct ceph_pg_pool_info *pi =
 
 71			rb_entry(n, struct ceph_pg_pool_info, node);
 72
 73		seq_printf(s, "pool %lld '%s' type %d size %d min_size %d pg_num %u pg_num_mask %d flags 0x%llx lfor %u read_tier %lld write_tier %lld\n",
 74			   pi->id, pi->name, pi->type, pi->size, pi->min_size,
 75			   pi->pg_num, pi->pg_num_mask, pi->flags,
 76			   pi->last_force_request_resend, pi->read_tier,
 77			   pi->write_tier);
 78	}
 79	for (i = 0; i < map->max_osd; i++) {
 80		struct ceph_entity_addr *addr = &map->osd_addr[i];
 81		u32 state = map->osd_state[i];
 82		char sb[64];
 83
 84		seq_printf(s, "osd%d\t%s\t%3d%%\t(%s)\t%3d%%\n",
 85			   i, ceph_pr_addr(&addr->in_addr),
 86			   ((map->osd_weight[i]*100) >> 16),
 87			   ceph_osdmap_state_str(sb, sizeof(sb), state),
 88			   ((ceph_get_primary_affinity(map, i)*100) >> 16));
 89	}
 90	for (n = rb_first(&map->pg_temp); n; n = rb_next(n)) {
 91		struct ceph_pg_mapping *pg =
 92			rb_entry(n, struct ceph_pg_mapping, node);
 93
 94		seq_printf(s, "pg_temp %llu.%x [", pg->pgid.pool,
 95			   pg->pgid.seed);
 96		for (i = 0; i < pg->pg_temp.len; i++)
 97			seq_printf(s, "%s%d", (i == 0 ? "" : ","),
 98				   pg->pg_temp.osds[i]);
 99		seq_printf(s, "]\n");
100	}
101	for (n = rb_first(&map->primary_temp); n; n = rb_next(n)) {
102		struct ceph_pg_mapping *pg =
103			rb_entry(n, struct ceph_pg_mapping, node);
104
105		seq_printf(s, "primary_temp %llu.%x %d\n", pg->pgid.pool,
106			   pg->pgid.seed, pg->primary_temp.osd);
107	}
108	for (n = rb_first(&map->pg_upmap); n; n = rb_next(n)) {
109		struct ceph_pg_mapping *pg =
110			rb_entry(n, struct ceph_pg_mapping, node);
111
112		seq_printf(s, "pg_upmap %llu.%x [", pg->pgid.pool,
113			   pg->pgid.seed);
114		for (i = 0; i < pg->pg_upmap.len; i++)
115			seq_printf(s, "%s%d", (i == 0 ? "" : ","),
116				   pg->pg_upmap.osds[i]);
117		seq_printf(s, "]\n");
118	}
119	for (n = rb_first(&map->pg_upmap_items); n; n = rb_next(n)) {
120		struct ceph_pg_mapping *pg =
121			rb_entry(n, struct ceph_pg_mapping, node);
122
123		seq_printf(s, "pg_upmap_items %llu.%x [", pg->pgid.pool,
124			   pg->pgid.seed);
125		for (i = 0; i < pg->pg_upmap_items.len; i++)
126			seq_printf(s, "%s%d->%d", (i == 0 ? "" : ","),
127				   pg->pg_upmap_items.from_to[i][0],
128				   pg->pg_upmap_items.from_to[i][1]);
129		seq_printf(s, "]\n");
130	}
131
132	up_read(&osdc->lock);
133	return 0;
134}
135
136static int monc_show(struct seq_file *s, void *p)
137{
138	struct ceph_client *client = s->private;
139	struct ceph_mon_generic_request *req;
140	struct ceph_mon_client *monc = &client->monc;
141	struct rb_node *rp;
142	int i;
143
144	mutex_lock(&monc->mutex);
145
146	for (i = 0; i < ARRAY_SIZE(monc->subs); i++) {
147		seq_printf(s, "have %s %u", ceph_sub_str[i],
148			   monc->subs[i].have);
149		if (monc->subs[i].want)
150			seq_printf(s, " want %llu%s",
151				   le64_to_cpu(monc->subs[i].item.start),
152				   (monc->subs[i].item.flags &
153					CEPH_SUBSCRIBE_ONETIME ?  "" : "+"));
154		seq_putc(s, '\n');
155	}
156	seq_printf(s, "fs_cluster_id %d\n", monc->fs_cluster_id);
157
158	for (rp = rb_first(&monc->generic_request_tree); rp; rp = rb_next(rp)) {
159		__u16 op;
160		req = rb_entry(rp, struct ceph_mon_generic_request, node);
161		op = le16_to_cpu(req->request->hdr.type);
162		if (op == CEPH_MSG_STATFS)
163			seq_printf(s, "%llu statfs\n", req->tid);
164		else if (op == CEPH_MSG_MON_GET_VERSION)
165			seq_printf(s, "%llu mon_get_version", req->tid);
166		else
167			seq_printf(s, "%llu unknown\n", req->tid);
168	}
169
170	mutex_unlock(&monc->mutex);
171	return 0;
172}
173
174static void dump_spgid(struct seq_file *s, const struct ceph_spg *spgid)
175{
176	seq_printf(s, "%llu.%x", spgid->pgid.pool, spgid->pgid.seed);
177	if (spgid->shard != CEPH_SPG_NOSHARD)
178		seq_printf(s, "s%d", spgid->shard);
179}
180
181static void dump_target(struct seq_file *s, struct ceph_osd_request_target *t)
182{
183	int i;
184
185	seq_printf(s, "osd%d\t%llu.%x\t", t->osd, t->pgid.pool, t->pgid.seed);
186	dump_spgid(s, &t->spgid);
187	seq_puts(s, "\t[");
188	for (i = 0; i < t->up.size; i++)
189		seq_printf(s, "%s%d", (!i ? "" : ","), t->up.osds[i]);
190	seq_printf(s, "]/%d\t[", t->up.primary);
191	for (i = 0; i < t->acting.size; i++)
192		seq_printf(s, "%s%d", (!i ? "" : ","), t->acting.osds[i]);
193	seq_printf(s, "]/%d\te%u\t", t->acting.primary, t->epoch);
194	if (t->target_oloc.pool_ns) {
195		seq_printf(s, "%*pE/%*pE\t0x%x",
196			(int)t->target_oloc.pool_ns->len,
197			t->target_oloc.pool_ns->str,
198			t->target_oid.name_len, t->target_oid.name, t->flags);
199	} else {
200		seq_printf(s, "%*pE\t0x%x", t->target_oid.name_len,
201			t->target_oid.name, t->flags);
202	}
203	if (t->paused)
204		seq_puts(s, "\tP");
205}
206
207static void dump_request(struct seq_file *s, struct ceph_osd_request *req)
208{
209	int i;
210
211	seq_printf(s, "%llu\t", req->r_tid);
212	dump_target(s, &req->r_t);
213
214	seq_printf(s, "\t%d", req->r_attempts);
215
216	for (i = 0; i < req->r_num_ops; i++) {
217		struct ceph_osd_req_op *op = &req->r_ops[i];
218
219		seq_printf(s, "%s%s", (i == 0 ? "\t" : ","),
220			   ceph_osd_op_name(op->op));
221		if (op->op == CEPH_OSD_OP_WATCH)
222			seq_printf(s, "-%s",
223				   ceph_osd_watch_op_name(op->watch.op));
224	}
225
226	seq_putc(s, '\n');
227}
228
229static void dump_requests(struct seq_file *s, struct ceph_osd *osd)
230{
231	struct rb_node *n;
232
233	mutex_lock(&osd->lock);
234	for (n = rb_first(&osd->o_requests); n; n = rb_next(n)) {
235		struct ceph_osd_request *req =
236		    rb_entry(n, struct ceph_osd_request, r_node);
237
238		dump_request(s, req);
239	}
240
241	mutex_unlock(&osd->lock);
242}
243
244static void dump_linger_request(struct seq_file *s,
245				struct ceph_osd_linger_request *lreq)
246{
247	seq_printf(s, "%llu\t", lreq->linger_id);
248	dump_target(s, &lreq->t);
249
250	seq_printf(s, "\t%u\t%s%s/%d\n", lreq->register_gen,
251		   lreq->is_watch ? "W" : "N", lreq->committed ? "C" : "",
252		   lreq->last_error);
253}
254
255static void dump_linger_requests(struct seq_file *s, struct ceph_osd *osd)
256{
257	struct rb_node *n;
258
259	mutex_lock(&osd->lock);
260	for (n = rb_first(&osd->o_linger_requests); n; n = rb_next(n)) {
261		struct ceph_osd_linger_request *lreq =
262		    rb_entry(n, struct ceph_osd_linger_request, node);
263
264		dump_linger_request(s, lreq);
265	}
266
267	mutex_unlock(&osd->lock);
268}
269
270static void dump_snapid(struct seq_file *s, u64 snapid)
271{
272	if (snapid == CEPH_NOSNAP)
273		seq_puts(s, "head");
274	else if (snapid == CEPH_SNAPDIR)
275		seq_puts(s, "snapdir");
276	else
277		seq_printf(s, "%llx", snapid);
278}
279
280static void dump_name_escaped(struct seq_file *s, unsigned char *name,
281			      size_t len)
282{
283	size_t i;
284
285	for (i = 0; i < len; i++) {
286		if (name[i] == '%' || name[i] == ':' || name[i] == '/' ||
287		    name[i] < 32 || name[i] >= 127) {
288			seq_printf(s, "%%%02x", name[i]);
289		} else {
290			seq_putc(s, name[i]);
291		}
292	}
293}
294
295static void dump_hoid(struct seq_file *s, const struct ceph_hobject_id *hoid)
296{
297	if (hoid->snapid == 0 && hoid->hash == 0 && !hoid->is_max &&
298	    hoid->pool == S64_MIN) {
299		seq_puts(s, "MIN");
300		return;
301	}
302	if (hoid->is_max) {
303		seq_puts(s, "MAX");
304		return;
305	}
306	seq_printf(s, "%lld:%08x:", hoid->pool, hoid->hash_reverse_bits);
307	dump_name_escaped(s, hoid->nspace, hoid->nspace_len);
308	seq_putc(s, ':');
309	dump_name_escaped(s, hoid->key, hoid->key_len);
310	seq_putc(s, ':');
311	dump_name_escaped(s, hoid->oid, hoid->oid_len);
312	seq_putc(s, ':');
313	dump_snapid(s, hoid->snapid);
314}
315
316static void dump_backoffs(struct seq_file *s, struct ceph_osd *osd)
317{
318	struct rb_node *n;
319
320	mutex_lock(&osd->lock);
321	for (n = rb_first(&osd->o_backoffs_by_id); n; n = rb_next(n)) {
322		struct ceph_osd_backoff *backoff =
323		    rb_entry(n, struct ceph_osd_backoff, id_node);
324
325		seq_printf(s, "osd%d\t", osd->o_osd);
326		dump_spgid(s, &backoff->spgid);
327		seq_printf(s, "\t%llu\t", backoff->id);
328		dump_hoid(s, backoff->begin);
329		seq_putc(s, '\t');
330		dump_hoid(s, backoff->end);
331		seq_putc(s, '\n');
332	}
333
334	mutex_unlock(&osd->lock);
335}
336
337static int osdc_show(struct seq_file *s, void *pp)
338{
339	struct ceph_client *client = s->private;
340	struct ceph_osd_client *osdc = &client->osdc;
341	struct rb_node *n;
342
343	down_read(&osdc->lock);
344	seq_printf(s, "REQUESTS %d homeless %d\n",
345		   atomic_read(&osdc->num_requests),
346		   atomic_read(&osdc->num_homeless));
347	for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
348		struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
350		dump_requests(s, osd);
351	}
352	dump_requests(s, &osdc->homeless_osd);
353
354	seq_puts(s, "LINGER REQUESTS\n");
355	for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
356		struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
357
358		dump_linger_requests(s, osd);
359	}
360	dump_linger_requests(s, &osdc->homeless_osd);
361
362	seq_puts(s, "BACKOFFS\n");
363	for (n = rb_first(&osdc->osds); n; n = rb_next(n)) {
364		struct ceph_osd *osd = rb_entry(n, struct ceph_osd, o_node);
365
366		dump_backoffs(s, osd);
367	}
368
369	up_read(&osdc->lock);
370	return 0;
371}
372
373static int client_options_show(struct seq_file *s, void *p)
374{
375	struct ceph_client *client = s->private;
376	int ret;
377
378	ret = ceph_print_client_options(s, client);
379	if (ret)
380		return ret;
381
382	seq_putc(s, '\n');
383	return 0;
384}
385
386CEPH_DEFINE_SHOW_FUNC(monmap_show)
387CEPH_DEFINE_SHOW_FUNC(osdmap_show)
388CEPH_DEFINE_SHOW_FUNC(monc_show)
389CEPH_DEFINE_SHOW_FUNC(osdc_show)
390CEPH_DEFINE_SHOW_FUNC(client_options_show)
391
392int __init ceph_debugfs_init(void)
393{
394	ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
395	if (!ceph_debugfs_dir)
396		return -ENOMEM;
397	return 0;
398}
399
400void ceph_debugfs_cleanup(void)
401{
402	debugfs_remove(ceph_debugfs_dir);
403}
404
405int ceph_debugfs_client_init(struct ceph_client *client)
406{
407	int ret = -ENOMEM;
408	char name[80];
409
410	snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid,
411		 client->monc.auth->global_id);
412
413	dout("ceph_debugfs_client_init %p %s\n", client, name);
414
415	BUG_ON(client->debugfs_dir);
416	client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
417	if (!client->debugfs_dir)
418		goto out;
419
420	client->monc.debugfs_file = debugfs_create_file("monc",
421						      0400,
422						      client->debugfs_dir,
423						      client,
424						      &monc_show_fops);
425	if (!client->monc.debugfs_file)
426		goto out;
427
428	client->osdc.debugfs_file = debugfs_create_file("osdc",
429						      0400,
430						      client->debugfs_dir,
431						      client,
432						      &osdc_show_fops);
433	if (!client->osdc.debugfs_file)
434		goto out;
435
436	client->debugfs_monmap = debugfs_create_file("monmap",
437					0400,
438					client->debugfs_dir,
439					client,
440					&monmap_show_fops);
441	if (!client->debugfs_monmap)
442		goto out;
443
444	client->debugfs_osdmap = debugfs_create_file("osdmap",
445					0400,
446					client->debugfs_dir,
447					client,
448					&osdmap_show_fops);
449	if (!client->debugfs_osdmap)
450		goto out;
451
452	client->debugfs_options = debugfs_create_file("client_options",
453					0400,
454					client->debugfs_dir,
455					client,
456					&client_options_show_fops);
457	if (!client->debugfs_options)
458		goto out;
459
460	return 0;
461
462out:
463	ceph_debugfs_client_cleanup(client);
464	return ret;
465}
466
467void ceph_debugfs_client_cleanup(struct ceph_client *client)
468{
469	dout("ceph_debugfs_client_cleanup %p\n", client);
470	debugfs_remove(client->debugfs_options);
471	debugfs_remove(client->debugfs_osdmap);
472	debugfs_remove(client->debugfs_monmap);
473	debugfs_remove(client->osdc.debugfs_file);
474	debugfs_remove(client->monc.debugfs_file);
475	debugfs_remove(client->debugfs_dir);
476}
477
478#else  /* CONFIG_DEBUG_FS */
479
480int __init ceph_debugfs_init(void)
481{
482	return 0;
483}
484
485void ceph_debugfs_cleanup(void)
486{
487}
488
489int ceph_debugfs_client_init(struct ceph_client *client)
490{
491	return 0;
492}
493
494void ceph_debugfs_client_cleanup(struct ceph_client *client)
495{
496}
497
498#endif  /* CONFIG_DEBUG_FS */