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