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