1 1.12 rin /* $NetBSD: t_etfs.c,v 1.12 2023/08/03 03:21:56 rin Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * Redistribution and use in source and binary forms, with or without 8 1.1 pooka * modification, are permitted provided that the following conditions 9 1.1 pooka * are met: 10 1.1 pooka * 1. Redistributions of source code must retain the above copyright 11 1.1 pooka * notice, this list of conditions and the following disclaimer. 12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 pooka * notice, this list of conditions and the following disclaimer in the 14 1.1 pooka * documentation and/or other materials provided with the distribution. 15 1.1 pooka * 16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 1.1 pooka * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 1.1 pooka * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 1.1 pooka * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 pooka * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 1.1 pooka * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 1.1 pooka * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 1.1 pooka * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 1.1 pooka * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 1.1 pooka * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 pooka */ 29 1.1 pooka 30 1.1 pooka #include <sys/types.h> 31 1.1 pooka #include <sys/mount.h> 32 1.1 pooka #include <sys/sysctl.h> 33 1.1 pooka 34 1.1 pooka #include <rump/rump.h> 35 1.1 pooka #include <rump/rump_syscalls.h> 36 1.1 pooka 37 1.1 pooka #include <atf-c.h> 38 1.1 pooka #include <fcntl.h> 39 1.1 pooka #include <stdio.h> 40 1.1 pooka #include <stdlib.h> 41 1.1 pooka #include <unistd.h> 42 1.1 pooka 43 1.11 christos #include "h_macros.h" 44 1.1 pooka 45 1.1 pooka ATF_TC(reregister_reg); 46 1.1 pooka ATF_TC_HEAD(reregister_reg, tc) 47 1.1 pooka { 48 1.1 pooka 49 1.1 pooka atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register " 50 1.1 pooka "for a regular file"); 51 1.1 pooka } 52 1.1 pooka 53 1.1 pooka #define TESTSTR1 "hi, it's me again!" 54 1.1 pooka #define TESTSTR1SZ (sizeof(TESTSTR1)-1) 55 1.1 pooka 56 1.1 pooka #define TESTSTR2 "what about the old vulcan proverb?" 57 1.1 pooka #define TESTSTR2SZ (sizeof(TESTSTR2)-1) 58 1.1 pooka 59 1.1 pooka #define TESTPATH1 "/trip/to/the/moon" 60 1.1 pooka #define TESTPATH2 "/but/not/the/dark/size" 61 1.1 pooka ATF_TC_BODY(reregister_reg, tc) 62 1.1 pooka { 63 1.1 pooka char buf[1024]; 64 1.1 pooka int localfd, etcfd; 65 1.1 pooka ssize_t n; 66 1.1 pooka int tfd; 67 1.1 pooka 68 1.1 pooka etcfd = open("/etc/passwd", O_RDONLY); 69 1.1 pooka ATF_REQUIRE(etcfd != -1); 70 1.1 pooka 71 1.1 pooka localfd = open("./testfile", O_RDWR | O_CREAT, 0666); 72 1.1 pooka ATF_REQUIRE(localfd != -1); 73 1.1 pooka 74 1.1 pooka ATF_REQUIRE_EQ(write(localfd, TESTSTR1, TESTSTR1SZ), TESTSTR1SZ); 75 1.1 pooka /* testfile now contains test string */ 76 1.1 pooka 77 1.1 pooka rump_init(); 78 1.1 pooka 79 1.1 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "/etc/passwd", 80 1.1 pooka RUMP_ETFS_REG), 0); 81 1.1 pooka tfd = rump_sys_open(TESTPATH1, O_RDONLY); 82 1.1 pooka ATF_REQUIRE(tfd != -1); 83 1.1 pooka ATF_REQUIRE(rump_sys_read(tfd, buf, sizeof(buf)) > 0); 84 1.1 pooka rump_sys_close(tfd); 85 1.1 pooka rump_pub_etfs_remove(TESTPATH1); 86 1.1 pooka 87 1.1 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./testfile", 88 1.1 pooka RUMP_ETFS_REG), 0); 89 1.1 pooka tfd = rump_sys_open(TESTPATH2, O_RDWR); 90 1.1 pooka ATF_REQUIRE(tfd != -1); 91 1.1 pooka memset(buf, 0, sizeof(buf)); 92 1.1 pooka ATF_REQUIRE((n = rump_sys_read(tfd, buf, sizeof(buf))) > 0); 93 1.1 pooka 94 1.1 pooka /* check that we have what we expected */ 95 1.1 pooka ATF_REQUIRE_STREQ(buf, TESTSTR1); 96 1.1 pooka 97 1.1 pooka /* ... while here, check that writing works too */ 98 1.1 pooka ATF_REQUIRE_EQ(rump_sys_lseek(tfd, 0, SEEK_SET), 0); 99 1.1 pooka ATF_REQUIRE(TESTSTR1SZ <= TESTSTR2SZ); 100 1.1 pooka ATF_REQUIRE_EQ(rump_sys_write(tfd, TESTSTR2, TESTSTR2SZ), TESTSTR2SZ); 101 1.1 pooka 102 1.1 pooka memset(buf, 0, sizeof(buf)); 103 1.1 pooka ATF_REQUIRE_EQ(lseek(localfd, 0, SEEK_SET), 0); 104 1.1 pooka ATF_REQUIRE(read(localfd, buf, sizeof(buf)) > 0); 105 1.1 pooka ATF_REQUIRE_STREQ(buf, TESTSTR2); 106 1.10 christos close(etcfd); 107 1.10 christos close(localfd); 108 1.1 pooka } 109 1.1 pooka 110 1.2 pooka ATF_TC(reregister_blk); 111 1.2 pooka ATF_TC_HEAD(reregister_blk, tc) 112 1.2 pooka { 113 1.2 pooka 114 1.2 pooka atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register " 115 1.2 pooka "for a block device"); 116 1.2 pooka } 117 1.2 pooka 118 1.2 pooka ATF_TC_BODY(reregister_blk, tc) 119 1.2 pooka { 120 1.2 pooka char buf[512 * 128]; 121 1.2 pooka char cmpbuf[512 * 128]; 122 1.2 pooka int rv, tfd; 123 1.2 pooka 124 1.2 pooka /* first, create some image files */ 125 1.2 pooka rv = system("dd if=/dev/zero bs=512 count=64 " 126 1.2 pooka "| tr '\\0' '\\1' > disk1.img"); 127 1.2 pooka ATF_REQUIRE_EQ(rv, 0); 128 1.2 pooka 129 1.2 pooka rv = system("dd if=/dev/zero bs=512 count=128 " 130 1.2 pooka "| tr '\\0' '\\2' > disk2.img"); 131 1.2 pooka ATF_REQUIRE_EQ(rv, 0); 132 1.2 pooka 133 1.2 pooka rump_init(); 134 1.2 pooka 135 1.2 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "./disk1.img", 136 1.2 pooka RUMP_ETFS_BLK), 0); 137 1.2 pooka tfd = rump_sys_open(TESTPATH1, O_RDONLY); 138 1.2 pooka ATF_REQUIRE(tfd != -1); 139 1.2 pooka ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 64*512); 140 1.2 pooka memset(cmpbuf, 1, sizeof(cmpbuf)); 141 1.2 pooka ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 64*512), 0); 142 1.3 pooka ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); 143 1.3 pooka ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); 144 1.2 pooka 145 1.2 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./disk2.img", 146 1.2 pooka RUMP_ETFS_BLK), 0); 147 1.2 pooka tfd = rump_sys_open(TESTPATH2, O_RDONLY); 148 1.2 pooka ATF_REQUIRE(tfd != -1); 149 1.2 pooka ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 128*512); 150 1.2 pooka memset(cmpbuf, 2, sizeof(cmpbuf)); 151 1.2 pooka ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 128*512), 0); 152 1.3 pooka ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); 153 1.3 pooka ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH2), 0); 154 1.2 pooka } 155 1.2 pooka 156 1.5 pooka ATF_TC_WITH_CLEANUP(large_blk); 157 1.5 pooka ATF_TC_HEAD(large_blk, tc) 158 1.5 pooka { 159 1.5 pooka 160 1.5 pooka atf_tc_set_md_var(tc, "descr", "Check etfs block devices work for " 161 1.5 pooka ">2TB images"); 162 1.5 pooka } 163 1.5 pooka 164 1.5 pooka #define IMG_ON_MFS "mfsdir/disk.img" 165 1.5 pooka ATF_TC_BODY(large_blk, tc) 166 1.5 pooka { 167 1.5 pooka char buf[128]; 168 1.5 pooka char cmpbuf[128]; 169 1.5 pooka ssize_t n; 170 1.5 pooka int rv, tfd; 171 1.5 pooka 172 1.12 rin if (sysconf(_SC_PAGESIZE) > 8192) { 173 1.12 rin atf_tc_skip( 174 1.12 rin "PR kern/55658: cause kernel freeze for page size > 8192"); 175 1.12 rin } 176 1.12 rin 177 1.5 pooka /* 178 1.5 pooka * mount mfs. it would be nice if this would not be required, 179 1.5 pooka * but a) tmpfs doesn't "support" sparse files b) we don't really 180 1.5 pooka * know what fs atf workdir is on anyway. 181 1.5 pooka */ 182 1.5 pooka if (mkdir("mfsdir", 0777) == -1) 183 1.5 pooka atf_tc_fail_errno("mkdir failed"); 184 1.5 pooka if (system("mount_mfs -s 64m -o nosuid,nodev mfs mfsdir") != 0) 185 1.5 pooka atf_tc_skip("could not mount mfs"); 186 1.5 pooka 187 1.5 pooka /* create a 8TB sparse file */ 188 1.5 pooka rv = system("dd if=/dev/zero of=" IMG_ON_MFS " bs=1 count=1 seek=8t"); 189 1.5 pooka ATF_REQUIRE_EQ(rv, 0); 190 1.5 pooka 191 1.5 pooka /* 192 1.5 pooka * map it and issue write at 6TB, then unmap+remap and check 193 1.5 pooka * we get the same stuff back 194 1.5 pooka */ 195 1.5 pooka 196 1.5 pooka rump_init(); 197 1.5 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, IMG_ON_MFS, 198 1.5 pooka RUMP_ETFS_BLK), 0); 199 1.5 pooka tfd = rump_sys_open(TESTPATH1, O_RDWR); 200 1.5 pooka ATF_REQUIRE(tfd != -1); 201 1.5 pooka memset(buf, 12, sizeof(buf)); 202 1.5 pooka n = rump_sys_pwrite(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL); 203 1.5 pooka ATF_REQUIRE_EQ(n, sizeof(buf)); 204 1.5 pooka ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); 205 1.5 pooka ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); 206 1.5 pooka 207 1.5 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, IMG_ON_MFS, 208 1.5 pooka RUMP_ETFS_BLK), 0); 209 1.5 pooka tfd = rump_sys_open(TESTPATH2, O_RDWR); 210 1.5 pooka ATF_REQUIRE(tfd != -1); 211 1.5 pooka memset(buf, 0, sizeof(buf)); 212 1.5 pooka n = rump_sys_pread(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL); 213 1.5 pooka ATF_REQUIRE_EQ(n, sizeof(buf)); 214 1.5 pooka 215 1.5 pooka memset(cmpbuf, 12, sizeof(cmpbuf)); 216 1.5 pooka ATF_REQUIRE_EQ(memcmp(cmpbuf, buf, 128), 0); 217 1.5 pooka } 218 1.5 pooka 219 1.5 pooka ATF_TC_CLEANUP(large_blk, tc) 220 1.5 pooka { 221 1.5 pooka 222 1.5 pooka system("umount mfsdir"); 223 1.5 pooka } 224 1.5 pooka 225 1.6 pooka ATF_TC(range_blk); 226 1.6 pooka ATF_TC_HEAD(range_blk, tc) 227 1.6 pooka { 228 1.6 pooka 229 1.6 pooka atf_tc_set_md_var(tc, "descr", "Checks ranged (offset,size) mappings"); 230 1.6 pooka } 231 1.6 pooka 232 1.6 pooka ATF_TC_BODY(range_blk, tc) 233 1.6 pooka { 234 1.6 pooka char buf[32000]; 235 1.6 pooka char cmpbuf[32000]; 236 1.6 pooka ssize_t n; 237 1.6 pooka int rv, tfd; 238 1.6 pooka 239 1.6 pooka /* create a 64000 byte file with 16 1's at offset = 32000 */ 240 1.6 pooka rv = system("dd if=/dev/zero of=disk.img bs=1000 count=64"); 241 1.6 pooka ATF_REQUIRE_EQ(rv, 0); 242 1.6 pooka rv = system("yes | tr '\\ny' '\\1' " 243 1.6 pooka "| dd of=disk.img conv=notrunc bs=1 count=16 seek=32000"); 244 1.6 pooka ATF_REQUIRE_EQ(rv, 0); 245 1.6 pooka 246 1.6 pooka /* map the file at [16000,48000]. this puts our 1's at offset 16000 */ 247 1.6 pooka rump_init(); 248 1.6 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register_withsize(TESTPATH1, "disk.img", 249 1.6 pooka RUMP_ETFS_BLK, 16000, 32000), 0); 250 1.6 pooka tfd = rump_sys_open(TESTPATH1, O_RDWR); 251 1.6 pooka ATF_REQUIRE(tfd != -1); 252 1.6 pooka n = rump_sys_read(tfd, buf, sizeof(buf)); 253 1.6 pooka ATF_REQUIRE_EQ(n, sizeof(buf)); 254 1.6 pooka ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); 255 1.6 pooka ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); 256 1.6 pooka 257 1.6 pooka /* check that we got what is expected */ 258 1.6 pooka memset(cmpbuf, 0, sizeof(cmpbuf)); 259 1.6 pooka memset(cmpbuf+16000, 1, 16); 260 1.6 pooka ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, sizeof(buf)), 0); 261 1.6 pooka } 262 1.6 pooka 263 1.8 pooka ATF_TC(key); 264 1.8 pooka ATF_TC_HEAD(key, tc) 265 1.8 pooka { 266 1.8 pooka 267 1.8 pooka atf_tc_set_md_var(tc, "descr", "Checks key format"); 268 1.8 pooka } 269 1.8 pooka 270 1.8 pooka ATF_TC_BODY(key, tc) 271 1.8 pooka { 272 1.8 pooka 273 1.8 pooka RZ(rump_init()); 274 1.8 pooka 275 1.8 pooka RL(open("hostfile", O_RDWR | O_CREAT, 0777)); 276 1.8 pooka 277 1.8 pooka RZ(rump_pub_etfs_register("/key", "hostfile", RUMP_ETFS_REG)); 278 1.8 pooka ATF_REQUIRE_EQ(rump_pub_etfs_register("key", "hostfile", RUMP_ETFS_REG), 279 1.8 pooka EINVAL); 280 1.8 pooka 281 1.8 pooka RL(rump_sys_open("/key", O_RDONLY)); 282 1.8 pooka RL(rump_sys_open("////////key", O_RDONLY)); 283 1.8 pooka 284 1.8 pooka RZ(rump_pub_etfs_register("////key//with/slashes", "hostfile", 285 1.8 pooka RUMP_ETFS_REG)); 286 1.8 pooka 287 1.8 pooka RL(rump_sys_open("/key//with/slashes", O_RDONLY)); 288 1.8 pooka RL(rump_sys_open("key//with/slashes", O_RDONLY)); 289 1.9 pooka ATF_REQUIRE_ERRNO(ENOENT, 290 1.9 pooka rump_sys_open("/key/with/slashes", O_RDONLY) == -1); 291 1.8 pooka 292 1.9 pooka RL(rump_sys_mkdir("/a", 0777)); 293 1.8 pooka ATF_REQUIRE_ERRNO(ENOENT, 294 1.9 pooka rump_sys_open("/a/key//with/slashes", O_RDONLY) == -1); 295 1.8 pooka } 296 1.8 pooka 297 1.1 pooka ATF_TP_ADD_TCS(tp) 298 1.1 pooka { 299 1.1 pooka 300 1.1 pooka ATF_TP_ADD_TC(tp, reregister_reg); 301 1.2 pooka ATF_TP_ADD_TC(tp, reregister_blk); 302 1.5 pooka ATF_TP_ADD_TC(tp, large_blk); 303 1.6 pooka ATF_TP_ADD_TC(tp, range_blk); 304 1.8 pooka ATF_TP_ADD_TC(tp, key); 305 1.1 pooka 306 1.1 pooka return atf_no_error(); 307 1.1 pooka } 308