master
c 391 lines 9.31 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 sysfs.c
8
9 Abstract:
10
11 This file contains tests for the sysfs file system.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <dirent.h>
22 #include <fcntl.h>
23
24 #define LXT_NAME "SysFs"
25
26 #define SYSFS_MNT "/sys"
27
28 int SysFsClassNet(PLXT_ARGS Args);
29
30 int SysFsDevicesSystemCpu(PLXT_ARGS Args);
31
32 int SysFsDevicesVirtualNet(PLXT_ARGS Args);
33
34 int SysFsKernelDebug(PLXT_ARGS Args);
35
36 int SysFsRoot(PLXT_ARGS Args);
37
38 //
39 // Global constants
40 //
41
42 static const LXT_VARIATION g_LxtVariations[] = {
43 {"SysFs - /sys root", SysFsRoot},
44 {"SysFs - /sys/class/net", SysFsClassNet},
45 {"SysFs - /sys/devices/virtual/net", SysFsDevicesVirtualNet},
46 {"SysFs - /sys/devices/system/cpu", SysFsDevicesSystemCpu},
47 {"SysFs - /sys/kernel/debug", SysFsKernelDebug},
48 };
49
50 static const LXT_CHILD_INFO g_SysFsRootChildren[] = {
51 {"block", DT_DIR},
52 {"bus", DT_DIR},
53 {"class", DT_DIR},
54 {"dev", DT_DIR},
55 {"devices", DT_DIR},
56 {"firmware", DT_DIR},
57 {"fs", DT_DIR},
58 {"kernel", DT_DIR},
59 {"module", DT_DIR},
60 {"power", DT_DIR}};
61
62 static const LXT_CHILD_INFO g_SysFsClassNetChildren[] = {{"lo", DT_LNK}};
63
64 static const LXT_CHILD_INFO g_SysFsDevicesVirtualNetChildren[] = {{"lo", DT_DIR}};
65
66 static const LXT_CHILD_INFO g_SysFsDevicesVirtualNetDeviceChildren[] = {
67 {"address", DT_REG}, {"ifindex", DT_REG}, {"flags", DT_REG}, {"mtu", DT_REG}};
68
69 static const LXT_CHILD_INFO g_SysFsDevicesSystemCpuChildren[] = {{"cpu0", DT_DIR}, {"present", DT_REG}, {"possible", DT_REG}};
70
71 static const LXT_CHILD_INFO g_SysFsDevicesSystemCpuDeviceChildren[] = {{"topology", DT_DIR}};
72
73 static const LXT_CHILD_INFO g_SysFsDevicesSystemCpuDeviceCpuFreqChildren[] = {{"cpuinfo_max_freq", DT_REG}, {"scaling_max_freq", DT_REG}};
74
75 static const LXT_CHILD_INFO g_SysFsDevicesSystemCpuDeviceTopologyChildren[] = {
76 {"core_id", DT_REG},
77 {"core_siblings", DT_REG},
78 {"core_siblings_list", DT_REG},
79 {"physical_package_id", DT_REG},
80 {"thread_siblings", DT_REG},
81 {"thread_siblings_list", DT_REG}};
82
83 static const LXT_CHILD_INFO g_SysFsKernelDebugChildren[] = {{"tracing", DT_DIR}, {"wakeup_sources", DT_REG}};
84
85 static const LXT_CHILD_INFO g_SysFsKernelDebugTracingChildren[] = {{"trace_marker", DT_REG}};
86
87 static const LXT_CHILD_INFO g_SysFsKernelIp4Children[] = {
88 {"tcp_rmem_min", DT_REG}, {"tcp_rmem_def", DT_REG}, {"tcp_rmem_max", DT_REG}, {"tcp_wmem_min", DT_REG}, {"tcp_wmem_def", DT_REG}, {"tcp_wmem_max", DT_REG}};
89
90 static const LXT_CHILD_INFO g_SysFsModuleLowmemorykillerChildren[] = {{"parameters", DT_DIR}};
91
92 static const LXT_CHILD_INFO g_SysFsModuleLowmemorykillerParametersChildren[] = {{"adj", DT_REG}, {"minfree", DT_REG}};
93
94 static const LXT_CHILD_INFO g_SysFsPowerChildren[] = {{"autosleep", DT_REG}};
95
96 int SysfsTestEntry(int Argc, char* Argv[])
97
98 /*++
99
100 Routine Description:
101
102 This routine is the main entry point for the procfs tests.
103
104 Arguments:
105
106 Argc - Supplies the number of command line arguments.
107
108 Argv - Supplies the command line arguments.
109
110 Return Value:
111
112 Returns 0 on success, -1 on failure.
113
114 --*/
115
116 {
117
118 LXT_ARGS Args;
119 int Result;
120
121 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
122 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
123
124 ErrorExit:
125 LxtUninitialize();
126 return !LXT_SUCCESS(Result);
127 }
128
129 int SysFsClassNet(PLXT_ARGS Args)
130
131 /*++
132
133 Description:
134
135 This routine tests the sysfs network class directory (/sys/class/net).
136
137 Arguments:
138
139 Args - Supplies the command line arguments.
140
141 Return Value:
142
143 Returns 0 on success, -1 on failure.
144
145 --*/
146
147 {
148
149 int Result;
150
151 //
152 // This test may fail on real Linux because the contents are not
153 // guaranteed to be the same on every system.
154 //
155
156 LxtCheckResult(LxtCheckDirectoryContents(SYSFS_MNT "/class/net", g_SysFsClassNetChildren, LXT_COUNT_OF(g_SysFsClassNetChildren)));
157
158 LxtCheckResult(LxtCheckLinkTarget(SYSFS_MNT "/class/net/lo", "../../devices/virtual/net/lo"));
159
160 ErrorExit:
161 return Result;
162 }
163
164 int SysFsDevicesSystemCpu(PLXT_ARGS Args)
165
166 /*++
167
168 Description:
169
170 This routine tests the cpu device directory (/sys/devices/system/cpu).
171
172 Arguments:
173
174 Args - Supplies the command line arguments.
175
176 Return Value:
177
178 Returns 0 on success, -1 on failure.
179
180 --*/
181
182 {
183
184 char Buffer[100];
185 char ChildPath[256];
186 int CpuInfoProcessorCount;
187 ssize_t BytesRead;
188 int Fd;
189 char* Line;
190 int ProcessorIndex;
191 int ProcessorCount;
192 int Result;
193 size_t Size;
194 FILE* Stream;
195
196 //
197 // First check always present contents.
198 //
199
200 Fd = 0;
201 Stream = NULL;
202 Line = NULL;
203 LxtCheckResult(LxtCheckDirectoryContents(
204 SYSFS_MNT "/devices/system/cpu", g_SysFsDevicesSystemCpuChildren, LXT_COUNT_OF(g_SysFsDevicesSystemCpuChildren)));
205
206 //
207 // Determine the number of CPUs.
208 //
209
210 LxtCheckErrno(Fd = open(SYSFS_MNT "/devices/system/cpu/present", O_RDONLY));
211 LxtCheckErrno(BytesRead = read(Fd, Buffer, sizeof(Buffer)));
212 LxtCheckEqual(Buffer[0], '0', "%c");
213 ProcessorCount = 1;
214 if (Buffer[1] != '\n')
215 {
216 LxtCheckEqual(Buffer[1], '-', "%c");
217 ProcessorCount = strtol(&Buffer[2], NULL, 10);
218 LxtCheckGreater(ProcessorCount, 0, "%d");
219 ProcessorCount += 1;
220 }
221
222 LxtCheckErrnoZeroSuccess(close(Fd));
223
224 //
225 // Check CPU directory for each CPU.
226 //
227
228 for (ProcessorIndex = 0; ProcessorIndex < ProcessorCount; ProcessorIndex += 1)
229 {
230
231 snprintf(ChildPath, sizeof(ChildPath), SYSFS_MNT "/devices/system/cpu/cpu%d", ProcessorIndex);
232
233 LxtCheckResult(LxtCheckDirectoryContents(
234 ChildPath, g_SysFsDevicesSystemCpuDeviceChildren, LXT_COUNT_OF(g_SysFsDevicesSystemCpuDeviceChildren)));
235
236 snprintf(ChildPath, sizeof(ChildPath), SYSFS_MNT "/devices/system/cpu/cpu%d/topology", ProcessorIndex);
237
238 LxtCheckResult(LxtCheckDirectoryContents(
239 ChildPath, g_SysFsDevicesSystemCpuDeviceTopologyChildren, LXT_COUNT_OF(g_SysFsDevicesSystemCpuDeviceTopologyChildren)));
240 }
241
242 //
243 // No more directories should exist.
244 //
245
246 snprintf(ChildPath, sizeof(ChildPath), SYSFS_MNT "/devices/system/cpu/cpu%d", ProcessorCount);
247
248 LxtCheckErrnoFailure(open(ChildPath, O_RDONLY | O_DIRECTORY), ENOENT);
249
250 //
251 // Check if the number of CPUs matches /proc/cpuinfo.
252 //
253
254 Stream = fopen("/proc/cpuinfo", "r");
255 if (Stream == NULL)
256 {
257 LxtLogError("fopen failed, errno: %d", errno);
258 Result = LXT_RESULT_FAILURE;
259 goto ErrorExit;
260 }
261
262 Size = 0;
263 CpuInfoProcessorCount = 0;
264 while (getline(&Line, &Size, Stream) != -1)
265 {
266 if (strstr(Line, "processor") == Line)
267 {
268 CpuInfoProcessorCount += 1;
269 }
270 }
271
272 LxtCheckEqual(ProcessorCount, CpuInfoProcessorCount, "%d");
273
274 ErrorExit:
275 if (Line != NULL)
276 {
277 free(Line);
278 }
279
280 if (Stream != NULL)
281 {
282 fclose(Stream);
283 }
284
285 if (Fd > 0)
286 {
287 close(Fd);
288 }
289
290 return Result;
291 }
292
293 int SysFsDevicesVirtualNet(PLXT_ARGS Args)
294
295 /*++
296
297 Description:
298
299 This routine tests the sysfs network device directory
300 (/sys/devices/virtual/net).
301
302 Arguments:
303
304 Args - Supplies the command line arguments.
305
306 Return Value:
307
308 Returns 0 on success, -1 on failure.
309
310 --*/
311
312 {
313
314 int Result;
315
316 //
317 // This test may fail on real Linux because the contents are not
318 // guaranteed to be the same on every system.
319 //
320
321 LxtCheckResult(LxtCheckDirectoryContents(
322 SYSFS_MNT "/devices/virtual/net", g_SysFsDevicesVirtualNetChildren, LXT_COUNT_OF(g_SysFsDevicesVirtualNetChildren)));
323
324 LxtCheckResult(LxtCheckDirectoryContents(
325 SYSFS_MNT "/devices/virtual/net/lo", g_SysFsDevicesVirtualNetDeviceChildren, LXT_COUNT_OF(g_SysFsDevicesVirtualNetDeviceChildren)));
326
327 ErrorExit:
328 return Result;
329 }
330
331 int SysFsKernelDebug(PLXT_ARGS Args)
332
333 /*++
334
335 Description:
336
337 This routine tests the debug directory (/sys/kernel/debug).
338
339 Arguments:
340
341 Args - Supplies the command line arguments.
342
343 Return Value:
344
345 Returns 0 on success, -1 on failure.
346
347 --*/
348
349 {
350
351 int Result;
352
353 LxtCheckResult(LxtCheckDirectoryContents(SYSFS_MNT "/kernel/debug", g_SysFsKernelDebugChildren, LXT_COUNT_OF(g_SysFsKernelDebugChildren)));
354
355 LxtCheckResult(LxtCheckDirectoryContents(
356 SYSFS_MNT "/kernel/debug/tracing", g_SysFsKernelDebugTracingChildren, LXT_COUNT_OF(g_SysFsKernelDebugTracingChildren)));
357
358 LxtCheckResult(LxtCheckWrite(SYSFS_MNT "/kernel/debug/tracing/trace_marker", "bogus"));
359
360 ErrorExit:
361 return Result;
362 }
363
364 int SysFsRoot(PLXT_ARGS Args)
365
366 /*++
367
368 Description:
369
370 This routine tests the sysfs root directory (/sys).
371
372 Arguments:
373
374 Args - Supplies the command line arguments.
375
376 Return Value:
377
378 Returns 0 on success, -1 on failure.
379
380 --*/
381
382 {
383
384 int Result;
385
386 LxtCheckResult(LxtCheckStat(SYSFS_MNT, 1, DT_DIR));
387 LxtCheckResult(LxtCheckDirectoryContents(SYSFS_MNT, g_SysFsRootChildren, LXT_COUNT_OF(g_SysFsRootChildren)));
388
389 ErrorExit:
390 return Result;
391 }