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