1 /****************************************************************************** 2 ******************************************************************************* 3 ** 4 ** Copyright (C) 2005-2009 Red Hat, Inc. All rights reserved. 5 ** 6 ** This copyrighted material is made available to anyone wishing to use, 7 ** modify, copy, or redistribute it subject to the terms and conditions 8 ** of the GNU General Public License v.2. 9 ** 10 ******************************************************************************* 11 ******************************************************************************/ 12 13 #include <linux/pagemap.h> 14 #include <linux/seq_file.h> 15 #include <linux/module.h> 16 #include <linux/ctype.h> 17 #include <linux/debugfs.h> 18 19 #include "dlm_internal.h" 20 #include "lock.h" 21 22 #define DLM_DEBUG_BUF_LEN 4096 23 static char debug_buf[DLM_DEBUG_BUF_LEN]; 24 static struct mutex debug_buf_lock; 25 26 static struct dentry *dlm_root; 27 28 static char *print_lockmode(int mode) 29 { 30 switch (mode) { 31 case DLM_LOCK_IV: 32 return "--"; 33 case DLM_LOCK_NL: 34 return "NL"; 35 case DLM_LOCK_CR: 36 return "CR"; 37 case DLM_LOCK_CW: 38 return "CW"; 39 case DLM_LOCK_PR: 40 return "PR"; 41 case DLM_LOCK_PW: 42 return "PW"; 43 case DLM_LOCK_EX: 44 return "EX"; 45 default: 46 return "??"; 47 } 48 } 49 50 static int print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb, 51 struct dlm_rsb *res) 52 { 53 seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode)); 54 55 if (lkb->lkb_status == DLM_LKSTS_CONVERT || 56 lkb->lkb_status == DLM_LKSTS_WAITING) 57 seq_printf(s, " (%s)", print_lockmode(lkb->lkb_rqmode)); 58 59 if (lkb->lkb_nodeid) { 60 if (lkb->lkb_nodeid != res->res_nodeid) 61 seq_printf(s, " Remote: %3d %08x", lkb->lkb_nodeid, 62 lkb->lkb_remid); 63 else 64 seq_printf(s, " Master: %08x", lkb->lkb_remid); 65 } 66 67 if (lkb->lkb_wait_type) 68 seq_printf(s, " wait_type: %d", lkb->lkb_wait_type); 69 70 return seq_printf(s, "\n"); 71 } 72 73 static int print_format1(struct dlm_rsb *res, struct seq_file *s) 74 { 75 struct dlm_lkb *lkb; 76 int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list; 77 int rv; 78 79 lock_rsb(res); 80 81 rv = seq_printf(s, "\nResource %p Name (len=%d) \"", 82 res, res->res_length); 83 if (rv) 84 goto out; 85 86 for (i = 0; i < res->res_length; i++) { 87 if (isprint(res->res_name[i])) 88 seq_printf(s, "%c", res->res_name[i]); 89 else 90 seq_printf(s, "%c", '.'); 91 } 92 93 if (res->res_nodeid > 0) 94 rv = seq_printf(s, "\" \nLocal Copy, Master is node %d\n", 95 res->res_nodeid); 96 else if (res->res_nodeid == 0) 97 rv = seq_printf(s, "\" \nMaster Copy\n"); 98 else if (res->res_nodeid == -1) 99 rv = seq_printf(s, "\" \nLooking up master (lkid %x)\n", 100 res->res_first_lkid); 101 else 102 rv = seq_printf(s, "\" \nInvalid master %d\n", 103 res->res_nodeid); 104 if (rv) 105 goto out; 106 107 /* Print the LVB: */ 108 if (res->res_lvbptr) { 109 seq_printf(s, "LVB: "); 110 for (i = 0; i < lvblen; i++) { 111 if (i == lvblen / 2) 112 seq_printf(s, "\n "); 113 seq_printf(s, "%02x ", 114 (unsigned char) res->res_lvbptr[i]); 115 } 116 if (rsb_flag(res, RSB_VALNOTVALID)) 117 seq_printf(s, " (INVALID)"); 118 rv = seq_printf(s, "\n"); 119 if (rv) 120 goto out; 121 } 122 123 root_list = !list_empty(&res->res_root_list); 124 recover_list = !list_empty(&res->res_recover_list); 125 126 if (root_list || recover_list) { 127 rv = seq_printf(s, "Recovery: root %d recover %d flags %lx " 128 "count %d\n", root_list, recover_list, 129 res->res_flags, res->res_recover_locks_count); 130 if (rv) 131 goto out; 132 } 133 134 /* Print the locks attached to this resource */ 135 seq_printf(s, "Granted Queue\n"); 136 list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) { 137 rv = print_format1_lock(s, lkb, res); 138 if (rv) 139 goto out; 140 } 141 142 seq_printf(s, "Conversion Queue\n"); 143 list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) { 144 rv = print_format1_lock(s, lkb, res); 145 if (rv) 146 goto out; 147 } 148 149 seq_printf(s, "Waiting Queue\n"); 150 list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) { 151 rv = print_format1_lock(s, lkb, res); 152 if (rv) 153 goto out; 154 } 155 156 if (list_empty(&res->res_lookup)) 157 goto out; 158 159 seq_printf(s, "Lookup Queue\n"); 160 list_for_each_entry(lkb, &res->res_lookup, lkb_rsb_lookup) { 161 rv = seq_printf(s, "%08x %s", lkb->lkb_id, 162 print_lockmode(lkb->lkb_rqmode)); 163 if (lkb->lkb_wait_type) 164 seq_printf(s, " wait_type: %d", lkb->lkb_wait_type); 165 rv = seq_printf(s, "\n"); 166 } 167 out: 168 unlock_rsb(res); 169 return rv; 170 } 171 172 static int print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb, 173 struct dlm_rsb *r) 174 { 175 u64 xid = 0; 176 u64 us; 177 int rv; 178 179 if (lkb->lkb_flags & DLM_IFL_USER) { 180 if (lkb->lkb_ua) 181 xid = lkb->lkb_ua->xid; 182 } 183 184 /* microseconds since lkb was added to current queue */ 185 us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_timestamp)); 186 187 /* id nodeid remid pid xid exflags flags sts grmode rqmode time_us 188 r_nodeid r_len r_name */ 189 190 rv = seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %llu %u %d \"%s\"\n", 191 lkb->lkb_id, 192 lkb->lkb_nodeid, 193 lkb->lkb_remid, 194 lkb->lkb_ownpid, 195 (unsigned long long)xid, 196 lkb->lkb_exflags, 197 lkb->lkb_flags, 198 lkb->lkb_status, 199 lkb->lkb_grmode, 200 lkb->lkb_rqmode, 201 (unsigned long long)us, 202 r->res_nodeid, 203 r->res_length, 204 r->res_name); 205 return rv; 206 } 207 208 static int print_format2(struct dlm_rsb *r, struct seq_file *s) 209 { 210 struct dlm_lkb *lkb; 211 int rv = 0; 212 213 lock_rsb(r); 214 215 list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { 216 rv = print_format2_lock(s, lkb, r); 217 if (rv) 218 goto out; 219 } 220 221 list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) { 222 rv = print_format2_lock(s, lkb, r); 223 if (rv) 224 goto out; 225 } 226 227 list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) { 228 rv = print_format2_lock(s, lkb, r); 229 if (rv) 230 goto out; 231 } 232 out: 233 unlock_rsb(r); 234 return rv; 235 } 236 237 static int print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb, 238 int rsb_lookup) 239 { 240 u64 xid = 0; 241 int rv; 242 243 if (lkb->lkb_flags & DLM_IFL_USER) { 244 if (lkb->lkb_ua) 245 xid = lkb->lkb_ua->xid; 246 } 247 248 rv = seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n", 249 lkb->lkb_id, 250 lkb->lkb_nodeid, 251 lkb->lkb_remid, 252 lkb->lkb_ownpid, 253 (unsigned long long)xid, 254 lkb->lkb_exflags, 255 lkb->lkb_flags, 256 lkb->lkb_status, 257 lkb->lkb_grmode, 258 lkb->lkb_rqmode, 259 lkb->lkb_highbast, 260 rsb_lookup, 261 lkb->lkb_wait_type, 262 lkb->lkb_lvbseq, 263 (unsigned long long)ktime_to_ns(lkb->lkb_timestamp), 264 (unsigned long long)ktime_to_ns(lkb->lkb_time_bast)); 265 return rv; 266 } 267 268 static int print_format3(struct dlm_rsb *r, struct seq_file *s) 269 { 270 struct dlm_lkb *lkb; 271 int i, lvblen = r->res_ls->ls_lvblen; 272 int print_name = 1; 273 int rv; 274 275 lock_rsb(r); 276 277 rv = seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ", 278 r, 279 r->res_nodeid, 280 r->res_first_lkid, 281 r->res_flags, 282 !list_empty(&r->res_root_list), 283 !list_empty(&r->res_recover_list), 284 r->res_recover_locks_count, 285 r->res_length); 286 if (rv) 287 goto out; 288 289 for (i = 0; i < r->res_length; i++) { 290 if (!isascii(r->res_name[i]) || !isprint(r->res_name[i])) 291 print_name = 0; 292 } 293 294 seq_printf(s, "%s", print_name ? "str " : "hex"); 295 296 for (i = 0; i < r->res_length; i++) { 297 if (print_name) 298 seq_printf(s, "%c", r->res_name[i]); 299 else 300 seq_printf(s, " %02x", (unsigned char)r->res_name[i]); 301 } 302 rv = seq_printf(s, "\n"); 303 if (rv) 304 goto out; 305 306 if (!r->res_lvbptr) 307 goto do_locks; 308 309 seq_printf(s, "lvb %u %d", r->res_lvbseq, lvblen); 310 311 for (i = 0; i < lvblen; i++) 312 seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]); 313 rv = seq_printf(s, "\n"); 314 if (rv) 315 goto out; 316 317 do_locks: 318 list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { 319 rv = print_format3_lock(s, lkb, 0); 320 if (rv) 321 goto out; 322 } 323 324 list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) { 325 rv = print_format3_lock(s, lkb, 0); 326 if (rv) 327 goto out; 328 } 329 330 list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) { 331 rv = print_format3_lock(s, lkb, 0); 332 if (rv) 333 goto out; 334 } 335 336 list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup) { 337 rv = print_format3_lock(s, lkb, 1); 338 if (rv) 339 goto out; 340 } 341 out: 342 unlock_rsb(r); 343 return rv; 344 } 345 346 struct rsbtbl_iter { 347 struct dlm_rsb *rsb; 348 unsigned bucket; 349 int format; 350 int header; 351 }; 352 353 /* seq_printf returns -1 if the buffer is full, and 0 otherwise. 354 If the buffer is full, seq_printf can be called again, but it 355 does nothing and just returns -1. So, the these printing routines 356 periodically check the return value to avoid wasting too much time 357 trying to print to a full buffer. */ 358 359 static int table_seq_show(struct seq_file *seq, void *iter_ptr) 360 { 361 struct rsbtbl_iter *ri = iter_ptr; 362 int rv = 0; 363 364 switch (ri->format) { 365 case 1: 366 rv = print_format1(ri->rsb, seq); 367 break; 368 case 2: 369 if (ri->header) { 370 seq_printf(seq, "id nodeid remid pid xid exflags " 371 "flags sts grmode rqmode time_ms " 372 "r_nodeid r_len r_name\n"); 373 ri->header = 0; 374 } 375 rv = print_format2(ri->rsb, seq); 376 break; 377 case 3: 378 if (ri->header) { 379 seq_printf(seq, "version rsb 1.1 lvb 1.1 lkb 1.1\n"); 380 ri->header = 0; 381 } 382 rv = print_format3(ri->rsb, seq); 383 break; 384 } 385 386 return rv; 387 } 388 389 static struct seq_operations format1_seq_ops; 390 static struct seq_operations format2_seq_ops; 391 static struct seq_operations format3_seq_ops; 392 393 static void *table_seq_start(struct seq_file *seq, loff_t *pos) 394 { 395 struct dlm_ls *ls = seq->private; 396 struct rsbtbl_iter *ri; 397 struct dlm_rsb *r; 398 loff_t n = *pos; 399 unsigned bucket, entry; 400 401 bucket = n >> 32; 402 entry = n & ((1LL << 32) - 1); 403 404 if (bucket >= ls->ls_rsbtbl_size) 405 return NULL; 406 407 ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_KERNEL); 408 if (!ri) 409 return NULL; 410 if (n == 0) 411 ri->header = 1; 412 if (seq->op == &format1_seq_ops) 413 ri->format = 1; 414 if (seq->op == &format2_seq_ops) 415 ri->format = 2; 416 if (seq->op == &format3_seq_ops) 417 ri->format = 3; 418 419 spin_lock(&ls->ls_rsbtbl[bucket].lock); 420 if (!list_empty(&ls->ls_rsbtbl[bucket].list)) { 421 list_for_each_entry(r, &ls->ls_rsbtbl[bucket].list, 422 res_hashchain) { 423 if (!entry--) { 424 dlm_hold_rsb(r); 425 ri->rsb = r; 426 ri->bucket = bucket; 427 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 428 return ri; 429 } 430 } 431 } 432 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 433 434 /* 435 * move to the first rsb in the next non-empty bucket 436 */ 437 438 /* zero the entry */ 439 n &= ~((1LL << 32) - 1); 440 441 while (1) { 442 bucket++; 443 n += 1LL << 32; 444 445 if (bucket >= ls->ls_rsbtbl_size) { 446 kfree(ri); 447 return NULL; 448 } 449 450 spin_lock(&ls->ls_rsbtbl[bucket].lock); 451 if (!list_empty(&ls->ls_rsbtbl[bucket].list)) { 452 r = list_first_entry(&ls->ls_rsbtbl[bucket].list, 453 struct dlm_rsb, res_hashchain); 454 dlm_hold_rsb(r); 455 ri->rsb = r; 456 ri->bucket = bucket; 457 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 458 *pos = n; 459 return ri; 460 } 461 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 462 } 463 } 464 465 static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos) 466 { 467 struct dlm_ls *ls = seq->private; 468 struct rsbtbl_iter *ri = iter_ptr; 469 struct list_head *next; 470 struct dlm_rsb *r, *rp; 471 loff_t n = *pos; 472 unsigned bucket; 473 474 bucket = n >> 32; 475 476 /* 477 * move to the next rsb in the same bucket 478 */ 479 480 spin_lock(&ls->ls_rsbtbl[bucket].lock); 481 rp = ri->rsb; 482 next = rp->res_hashchain.next; 483 484 if (next != &ls->ls_rsbtbl[bucket].list) { 485 r = list_entry(next, struct dlm_rsb, res_hashchain); 486 dlm_hold_rsb(r); 487 ri->rsb = r; 488 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 489 dlm_put_rsb(rp); 490 ++*pos; 491 return ri; 492 } 493 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 494 dlm_put_rsb(rp); 495 496 /* 497 * move to the first rsb in the next non-empty bucket 498 */ 499 500 /* zero the entry */ 501 n &= ~((1LL << 32) - 1); 502 503 while (1) { 504 bucket++; 505 n += 1LL << 32; 506 507 if (bucket >= ls->ls_rsbtbl_size) { 508 kfree(ri); 509 return NULL; 510 } 511 512 spin_lock(&ls->ls_rsbtbl[bucket].lock); 513 if (!list_empty(&ls->ls_rsbtbl[bucket].list)) { 514 r = list_first_entry(&ls->ls_rsbtbl[bucket].list, 515 struct dlm_rsb, res_hashchain); 516 dlm_hold_rsb(r); 517 ri->rsb = r; 518 ri->bucket = bucket; 519 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 520 *pos = n; 521 return ri; 522 } 523 spin_unlock(&ls->ls_rsbtbl[bucket].lock); 524 } 525 } 526 527 static void table_seq_stop(struct seq_file *seq, void *iter_ptr) 528 { 529 struct rsbtbl_iter *ri = iter_ptr; 530 531 if (ri) { 532 dlm_put_rsb(ri->rsb); 533 kfree(ri); 534 } 535 } 536 537 static struct seq_operations format1_seq_ops = { 538 .start = table_seq_start, 539 .next = table_seq_next, 540 .stop = table_seq_stop, 541 .show = table_seq_show, 542 }; 543 544 static struct seq_operations format2_seq_ops = { 545 .start = table_seq_start, 546 .next = table_seq_next, 547 .stop = table_seq_stop, 548 .show = table_seq_show, 549 }; 550 551 static struct seq_operations format3_seq_ops = { 552 .start = table_seq_start, 553 .next = table_seq_next, 554 .stop = table_seq_stop, 555 .show = table_seq_show, 556 }; 557 558 static const struct file_operations format1_fops; 559 static const struct file_operations format2_fops; 560 static const struct file_operations format3_fops; 561 562 static int table_open(struct inode *inode, struct file *file) 563 { 564 struct seq_file *seq; 565 int ret = -1; 566 567 if (file->f_op == &format1_fops) 568 ret = seq_open(file, &format1_seq_ops); 569 else if (file->f_op == &format2_fops) 570 ret = seq_open(file, &format2_seq_ops); 571 else if (file->f_op == &format3_fops) 572 ret = seq_open(file, &format3_seq_ops); 573 574 if (ret) 575 return ret; 576 577 seq = file->private_data; 578 seq->private = inode->i_private; /* the dlm_ls */ 579 return 0; 580 } 581 582 static const struct file_operations format1_fops = { 583 .owner = THIS_MODULE, 584 .open = table_open, 585 .read = seq_read, 586 .llseek = seq_lseek, 587 .release = seq_release 588 }; 589 590 static const struct file_operations format2_fops = { 591 .owner = THIS_MODULE, 592 .open = table_open, 593 .read = seq_read, 594 .llseek = seq_lseek, 595 .release = seq_release 596 }; 597 598 static const struct file_operations format3_fops = { 599 .owner = THIS_MODULE, 600 .open = table_open, 601 .read = seq_read, 602 .llseek = seq_lseek, 603 .release = seq_release 604 }; 605 606 /* 607 * dump lkb's on the ls_waiters list 608 */ 609 610 static int waiters_open(struct inode *inode, struct file *file) 611 { 612 file->private_data = inode->i_private; 613 return 0; 614 } 615 616 static ssize_t waiters_read(struct file *file, char __user *userbuf, 617 size_t count, loff_t *ppos) 618 { 619 struct dlm_ls *ls = file->private_data; 620 struct dlm_lkb *lkb; 621 size_t len = DLM_DEBUG_BUF_LEN, pos = 0, ret, rv; 622 623 mutex_lock(&debug_buf_lock); 624 mutex_lock(&ls->ls_waiters_mutex); 625 memset(debug_buf, 0, sizeof(debug_buf)); 626 627 list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) { 628 ret = snprintf(debug_buf + pos, len - pos, "%x %d %d %s\n", 629 lkb->lkb_id, lkb->lkb_wait_type, 630 lkb->lkb_nodeid, lkb->lkb_resource->res_name); 631 if (ret >= len - pos) 632 break; 633 pos += ret; 634 } 635 mutex_unlock(&ls->ls_waiters_mutex); 636 637 rv = simple_read_from_buffer(userbuf, count, ppos, debug_buf, pos); 638 mutex_unlock(&debug_buf_lock); 639 return rv; 640 } 641 642 static const struct file_operations waiters_fops = { 643 .owner = THIS_MODULE, 644 .open = waiters_open, 645 .read = waiters_read 646 }; 647 648 void dlm_delete_debug_file(struct dlm_ls *ls) 649 { 650 if (ls->ls_debug_rsb_dentry) 651 debugfs_remove(ls->ls_debug_rsb_dentry); 652 if (ls->ls_debug_waiters_dentry) 653 debugfs_remove(ls->ls_debug_waiters_dentry); 654 if (ls->ls_debug_locks_dentry) 655 debugfs_remove(ls->ls_debug_locks_dentry); 656 if (ls->ls_debug_all_dentry) 657 debugfs_remove(ls->ls_debug_all_dentry); 658 } 659 660 int dlm_create_debug_file(struct dlm_ls *ls) 661 { 662 char name[DLM_LOCKSPACE_LEN+8]; 663 664 /* format 1 */ 665 666 ls->ls_debug_rsb_dentry = debugfs_create_file(ls->ls_name, 667 S_IFREG | S_IRUGO, 668 dlm_root, 669 ls, 670 &format1_fops); 671 if (!ls->ls_debug_rsb_dentry) 672 goto fail; 673 674 /* format 2 */ 675 676 memset(name, 0, sizeof(name)); 677 snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name); 678 679 ls->ls_debug_locks_dentry = debugfs_create_file(name, 680 S_IFREG | S_IRUGO, 681 dlm_root, 682 ls, 683 &format2_fops); 684 if (!ls->ls_debug_locks_dentry) 685 goto fail; 686 687 /* format 3 */ 688 689 memset(name, 0, sizeof(name)); 690 snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_all", ls->ls_name); 691 692 ls->ls_debug_all_dentry = debugfs_create_file(name, 693 S_IFREG | S_IRUGO, 694 dlm_root, 695 ls, 696 &format3_fops); 697 if (!ls->ls_debug_all_dentry) 698 goto fail; 699 700 memset(name, 0, sizeof(name)); 701 snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_waiters", ls->ls_name); 702 703 ls->ls_debug_waiters_dentry = debugfs_create_file(name, 704 S_IFREG | S_IRUGO, 705 dlm_root, 706 ls, 707 &waiters_fops); 708 if (!ls->ls_debug_waiters_dentry) 709 goto fail; 710 711 return 0; 712 713 fail: 714 dlm_delete_debug_file(ls); 715 return -ENOMEM; 716 } 717 718 int __init dlm_register_debugfs(void) 719 { 720 mutex_init(&debug_buf_lock); 721 dlm_root = debugfs_create_dir("dlm", NULL); 722 return dlm_root ? 0 : -ENOMEM; 723 } 724 725 void dlm_unregister_debugfs(void) 726 { 727 debugfs_remove(dlm_root); 728 } 729 730