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