1*8d741a5dSApple OSS Distributions #include <stdlib.h>
2*8d741a5dSApple OSS Distributions #include <sys/types.h>
3*8d741a5dSApple OSS Distributions #include <sys/sysctl.h>
4*8d741a5dSApple OSS Distributions #include <skywalk/os_skywalk_private.h>
5*8d741a5dSApple OSS Distributions
6*8d741a5dSApple OSS Distributions #include <darwintest.h>
7*8d741a5dSApple OSS Distributions
8*8d741a5dSApple OSS Distributions
9*8d741a5dSApple OSS Distributions /*
10*8d741a5dSApple OSS Distributions * Get all entries in the kernel oid, by calling sysctlbyname twice.
11*8d741a5dSApple OSS Distributions */
12*8d741a5dSApple OSS Distributions static int
sysctl_get_all(const char * oid_name,void ** buffer,size_t * len,void * newp,size_t newlen)13*8d741a5dSApple OSS Distributions sysctl_get_all(const char *oid_name, void **buffer, size_t *len, void *newp,
14*8d741a5dSApple OSS Distributions size_t newlen)
15*8d741a5dSApple OSS Distributions {
16*8d741a5dSApple OSS Distributions int ret;
17*8d741a5dSApple OSS Distributions
18*8d741a5dSApple OSS Distributions *buffer = NULL;
19*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret = sysctlbyname(oid_name, NULL, len, NULL, 0),
20*8d741a5dSApple OSS Distributions NULL);
21*8d741a5dSApple OSS Distributions if (*len == 0) {
22*8d741a5dSApple OSS Distributions /* There's no entry in this oid. */
23*8d741a5dSApple OSS Distributions *buffer = NULL;
24*8d741a5dSApple OSS Distributions return 0;
25*8d741a5dSApple OSS Distributions }
26*8d741a5dSApple OSS Distributions T_EXPECT_NOTNULL(*buffer = malloc(*len), NULL);
27*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret = sysctlbyname(oid_name, *buffer, len, newp,
28*8d741a5dSApple OSS Distributions newlen), NULL);
29*8d741a5dSApple OSS Distributions if (ret != 0) {
30*8d741a5dSApple OSS Distributions if (errno == ENOMEM) {
31*8d741a5dSApple OSS Distributions free(*buffer);
32*8d741a5dSApple OSS Distributions *buffer = NULL;
33*8d741a5dSApple OSS Distributions }
34*8d741a5dSApple OSS Distributions }
35*8d741a5dSApple OSS Distributions return 0;
36*8d741a5dSApple OSS Distributions }
37*8d741a5dSApple OSS Distributions
38*8d741a5dSApple OSS Distributions /*
39*8d741a5dSApple OSS Distributions * Get the given amount of data (*len) from the kernel oid, which has total_size
40*8d741a5dSApple OSS Distributions * amount of data.
41*8d741a5dSApple OSS Distributions */
42*8d741a5dSApple OSS Distributions static int
sysctl_get(const char * oid_name,void ** buffer,size_t * len,size_t total_size)43*8d741a5dSApple OSS Distributions sysctl_get(const char *oid_name, void **buffer, size_t *len, size_t total_size)
44*8d741a5dSApple OSS Distributions {
45*8d741a5dSApple OSS Distributions int ret;
46*8d741a5dSApple OSS Distributions
47*8d741a5dSApple OSS Distributions ret = sysctlbyname(oid_name, *buffer, len, NULL, 0);
48*8d741a5dSApple OSS Distributions /*
49*8d741a5dSApple OSS Distributions * If we ask for less than what the kernel has, sysctlbyname for
50*8d741a5dSApple OSS Distributions * SK_STATS_ARENA, SK_STATS_REGION, and SK_STATS_CACHE will return -1
51*8d741a5dSApple OSS Distributions * and set errno to ENOMEM.
52*8d741a5dSApple OSS Distributions * If we ask for more than what the kernel has, sysctlbyname for the
53*8d741a5dSApple OSS Distributions * aforementioned oids will return 0 and set the *len to the size
54*8d741a5dSApple OSS Distributions * mantinated by the kernel.
55*8d741a5dSApple OSS Distributions */
56*8d741a5dSApple OSS Distributions if (*len < total_size) {
57*8d741a5dSApple OSS Distributions T_ASSERT_EQ(ret, -1, NULL);
58*8d741a5dSApple OSS Distributions T_ASSERT_EQ(errno, ENOMEM, NULL);
59*8d741a5dSApple OSS Distributions } else {
60*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret, NULL);
61*8d741a5dSApple OSS Distributions T_ASSERT_EQ(*len, total_size, NULL);
62*8d741a5dSApple OSS Distributions }
63*8d741a5dSApple OSS Distributions
64*8d741a5dSApple OSS Distributions return ret;
65*8d741a5dSApple OSS Distributions }
66*8d741a5dSApple OSS Distributions
67*8d741a5dSApple OSS Distributions T_DECL(skmem_arena_sysctl_get_all, "Get all entries in kern.skywalk.stats.arena")
68*8d741a5dSApple OSS Distributions {
69*8d741a5dSApple OSS Distributions void *buffer;
70*8d741a5dSApple OSS Distributions size_t len;
71*8d741a5dSApple OSS Distributions
72*8d741a5dSApple OSS Distributions (void) sysctl_get_all(SK_STATS_ARENA, &buffer, &len, NULL, 0);
73*8d741a5dSApple OSS Distributions }
74*8d741a5dSApple OSS Distributions
75*8d741a5dSApple OSS Distributions T_DECL(skmem_region_sysctl_get_all, "Get all entries in kern.skywalk.stats.region")
76*8d741a5dSApple OSS Distributions {
77*8d741a5dSApple OSS Distributions void *buffer;
78*8d741a5dSApple OSS Distributions size_t len;
79*8d741a5dSApple OSS Distributions
80*8d741a5dSApple OSS Distributions (void) sysctl_get_all(SK_STATS_REGION, &buffer, &len, NULL, 0);
81*8d741a5dSApple OSS Distributions }
82*8d741a5dSApple OSS Distributions
83*8d741a5dSApple OSS Distributions T_DECL(skmem_cache_sysctl_get_all, "Get all entries in kern.skywalk.stats.cache")
84*8d741a5dSApple OSS Distributions {
85*8d741a5dSApple OSS Distributions void *buffer;
86*8d741a5dSApple OSS Distributions size_t len;
87*8d741a5dSApple OSS Distributions
88*8d741a5dSApple OSS Distributions (void) sysctl_get_all(SK_STATS_CACHE, &buffer, &len, NULL, 0);
89*8d741a5dSApple OSS Distributions }
90*8d741a5dSApple OSS Distributions
91*8d741a5dSApple OSS Distributions T_DECL(skmem_arena_sysctl_get_single, "Get a single entry in kern.skywalk.stats.arena")
92*8d741a5dSApple OSS Distributions {
93*8d741a5dSApple OSS Distributions void *buffer;
94*8d741a5dSApple OSS Distributions size_t len;
95*8d741a5dSApple OSS Distributions size_t total_size;
96*8d741a5dSApple OSS Distributions
97*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_ARENA, NULL, &total_size,
98*8d741a5dSApple OSS Distributions NULL, 0), NULL);
99*8d741a5dSApple OSS Distributions len = sizeof(struct sk_stats_arena);
100*8d741a5dSApple OSS Distributions buffer = malloc(len);
101*8d741a5dSApple OSS Distributions
102*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_ARENA, total_size);
103*8d741a5dSApple OSS Distributions T_LOG("Size of single entry: %zu\n", len);
104*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_ARENA, &buffer, &len, total_size);
105*8d741a5dSApple OSS Distributions }
106*8d741a5dSApple OSS Distributions
107*8d741a5dSApple OSS Distributions T_DECL(skmem_region_sysctl_get_single, "Get a single entry in kern.skywalk.stats.region")
108*8d741a5dSApple OSS Distributions {
109*8d741a5dSApple OSS Distributions void *buffer;
110*8d741a5dSApple OSS Distributions size_t len;
111*8d741a5dSApple OSS Distributions size_t total_size;
112*8d741a5dSApple OSS Distributions
113*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_REGION, NULL, &total_size,
114*8d741a5dSApple OSS Distributions NULL, 0), NULL);
115*8d741a5dSApple OSS Distributions len = sizeof(struct sk_stats_region);
116*8d741a5dSApple OSS Distributions buffer = malloc(len);
117*8d741a5dSApple OSS Distributions
118*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_REGION, total_size);
119*8d741a5dSApple OSS Distributions T_LOG("Size of single entry: %zu\n", len);
120*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_REGION, &buffer, &len, total_size);
121*8d741a5dSApple OSS Distributions }
122*8d741a5dSApple OSS Distributions
123*8d741a5dSApple OSS Distributions T_DECL(skmem_cache_sysctl_get_single, "Get a single entry in kern.skywalk.stats.cache")
124*8d741a5dSApple OSS Distributions {
125*8d741a5dSApple OSS Distributions void *buffer;
126*8d741a5dSApple OSS Distributions size_t len;
127*8d741a5dSApple OSS Distributions size_t total_size;
128*8d741a5dSApple OSS Distributions
129*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_CACHE, NULL, &total_size,
130*8d741a5dSApple OSS Distributions NULL, 0), NULL);
131*8d741a5dSApple OSS Distributions len = sizeof(struct sk_stats_cache);
132*8d741a5dSApple OSS Distributions buffer = malloc(len);
133*8d741a5dSApple OSS Distributions
134*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_CACHE, total_size);
135*8d741a5dSApple OSS Distributions T_LOG("Size of single entry: %zu\n", len);
136*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_CACHE, &buffer, &len, total_size);
137*8d741a5dSApple OSS Distributions }
138*8d741a5dSApple OSS Distributions
139*8d741a5dSApple OSS Distributions T_DECL(skmem_arena_sysctl_get_over, "Ask for more entries than kern.skywalk.stats.arena")
140*8d741a5dSApple OSS Distributions {
141*8d741a5dSApple OSS Distributions void *buffer;
142*8d741a5dSApple OSS Distributions size_t len;
143*8d741a5dSApple OSS Distributions size_t total_size;
144*8d741a5dSApple OSS Distributions
145*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_ARENA, NULL, &total_size,
146*8d741a5dSApple OSS Distributions NULL, 0), NULL);
147*8d741a5dSApple OSS Distributions len = total_size + sizeof(struct sk_stats_arena);
148*8d741a5dSApple OSS Distributions buffer = malloc(len);
149*8d741a5dSApple OSS Distributions
150*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_ARENA, total_size);
151*8d741a5dSApple OSS Distributions T_LOG("Total size + single entry: %zu\n", len);
152*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_ARENA, &buffer, &len, total_size);
153*8d741a5dSApple OSS Distributions }
154*8d741a5dSApple OSS Distributions
155*8d741a5dSApple OSS Distributions T_DECL(skmem_region_sysctl_get_over, "Ask for more entries than kern.skywalk.stats.region")
156*8d741a5dSApple OSS Distributions {
157*8d741a5dSApple OSS Distributions void *buffer;
158*8d741a5dSApple OSS Distributions size_t len;
159*8d741a5dSApple OSS Distributions size_t total_size;
160*8d741a5dSApple OSS Distributions
161*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_REGION, NULL, &total_size,
162*8d741a5dSApple OSS Distributions NULL, 0), NULL);
163*8d741a5dSApple OSS Distributions len = total_size + sizeof(struct sk_stats_region);
164*8d741a5dSApple OSS Distributions buffer = malloc(len);
165*8d741a5dSApple OSS Distributions
166*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_REGION, total_size);
167*8d741a5dSApple OSS Distributions T_LOG("Total size + single entry: %zu\n", len);
168*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_REGION, &buffer, &len, total_size);
169*8d741a5dSApple OSS Distributions }
170*8d741a5dSApple OSS Distributions
171*8d741a5dSApple OSS Distributions T_DECL(skmem_cache_sysctl_get_over, "Ask for more entries than kern.skywalk.stats.cache")
172*8d741a5dSApple OSS Distributions {
173*8d741a5dSApple OSS Distributions void *buffer;
174*8d741a5dSApple OSS Distributions size_t len;
175*8d741a5dSApple OSS Distributions size_t total_size;
176*8d741a5dSApple OSS Distributions
177*8d741a5dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname(SK_STATS_CACHE, NULL, &total_size,
178*8d741a5dSApple OSS Distributions NULL, 0), NULL);
179*8d741a5dSApple OSS Distributions len = total_size + sizeof(struct sk_stats_cache);
180*8d741a5dSApple OSS Distributions buffer = malloc(len);
181*8d741a5dSApple OSS Distributions
182*8d741a5dSApple OSS Distributions T_LOG("Total size of %s: %zu\n", SK_STATS_CACHE, total_size);
183*8d741a5dSApple OSS Distributions T_LOG("Total size + single entry: %zu\n", len);
184*8d741a5dSApple OSS Distributions (void) sysctl_get(SK_STATS_CACHE, &buffer, &len, total_size);
185*8d741a5dSApple OSS Distributions }
186