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