xref: /dflybsd-src/usr.bin/dfregress/kernel.c (revision a563ca70e68142ccf7f50a6f129665fd8cb66d98)
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/stat.h>
37*a563ca70SAlex Hornung #include <sys/ioctl.h>
38*a563ca70SAlex Hornung #include <sys/wait.h>
39*a563ca70SAlex Hornung 
40*a563ca70SAlex Hornung #include <errno.h>
41*a563ca70SAlex Hornung #include <fcntl.h>
42*a563ca70SAlex Hornung #include <signal.h>
43*a563ca70SAlex Hornung #include <stdio.h>
44*a563ca70SAlex Hornung #include <stdlib.h>
45*a563ca70SAlex Hornung #include <stdint.h>
46*a563ca70SAlex Hornung #include <string.h>
47*a563ca70SAlex Hornung #include <unistd.h>
48*a563ca70SAlex Hornung #include <pwd.h>
49*a563ca70SAlex Hornung 
50*a563ca70SAlex Hornung #include <err.h>
51*a563ca70SAlex Hornung 
52*a563ca70SAlex Hornung #include <libprop/proplib.h>
53*a563ca70SAlex Hornung 
54*a563ca70SAlex Hornung #include "parser.h"
55*a563ca70SAlex Hornung #include "testcase.h"
56*a563ca70SAlex Hornung #include "runlist.h"
57*a563ca70SAlex Hornung #include "config.h"
58*a563ca70SAlex Hornung #include "kernel.h"
59*a563ca70SAlex Hornung #include <dfregress.h>
60*a563ca70SAlex Hornung #include <sys/tbridge.h>
61*a563ca70SAlex Hornung 
62*a563ca70SAlex Hornung 
63*a563ca70SAlex Hornung int
64*a563ca70SAlex Hornung run_kernel(const char *kmod, prop_dictionary_t testcase)
65*a563ca70SAlex Hornung {
66*a563ca70SAlex Hornung 	char errmsg[1024];
67*a563ca70SAlex Hornung 	prop_dictionary_t tkcase = NULL;
68*a563ca70SAlex Hornung 	struct stat sb;
69*a563ca70SAlex Hornung 	int fd, r, kmod_id, ret = 0;
70*a563ca70SAlex Hornung 
71*a563ca70SAlex Hornung 	if ((r = stat("/dev/tbridge", &sb)) != 0) {
72*a563ca70SAlex Hornung 		sprintf(errmsg, "Kernel bridge module probably not loaded: %s",
73*a563ca70SAlex Hornung 		    strerror(errno));
74*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
75*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
76*a563ca70SAlex Hornung 
77*a563ca70SAlex Hornung 		return -1;
78*a563ca70SAlex Hornung 	}
79*a563ca70SAlex Hornung 
80*a563ca70SAlex Hornung 	/* First kldload the testcase */
81*a563ca70SAlex Hornung 	kmod_id = kldload(kmod);
82*a563ca70SAlex Hornung 	if (kmod_id < 0) {
83*a563ca70SAlex Hornung 		sprintf(errmsg, "Could not load testcase kmod %s: %s", kmod,
84*a563ca70SAlex Hornung 		    strerror(errno));
85*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
86*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
87*a563ca70SAlex Hornung 
88*a563ca70SAlex Hornung 		return -1;
89*a563ca70SAlex Hornung 	}
90*a563ca70SAlex Hornung 
91*a563ca70SAlex Hornung 	/* Open control device */
92*a563ca70SAlex Hornung 	fd = open("/dev/tbridge", O_RDWR);
93*a563ca70SAlex Hornung 	if (fd < 0) {
94*a563ca70SAlex Hornung 		sprintf(errmsg, "Could not open kernel bridge interface: %s",
95*a563ca70SAlex Hornung 		    strerror(errno));
96*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
97*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
98*a563ca70SAlex Hornung 
99*a563ca70SAlex Hornung 		ret = -1;
100*a563ca70SAlex Hornung 		goto unload;
101*a563ca70SAlex Hornung 	}
102*a563ca70SAlex Hornung 
103*a563ca70SAlex Hornung 	/* Then load the testcase description into the kernel */
104*a563ca70SAlex Hornung 	r = prop_dictionary_send_ioctl(testcase, fd, TBRIDGE_LOADTEST);
105*a563ca70SAlex Hornung 	if (r < 0) {
106*a563ca70SAlex Hornung 		sprintf(errmsg, "sending testcase to kernel failed: %s",
107*a563ca70SAlex Hornung 		    strerror(errno));
108*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
109*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
110*a563ca70SAlex Hornung 
111*a563ca70SAlex Hornung 		ret = -1;
112*a563ca70SAlex Hornung 		goto unload;
113*a563ca70SAlex Hornung 	}
114*a563ca70SAlex Hornung 
115*a563ca70SAlex Hornung 	/* Then wait for the result */
116*a563ca70SAlex Hornung 	r = prop_dictionary_recv_ioctl(fd, TBRIDGE_GETRESULT, &tkcase);
117*a563ca70SAlex Hornung 	if (r < 0) {
118*a563ca70SAlex Hornung 		sprintf(errmsg, "receiving test results from kernel failed: %s",
119*a563ca70SAlex Hornung 		    strerror(errno));
120*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
121*a563ca70SAlex Hornung 		testcase_set_result(testcase, RESULT_PREFAIL);
122*a563ca70SAlex Hornung 
123*a563ca70SAlex Hornung 		ret = -1;
124*a563ca70SAlex Hornung 		goto unload;
125*a563ca70SAlex Hornung 	}
126*a563ca70SAlex Hornung 
127*a563ca70SAlex Hornung 	/* Copy over the values of interest */
128*a563ca70SAlex Hornung 	testcase_set_result(testcase, testcase_get_result(tkcase));
129*a563ca70SAlex Hornung 	testcase_set_stdout_buf(testcase, testcase_get_stdout_buf(tkcase));
130*a563ca70SAlex Hornung 
131*a563ca70SAlex Hornung 	/* Release copy received from kernel */
132*a563ca70SAlex Hornung 	prop_object_release(tkcase);
133*a563ca70SAlex Hornung 
134*a563ca70SAlex Hornung unload:
135*a563ca70SAlex Hornung 	r = kldunload(kmod_id);
136*a563ca70SAlex Hornung 	if (r < 0) {
137*a563ca70SAlex Hornung 		sprintf(errmsg, "kldunload for %s failed: %s", kmod,
138*a563ca70SAlex Hornung 		    strerror(errno));
139*a563ca70SAlex Hornung 		testcase_set_sys_buf(testcase, errmsg);
140*a563ca70SAlex Hornung 
141*a563ca70SAlex Hornung 		ret = -1;
142*a563ca70SAlex Hornung 	}
143*a563ca70SAlex Hornung 
144*a563ca70SAlex Hornung 	return ret;
145*a563ca70SAlex Hornung }
146