Changes in kernel/generic/src/sysinfo/sysinfo.c [f97f1e51:9a426d1f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/sysinfo/sysinfo.c
rf97f1e51 r9a426d1f 1 1 /* 2 2 * Copyright (c) 2006 Jakub Vana 3 * Copyright (c) 2012 Martin Decky4 3 * All rights reserved. 5 4 * … … 97 96 void sysinfo_init(void) 98 97 { 99 sysinfo_item_slab = slab_cache_create("sysinfo_item_ t",98 sysinfo_item_slab = slab_cache_create("sysinfo_item_slab", 100 99 sizeof(sysinfo_item_t), 0, sysinfo_item_constructor, 101 100 sysinfo_item_destructor, SLAB_CACHE_MAGDEFERRED); 102 101 103 102 mutex_initialize(&sysinfo_lock, MUTEX_ACTIVE); 104 103 } … … 111 110 * @param subtree Current sysinfo (sub)tree root item. 112 111 * @param ret If the return value is NULL, this argument 113 * can be set either to NULL (i.e. no item was112 * can be either also NULL (i.e. no item was 114 113 * found and no data was generated) or the 115 114 * original pointer is used to store the value … … 126 125 { 127 126 ASSERT(subtree != NULL); 127 ASSERT(ret != NULL); 128 128 129 129 sysinfo_item_t *cur = subtree; … … 151 151 case SYSINFO_SUBTREE_FUNCTION: 152 152 /* Get generated data */ 153 if (ret != NULL) 154 **ret = cur->subtree.generator.fn(name + i + 1, 155 dry_run, cur->subtree.generator.data); 156 153 **ret = cur->subtree.get_data(name + i + 1, dry_run); 157 154 return NULL; 158 155 default: 159 156 /* Not found, no data generated */ 160 if (ret != NULL) 161 *ret = NULL; 162 157 *ret = NULL; 163 158 return NULL; 164 159 } … … 169 164 170 165 /* Not found, no data generated */ 171 if (ret != NULL) 172 *ret = NULL; 173 166 *ret = NULL; 174 167 return NULL; 175 168 } … … 359 352 * a new root item (NULL for global sysinfo root). 360 353 * @param fn Numeric value generator function. 361 * @param data Private data. 362 * 363 */ 364 void sysinfo_set_item_gen_val(const char *name, sysinfo_item_t **root, 365 sysinfo_fn_val_t fn, void *data) 354 * 355 */ 356 void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root, 357 sysinfo_fn_val_t fn) 366 358 { 367 359 /* Protect sysinfo tree consistency */ … … 374 366 if (item != NULL) { 375 367 item->val_type = SYSINFO_VAL_FUNCTION_VAL; 376 item->val.gen_val.fn = fn; 377 item->val.gen_val.data = data; 368 item->val.fn_val = fn; 378 369 } 379 370 … … 392 383 * a new root item (NULL for global sysinfo root). 393 384 * @param fn Binary data generator function. 394 * @param data Private data. 395 * 396 */ 397 void sysinfo_set_item_gen_data(const char *name, sysinfo_item_t **root, 398 sysinfo_fn_data_t fn, void *data) 385 * 386 */ 387 void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root, 388 sysinfo_fn_data_t fn) 399 389 { 400 390 /* Protect sysinfo tree consistency */ … … 407 397 if (item != NULL) { 408 398 item->val_type = SYSINFO_VAL_FUNCTION_DATA; 409 item->val.gen_data.fn = fn; 410 item->val.gen_data.data = data; 399 item->val.fn_data = fn; 411 400 } 412 401 … … 442 431 * a new root item (NULL for global sysinfo root). 443 432 * @param fn Subtree generator function. 444 * @param data Private data to be passed to the generator.445 433 * 446 434 */ 447 435 void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root, 448 sysinfo_fn_subtree_t fn , void *data)436 sysinfo_fn_subtree_t fn) 449 437 { 450 438 /* Protect sysinfo tree consistency */ … … 460 448 if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) { 461 449 item->subtree_type = SYSINFO_SUBTREE_FUNCTION; 462 item->subtree.generator.fn = fn; 463 item->subtree.generator.data = data; 450 item->subtree.get_data = fn; 464 451 } 465 452 … … 469 456 /** Sysinfo dump indentation helper routine 470 457 * 471 * @param depth Number of spaces to print. 472 * 473 */ 474 NO_TRACE static void sysinfo_indent(size_t spaces) 475 { 476 for (size_t i = 0; i < spaces; i++) 477 printf(" "); 458 * @param depth Number of indentation characters to print. 459 * 460 */ 461 NO_TRACE static void sysinfo_indent(unsigned int depth) 462 { 463 unsigned int i; 464 for (i = 0; i < depth; i++) 465 printf(" "); 478 466 } 479 467 … … 482 470 * Should be called with sysinfo_lock held. 483 471 * 484 * @param root Root item of the current (sub)tree. 485 * @param spaces Current indentation level. 486 * 487 */ 488 NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, size_t spaces) 489 { 472 * @param root Root item of the current (sub)tree. 473 * @param depth Current depth in the sysinfo tree. 474 * 475 */ 476 NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth) 477 { 478 sysinfo_item_t *cur = root; 479 490 480 /* Walk all siblings */ 491 for (sysinfo_item_t *cur = root; cur; cur = cur->next) { 492 size_t length; 493 494 if (spaces == 0) { 495 printf("%s", cur->name); 496 length = str_length(cur->name); 497 } else { 498 sysinfo_indent(spaces); 499 printf(".%s", cur->name); 500 length = str_length(cur->name) + 1; 501 } 481 while (cur != NULL) { 482 sysinfo_indent(depth); 502 483 503 484 sysarg_t val; … … 507 488 switch (cur->val_type) { 508 489 case SYSINFO_VAL_UNDEFINED: 509 printf(" [undefined]\n");490 printf("+ %s\n", cur->name); 510 491 break; 511 492 case SYSINFO_VAL_VAL: 512 printf(" -> %" PRIun" (%#" PRIxn ")\n", cur->val.val,513 cur->val.val );493 printf("+ %s -> %" PRIun" (%#" PRIxn ")\n", cur->name, 494 cur->val.val, cur->val.val); 514 495 break; 515 496 case SYSINFO_VAL_DATA: 516 printf(" (%zu bytes)\n", cur->val.data.size); 497 printf("+ %s (%zu bytes)\n", cur->name, 498 cur->val.data.size); 517 499 break; 518 500 case SYSINFO_VAL_FUNCTION_VAL: 519 val = cur->val. gen_val.fn(cur, cur->val.gen_val.data);520 printf(" -> %" PRIun" (%#" PRIxn ") [generated]\n", val,521 val);501 val = cur->val.fn_val(cur); 502 printf("+ %s -> %" PRIun" (%#" PRIxn ") [generated]\n", 503 cur->name, val, val); 522 504 break; 523 505 case SYSINFO_VAL_FUNCTION_DATA: 524 506 /* N.B.: No data was actually returned (only a dry run) */ 525 (void) cur->val. gen_data.fn(cur, &size, true,526 cur->val.gen_data.data);527 printf(" (%zu bytes) [generated]\n",size);507 (void) cur->val.fn_data(cur, &size, true); 508 printf("+ %s (%zu bytes) [generated]\n", cur->name, 509 size); 528 510 break; 529 511 default: … … 536 518 break; 537 519 case SYSINFO_SUBTREE_TABLE: 538 sysinfo_dump_internal(cur->subtree.table, spaces + length);520 sysinfo_dump_internal(cur->subtree.table, depth + 1); 539 521 break; 540 522 case SYSINFO_SUBTREE_FUNCTION: 541 sysinfo_indent( spaces + length);542 printf(" <generated subtree>\n");523 sysinfo_indent(depth + 1); 524 printf("+ [generated subtree]\n"); 543 525 break; 544 526 default: 545 sysinfo_indent( spaces + length);546 printf(" <unknown subtree>\n");527 sysinfo_indent(depth + 1); 528 printf("+ [unknown subtree]\n"); 547 529 } 530 531 cur = cur->next; 548 532 } 549 533 } … … 610 594 break; 611 595 case SYSINFO_VAL_FUNCTION_VAL: 612 ret.val = item->val. gen_val.fn(item, item->val.gen_val.data);596 ret.val = item->val.fn_val(item); 613 597 break; 614 598 case SYSINFO_VAL_FUNCTION_DATA: 615 ret.data.data = item->val. gen_data.fn(item, &ret.data.size,616 dry_run , item->val.gen_data.data);599 ret.data.data = item->val.fn_data(item, &ret.data.size, 600 dry_run); 617 601 break; 618 602 } … … 651 635 ASSERT(path); 652 636 653 if ((copy_from_uspace(path, ptr, size + 1) == 0) &&654 (path[size] == 0)) {637 if ((copy_from_uspace(path, ptr, size + 1) == 0) 638 && (path[size] == 0)) { 655 639 /* 656 640 * Prevent other functions from messing with sysinfo while we … … 661 645 mutex_unlock(&sysinfo_lock); 662 646 } 663 664 647 free(path); 665 648 return ret; 666 }667 668 /** Return sysinfo keys determined by name669 *670 * Should be called with sysinfo_lock held.671 *672 * @param name Sysinfo path.673 * @param root Root item of the sysinfo (sub)tree.674 * If it is NULL then consider the global675 * sysinfo tree.676 * @param dry_run Do not actually get any generated677 * binary data, just calculate the size.678 *679 * @return Item value (constant or generated).680 *681 */682 NO_TRACE static sysinfo_return_t sysinfo_get_keys(const char *name,683 sysinfo_item_t **root, bool dry_run)684 {685 if (root == NULL)686 root = &global_root;687 688 sysinfo_item_t *subtree = NULL;689 690 if (name[0] != 0) {691 /* Try to find the item */692 sysinfo_item_t *item =693 sysinfo_find_item(name, *root, NULL, dry_run);694 if ((item != NULL) &&695 (item->subtree_type == SYSINFO_SUBTREE_TABLE))696 subtree = item->subtree.table;697 } else698 subtree = *root;699 700 sysinfo_return_t ret;701 702 if (subtree != NULL) {703 /*704 * Calculate the size of subkeys.705 */706 size_t size = 0;707 for (sysinfo_item_t *cur = subtree; cur; cur = cur->next)708 size += str_size(cur->name) + 1;709 710 if (dry_run) {711 ret.tag = SYSINFO_VAL_DATA;712 ret.data.data = NULL;713 ret.data.size = size;714 } else {715 /* Allocate buffer for subkeys */716 char *names = (char *) malloc(size, FRAME_ATOMIC);717 if (names == NULL)718 return ret;719 720 size_t pos = 0;721 for (sysinfo_item_t *cur = subtree; cur; cur = cur->next) {722 str_cpy(names + pos, size - pos, cur->name);723 pos += str_size(cur->name) + 1;724 }725 726 /* Correct return value */727 ret.tag = SYSINFO_VAL_DATA;728 ret.data.data = (void *) names;729 ret.data.size = size;730 }731 } else {732 /* No item in the fixed sysinfo tree */733 ret.tag = SYSINFO_VAL_UNDEFINED;734 }735 736 return ret;737 }738 739 /** Return sysinfo keys determined by name from user space740 *741 * The path string passed from the user space has to be properly742 * null-terminated (the last passed character must be null).743 *744 * @param ptr Sysinfo path in the user address space.745 * @param size Size of the path string.746 * @param dry_run Do not actually get any generated747 * binary data, just calculate the size.748 *749 */750 NO_TRACE static sysinfo_return_t sysinfo_get_keys_uspace(void *ptr, size_t size,751 bool dry_run)752 {753 sysinfo_return_t ret;754 ret.tag = SYSINFO_VAL_UNDEFINED;755 756 if (size > SYSINFO_MAX_PATH)757 return ret;758 759 char *path = (char *) malloc(size + 1, 0);760 ASSERT(path);761 762 if ((copy_from_uspace(path, ptr, size + 1) == 0) &&763 (path[size] == 0)) {764 /*765 * Prevent other functions from messing with sysinfo while we766 * are reading it.767 */768 mutex_lock(&sysinfo_lock);769 ret = sysinfo_get_keys(path, NULL, dry_run);770 mutex_unlock(&sysinfo_lock);771 }772 773 free(path);774 return ret;775 }776 777 /** Get the sysinfo keys size (syscall)778 *779 * The path string passed from the user space has780 * to be properly null-terminated (the last passed781 * character must be null).782 *783 * @param path_ptr Sysinfo path in the user address space.784 * @param path_size Size of the path string.785 * @param size_ptr User space pointer where to store the786 * keys size.787 *788 * @return Error code (EOK in case of no error).789 *790 */791 sysarg_t sys_sysinfo_get_keys_size(void *path_ptr, size_t path_size,792 void *size_ptr)793 {794 int rc;795 796 /*797 * Get the keys.798 *799 * N.B.: There is no need to free any potential keys800 * since we request a dry run.801 */802 sysinfo_return_t ret =803 sysinfo_get_keys_uspace(path_ptr, path_size, true);804 805 /* Check return data tag */806 if (ret.tag == SYSINFO_VAL_DATA)807 rc = copy_to_uspace(size_ptr, &ret.data.size,808 sizeof(ret.data.size));809 else810 rc = EINVAL;811 812 return (sysarg_t) rc;813 }814 815 /** Get the sysinfo keys (syscall)816 *817 * The path string passed from the user space has818 * to be properly null-terminated (the last passed819 * character must be null).820 *821 * If the user space buffer size does not equal822 * the actual size of the returned data, the data823 * is truncated.824 *825 * The actual size of data returned is stored to826 * size_ptr.827 *828 * @param path_ptr Sysinfo path in the user address space.829 * @param path_size Size of the path string.830 * @param buffer_ptr User space pointer to the buffer where831 * to store the binary data.832 * @param buffer_size User space buffer size.833 * @param size_ptr User space pointer where to store the834 * binary data size.835 *836 * @return Error code (EOK in case of no error).837 *838 */839 sysarg_t sys_sysinfo_get_keys(void *path_ptr, size_t path_size,840 void *buffer_ptr, size_t buffer_size, size_t *size_ptr)841 {842 int rc;843 844 /* Get the keys */845 sysinfo_return_t ret = sysinfo_get_keys_uspace(path_ptr, path_size,846 false);847 848 /* Check return data tag */849 if (ret.tag == SYSINFO_VAL_DATA) {850 size_t size = min(ret.data.size, buffer_size);851 rc = copy_to_uspace(buffer_ptr, ret.data.data, size);852 if (rc == EOK)853 rc = copy_to_uspace(size_ptr, &size, sizeof(size));854 855 free(ret.data.data);856 } else857 rc = EINVAL;858 859 return (sysarg_t) rc;860 649 } 861 650 … … 883 672 884 673 /* 885 * Map generated value types to constant types (user space does 886 * not carewhether the value is constant or generated).674 * Map generated value types to constant types (user space does not care 675 * whether the value is constant or generated). 887 676 */ 888 677 if (ret.tag == SYSINFO_VAL_FUNCTION_VAL) … … 912 701 { 913 702 int rc; 914 703 915 704 /* 916 705 * Get the item. 917 706 * 918 * N.B.: There is no need to free any potential generated binary 919 * datasince we request a dry run.707 * N.B.: There is no need to free any potential generated binary data 708 * since we request a dry run. 920 709 */ 921 710 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true); … … 952 741 * Get the item. 953 742 * 954 * N.B.: There is no need to free any potential generated binary 955 * datasince we request a dry run.743 * N.B.: There is no need to free any potential generated binary data 744 * since we request a dry run. 956 745 */ 957 746 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
Note:
See TracChangeset
for help on using the changeset viewer.