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