xref: /dflybsd-src/usr.bin/dfregress/kernel.c (revision eb403c9356ce5a2d494a31e006698fd95cf594b1)
1*a563ca70SAlex Hornung  /*
2*a563ca70SAlex Hornung  * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3*a563ca70SAlex Hornung  * All rights reserved.
4*a563ca70SAlex Hornung  *
5*a563ca70SAlex Hornung  * Redistribution and use in source and binary forms, with or without
6*a563ca70SAlex Hornung  * modification, are permitted provided that the following conditions
7*a563ca70SAlex Hornung  * are met:
8*a563ca70SAlex Hornung  *
9*a563ca70SAlex Hornung  * 1. Redistributions of source code must retain the above copyright
10*a563ca70SAlex Hornung  *    notice, this list of conditions and the following disclaimer.
11*a563ca70SAlex Hornung  * 2. Redistributions in binary form must reproduce the above copyright
12*a563ca70SAlex Hornung  *    notice, this list of conditions and the following disclaimer in
13*a563ca70SAlex Hornung  *    the documentation and/or other materials provided with the
14*a563ca70SAlex Hornung  *    distribution.
15*a563ca70SAlex Hornung  *
16*a563ca70SAlex Hornung  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17*a563ca70SAlex Hornung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18*a563ca70SAlex Hornung  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19*a563ca70SAlex Hornung  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
20*a563ca70SAlex Hornung  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21*a563ca70SAlex Hornung  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22*a563ca70SAlex Hornung  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23*a563ca70SAlex Hornung  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24*a563ca70SAlex Hornung  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25*a563ca70SAlex Hornung  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26*a563ca70SAlex Hornung  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*a563ca70SAlex Hornung  * SUCH DAMAGE.
28*a563ca70SAlex Hornung  */
29*a563ca70SAlex Hornung 
30*a563ca70SAlex Hornung #include <sys/resource.h>
31*a563ca70SAlex Hornung #include <sys/time.h>
32*a563ca70SAlex Hornung #include <sys/types.h>
33*a563ca70SAlex Hornung #include <sys/param.h>
34*a563ca70SAlex Hornung #include <sys/stat.h>
35*a563ca70SAlex Hornung #include <sys/linker.h>
36*a563ca70SAlex Hornung #include <sys/ioctl.h>
37*a563ca70SAlex Hornung #include <sys/wait.h>
38*a563ca70SAlex Hornung 
39*a563ca70SAlex Hornung #include <errno.h>
40*a563ca70SAlex Hornung #include <fcntl.h>
41*a563ca70SAlex Hornung #include <signal.h>
42*a563ca70SAlex Hornung #include <stdio.h>
43*a563ca70SAlex Hornung #include <stdlib.h>
44*a563ca70SAlex Hornung #include <stdint.h>
45*a563ca70SAlex Hornung #include <string.h>
46*a563ca70SAlex Hornung #include <unistd.h>
47*a563ca70SAlex Hornung #include <pwd.h>
48*a563ca70SAlex Hornung 
49*a563ca70SAlex Hornung #include <err.h>
50*a563ca70SAlex Hornung 
51*a563ca70SAlex Hornung #include <libprop/proplib.h>
52*a563ca70SAlex Hornung 
53*a563ca70SAlex Hornung #include "parser.h"
54*a563ca70SAlex Hornung #include "testcase.h"
55*a563ca70SAlex Hornung #include "runlist.h"
56*a563ca70SAlex Hornung #include "config.h"
57*a563ca70SAlex Hornung #include "kernel.h"
58*a563ca70SAlex Hornung #include <dfregress.h>
59*a563ca70SAlex Hornung #include <sys/tbridge.h>
60*a563ca70SAlex Hornung 
61*a563ca70SAlex Hornung 
62*a563ca70SAlex Hornung int
run_kernel(const char * kmod,prop_dictionary_t testcase)63*a563ca70SAlex Hornung run_kernel(const char *kmod, prop_dictionary_t testcase)
64*a563ca70SAlex Hornung {
65*a563ca70SAlex Hornung 	char errmsg[1024];
66*a563ca70SAlex Hornung 	prop_dictionary_t tkcase = NULL;
67*a563ca70SAlex Hornung 	struct stat sb;
68*a563ca70SAlex Hornung 	int fd, r, kmod_id, ret = 0;
69*a563ca70SAlex Hornung 
70*a563ca70SAlex Hornung 	if ((r = stat("/dev/tbridge", &sb)) != 0) {
71*a563ca70SAlex Hornung 		sprintf(errmsg, "Kernel bridge module probably not loaded: %s",
72*a563ca70SAlex Hornung 		    strerror(errno));
73*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
74*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
75*a563ca70SAlex Hornung 
76*a563ca70SAlex Hornung 		return -1;
77*a563ca70SAlex Hornung 	}
78*a563ca70SAlex Hornung 
79*a563ca70SAlex Hornung 	/* First kldload the testcase */
80*a563ca70SAlex Hornung 	kmod_id = kldload(kmod);
81*a563ca70SAlex Hornung 	if (kmod_id < 0) {
82*a563ca70SAlex Hornung 		sprintf(errmsg, "Could not load testcase kmod %s: %s", kmod,
83*a563ca70SAlex Hornung 		    strerror(errno));
84*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
85*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
86*a563ca70SAlex Hornung 
87*a563ca70SAlex Hornung 		return -1;
88*a563ca70SAlex Hornung 	}
89*a563ca70SAlex Hornung 
90*a563ca70SAlex Hornung 	/* Open control device */
91*a563ca70SAlex Hornung 	fd = open("/dev/tbridge", O_RDWR);
92*a563ca70SAlex Hornung 	if (fd < 0) {
93*a563ca70SAlex Hornung 		sprintf(errmsg, "Could not open kernel bridge interface: %s",
94*a563ca70SAlex Hornung 		    strerror(errno));
95*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
96*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
97*a563ca70SAlex Hornung 
98*a563ca70SAlex Hornung 		ret = -1;
99*a563ca70SAlex Hornung 		goto unload;
100*a563ca70SAlex Hornung 	}
101*a563ca70SAlex Hornung 
102*a563ca70SAlex Hornung 	/* Then load the testcase description into the kernel */
103*a563ca70SAlex Hornung 	r = prop_dictionary_send_ioctl(testcase, fd, TBRIDGE_LOADTEST);
104*a563ca70SAlex Hornung 	if (r < 0) {
105*a563ca70SAlex Hornung 		sprintf(errmsg, "sending testcase to kernel failed: %s",
106*a563ca70SAlex Hornung 		    strerror(errno));
107*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
108*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
109*a563ca70SAlex Hornung 
110*a563ca70SAlex Hornung 		ret = -1;
111*a563ca70SAlex Hornung 		goto unload;
112*a563ca70SAlex Hornung 	}
113*a563ca70SAlex Hornung 
114*a563ca70SAlex Hornung 	/* Then wait for the result */
115*a563ca70SAlex Hornung 	r = prop_dictionary_recv_ioctl(fd, TBRIDGE_GETRESULT, &tkcase);
116*a563ca70SAlex Hornung 	if (r < 0) {
117*a563ca70SAlex Hornung 		sprintf(errmsg, "receiving test results from kernel failed: %s",
118*a563ca70SAlex Hornung 		    strerror(errno));
119*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
120*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
121*a563ca70SAlex Hornung 
122*a563ca70SAlex Hornung 		ret = -1;
123*a563ca70SAlex Hornung 		goto unload;
124*a563ca70SAlex Hornung 	}
125*a563ca70SAlex Hornung 
126*a563ca70SAlex Hornung 	/* Copy over the values of interest */
127*a563ca70SAlex Hornung 	testcase_set_result(testcase, testcase_get_result(tkcase));
128*a563ca70SAlex Hornung 	testcase_set_stdout_buf(testcase, testcase_get_stdout_buf(tkcase));
129*a563ca70SAlex Hornung 
130*a563ca70SAlex Hornung 	/* Release copy received from kernel */
131*a563ca70SAlex Hornung 	prop_object_release(tkcase);
132*a563ca70SAlex Hornung 
133*a563ca70SAlex Hornung unload:
134*a563ca70SAlex Hornung 	r = kldunload(kmod_id);
135*a563ca70SAlex Hornung 	if (r < 0) {
136*a563ca70SAlex Hornung 		sprintf(errmsg, "kldunload for %s failed: %s", kmod,
137*a563ca70SAlex Hornung 		    strerror(errno));
138*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
139*a563ca70SAlex Hornung 
140*a563ca70SAlex Hornung 		ret = -1;
141*a563ca70SAlex Hornung 	}
142*a563ca70SAlex Hornung 
143*a563ca70SAlex Hornung 	return ret;
144*a563ca70SAlex Hornung }
145