Bug Summary

File:libglusterfs/src/statedump.c
Location:line 147, column 18
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11#include <stdarg.h>
12#include "glusterfs.h"
13#include "logging.h"
14#include "iobuf.h"
15#include "statedump.h"
16#include "stack.h"
17#include "common-utils.h"
18
19#ifdef HAVE_MALLOC_H1
20#include <malloc.h>
21#endif /* MALLOC_H */
22
23/* We don't want gf_log in this function because it may cause
24 'deadlock' with statedump. This is because statedump happens
25 inside a signal handler and cannot afford to block on a lock.*/
26#ifdef gf_log
27# undef gf_log
28#endif
29
30#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt)(dump_options.dump_opt == _gf_true) \
31 (dump_options.dump_##opt == _gf_true)
32
33#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt)(dump_options.xl_options.dump_opt == _gf_true) \
34 (dump_options.xl_options.dump_##opt == _gf_true)
35
36extern xlator_t global_xlator;
37
38static pthread_mutex_t gf_proc_dump_mutex;
39static int gf_dump_fd = -1;
40gf_dump_options_t dump_options;
41
42
43static void
44gf_proc_dump_lock (void)
45{
46 pthread_mutex_lock (&gf_proc_dump_mutex);
47}
48
49
50static void
51gf_proc_dump_unlock (void)
52{
53 pthread_mutex_unlock (&gf_proc_dump_mutex);
54}
55
56static int
57gf_proc_dump_open (char *tmpname)
58{
59 int dump_fd = -1;
60
61 dump_fd = mkstemp (tmpname);
62 if (dump_fd < 0)
63 return -1;
64
65 gf_dump_fd = dump_fd;
66 return 0;
67}
68
69static void
70gf_proc_dump_close (void)
71{
72 close (gf_dump_fd);
73 gf_dump_fd = -1;
74}
75
76static int
77gf_proc_dump_set_path (char *dump_options_file)
78{
79 int ret = -1;
80 FILE *fp = NULL((void*)0);
81 char buf[256];
82 char *key = NULL((void*)0), *value = NULL((void*)0);
83 char *saveptr = NULL((void*)0);
84
85 fp = fopen (dump_options_file, "r");
86 if (!fp)
87 goto out;
88
89 ret = fscanf (fp, "%s", buf);
90
91 while (ret != EOF(-1)) {
92 key = strtok_r (buf, "=", &saveptr);
93 if (!key) {
94 ret = fscanf (fp, "%s", buf);
95 continue;
96 }
97
98 value = strtok_r (NULL((void*)0), "=", &saveptr);
99
100 if (!value) {
101 ret = fscanf (fp, "%s", buf);
102 continue;
103 }
104 if (!strcmp (key, "path")) {
105 dump_options.dump_path = gf_strdup (value);
106 break;
107 }
108 }
109
110out:
111 if (fp)
112 fclose (fp);
113 return ret;
114}
115
116int
117gf_proc_dump_add_section (char *key, ...)
118{
119
120 char buf[GF_DUMP_MAX_BUF_LEN4096];
121 va_list ap;
122
123 GF_ASSERT(key)do { if (!(key)) { do { do { if (0) printf ("Assertion failed: "
"key"); } while (0); _gf_log_callingfn ("", "statedump.c", __FUNCTION__
, 123, GF_LOG_ERROR, "Assertion failed: " "key"); } while (0)
; } } while (0)
;
124
125 memset (buf, 0, sizeof(buf));
126 snprintf (buf, GF_DUMP_MAX_BUF_LEN4096, "\n[");
127 va_start (ap, key)__builtin_va_start(ap, key);
128 vsnprintf (buf + strlen(buf),
129 GF_DUMP_MAX_BUF_LEN4096 - strlen (buf), key, ap);
130 va_end (ap)__builtin_va_end(ap);
131 snprintf (buf + strlen(buf),
132 GF_DUMP_MAX_BUF_LEN4096 - strlen (buf), "]\n");
133 return write (gf_dump_fd, buf, strlen (buf));
134}
135
136
137int
138gf_proc_dump_write (char *key, char *value,...)
139{
140
141 char buf[GF_DUMP_MAX_BUF_LEN4096];
142 int offset = 0;
143 va_list ap;
144
145 GF_ASSERT (key)do { if (!(key)) { do { do { if (0) printf ("Assertion failed: "
"key"); } while (0); _gf_log_callingfn ("", "statedump.c", __FUNCTION__
, 145, GF_LOG_ERROR, "Assertion failed: " "key"); } while (0)
; } } while (0)
;
1
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'key' is null
146
147 offset = strlen (key);
2
Null pointer passed as an argument to a 'nonnull' parameter
148
149 memset (buf, 0, GF_DUMP_MAX_BUF_LEN4096);
150 snprintf (buf, GF_DUMP_MAX_BUF_LEN4096, "%s", key);
151 snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN4096 - offset, "=");
152 offset += 1;
153 va_start (ap, value)__builtin_va_start(ap, value);
154 vsnprintf (buf + offset, GF_DUMP_MAX_BUF_LEN4096 - offset, value, ap);
155 va_end (ap)__builtin_va_end(ap);
156
157 offset = strlen (buf);
158 snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN4096 - offset, "\n");
159 return write (gf_dump_fd, buf, strlen (buf));
160}
161
162static void
163gf_proc_dump_xlator_mem_info (xlator_t *xl)
164{
165 int i = 0;
166 struct mem_acct rec = {0,};
167
168 if (!xl)
169 return;
170
171 if (!xl->mem_acct.rec)
172 return;
173
174 gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
175 gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
176
177 for (i = 0; i < xl->mem_acct.num_types; i++) {
178 if (!(memcmp (&xl->mem_acct.rec[i], &rec,
179 sizeof (struct mem_acct))))
180 continue;
181
182 gf_proc_dump_add_section ("%s.%s - usage-type %d memusage",
183 xl->type, xl->name, i);
184 gf_proc_dump_write ("size", "%u", xl->mem_acct.rec[i].size);
185 gf_proc_dump_write ("num_allocs", "%u",
186 xl->mem_acct.rec[i].num_allocs);
187 gf_proc_dump_write ("max_size", "%u",
188 xl->mem_acct.rec[i].max_size);
189 gf_proc_dump_write ("max_num_allocs", "%u",
190 xl->mem_acct.rec[i].max_num_allocs);
191 gf_proc_dump_write ("total_allocs", "%u",
192 xl->mem_acct.rec[i].total_allocs);
193 }
194
195 return;
196}
197
198static void
199gf_proc_dump_xlator_mem_info_only_in_use (xlator_t *xl)
200{
201 int i = 0;
202
203 if (!xl)
204 return;
205
206 if (!xl->mem_acct.rec)
207 return;
208
209 gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
210 gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
211
212 for (i = 0; i < xl->mem_acct.num_types; i++) {
213 if (!xl->mem_acct.rec[i].size)
214 continue;
215
216 gf_proc_dump_add_section ("%s.%s - usage-type %d", xl->type,
217 xl->name,i);
218
219 gf_proc_dump_write ("size", "%u",
220 xl->mem_acct.rec[i].size);
221 gf_proc_dump_write ("max_size", "%u",
222 xl->mem_acct.rec[i].max_size);
223 gf_proc_dump_write ("num_allocs", "%u",
224 xl->mem_acct.rec[i].num_allocs);
225 gf_proc_dump_write ("max_num_allocs", "%u",
226 xl->mem_acct.rec[i].max_num_allocs);
227 gf_proc_dump_write ("total_allocs", "%u",
228 xl->mem_acct.rec[i].total_allocs);
229 }
230
231 return;
232}
233
234
235
236/* Currently this dumps only mallinfo. More can be built on here */
237void
238gf_proc_dump_mem_info ()
239{
240#ifdef HAVE_MALLOC_STATS1
241 struct mallinfo info;
242
243 memset (&info, 0, sizeof (struct mallinfo));
244 info = mallinfo ();
245
246 gf_proc_dump_add_section ("mallinfo");
247 gf_proc_dump_write ("mallinfo_arena", "%d", info.arena);
248 gf_proc_dump_write ("mallinfo_ordblks", "%d", info.ordblks);
249 gf_proc_dump_write ("mallinfo_smblks", "%d", info.smblks);
250 gf_proc_dump_write ("mallinfo_hblks", "%d", info.hblks);
251 gf_proc_dump_write ("mallinfo_hblkhd", "%d", info.hblkhd);
252 gf_proc_dump_write ("mallinfo_usmblks", "%d", info.usmblks);
253 gf_proc_dump_write ("mallinfo_fsmblks", "%d", info.fsmblks);
254 gf_proc_dump_write ("mallinfo_uordblks", "%d", info.uordblks);
255 gf_proc_dump_write ("mallinfo_fordblks", "%d", info.fordblks);
256 gf_proc_dump_write ("mallinfo_keepcost", "%d", info.keepcost);
257#endif
258 gf_proc_dump_xlator_mem_info(&global_xlator);
259
260}
261
262void
263gf_proc_dump_mem_info_to_dict (dict_t *dict)
264{
265 if (!dict)
266 return;
267#ifdef HAVE_MALLOC_STATS1
268 struct mallinfo info;
269 int ret = -1;
270
271 memset (&info, 0, sizeof(struct mallinfo));
272 info = mallinfo ();
273
274 ret = dict_set_int32 (dict, "mallinfo.arena", info.arena);
275 if (ret)
276 return;
277
278 ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks);
279 if (ret)
280 return;
281
282 ret = dict_set_int32 (dict, "mallinfo.smblks", info.smblks);
283 if (ret)
284 return;
285
286 ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks);
287 if (ret)
288 return;
289
290 ret = dict_set_int32 (dict, "mallinfo.hblkhd", info.hblkhd);
291 if (ret)
292 return;
293
294 ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks);
295 if (ret)
296 return;
297
298 ret = dict_set_int32 (dict, "mallinfo.fsmblks", info.fsmblks);
299 if (ret)
300 return;
301
302 ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks);
303 if (ret)
304 return;
305
306 ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks);
307 if (ret)
308 return;
309
310 ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost);
311 if (ret)
312 return;
313#endif
314 return;
315}
316
317void
318gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)
319{
320 struct mem_pool *pool = NULL((void*)0);
321
322 gf_proc_dump_add_section ("mempool");
323
324 list_for_each_entry (pool, &ctx->mempool_list, global_list)for (pool = ((typeof(*pool) *)((char *)((&ctx->mempool_list
)->next)-(unsigned long)(&((typeof(*pool) *)0)->global_list
))); &pool->global_list != (&ctx->mempool_list)
; pool = ((typeof(*pool) *)((char *)(pool->global_list.next
)-(unsigned long)(&((typeof(*pool) *)0)->global_list))
))
{
325 gf_proc_dump_write ("-----", "-----");
326 gf_proc_dump_write ("pool-name", "%s", pool->name);
327 gf_proc_dump_write ("hot-count", "%d", pool->hot_count);
328 gf_proc_dump_write ("cold-count", "%d", pool->cold_count);
329 gf_proc_dump_write ("padded_sizeof", "%lu",
330 pool->padded_sizeof_type);
331 gf_proc_dump_write ("alloc-count", "%"PRIu64"ll" "u", pool->alloc_count);
332 gf_proc_dump_write ("max-alloc", "%d", pool->max_alloc);
333
334 gf_proc_dump_write ("pool-misses", "%"PRIu64"ll" "u", pool->pool_misses);
335 gf_proc_dump_write ("max-stdalloc", "%d", pool->max_stdalloc);
336 }
337}
338
339void
340gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict)
341{
342 struct mem_pool *pool = NULL((void*)0);
343 char key[GF_DUMP_MAX_BUF_LEN4096] = {0,};
344 int count = 0;
345 int ret = -1;
346
347 if (!ctx || !dict)
348 return;
349
350 list_for_each_entry (pool, &ctx->mempool_list, global_list)for (pool = ((typeof(*pool) *)((char *)((&ctx->mempool_list
)->next)-(unsigned long)(&((typeof(*pool) *)0)->global_list
))); &pool->global_list != (&ctx->mempool_list)
; pool = ((typeof(*pool) *)((char *)(pool->global_list.next
)-(unsigned long)(&((typeof(*pool) *)0)->global_list))
))
{
351 memset (key, 0, sizeof (key));
352 snprintf (key, sizeof (key), "pool%d.name", count);
353 ret = dict_set_str (dict, key, pool->name);
354 if (ret)
355 return;
356
357 memset (key, 0, sizeof (key));
358 snprintf (key, sizeof (key), "pool%d.hotcount", count);
359 ret = dict_set_int32 (dict, key, pool->hot_count);
360 if (ret)
361 return;
362
363 memset (key, 0, sizeof (key));
364 snprintf (key, sizeof (key), "pool%d.coldcount", count);
365 ret = dict_set_int32 (dict, key, pool->cold_count);
366 if (ret)
367 return;
368
369 memset (key, 0, sizeof (key));
370 snprintf (key, sizeof (key), "pool%d.paddedsizeof", count);
371 ret = dict_set_uint64 (dict, key, pool->padded_sizeof_type);
372 if (ret)
373 return;
374
375 memset (key, 0, sizeof (key));
376 snprintf (key, sizeof (key), "pool%d.alloccount", count);
377 ret = dict_set_uint64 (dict, key, pool->alloc_count);
378 if (ret)
379 return;
380
381 memset (key, 0, sizeof (key));
382 snprintf (key, sizeof (key), "pool%d.max_alloc", count);
383 ret = dict_set_int32 (dict, key, pool->max_alloc);
384 if (ret)
385 return;
386
387 memset (key, 0, sizeof (key));
388 snprintf (key, sizeof (key), "pool%d.max-stdalloc", count);
389 ret = dict_set_int32 (dict, key, pool->max_stdalloc);
390 if (ret)
391 return;
392
393 memset (key, 0, sizeof (key));
394 snprintf (key, sizeof (key), "pool%d.pool-misses", count);
395 ret = dict_set_uint64 (dict, key, pool->pool_misses);
396 if (ret)
397 return;
398 count++;
399 }
400 ret = dict_set_int32 (dict, "mempool-count", count);
401
402 return;
403}
404
405void gf_proc_dump_latency_info (xlator_t *xl);
406
407void
408gf_proc_dump_xlator_info (xlator_t *top)
409{
410 xlator_t *trav = NULL((void*)0);
411 glusterfs_ctx_t *ctx = NULL((void*)0);
412 char itable_key[1024] = {0,};
413
414 if (!top)
415 return;
416
417 ctx = top->ctx;
418
419 trav = top;
420 while (trav) {
421
422 if (ctx->measure_latency)
423 gf_proc_dump_latency_info (trav);
424
425 gf_proc_dump_xlator_mem_info(trav);
426
427 if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)(dump_options.xl_options.dump_inode == _gf_true) &&
428 (trav->itable)) {
429 snprintf (itable_key, 1024, "%d.%s.itable",
430 ctx->graph_id, trav->name);
431 }
432
433 if (!trav->dumpops) {
434 trav = trav->next;
435 continue;
436 }
437
438 if (trav->dumpops->priv &&
439 GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv)(dump_options.xl_options.dump_priv == _gf_true))
440 trav->dumpops->priv (trav);
441
442 if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)(dump_options.xl_options.dump_inode == _gf_true) &&
443 (trav->dumpops->inode))
444 trav->dumpops->inode (trav);
445
446 if (trav->dumpops->fd &&
447 GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd)(dump_options.xl_options.dump_fd == _gf_true))
448 trav->dumpops->fd (trav);
449
450 if (trav->dumpops->history &&
451 GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history)(dump_options.xl_options.dump_history == _gf_true))
452 trav->dumpops->history (trav);
453
454 trav = trav->next;
455 }
456
457 return;
458}
459
460static void
461gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
462{
463 xlator_t *trav = NULL((void*)0);
464
465 if (!top)
466 return;
467
468 trav = top;
469 while (trav) {
470 gf_proc_dump_xlator_mem_info_only_in_use (trav);
471
472 if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)(dump_options.xl_options.dump_inode == _gf_true) &&
473 (trav->itable)) {
474 /*TODO: dump inode table info if necessary by
475 printing the graph id (taken by glusterfs_cbtx_t)
476 in the key
477 */
478 }
479
480 if (!trav->dumpops) {
481 trav = trav->next;
482 continue;
483 }
484
485 if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)(dump_options.xl_options.dump_inode == _gf_true) &&
486 (trav->dumpops->inode))
487 trav->dumpops->inode (trav);
488
489 if (trav->dumpops->fd &&
490 GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd)(dump_options.xl_options.dump_fd == _gf_true))
491 trav->dumpops->fd (trav);
492
493 trav = trav->next;
494 }
495
496 return;
497}
498
499static int
500gf_proc_dump_enable_all_options ()
501{
502
503 GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true)dump_options.dump_mem = _gf_true;
504 GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_true)dump_options.dump_iobuf = _gf_true;
505 GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true)dump_options.dump_callpool = _gf_true;
506 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_true)dump_options.xl_options.dump_priv = _gf_true;
507 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode, _gf_true)dump_options.xl_options.dump_inode = _gf_true;
508 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_true)dump_options.xl_options.dump_fd = _gf_true;
509 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,dump_options.xl_options.dump_inodectx = _gf_true
510 _gf_true)dump_options.xl_options.dump_inodectx = _gf_true;
511 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_true)dump_options.xl_options.dump_fdctx = _gf_true;
512 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,dump_options.xl_options.dump_history = _gf_true
513 _gf_true)dump_options.xl_options.dump_history = _gf_true;
514
515 return 0;
516}
517
518gf_boolean_t
519is_gf_proc_dump_all_disabled ()
520{
521 gf_boolean_t all_disabled = _gf_true;
522
523 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_mem, all_disabled, out)do { if (dump_options.dump_mem == _gf_true) { all_disabled = _gf_false
; goto out; } } while (0);
;
524 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_iobuf, all_disabled, out)do { if (dump_options.dump_iobuf == _gf_true) { all_disabled =
_gf_false; goto out; } } while (0);
;
525 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_callpool, all_disabled,do { if (dump_options.dump_callpool == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
526 out)do { if (dump_options.dump_callpool == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
527 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_priv,do { if (dump_options.xl_options.dump_priv == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
528 all_disabled, out)do { if (dump_options.xl_options.dump_priv == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
529 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inode,do { if (dump_options.xl_options.dump_inode == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
530 all_disabled, out)do { if (dump_options.xl_options.dump_inode == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
531 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fd,do { if (dump_options.xl_options.dump_fd == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
532 all_disabled, out)do { if (dump_options.xl_options.dump_fd == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
533 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inodectx,do { if (dump_options.xl_options.dump_inodectx == _gf_true) {
all_disabled = _gf_false; goto out; } } while (0);
534 all_disabled, out)do { if (dump_options.xl_options.dump_inodectx == _gf_true) {
all_disabled = _gf_false; goto out; } } while (0);
;
535 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fdctx,do { if (dump_options.xl_options.dump_fdctx == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
536 all_disabled, out)do { if (dump_options.xl_options.dump_fdctx == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
537 GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_history,do { if (dump_options.xl_options.dump_history == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
538 all_disabled, out)do { if (dump_options.xl_options.dump_history == _gf_true) { all_disabled
= _gf_false; goto out; } } while (0);
;
539
540out:
541 return all_disabled;
542}
543
544/* These options are dumped by default if glusterdump.options
545 file exists and it is emtpty
546*/
547static int
548gf_proc_dump_enable_default_options ()
549{
550 GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true)dump_options.dump_mem = _gf_true;
551 GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true)dump_options.dump_callpool = _gf_true;
552
553 return 0;
554}
555
556static int
557gf_proc_dump_disable_all_options ()
558{
559
560 GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_false)dump_options.dump_mem = _gf_false;
561 GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_false)dump_options.dump_iobuf = _gf_false;
562 GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_false)dump_options.dump_callpool = _gf_false;
563 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_false)dump_options.xl_options.dump_priv = _gf_false;
564 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode,dump_options.xl_options.dump_inode = _gf_false
565 _gf_false)dump_options.xl_options.dump_inode = _gf_false;
566 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_false)dump_options.xl_options.dump_fd = _gf_false;
567 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,dump_options.xl_options.dump_inodectx = _gf_false
568 _gf_false)dump_options.xl_options.dump_inodectx = _gf_false;
569 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_false)dump_options.xl_options.dump_fdctx = _gf_false;
570 GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,dump_options.xl_options.dump_history = _gf_false
571 _gf_false)dump_options.xl_options.dump_history = _gf_false;
572 return 0;
573}
574
575static int
576gf_proc_dump_parse_set_option (char *key, char *value)
577{
578 gf_boolean_t *opt_key = NULL((void*)0);
579 gf_boolean_t opt_value = _gf_false;
580 char buf[GF_DUMP_MAX_BUF_LEN4096];
581 int ret = -1;
582
583 if (!strcasecmp (key, "all")) {
584 (void)gf_proc_dump_enable_all_options ();
585 return 0;
586 } else if (!strcasecmp (key, "mem")) {
587 opt_key = &dump_options.dump_mem;
588 } else if (!strcasecmp (key, "iobuf")) {
589 opt_key = &dump_options.dump_iobuf;
590 } else if (!strcasecmp (key, "callpool")) {
591 opt_key = &dump_options.dump_callpool;
592 } else if (!strcasecmp (key, "priv")) {
593 opt_key = &dump_options.xl_options.dump_priv;
594 } else if (!strcasecmp (key, "fd")) {
595 opt_key = &dump_options.xl_options.dump_fd;
596 } else if (!strcasecmp (key, "inode")) {
597 opt_key = &dump_options.xl_options.dump_inode;
598 } else if (!strcasecmp (key, "inodectx")) {
599 opt_key = &dump_options.xl_options.dump_inodectx;
600 } else if (!strcasecmp (key, "fdctx")) {
601 opt_key = &dump_options.xl_options.dump_fdctx;
602 } else if (!strcasecmp (key, "history")) {
603 opt_key = &dump_options.xl_options.dump_history;
604 }
605
606 if (!opt_key) {
607 //None of dump options match the key, return back
608 snprintf (buf, sizeof (buf), "[Warning]:None of the options "
609 "matched key : %s\n", key);
610 ret = write (gf_dump_fd, buf, strlen (buf));
611
612 if (ret >= 0)
613 ret = -1;
614 goto out;
615
616 }
617
618 opt_value = (strncasecmp (value, "yes", 3) ?
619 _gf_false: _gf_true);
620
621 GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value)*opt_key = opt_value;
622
623 ret = 0;
624out:
625 return ret;
626}
627
628static int
629gf_proc_dump_options_init ()
630{
631 int ret = -1;
632 FILE *fp = NULL((void*)0);
633 char buf[256];
634 char *key = NULL((void*)0), *value = NULL((void*)0);
635 char *saveptr = NULL((void*)0);
636 char dump_option_file[PATH_MAX4096];
637
638 /* glusterd will create a file glusterdump.<pid>.options and
639 sets the statedump options for the process and the file is removed
640 after the statedump is taken. Direct issue of SIGUSR1 does not have
641 mechanism for considering the statedump options. So to have a way
642 of configuring the statedump of all the glusterfs processes through
643 both cli command and SIGUSR1, glusterdump.options file is searched
644 and the options mentioned in it are given the higher priority.
645 */
646 snprintf (dump_option_file, sizeof (dump_option_file),
647 DEFAULT_VAR_RUN_DIRECTORY"/usr/local/var" "/run/gluster"
648 "/glusterdump.options");
649 fp = fopen (dump_option_file, "r");
650 if (!fp) {
651 snprintf (dump_option_file, sizeof (dump_option_file),
652 DEFAULT_VAR_RUN_DIRECTORY"/usr/local/var" "/run/gluster"
653 "/glusterdump.%d.options", getpid ());
654
655 fp = fopen (dump_option_file, "r");
656
657 if (!fp) {
658 //ENOENT, return success
659 (void) gf_proc_dump_enable_all_options ();
660 return 0;
661 }
662 }
663
664 (void) gf_proc_dump_disable_all_options ();
665
666 // swallow the errors if setting statedump file path is failed.
667 ret = gf_proc_dump_set_path (dump_option_file);
668
669 ret = fscanf (fp, "%s", buf);
670
671 while (ret != EOF(-1)) {
672 key = strtok_r (buf, "=", &saveptr);
673 if (!key) {
674 ret = fscanf (fp, "%s", buf);
675 continue;
676 }
677
678 value = strtok_r (NULL((void*)0), "=", &saveptr);
679
680 if (!value) {
681 ret = fscanf (fp, "%s", buf);
682 continue;
683 }
684
685 gf_proc_dump_parse_set_option (key, value);
686 }
687
688 if (is_gf_proc_dump_all_disabled ())
689 (void) gf_proc_dump_enable_default_options ();
690
691 if (fp)
692 fclose (fp);
693
694 return 0;
695}
696
697void
698gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
699{
700 int i = 0;
701 int ret = -1;
702 glusterfs_graph_t *trav = NULL((void*)0);
703 char brick_name[PATH_MAX4096] = {0,};
704 char timestr[256] = {0,};
705 char sign_string[512] = {0,};
706 char tmp_dump_name[PATH_MAX4096] = {0,};
707 char path[PATH_MAX4096] = {0,};
708 struct timeval tv = {0,};
709
710 gf_proc_dump_lock ();
711
712 if (!ctx)
713 goto out;
714
715 if (ctx->cmd_args.brick_name) {
716 GF_REMOVE_SLASH_FROM_PATH (ctx->cmd_args.brick_name, brick_name)do { int i = 0; for (i = 1; i < strlen (ctx->cmd_args.brick_name
); i++) { brick_name[i-1] = ctx->cmd_args.brick_name[i]; if
(brick_name[i-1] == '/') brick_name[i-1] = '-'; } } while (0
)
;
717 } else
718 strncpy (brick_name, "glusterdump", sizeof (brick_name));
719
720 ret = gf_proc_dump_options_init ();
721 if (ret < 0)
722 goto out;
723
724 snprintf (path, sizeof (path), "%s/%s.%d.dump.%"PRIu64"ll" "u",
725 ((dump_options.dump_path != NULL((void*)0))?dump_options.dump_path:
726 ((ctx->statedump_path != NULL((void*)0))?ctx->statedump_path:
727 DEFAULT_VAR_RUN_DIRECTORY"/usr/local/var" "/run/gluster")), brick_name, getpid(),
728 (uint64_t) time (NULL((void*)0)));
729
730 snprintf (tmp_dump_name, PATH_MAX4096, "%s/dumpXXXXXX",
731 ((dump_options.dump_path != NULL((void*)0))?dump_options.dump_path:
732 ((ctx->statedump_path != NULL((void*)0))?ctx->statedump_path:
733 DEFAULT_VAR_RUN_DIRECTORY"/usr/local/var" "/run/gluster")));
734
735 ret = gf_proc_dump_open (tmp_dump_name);
736 if (ret < 0)
737 goto out;
738
739 //continue even though gettimeofday() has failed
740 ret = gettimeofday (&tv, NULL((void*)0));
741 if (0 == ret) {
742 gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
743 snprintf (timestr + strlen (timestr),
744 sizeof timestr - strlen (timestr),
745 ".%"GF_PRI_SUSECONDS"06ld", tv.tv_usec);
746 }
747
748 snprintf (sign_string, sizeof (sign_string), "DUMP-START-TIME: %s\n",
749 timestr);
750
751 //swallow the errors of write for start and end marker
752 ret = write (gf_dump_fd, sign_string, strlen (sign_string));
753
754 memset (sign_string, 0, sizeof (sign_string));
755 memset (timestr, 0, sizeof (timestr));
756 memset (&tv, 0, sizeof (tv));
757
758 if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)(dump_options.dump_mem == _gf_true)) {
759 gf_proc_dump_mem_info ();
760 gf_proc_dump_mempool_info (ctx);
761 }
762
763 if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf)(dump_options.dump_iobuf == _gf_true))
764 iobuf_stats_dump (ctx->iobuf_pool);
765 if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool)(dump_options.dump_callpool == _gf_true))
766 gf_proc_dump_pending_frames (ctx->pool);
767
768 if (ctx->master) {
769 gf_proc_dump_add_section ("fuse");
770 gf_proc_dump_xlator_info (ctx->master);
771 }
772
773 if (ctx->active) {
774 gf_proc_dump_add_section ("active graph - %d", ctx->graph_id);
775 gf_proc_dump_xlator_info (ctx->active->top);
776 }
777
778 i = 0;
779 list_for_each_entry (trav, &ctx->graphs, list)for (trav = ((typeof(*trav) *)((char *)((&ctx->graphs)
->next)-(unsigned long)(&((typeof(*trav) *)0)->list
))); &trav->list != (&ctx->graphs); trav = ((typeof
(*trav) *)((char *)(trav->list.next)-(unsigned long)(&
((typeof(*trav) *)0)->list))))
{
780 if (trav == ctx->active)
781 continue;
782
783 gf_proc_dump_add_section ("oldgraph[%d]", i);
784
785 gf_proc_dump_oldgraph_xlator_info (trav->top);
786 i++;
787 }
788
789 ret = gettimeofday (&tv, NULL((void*)0));
790 if (0 == ret) {
791 gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
792 snprintf (timestr + strlen (timestr),
793 sizeof timestr - strlen (timestr),
794 ".%"GF_PRI_SUSECONDS"06ld", tv.tv_usec);
795 }
796
797 snprintf (sign_string, sizeof (sign_string), "\nDUMP-END-TIME: %s",
798 timestr);
799 ret = write (gf_dump_fd, sign_string, strlen (sign_string));
800
801out:
802 if (gf_dump_fd != -1)
803 gf_proc_dump_close ();
804 rename (tmp_dump_name, path);
805 GF_FREE (dump_options.dump_path)__gf_free (dump_options.dump_path);
806 dump_options.dump_path = NULL((void*)0);
807 gf_proc_dump_unlock ();
808
809 return;
810}
811
812
813void
814gf_proc_dump_fini (void)
815{
816 pthread_mutex_destroy (&gf_proc_dump_mutex);
817}
818
819
820void
821gf_proc_dump_init ()
822{
823 pthread_mutex_init (&gf_proc_dump_mutex, NULL((void*)0));
824
825 return;
826}
827
828
829void
830gf_proc_dump_cleanup (void)
831{
832 pthread_mutex_destroy (&gf_proc_dump_mutex);
833}