1 /* $NetBSD: t_basic.c,v 1.1 2010/03/31 19:14:30 pooka Exp $ */ 2 3 #include <sys/types.h> 4 #include <sys/mount.h> 5 #include <sys/module.h> 6 #include <sys/dirent.h> 7 #include <sys/sysctl.h> 8 9 #include <atf-c.h> 10 #include <err.h> 11 #include <errno.h> 12 #include <fcntl.h> 13 #include <stdio.h> 14 #include <unistd.h> 15 #include <string.h> 16 #include <stdlib.h> 17 18 #include <rump/rump.h> 19 #include <rump/rump_syscalls.h> 20 21 #include <miscfs/kernfs/kernfs.h> 22 23 #define USE_ATF 24 #include "../../h_macros.h" 25 26 #ifdef USE_ATF 27 ATF_TC(getdents); 28 ATF_TC_HEAD(getdents, tc) 29 { 30 31 atf_tc_set_md_var(tc, "descr", "kernfs directory contains files"); 32 } 33 #else 34 #define atf_tc_fail(...) errx(1, __VA_ARGS__) 35 #endif 36 37 #ifdef MODDIR 38 /* 39 * Try to load kernfs module (only on archs where ABIs match). 40 * This is slightly ... inconvenient currently. Let's try to improve 41 * it in the future. 42 * 43 * steps: 44 * 1) copy it into our working directory 45 * 2) rename symbols 46 * 3) lock & load 47 */ 48 static int 49 loadmodule(void) 50 { 51 modctl_load_t ml; 52 int error; 53 54 if (system("cp " MODDIR MODBASE " .") == -1) { 55 warn("failed to copy %s into pwd", MODDIR MODBASE); 56 return errno; 57 } 58 if (chmod(MODBASE, 0666) == -1) { 59 warn("chmod %s", MODBASE); 60 return errno; 61 } 62 if (system("make -f /usr/src/sys/rump/Makefile.rump RUMP_SYMREN=" 63 MODBASE) == -1) { 64 warn("objcopy failed"); 65 return errno; 66 } 67 68 if ((error = rump_pub_etfs_register(MODBASE, MODBASE, RUMP_ETFS_REG))) { 69 warn("rump etfs"); 70 return error; 71 } 72 73 memset(&ml, 0, sizeof(ml)); 74 ml.ml_filename = MODBASE; 75 if (rump_sys_modctl(MODCTL_LOAD, &ml) == -1) { 76 warn("module load"); 77 return errno; 78 } 79 80 return 0; 81 } 82 #endif 83 84 static void 85 mountkernfs(void) 86 { 87 88 rump_init(); 89 90 #ifdef MODDIR 91 if (loadmodule() != 0) { 92 /* failed? fallback to dlopen() .... some day */ 93 atf_tc_fail("could not load kernfs"); 94 } 95 #endif 96 97 if (rump_sys_mkdir("/kern", 0777) == -1) 98 atf_tc_fail_errno("mkdir /kern"); 99 if (rump_sys_mount(MOUNT_KERNFS, "/kern", 0, NULL, 0) == -1) 100 atf_tc_fail_errno("could not mount kernfs"); 101 } 102 103 #ifdef USE_ATF 104 ATF_TC_BODY(getdents, tc) 105 #else 106 int main(int argc, char *argv[]) 107 #endif 108 { 109 struct dirent *dent; 110 char buf[8192]; 111 int dfd; 112 113 mountkernfs(); 114 115 if ((dfd = rump_sys_open("/kern", O_RDONLY)) == -1) 116 atf_tc_fail_errno("can't open directory"); 117 if (rump_sys_getdents(dfd, buf, sizeof(buf)) == -1) 118 atf_tc_fail_errno("getdents"); 119 120 /* 121 * Check that we get the first three values (., .., boottime). 122 * Make more complete by autogenerating list from kernfs_vnops.c? 123 */ 124 dent = (void *)buf; 125 ATF_REQUIRE_STREQ(dent->d_name, "."); 126 dent = _DIRENT_NEXT(dent); 127 ATF_REQUIRE_STREQ(dent->d_name, ".."); 128 dent = _DIRENT_NEXT(dent); 129 ATF_REQUIRE_STREQ(dent->d_name, "boottime"); 130 131 /* done */ 132 } 133 134 #ifdef USE_ATF 135 ATF_TC(hostname); 136 ATF_TC_HEAD(hostname, tc) 137 { 138 139 atf_tc_set_md_var(tc, "descr", "/kern/hostname changes hostname"); 140 } 141 142 static char * 143 getthehost(void) 144 { 145 static char buf[8192]; 146 int mib[2]; 147 size_t blen; 148 149 mib[0] = CTL_KERN; 150 mib[1] = KERN_HOSTNAME; 151 blen = sizeof(buf); 152 if (rump_sys___sysctl(mib, 2, buf, &blen, NULL, 0) == -1) 153 atf_tc_fail_errno("sysctl gethostname"); 154 155 return buf; 156 } 157 158 #define NEWHOSTNAME "turboton roos-berg" 159 ATF_TC_BODY(hostname, tc) 160 { 161 char buf[8192]; 162 char *shost, *p; 163 int fd; 164 165 mountkernfs(); 166 if ((fd = rump_sys_open("/kern/hostname", O_RDWR)) == -1) 167 atf_tc_fail_errno("open hostname"); 168 169 /* check initial match */ 170 shost = getthehost(); 171 buf[0] = '\0'; 172 if (rump_sys_read(fd, buf, sizeof(buf)) == -1) 173 atf_tc_fail_errno("read hostname"); 174 p = strchr(buf, '\n'); 175 if (p) 176 *p = '\0'; 177 ATF_REQUIRE_STREQ_MSG(buf, shost, "initial hostname mismatch"); 178 179 /* check changing hostname works */ 180 if (rump_sys_pwrite(fd, NEWHOSTNAME, strlen(NEWHOSTNAME), 0) 181 != strlen(NEWHOSTNAME)) { 182 atf_tc_fail_errno("write new hostname"); 183 } 184 185 shost = getthehost(); 186 ATF_REQUIRE_STREQ_MSG(NEWHOSTNAME, shost, "modified hostname mismatch"); 187 188 /* done */ 189 } 190 191 ATF_TP_ADD_TCS(tp) 192 { 193 ATF_TP_ADD_TC(tp, hostname); 194 ATF_TP_ADD_TC(tp, getdents); 195 196 return atf_no_error(); 197 } 198 #endif 199