1 /* 2 * What: /sys/kernel/debug/orangefs/debug-help 3 * Date: June 2015 4 * Contact: Mike Marshall <hubcap@omnibond.com> 5 * Description: 6 * List of client and kernel debug keywords. 7 * 8 * 9 * What: /sys/kernel/debug/orangefs/client-debug 10 * Date: June 2015 11 * Contact: Mike Marshall <hubcap@omnibond.com> 12 * Description: 13 * Debug setting for "the client", the userspace 14 * helper for the kernel module. 15 * 16 * 17 * What: /sys/kernel/debug/orangefs/kernel-debug 18 * Date: June 2015 19 * Contact: Mike Marshall <hubcap@omnibond.com> 20 * Description: 21 * Debug setting for the orangefs kernel module. 22 * 23 * Any of the keywords, or comma-separated lists 24 * of keywords, from debug-help can be catted to 25 * client-debug or kernel-debug. 26 * 27 * "none", "all" and "verbose" are special keywords 28 * for client-debug. Setting client-debug to "all" 29 * is kind of like trying to drink water from a 30 * fire hose, "verbose" triggers most of the same 31 * output except for the constant flow of output 32 * from the main wait loop. 33 * 34 * "none" and "all" are similar settings for kernel-debug 35 * no need for a "verbose". 36 */ 37 #include <linux/debugfs.h> 38 #include <linux/slab.h> 39 40 #include <linux/uaccess.h> 41 42 #include "orangefs-debugfs.h" 43 #include "protocol.h" 44 #include "orangefs-kernel.h" 45 46 #define DEBUG_HELP_STRING_SIZE 4096 47 #define HELP_STRING_UNINITIALIZED \ 48 "Client Debug Keywords are unknown until the first time\n" \ 49 "the client is started after boot.\n" 50 #define ORANGEFS_KMOD_DEBUG_HELP_FILE "debug-help" 51 #define ORANGEFS_KMOD_DEBUG_FILE "kernel-debug" 52 #define ORANGEFS_CLIENT_DEBUG_FILE "client-debug" 53 #define ORANGEFS_VERBOSE "verbose" 54 #define ORANGEFS_ALL "all" 55 56 /* 57 * An array of client_debug_mask will be built to hold debug keyword/mask 58 * values fetched from userspace. 59 */ 60 struct client_debug_mask { 61 char *keyword; 62 __u64 mask1; 63 __u64 mask2; 64 }; 65 66 static int orangefs_kernel_debug_init(void); 67 68 static int orangefs_debug_help_open(struct inode *, struct file *); 69 static void *help_start(struct seq_file *, loff_t *); 70 static void *help_next(struct seq_file *, void *, loff_t *); 71 static void help_stop(struct seq_file *, void *); 72 static int help_show(struct seq_file *, void *); 73 74 static int orangefs_debug_open(struct inode *, struct file *); 75 76 static ssize_t orangefs_debug_read(struct file *, 77 char __user *, 78 size_t, 79 loff_t *); 80 81 static ssize_t orangefs_debug_write(struct file *, 82 const char __user *, 83 size_t, 84 loff_t *); 85 86 static int orangefs_prepare_cdm_array(char *); 87 static void debug_mask_to_string(void *, int); 88 static void do_k_string(void *, int); 89 static void do_c_string(void *, int); 90 static int keyword_is_amalgam(char *); 91 static int check_amalgam_keyword(void *, int); 92 static void debug_string_to_mask(char *, void *, int); 93 static void do_c_mask(int, char *, struct client_debug_mask **); 94 static void do_k_mask(int, char *, __u64 **); 95 96 static char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN] = "none"; 97 static char *debug_help_string; 98 static char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; 99 static char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; 100 101 static struct dentry *help_file_dentry; 102 static struct dentry *client_debug_dentry; 103 static struct dentry *debug_dir; 104 105 static unsigned int kernel_mask_set_mod_init; 106 static int orangefs_debug_disabled = 1; 107 static int help_string_initialized; 108 109 static const struct seq_operations help_debug_ops = { 110 .start = help_start, 111 .next = help_next, 112 .stop = help_stop, 113 .show = help_show, 114 }; 115 116 const struct file_operations debug_help_fops = { 117 .open = orangefs_debug_help_open, 118 .read = seq_read, 119 .release = seq_release, 120 .llseek = seq_lseek, 121 }; 122 123 static const struct file_operations kernel_debug_fops = { 124 .open = orangefs_debug_open, 125 .read = orangefs_debug_read, 126 .write = orangefs_debug_write, 127 .llseek = generic_file_llseek, 128 }; 129 130 static int client_all_index; 131 static int client_verbose_index; 132 133 static struct client_debug_mask *cdm_array; 134 static int cdm_element_count; 135 136 static struct client_debug_mask client_debug_mask; 137 138 /* 139 * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and 140 * ORANGEFS_KMOD_DEBUG_FILE. 141 */ 142 static DEFINE_MUTEX(orangefs_debug_lock); 143 144 /* 145 * initialize kmod debug operations, create orangefs debugfs dir and 146 * ORANGEFS_KMOD_DEBUG_HELP_FILE. 147 */ 148 int orangefs_debugfs_init(int debug_mask) 149 { 150 int rc = -ENOMEM; 151 152 /* convert input debug mask to a 64-bit unsigned integer */ 153 orangefs_gossip_debug_mask = (unsigned long long)debug_mask; 154 155 /* 156 * set the kernel's gossip debug string; invalid mask values will 157 * be ignored. 158 */ 159 debug_mask_to_string(&orangefs_gossip_debug_mask, 0); 160 161 /* remove any invalid values from the mask */ 162 debug_string_to_mask(kernel_debug_string, &orangefs_gossip_debug_mask, 163 0); 164 165 /* 166 * if the mask has a non-zero value, then indicate that the mask 167 * was set when the kernel module was loaded. The orangefs dev ioctl 168 * command will look at this boolean to determine if the kernel's 169 * debug mask should be overwritten when the client-core is started. 170 */ 171 if (orangefs_gossip_debug_mask != 0) 172 kernel_mask_set_mod_init = true; 173 174 pr_info("%s: called with debug mask: :%s: :%llx:\n", 175 __func__, 176 kernel_debug_string, 177 (unsigned long long)orangefs_gossip_debug_mask); 178 179 debug_dir = debugfs_create_dir("orangefs", NULL); 180 if (!debug_dir) { 181 pr_info("%s: debugfs_create_dir failed.\n", __func__); 182 goto out; 183 } 184 185 help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, 186 0444, 187 debug_dir, 188 debug_help_string, 189 &debug_help_fops); 190 if (!help_file_dentry) { 191 pr_info("%s: debugfs_create_file failed.\n", __func__); 192 goto out; 193 } 194 195 orangefs_debug_disabled = 0; 196 197 rc = orangefs_kernel_debug_init(); 198 199 out: 200 201 return rc; 202 } 203 204 /* 205 * initialize the kernel-debug file. 206 */ 207 static int orangefs_kernel_debug_init(void) 208 { 209 int rc = -ENOMEM; 210 struct dentry *ret; 211 char *k_buffer = NULL; 212 213 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); 214 215 k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); 216 if (!k_buffer) 217 goto out; 218 219 if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) { 220 strcpy(k_buffer, kernel_debug_string); 221 strcat(k_buffer, "\n"); 222 } else { 223 strcpy(k_buffer, "none\n"); 224 pr_info("%s: overflow 1!\n", __func__); 225 } 226 227 ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 228 0444, 229 debug_dir, 230 k_buffer, 231 &kernel_debug_fops); 232 if (!ret) { 233 pr_info("%s: failed to create %s.\n", 234 __func__, 235 ORANGEFS_KMOD_DEBUG_FILE); 236 goto out; 237 } 238 239 rc = 0; 240 241 out: 242 243 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); 244 return rc; 245 } 246 247 248 void orangefs_debugfs_cleanup(void) 249 { 250 debugfs_remove_recursive(debug_dir); 251 } 252 253 /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */ 254 static int orangefs_debug_help_open(struct inode *inode, struct file *file) 255 { 256 int rc = -ENODEV; 257 int ret; 258 259 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 260 "orangefs_debug_help_open: start\n"); 261 262 if (orangefs_debug_disabled) 263 goto out; 264 265 ret = seq_open(file, &help_debug_ops); 266 if (ret) 267 goto out; 268 269 ((struct seq_file *)(file->private_data))->private = inode->i_private; 270 271 rc = 0; 272 273 out: 274 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 275 "orangefs_debug_help_open: rc:%d:\n", 276 rc); 277 return rc; 278 } 279 280 /* 281 * I think start always gets called again after stop. Start 282 * needs to return NULL when it is done. The whole "payload" 283 * in this case is a single (long) string, so by the second 284 * time we get to start (pos = 1), we're done. 285 */ 286 static void *help_start(struct seq_file *m, loff_t *pos) 287 { 288 void *payload = NULL; 289 290 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n"); 291 292 if (*pos == 0) 293 payload = m->private; 294 295 return payload; 296 } 297 298 static void *help_next(struct seq_file *m, void *v, loff_t *pos) 299 { 300 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n"); 301 302 return NULL; 303 } 304 305 static void help_stop(struct seq_file *m, void *p) 306 { 307 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n"); 308 } 309 310 static int help_show(struct seq_file *m, void *v) 311 { 312 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_show: start\n"); 313 314 seq_puts(m, v); 315 316 return 0; 317 } 318 319 /* 320 * initialize the client-debug file. 321 */ 322 int orangefs_client_debug_init(void) 323 { 324 325 int rc = -ENOMEM; 326 char *c_buffer = NULL; 327 328 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); 329 330 c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); 331 if (!c_buffer) 332 goto out; 333 334 if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) { 335 strcpy(c_buffer, client_debug_string); 336 strcat(c_buffer, "\n"); 337 } else { 338 strcpy(c_buffer, "none\n"); 339 pr_info("%s: overflow! 2\n", __func__); 340 } 341 342 client_debug_dentry = debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE, 343 0444, 344 debug_dir, 345 c_buffer, 346 &kernel_debug_fops); 347 if (!client_debug_dentry) { 348 pr_info("%s: failed to create updated %s.\n", 349 __func__, 350 ORANGEFS_CLIENT_DEBUG_FILE); 351 goto out; 352 } 353 354 rc = 0; 355 356 out: 357 358 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); 359 return rc; 360 } 361 362 /* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/ 363 static int orangefs_debug_open(struct inode *inode, struct file *file) 364 { 365 int rc = -ENODEV; 366 367 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 368 "%s: orangefs_debug_disabled: %d\n", 369 __func__, 370 orangefs_debug_disabled); 371 372 if (orangefs_debug_disabled) 373 goto out; 374 375 rc = 0; 376 mutex_lock(&orangefs_debug_lock); 377 file->private_data = inode->i_private; 378 mutex_unlock(&orangefs_debug_lock); 379 380 out: 381 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 382 "orangefs_debug_open: rc: %d\n", 383 rc); 384 return rc; 385 } 386 387 static ssize_t orangefs_debug_read(struct file *file, 388 char __user *ubuf, 389 size_t count, 390 loff_t *ppos) 391 { 392 char *buf; 393 int sprintf_ret; 394 ssize_t read_ret = -ENOMEM; 395 396 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "orangefs_debug_read: start\n"); 397 398 buf = kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); 399 if (!buf) 400 goto out; 401 402 mutex_lock(&orangefs_debug_lock); 403 sprintf_ret = sprintf(buf, "%s", (char *)file->private_data); 404 mutex_unlock(&orangefs_debug_lock); 405 406 read_ret = simple_read_from_buffer(ubuf, count, ppos, buf, sprintf_ret); 407 408 kfree(buf); 409 410 out: 411 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 412 "orangefs_debug_read: ret: %zu\n", 413 read_ret); 414 415 return read_ret; 416 } 417 418 static ssize_t orangefs_debug_write(struct file *file, 419 const char __user *ubuf, 420 size_t count, 421 loff_t *ppos) 422 { 423 char *buf; 424 int rc = -EFAULT; 425 size_t silly = 0; 426 char *debug_string; 427 struct orangefs_kernel_op_s *new_op = NULL; 428 struct client_debug_mask c_mask = { NULL, 0, 0 }; 429 430 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 431 "orangefs_debug_write: %pD\n", 432 file); 433 434 /* 435 * Thwart users who try to jamb a ridiculous number 436 * of bytes into the debug file... 437 */ 438 if (count > ORANGEFS_MAX_DEBUG_STRING_LEN + 1) { 439 silly = count; 440 count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1; 441 } 442 443 buf = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); 444 if (!buf) 445 goto out; 446 447 if (copy_from_user(buf, ubuf, count - 1)) { 448 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 449 "%s: copy_from_user failed!\n", 450 __func__); 451 goto out; 452 } 453 454 /* 455 * Map the keyword string from userspace into a valid debug mask. 456 * The mapping process involves mapping the human-inputted string 457 * into a valid mask, and then rebuilding the string from the 458 * verified valid mask. 459 * 460 * A service operation is required to set a new client-side 461 * debug mask. 462 */ 463 if (!strcmp(file->f_path.dentry->d_name.name, 464 ORANGEFS_KMOD_DEBUG_FILE)) { 465 debug_string_to_mask(buf, &orangefs_gossip_debug_mask, 0); 466 debug_mask_to_string(&orangefs_gossip_debug_mask, 0); 467 debug_string = kernel_debug_string; 468 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 469 "New kernel debug string is %s\n", 470 kernel_debug_string); 471 } else { 472 /* Can't reset client debug mask if client is not running. */ 473 if (is_daemon_in_service()) { 474 pr_info("%s: Client not running :%d:\n", 475 __func__, 476 is_daemon_in_service()); 477 goto out; 478 } 479 480 debug_string_to_mask(buf, &c_mask, 1); 481 debug_mask_to_string(&c_mask, 1); 482 debug_string = client_debug_string; 483 484 new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); 485 if (!new_op) { 486 pr_info("%s: op_alloc failed!\n", __func__); 487 goto out; 488 } 489 490 new_op->upcall.req.param.op = 491 ORANGEFS_PARAM_REQUEST_OP_TWO_MASK_VALUES; 492 new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET; 493 memset(new_op->upcall.req.param.s_value, 494 0, 495 ORANGEFS_MAX_DEBUG_STRING_LEN); 496 sprintf(new_op->upcall.req.param.s_value, 497 "%llx %llx\n", 498 c_mask.mask1, 499 c_mask.mask2); 500 501 /* service_operation returns 0 on success... */ 502 rc = service_operation(new_op, 503 "orangefs_param", 504 ORANGEFS_OP_INTERRUPTIBLE); 505 506 if (rc) 507 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 508 "%s: service_operation failed! rc:%d:\n", 509 __func__, 510 rc); 511 512 op_release(new_op); 513 } 514 515 mutex_lock(&orangefs_debug_lock); 516 memset(file->f_inode->i_private, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); 517 sprintf((char *)file->f_inode->i_private, "%s\n", debug_string); 518 mutex_unlock(&orangefs_debug_lock); 519 520 *ppos += count; 521 if (silly) 522 rc = silly; 523 else 524 rc = count; 525 526 out: 527 gossip_debug(GOSSIP_DEBUGFS_DEBUG, 528 "orangefs_debug_write: rc: %d\n", 529 rc); 530 kfree(buf); 531 return rc; 532 } 533 534 /* 535 * After obtaining a string representation of the client's debug 536 * keywords and their associated masks, this function is called to build an 537 * array of these values. 538 */ 539 static int orangefs_prepare_cdm_array(char *debug_array_string) 540 { 541 int i; 542 int rc = -EINVAL; 543 char *cds_head = NULL; 544 char *cds_delimiter = NULL; 545 int keyword_len = 0; 546 547 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); 548 549 /* 550 * figure out how many elements the cdm_array needs. 551 */ 552 for (i = 0; i < strlen(debug_array_string); i++) 553 if (debug_array_string[i] == '\n') 554 cdm_element_count++; 555 556 if (!cdm_element_count) { 557 pr_info("No elements in client debug array string!\n"); 558 goto out; 559 } 560 561 cdm_array = 562 kzalloc(cdm_element_count * sizeof(struct client_debug_mask), 563 GFP_KERNEL); 564 if (!cdm_array) { 565 pr_info("malloc failed for cdm_array!\n"); 566 rc = -ENOMEM; 567 goto out; 568 } 569 570 cds_head = debug_array_string; 571 572 for (i = 0; i < cdm_element_count; i++) { 573 cds_delimiter = strchr(cds_head, '\n'); 574 *cds_delimiter = '\0'; 575 576 keyword_len = strcspn(cds_head, " "); 577 578 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL); 579 if (!cdm_array[i].keyword) { 580 rc = -ENOMEM; 581 goto out; 582 } 583 584 sscanf(cds_head, 585 "%s %llx %llx", 586 cdm_array[i].keyword, 587 (unsigned long long *)&(cdm_array[i].mask1), 588 (unsigned long long *)&(cdm_array[i].mask2)); 589 590 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE)) 591 client_verbose_index = i; 592 593 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL)) 594 client_all_index = i; 595 596 cds_head = cds_delimiter + 1; 597 } 598 599 rc = cdm_element_count; 600 601 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc); 602 603 out: 604 605 return rc; 606 607 } 608 609 /* 610 * /sys/kernel/debug/orangefs/debug-help can be catted to 611 * see all the available kernel and client debug keywords. 612 * 613 * When the kernel boots, we have no idea what keywords the 614 * client supports, nor their associated masks. 615 * 616 * We pass through this function once at boot and stamp a 617 * boilerplate "we don't know" message for the client in the 618 * debug-help file. We pass through here again when the client 619 * starts and then we can fill out the debug-help file fully. 620 * 621 * The client might be restarted any number of times between 622 * reboots, we only build the debug-help file the first time. 623 */ 624 int orangefs_prepare_debugfs_help_string(int at_boot) 625 { 626 int rc = -EINVAL; 627 int i; 628 int byte_count = 0; 629 char *client_title = "Client Debug Keywords:\n"; 630 char *kernel_title = "Kernel Debug Keywords:\n"; 631 632 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); 633 634 if (at_boot) { 635 byte_count += strlen(HELP_STRING_UNINITIALIZED); 636 client_title = HELP_STRING_UNINITIALIZED; 637 } else { 638 /* 639 * fill the client keyword/mask array and remember 640 * how many elements there were. 641 */ 642 cdm_element_count = 643 orangefs_prepare_cdm_array(client_debug_array_string); 644 if (cdm_element_count <= 0) 645 goto out; 646 647 /* Count the bytes destined for debug_help_string. */ 648 byte_count += strlen(client_title); 649 650 for (i = 0; i < cdm_element_count; i++) { 651 byte_count += strlen(cdm_array[i].keyword + 2); 652 if (byte_count >= DEBUG_HELP_STRING_SIZE) { 653 pr_info("%s: overflow 1!\n", __func__); 654 goto out; 655 } 656 } 657 658 gossip_debug(GOSSIP_UTILS_DEBUG, 659 "%s: cdm_element_count:%d:\n", 660 __func__, 661 cdm_element_count); 662 } 663 664 byte_count += strlen(kernel_title); 665 for (i = 0; i < num_kmod_keyword_mask_map; i++) { 666 byte_count += 667 strlen(s_kmod_keyword_mask_map[i].keyword + 2); 668 if (byte_count >= DEBUG_HELP_STRING_SIZE) { 669 pr_info("%s: overflow 2!\n", __func__); 670 goto out; 671 } 672 } 673 674 /* build debug_help_string. */ 675 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL); 676 if (!debug_help_string) { 677 rc = -ENOMEM; 678 goto out; 679 } 680 681 strcat(debug_help_string, client_title); 682 683 if (!at_boot) { 684 for (i = 0; i < cdm_element_count; i++) { 685 strcat(debug_help_string, "\t"); 686 strcat(debug_help_string, cdm_array[i].keyword); 687 strcat(debug_help_string, "\n"); 688 } 689 } 690 691 strcat(debug_help_string, "\n"); 692 strcat(debug_help_string, kernel_title); 693 694 for (i = 0; i < num_kmod_keyword_mask_map; i++) { 695 strcat(debug_help_string, "\t"); 696 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword); 697 strcat(debug_help_string, "\n"); 698 } 699 700 rc = 0; 701 702 out: 703 704 return rc; 705 706 } 707 708 /* 709 * kernel = type 0 710 * client = type 1 711 */ 712 static void debug_mask_to_string(void *mask, int type) 713 { 714 int i; 715 int len = 0; 716 char *debug_string; 717 int element_count = 0; 718 719 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); 720 721 if (type) { 722 debug_string = client_debug_string; 723 element_count = cdm_element_count; 724 } else { 725 debug_string = kernel_debug_string; 726 element_count = num_kmod_keyword_mask_map; 727 } 728 729 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); 730 731 /* 732 * Some keywords, like "all" or "verbose", are amalgams of 733 * numerous other keywords. Make a special check for those 734 * before grinding through the whole mask only to find out 735 * later... 736 */ 737 if (check_amalgam_keyword(mask, type)) 738 goto out; 739 740 /* Build the debug string. */ 741 for (i = 0; i < element_count; i++) 742 if (type) 743 do_c_string(mask, i); 744 else 745 do_k_string(mask, i); 746 747 len = strlen(debug_string); 748 749 if ((len) && (type)) 750 client_debug_string[len - 1] = '\0'; 751 else if (len) 752 kernel_debug_string[len - 1] = '\0'; 753 else if (type) 754 strcpy(client_debug_string, "none"); 755 else 756 strcpy(kernel_debug_string, "none"); 757 758 out: 759 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string); 760 761 return; 762 763 } 764 765 static void do_k_string(void *k_mask, int index) 766 { 767 __u64 *mask = (__u64 *) k_mask; 768 769 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword)) 770 goto out; 771 772 if (*mask & s_kmod_keyword_mask_map[index].mask_val) { 773 if ((strlen(kernel_debug_string) + 774 strlen(s_kmod_keyword_mask_map[index].keyword)) 775 < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) { 776 strcat(kernel_debug_string, 777 s_kmod_keyword_mask_map[index].keyword); 778 strcat(kernel_debug_string, ","); 779 } else { 780 gossip_err("%s: overflow!\n", __func__); 781 strcpy(kernel_debug_string, ORANGEFS_ALL); 782 goto out; 783 } 784 } 785 786 out: 787 788 return; 789 } 790 791 static void do_c_string(void *c_mask, int index) 792 { 793 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask; 794 795 if (keyword_is_amalgam(cdm_array[index].keyword)) 796 goto out; 797 798 if ((mask->mask1 & cdm_array[index].mask1) || 799 (mask->mask2 & cdm_array[index].mask2)) { 800 if ((strlen(client_debug_string) + 801 strlen(cdm_array[index].keyword) + 1) 802 < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) { 803 strcat(client_debug_string, 804 cdm_array[index].keyword); 805 strcat(client_debug_string, ","); 806 } else { 807 gossip_err("%s: overflow!\n", __func__); 808 strcpy(client_debug_string, ORANGEFS_ALL); 809 goto out; 810 } 811 } 812 out: 813 return; 814 } 815 816 static int keyword_is_amalgam(char *keyword) 817 { 818 int rc = 0; 819 820 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE))) 821 rc = 1; 822 823 return rc; 824 } 825 826 /* 827 * kernel = type 0 828 * client = type 1 829 * 830 * return 1 if we found an amalgam. 831 */ 832 static int check_amalgam_keyword(void *mask, int type) 833 { 834 __u64 *k_mask; 835 struct client_debug_mask *c_mask; 836 int k_all_index = num_kmod_keyword_mask_map - 1; 837 int rc = 0; 838 839 if (type) { 840 c_mask = (struct client_debug_mask *) mask; 841 842 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) && 843 (c_mask->mask2 == cdm_array[client_all_index].mask2)) { 844 strcpy(client_debug_string, ORANGEFS_ALL); 845 rc = 1; 846 goto out; 847 } 848 849 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) && 850 (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) { 851 strcpy(client_debug_string, ORANGEFS_VERBOSE); 852 rc = 1; 853 goto out; 854 } 855 856 } else { 857 k_mask = (__u64 *) mask; 858 859 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) { 860 strcpy(kernel_debug_string, ORANGEFS_ALL); 861 rc = 1; 862 goto out; 863 } 864 } 865 866 out: 867 868 return rc; 869 } 870 871 /* 872 * kernel = type 0 873 * client = type 1 874 */ 875 static void debug_string_to_mask(char *debug_string, void *mask, int type) 876 { 877 char *unchecked_keyword; 878 int i; 879 char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL); 880 char *original_pointer; 881 int element_count = 0; 882 struct client_debug_mask *c_mask = NULL; 883 __u64 *k_mask = NULL; 884 885 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); 886 887 if (type) { 888 c_mask = (struct client_debug_mask *)mask; 889 element_count = cdm_element_count; 890 } else { 891 k_mask = (__u64 *)mask; 892 *k_mask = 0; 893 element_count = num_kmod_keyword_mask_map; 894 } 895 896 original_pointer = strsep_fodder; 897 while ((unchecked_keyword = strsep(&strsep_fodder, ","))) 898 if (strlen(unchecked_keyword)) { 899 for (i = 0; i < element_count; i++) 900 if (type) 901 do_c_mask(i, 902 unchecked_keyword, 903 &c_mask); 904 else 905 do_k_mask(i, 906 unchecked_keyword, 907 &k_mask); 908 } 909 910 kfree(original_pointer); 911 } 912 913 static void do_c_mask(int i, char *unchecked_keyword, 914 struct client_debug_mask **sane_mask) 915 { 916 917 if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) { 918 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1; 919 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2; 920 } 921 } 922 923 static void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask) 924 { 925 926 if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword)) 927 **sane_mask = (**sane_mask) | 928 s_kmod_keyword_mask_map[i].mask_val; 929 } 930 931 int orangefs_debugfs_new_client_mask(void __user *arg) 932 { 933 struct dev_mask2_info_s mask2_info = {0}; 934 int ret; 935 936 ret = copy_from_user(&mask2_info, 937 (void __user *)arg, 938 sizeof(struct dev_mask2_info_s)); 939 940 if (ret != 0) 941 return -EIO; 942 943 client_debug_mask.mask1 = mask2_info.mask1_value; 944 client_debug_mask.mask2 = mask2_info.mask2_value; 945 946 pr_info("%s: client debug mask has been been received " 947 ":%llx: :%llx:\n", 948 __func__, 949 (unsigned long long)client_debug_mask.mask1, 950 (unsigned long long)client_debug_mask.mask2); 951 952 return ret; 953 } 954 955 int orangefs_debugfs_new_client_string(void __user *arg) 956 { 957 int ret; 958 959 ret = copy_from_user(&client_debug_array_string, 960 (void __user *)arg, 961 ORANGEFS_MAX_DEBUG_STRING_LEN); 962 if (ret != 0) 963 return -EIO; 964 965 /* 966 * The real client-core makes an effort to ensure 967 * that actual strings that aren't too long to fit in 968 * this buffer is what we get here. We're going to use 969 * string functions on the stuff we got, so we'll make 970 * this extra effort to try and keep from 971 * flowing out of this buffer when we use the string 972 * functions, even if somehow the stuff we end up 973 * with here is garbage. 974 */ 975 client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] = 976 '\0'; 977 978 if (ret != 0) { 979 pr_info("%s: CLIENT_STRING: copy_from_user failed\n", 980 __func__); 981 return -EIO; 982 } 983 984 pr_info("%s: client debug array string has been received.\n", 985 __func__); 986 987 if (!help_string_initialized) { 988 989 /* Free the "we don't know yet" default string... */ 990 kfree(debug_help_string); 991 992 /* build a proper debug help string */ 993 if (orangefs_prepare_debugfs_help_string(0)) { 994 gossip_err("%s: no debug help string \n", 995 __func__); 996 return -EIO; 997 } 998 999 /* Replace the boilerplate boot-time debug-help file. */ 1000 debugfs_remove(help_file_dentry); 1001 1002 help_file_dentry = 1003 debugfs_create_file( 1004 ORANGEFS_KMOD_DEBUG_HELP_FILE, 1005 0444, 1006 debug_dir, 1007 debug_help_string, 1008 &debug_help_fops); 1009 1010 if (!help_file_dentry) { 1011 gossip_err("%s: debugfs_create_file failed for" 1012 " :%s:!\n", 1013 __func__, 1014 ORANGEFS_KMOD_DEBUG_HELP_FILE); 1015 return -EIO; 1016 } 1017 } 1018 1019 debug_mask_to_string(&client_debug_mask, 1); 1020 1021 debugfs_remove(client_debug_dentry); 1022 1023 orangefs_client_debug_init(); 1024 1025 help_string_initialized++; 1026 1027 return ret; 1028 } 1029 1030 int orangefs_debugfs_new_debug(void __user *arg) 1031 { 1032 struct dev_mask_info_s mask_info = {0}; 1033 int ret; 1034 1035 ret = copy_from_user(&mask_info, 1036 (void __user *)arg, 1037 sizeof(mask_info)); 1038 1039 if (ret != 0) 1040 return -EIO; 1041 1042 if (mask_info.mask_type == KERNEL_MASK) { 1043 if ((mask_info.mask_value == 0) 1044 && (kernel_mask_set_mod_init)) { 1045 /* 1046 * the kernel debug mask was set when the 1047 * kernel module was loaded; don't override 1048 * it if the client-core was started without 1049 * a value for ORANGEFS_KMODMASK. 1050 */ 1051 return 0; 1052 } 1053 debug_mask_to_string(&mask_info.mask_value, 1054 mask_info.mask_type); 1055 orangefs_gossip_debug_mask = mask_info.mask_value; 1056 pr_info("%s: kernel debug mask has been modified to " 1057 ":%s: :%llx:\n", 1058 __func__, 1059 kernel_debug_string, 1060 (unsigned long long)orangefs_gossip_debug_mask); 1061 } else if (mask_info.mask_type == CLIENT_MASK) { 1062 debug_mask_to_string(&mask_info.mask_value, 1063 mask_info.mask_type); 1064 pr_info("%s: client debug mask has been modified to" 1065 ":%s: :%llx:\n", 1066 __func__, 1067 client_debug_string, 1068 llu(mask_info.mask_value)); 1069 } else { 1070 gossip_lerr("Invalid mask type....\n"); 1071 return -EINVAL; 1072 } 1073 1074 return ret; 1075 } 1076