1*d4514f0bSApple OSS DistributionsKernel Data Descriptors 2*d4514f0bSApple OSS Distributions======================= 3*d4514f0bSApple OSS Distributions 4*d4514f0bSApple OSS DistributionsThis project allows for dynamic data to be passed from the kernel to userspace tools without binding them to particular version of 5*d4514f0bSApple OSS Distributionsstruct definition. The `libkdd` library provides convenient API for parsing and interpreting `kernel chunked data`. 6*d4514f0bSApple OSS Distributions 7*d4514f0bSApple OSS DistributionsThe libkdd APIs are defined in [kdd.h](./kdd.h) 8*d4514f0bSApple OSS Distributions 9*d4514f0bSApple OSS DistributionsThe `KCDATA` format 10*d4514f0bSApple OSS Distributions=================== 11*d4514f0bSApple OSS Distributions 12*d4514f0bSApple OSS DistributionsThe format for data is setup in a generic format as follows 13*d4514f0bSApple OSS Distributions 14*d4514f0bSApple OSS DistributionsLayout of data structure 15*d4514f0bSApple OSS Distributions------------------------ 16*d4514f0bSApple OSS Distributions 17*d4514f0bSApple OSS Distributions | 8 - bytes | 18*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 00 19*d4514f0bSApple OSS Distributions | type = MAGIC | LENGTH | # BEGIN Header 20*d4514f0bSApple OSS Distributions | 0 | 21*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 16 22*d4514f0bSApple OSS Distributions | type | size | # chunk header 23*d4514f0bSApple OSS Distributions | flags | 24*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 32 25*d4514f0bSApple OSS Distributions | data | # arbitrary data (len=16) 26*d4514f0bSApple OSS Distributions |___________data____________| 27*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 48 28*d4514f0bSApple OSS Distributions | type | size | # chunk header 29*d4514f0bSApple OSS Distributions | flags | 30*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 64 31*d4514f0bSApple OSS Distributions | data | # arbitrary data (len=32) 32*d4514f0bSApple OSS Distributions | data | 33*d4514f0bSApple OSS Distributions | data | 34*d4514f0bSApple OSS Distributions |___________data____________| 35*d4514f0bSApple OSS Distributions |---------------------------| ------ offset = 96 36*d4514f0bSApple OSS Distributions | type = END | size=0 | # chunk header 37*d4514f0bSApple OSS Distributions | 0 | 38*d4514f0bSApple OSS Distributions 39*d4514f0bSApple OSS Distributions 40*d4514f0bSApple OSS DistributionsThe type field describes what kind of data is passed. For example type = `TASK_CRASHINFO_UUID` means the following data is a uuid. 41*d4514f0bSApple OSS DistributionsThese types need to be defined in task_corpses.h for easy consumption by userspace inspection tools. 42*d4514f0bSApple OSS Distributions 43*d4514f0bSApple OSS DistributionsSome range of types is reserved for special types like ints, longs etc. A cool new functionality made possible with this 44*d4514f0bSApple OSS Distributionsextensible data format is that kernel can decide to put more information as required without requiring user space tools to 45*d4514f0bSApple OSS Distributionsre-compile to be compatible. The case of `rusage` struct versions could be introduced without breaking existing tools. 46*d4514f0bSApple OSS Distributions 47*d4514f0bSApple OSS DistributionsFeature description: Generic data with description 48*d4514f0bSApple OSS Distributions------------------- 49*d4514f0bSApple OSS DistributionsFurther more generic data with description is very much possible now. For example 50*d4514f0bSApple OSS Distributions 51*d4514f0bSApple OSS Distributions - kcdata_add_uint64_with_description(cdatainfo, 0x700, "NUM MACH PORTS"); 52*d4514f0bSApple OSS Distributions - and more functions that allow adding description. 53*d4514f0bSApple OSS Distributions 54*d4514f0bSApple OSS DistributionsThe userspace tools can then look at the description and print the data even if they are not compiled with knowledge of the field apriori. 55*d4514f0bSApple OSS Distributions 56*d4514f0bSApple OSS Distributions Example data: 57*d4514f0bSApple OSS Distributions 0000 57 f1 ad de 00 00 00 00 00 00 00 00 00 00 00 00 W............... 58*d4514f0bSApple OSS Distributions 0010 01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 ........0....... 59*d4514f0bSApple OSS Distributions 0020 50 49 44 00 00 00 00 00 00 00 00 00 00 00 00 00 PID............. 60*d4514f0bSApple OSS Distributions 0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 61*d4514f0bSApple OSS Distributions 0040 9c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 62*d4514f0bSApple OSS Distributions 0050 01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 ........0....... 63*d4514f0bSApple OSS Distributions 0060 50 41 52 45 4e 54 20 50 49 44 00 00 00 00 00 00 PARENT PID...... 64*d4514f0bSApple OSS Distributions 0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 65*d4514f0bSApple OSS Distributions 0080 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 66*d4514f0bSApple OSS Distributions 0090 ed 58 91 f1 67*d4514f0bSApple OSS Distributions 68*d4514f0bSApple OSS Distributions 69*d4514f0bSApple OSS DistributionsFeature description: Container markers for compound data 70*d4514f0bSApple OSS Distributions------------------ 71*d4514f0bSApple OSS Distributions 72*d4514f0bSApple OSS DistributionsIf a given kernel data type is complex and requires adding multiple optional fields inside a container 73*d4514f0bSApple OSS Distributionsobject for a consumer to understand arbitrary data, we package it using container markers. 74*d4514f0bSApple OSS Distributions 75*d4514f0bSApple OSS DistributionsFor example, the stackshot code gathers information and describes the state of a given task with respect 76*d4514f0bSApple OSS Distributionsto many subsystems. It includes data such as io stats, vm counters, process names/flags and syscall counts. 77*d4514f0bSApple OSS Distributions 78*d4514f0bSApple OSS Distributions kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_BEGIN, STACKSHOT_KCCONTAINER_TASK, task_uniqueid); 79*d4514f0bSApple OSS Distributions // add multiple data, or add_<type>_with_description()s here 80*d4514f0bSApple OSS Distributions 81*d4514f0bSApple OSS Distributions kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_END, STACKSHOT_KCCONTAINER_TASK, task_uniqueid); 82*d4514f0bSApple OSS Distributions 83*d4514f0bSApple OSS Distributions 84*d4514f0bSApple OSS DistributionsFeature description: Custom Data formats on demand 85*d4514f0bSApple OSS Distributions-------------------- 86*d4514f0bSApple OSS Distributions 87*d4514f0bSApple OSS DistributionsWith the self describing nature of format, the kernel provider can describe a data type (uniquely identified by a number) and use 88*d4514f0bSApple OSS Distributionsit in the buffer for sending data. The consumer can parse the type information and have knowledge of describing incoming data. 89*d4514f0bSApple OSS DistributionsFollowing is an example of how we can describe a kernel specific struct sample_disk_io_stats in buffer. 90*d4514f0bSApple OSS Distributions 91*d4514f0bSApple OSS Distributions struct sample_disk_io_stats { 92*d4514f0bSApple OSS Distributions uint64_t disk_reads_count; 93*d4514f0bSApple OSS Distributions uint64_t disk_reads_size; 94*d4514f0bSApple OSS Distributions uint64_t io_priority_count[4]; 95*d4514f0bSApple OSS Distributions uint64_t io_priority_size; 96*d4514f0bSApple OSS Distributions } __attribute__ ((packed)); 97*d4514f0bSApple OSS Distributions 98*d4514f0bSApple OSS Distributions 99*d4514f0bSApple OSS Distributions struct kcdata_subtype_descriptor disk_io_stats_def[] = { 100*d4514f0bSApple OSS Distributions {KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 0 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_count"}, 101*d4514f0bSApple OSS Distributions {KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 1 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_size"}, 102*d4514f0bSApple OSS Distributions {KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, 2 * sizeof(uint64_t), KCS_SUBTYPE_PACK_SIZE(4, sizeof(uint64_t)), "io_priority_count"}, 103*d4514f0bSApple OSS Distributions {KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, (2 + 4) * sizeof(uint64_t), sizeof(uint64_t), "io_priority_size"}, 104*d4514f0bSApple OSS Distributions }; 105*d4514f0bSApple OSS Distributions 106*d4514f0bSApple OSS DistributionsNow you can add this custom type definition into the buffer as 107*d4514f0bSApple OSS Distributions kcdata_add_type_definition(kcdata_p, KCTYPE_SAMPLE_DISK_IO_STATS, "sample_disk_io_stats", 108*d4514f0bSApple OSS Distributions &disk_io_stats_def[0], sizeof(disk_io_stats_def)/sizeof(struct kcdata_subtype_descriptor)); 109*d4514f0bSApple OSS Distributions 110