1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_etfs.c,v 1.10 2014/05/12 15:33:12 christos Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*-
411be35a1SLionel Sambuc * Copyright (c) 2010 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc * All rights reserved.
611be35a1SLionel Sambuc *
711be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without
811be35a1SLionel Sambuc * modification, are permitted provided that the following conditions
911be35a1SLionel Sambuc * are met:
1011be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
1111be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer.
1211be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
1311be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
1411be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution.
1511be35a1SLionel Sambuc *
1611be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
1711be35a1SLionel Sambuc * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1811be35a1SLionel Sambuc * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1911be35a1SLionel Sambuc * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2011be35a1SLionel Sambuc * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
2111be35a1SLionel Sambuc * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2211be35a1SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2311be35a1SLionel Sambuc * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2411be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2511be35a1SLionel Sambuc * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2611be35a1SLionel Sambuc * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2711be35a1SLionel Sambuc * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811be35a1SLionel Sambuc */
2911be35a1SLionel Sambuc
3011be35a1SLionel Sambuc #include <sys/types.h>
3111be35a1SLionel Sambuc #include <sys/mount.h>
3211be35a1SLionel Sambuc #include <sys/sysctl.h>
3311be35a1SLionel Sambuc
3411be35a1SLionel Sambuc #include <rump/rump.h>
3511be35a1SLionel Sambuc #include <rump/rump_syscalls.h>
3611be35a1SLionel Sambuc
3711be35a1SLionel Sambuc #include <atf-c.h>
3811be35a1SLionel Sambuc #include <fcntl.h>
3911be35a1SLionel Sambuc #include <stdio.h>
4011be35a1SLionel Sambuc #include <stdlib.h>
4111be35a1SLionel Sambuc #include <unistd.h>
4211be35a1SLionel Sambuc
4311be35a1SLionel Sambuc #include "../../h_macros.h"
4411be35a1SLionel Sambuc
4511be35a1SLionel Sambuc ATF_TC(reregister_reg);
ATF_TC_HEAD(reregister_reg,tc)4611be35a1SLionel Sambuc ATF_TC_HEAD(reregister_reg, tc)
4711be35a1SLionel Sambuc {
4811be35a1SLionel Sambuc
4911be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register "
5011be35a1SLionel Sambuc "for a regular file");
5111be35a1SLionel Sambuc }
5211be35a1SLionel Sambuc
5311be35a1SLionel Sambuc #define TESTSTR1 "hi, it's me again!"
5411be35a1SLionel Sambuc #define TESTSTR1SZ (sizeof(TESTSTR1)-1)
5511be35a1SLionel Sambuc
5611be35a1SLionel Sambuc #define TESTSTR2 "what about the old vulcan proverb?"
5711be35a1SLionel Sambuc #define TESTSTR2SZ (sizeof(TESTSTR2)-1)
5811be35a1SLionel Sambuc
5911be35a1SLionel Sambuc #define TESTPATH1 "/trip/to/the/moon"
6011be35a1SLionel Sambuc #define TESTPATH2 "/but/not/the/dark/size"
ATF_TC_BODY(reregister_reg,tc)6111be35a1SLionel Sambuc ATF_TC_BODY(reregister_reg, tc)
6211be35a1SLionel Sambuc {
6311be35a1SLionel Sambuc char buf[1024];
6411be35a1SLionel Sambuc int localfd, etcfd;
6511be35a1SLionel Sambuc ssize_t n;
6611be35a1SLionel Sambuc int tfd;
6711be35a1SLionel Sambuc
6811be35a1SLionel Sambuc etcfd = open("/etc/passwd", O_RDONLY);
6911be35a1SLionel Sambuc ATF_REQUIRE(etcfd != -1);
7011be35a1SLionel Sambuc
7111be35a1SLionel Sambuc localfd = open("./testfile", O_RDWR | O_CREAT, 0666);
7211be35a1SLionel Sambuc ATF_REQUIRE(localfd != -1);
7311be35a1SLionel Sambuc
7411be35a1SLionel Sambuc ATF_REQUIRE_EQ(write(localfd, TESTSTR1, TESTSTR1SZ), TESTSTR1SZ);
7511be35a1SLionel Sambuc /* testfile now contains test string */
7611be35a1SLionel Sambuc
7711be35a1SLionel Sambuc rump_init();
7811be35a1SLionel Sambuc
7911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "/etc/passwd",
8011be35a1SLionel Sambuc RUMP_ETFS_REG), 0);
8111be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH1, O_RDONLY);
8211be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
8311be35a1SLionel Sambuc ATF_REQUIRE(rump_sys_read(tfd, buf, sizeof(buf)) > 0);
8411be35a1SLionel Sambuc rump_sys_close(tfd);
8511be35a1SLionel Sambuc rump_pub_etfs_remove(TESTPATH1);
8611be35a1SLionel Sambuc
8711be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./testfile",
8811be35a1SLionel Sambuc RUMP_ETFS_REG), 0);
8911be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH2, O_RDWR);
9011be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
9111be35a1SLionel Sambuc memset(buf, 0, sizeof(buf));
9211be35a1SLionel Sambuc ATF_REQUIRE((n = rump_sys_read(tfd, buf, sizeof(buf))) > 0);
9311be35a1SLionel Sambuc
9411be35a1SLionel Sambuc /* check that we have what we expected */
9511be35a1SLionel Sambuc ATF_REQUIRE_STREQ(buf, TESTSTR1);
9611be35a1SLionel Sambuc
9711be35a1SLionel Sambuc /* ... while here, check that writing works too */
9811be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_lseek(tfd, 0, SEEK_SET), 0);
9911be35a1SLionel Sambuc ATF_REQUIRE(TESTSTR1SZ <= TESTSTR2SZ);
10011be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_write(tfd, TESTSTR2, TESTSTR2SZ), TESTSTR2SZ);
10111be35a1SLionel Sambuc
10211be35a1SLionel Sambuc memset(buf, 0, sizeof(buf));
10311be35a1SLionel Sambuc ATF_REQUIRE_EQ(lseek(localfd, 0, SEEK_SET), 0);
10411be35a1SLionel Sambuc ATF_REQUIRE(read(localfd, buf, sizeof(buf)) > 0);
10511be35a1SLionel Sambuc ATF_REQUIRE_STREQ(buf, TESTSTR2);
106*0a6a1f1dSLionel Sambuc close(etcfd);
107*0a6a1f1dSLionel Sambuc close(localfd);
10811be35a1SLionel Sambuc }
10911be35a1SLionel Sambuc
11011be35a1SLionel Sambuc ATF_TC(reregister_blk);
ATF_TC_HEAD(reregister_blk,tc)11111be35a1SLionel Sambuc ATF_TC_HEAD(reregister_blk, tc)
11211be35a1SLionel Sambuc {
11311be35a1SLionel Sambuc
11411be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register "
11511be35a1SLionel Sambuc "for a block device");
11611be35a1SLionel Sambuc }
11711be35a1SLionel Sambuc
ATF_TC_BODY(reregister_blk,tc)11811be35a1SLionel Sambuc ATF_TC_BODY(reregister_blk, tc)
11911be35a1SLionel Sambuc {
12011be35a1SLionel Sambuc char buf[512 * 128];
12111be35a1SLionel Sambuc char cmpbuf[512 * 128];
12211be35a1SLionel Sambuc int rv, tfd;
12311be35a1SLionel Sambuc
12411be35a1SLionel Sambuc /* first, create some image files */
12511be35a1SLionel Sambuc rv = system("dd if=/dev/zero bs=512 count=64 "
12611be35a1SLionel Sambuc "| tr '\\0' '\\1' > disk1.img");
12711be35a1SLionel Sambuc ATF_REQUIRE_EQ(rv, 0);
12811be35a1SLionel Sambuc
12911be35a1SLionel Sambuc rv = system("dd if=/dev/zero bs=512 count=128 "
13011be35a1SLionel Sambuc "| tr '\\0' '\\2' > disk2.img");
13111be35a1SLionel Sambuc ATF_REQUIRE_EQ(rv, 0);
13211be35a1SLionel Sambuc
13311be35a1SLionel Sambuc rump_init();
13411be35a1SLionel Sambuc
13511be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "./disk1.img",
13611be35a1SLionel Sambuc RUMP_ETFS_BLK), 0);
13711be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH1, O_RDONLY);
13811be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
13911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 64*512);
14011be35a1SLionel Sambuc memset(cmpbuf, 1, sizeof(cmpbuf));
14111be35a1SLionel Sambuc ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 64*512), 0);
14211be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_close(tfd), 0);
14311be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0);
14411be35a1SLionel Sambuc
14511be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./disk2.img",
14611be35a1SLionel Sambuc RUMP_ETFS_BLK), 0);
14711be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH2, O_RDONLY);
14811be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
14911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 128*512);
15011be35a1SLionel Sambuc memset(cmpbuf, 2, sizeof(cmpbuf));
15111be35a1SLionel Sambuc ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 128*512), 0);
15211be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_close(tfd), 0);
15311be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH2), 0);
15411be35a1SLionel Sambuc }
15511be35a1SLionel Sambuc
15611be35a1SLionel Sambuc ATF_TC_WITH_CLEANUP(large_blk);
ATF_TC_HEAD(large_blk,tc)15711be35a1SLionel Sambuc ATF_TC_HEAD(large_blk, tc)
15811be35a1SLionel Sambuc {
15911be35a1SLionel Sambuc
16011be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Check etfs block devices work for "
16111be35a1SLionel Sambuc ">2TB images");
16211be35a1SLionel Sambuc }
16311be35a1SLionel Sambuc
16411be35a1SLionel Sambuc #define IMG_ON_MFS "mfsdir/disk.img"
ATF_TC_BODY(large_blk,tc)16511be35a1SLionel Sambuc ATF_TC_BODY(large_blk, tc)
16611be35a1SLionel Sambuc {
16711be35a1SLionel Sambuc char buf[128];
16811be35a1SLionel Sambuc char cmpbuf[128];
16911be35a1SLionel Sambuc ssize_t n;
17011be35a1SLionel Sambuc int rv, tfd;
17111be35a1SLionel Sambuc
17211be35a1SLionel Sambuc /*
17311be35a1SLionel Sambuc * mount mfs. it would be nice if this would not be required,
17411be35a1SLionel Sambuc * but a) tmpfs doesn't "support" sparse files b) we don't really
17511be35a1SLionel Sambuc * know what fs atf workdir is on anyway.
17611be35a1SLionel Sambuc */
17711be35a1SLionel Sambuc if (mkdir("mfsdir", 0777) == -1)
17811be35a1SLionel Sambuc atf_tc_fail_errno("mkdir failed");
17911be35a1SLionel Sambuc if (system("mount_mfs -s 64m -o nosuid,nodev mfs mfsdir") != 0)
18011be35a1SLionel Sambuc atf_tc_skip("could not mount mfs");
18111be35a1SLionel Sambuc
18211be35a1SLionel Sambuc /* create a 8TB sparse file */
18311be35a1SLionel Sambuc rv = system("dd if=/dev/zero of=" IMG_ON_MFS " bs=1 count=1 seek=8t");
18411be35a1SLionel Sambuc ATF_REQUIRE_EQ(rv, 0);
18511be35a1SLionel Sambuc
18611be35a1SLionel Sambuc /*
18711be35a1SLionel Sambuc * map it and issue write at 6TB, then unmap+remap and check
18811be35a1SLionel Sambuc * we get the same stuff back
18911be35a1SLionel Sambuc */
19011be35a1SLionel Sambuc
19111be35a1SLionel Sambuc rump_init();
19211be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, IMG_ON_MFS,
19311be35a1SLionel Sambuc RUMP_ETFS_BLK), 0);
19411be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH1, O_RDWR);
19511be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
19611be35a1SLionel Sambuc memset(buf, 12, sizeof(buf));
19711be35a1SLionel Sambuc n = rump_sys_pwrite(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL);
19811be35a1SLionel Sambuc ATF_REQUIRE_EQ(n, sizeof(buf));
19911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_close(tfd), 0);
20011be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0);
20111be35a1SLionel Sambuc
20211be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, IMG_ON_MFS,
20311be35a1SLionel Sambuc RUMP_ETFS_BLK), 0);
20411be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH2, O_RDWR);
20511be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
20611be35a1SLionel Sambuc memset(buf, 0, sizeof(buf));
20711be35a1SLionel Sambuc n = rump_sys_pread(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL);
20811be35a1SLionel Sambuc ATF_REQUIRE_EQ(n, sizeof(buf));
20911be35a1SLionel Sambuc
21011be35a1SLionel Sambuc memset(cmpbuf, 12, sizeof(cmpbuf));
21111be35a1SLionel Sambuc ATF_REQUIRE_EQ(memcmp(cmpbuf, buf, 128), 0);
21211be35a1SLionel Sambuc }
21311be35a1SLionel Sambuc
ATF_TC_CLEANUP(large_blk,tc)21411be35a1SLionel Sambuc ATF_TC_CLEANUP(large_blk, tc)
21511be35a1SLionel Sambuc {
21611be35a1SLionel Sambuc
21711be35a1SLionel Sambuc system("umount mfsdir");
21811be35a1SLionel Sambuc }
21911be35a1SLionel Sambuc
22011be35a1SLionel Sambuc ATF_TC(range_blk);
ATF_TC_HEAD(range_blk,tc)22111be35a1SLionel Sambuc ATF_TC_HEAD(range_blk, tc)
22211be35a1SLionel Sambuc {
22311be35a1SLionel Sambuc
22411be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks ranged (offset,size) mappings");
22511be35a1SLionel Sambuc }
22611be35a1SLionel Sambuc
ATF_TC_BODY(range_blk,tc)22711be35a1SLionel Sambuc ATF_TC_BODY(range_blk, tc)
22811be35a1SLionel Sambuc {
22911be35a1SLionel Sambuc char buf[32000];
23011be35a1SLionel Sambuc char cmpbuf[32000];
23111be35a1SLionel Sambuc ssize_t n;
23211be35a1SLionel Sambuc int rv, tfd;
23311be35a1SLionel Sambuc
23411be35a1SLionel Sambuc /* create a 64000 byte file with 16 1's at offset = 32000 */
23511be35a1SLionel Sambuc rv = system("dd if=/dev/zero of=disk.img bs=1000 count=64");
23611be35a1SLionel Sambuc ATF_REQUIRE_EQ(rv, 0);
23711be35a1SLionel Sambuc rv = system("yes | tr '\\ny' '\\1' "
23811be35a1SLionel Sambuc "| dd of=disk.img conv=notrunc bs=1 count=16 seek=32000");
23911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rv, 0);
24011be35a1SLionel Sambuc
24111be35a1SLionel Sambuc /* map the file at [16000,48000]. this puts our 1's at offset 16000 */
24211be35a1SLionel Sambuc rump_init();
24311be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register_withsize(TESTPATH1, "disk.img",
24411be35a1SLionel Sambuc RUMP_ETFS_BLK, 16000, 32000), 0);
24511be35a1SLionel Sambuc tfd = rump_sys_open(TESTPATH1, O_RDWR);
24611be35a1SLionel Sambuc ATF_REQUIRE(tfd != -1);
24711be35a1SLionel Sambuc n = rump_sys_read(tfd, buf, sizeof(buf));
24811be35a1SLionel Sambuc ATF_REQUIRE_EQ(n, sizeof(buf));
24911be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_close(tfd), 0);
25011be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0);
25111be35a1SLionel Sambuc
25211be35a1SLionel Sambuc /* check that we got what is expected */
25311be35a1SLionel Sambuc memset(cmpbuf, 0, sizeof(cmpbuf));
25411be35a1SLionel Sambuc memset(cmpbuf+16000, 1, 16);
25511be35a1SLionel Sambuc ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, sizeof(buf)), 0);
25611be35a1SLionel Sambuc }
25711be35a1SLionel Sambuc
25811be35a1SLionel Sambuc ATF_TC(key);
ATF_TC_HEAD(key,tc)25911be35a1SLionel Sambuc ATF_TC_HEAD(key, tc)
26011be35a1SLionel Sambuc {
26111be35a1SLionel Sambuc
26211be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks key format");
26311be35a1SLionel Sambuc }
26411be35a1SLionel Sambuc
ATF_TC_BODY(key,tc)26511be35a1SLionel Sambuc ATF_TC_BODY(key, tc)
26611be35a1SLionel Sambuc {
26711be35a1SLionel Sambuc
26811be35a1SLionel Sambuc RZ(rump_init());
26911be35a1SLionel Sambuc
27011be35a1SLionel Sambuc RL(open("hostfile", O_RDWR | O_CREAT, 0777));
27111be35a1SLionel Sambuc
27211be35a1SLionel Sambuc RZ(rump_pub_etfs_register("/key", "hostfile", RUMP_ETFS_REG));
27311be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_pub_etfs_register("key", "hostfile", RUMP_ETFS_REG),
27411be35a1SLionel Sambuc EINVAL);
27511be35a1SLionel Sambuc
27611be35a1SLionel Sambuc RL(rump_sys_open("/key", O_RDONLY));
27711be35a1SLionel Sambuc RL(rump_sys_open("////////key", O_RDONLY));
27811be35a1SLionel Sambuc
27911be35a1SLionel Sambuc RZ(rump_pub_etfs_register("////key//with/slashes", "hostfile",
28011be35a1SLionel Sambuc RUMP_ETFS_REG));
28111be35a1SLionel Sambuc
28211be35a1SLionel Sambuc RL(rump_sys_open("/key//with/slashes", O_RDONLY));
28311be35a1SLionel Sambuc RL(rump_sys_open("key//with/slashes", O_RDONLY));
28411be35a1SLionel Sambuc ATF_REQUIRE_ERRNO(ENOENT,
28511be35a1SLionel Sambuc rump_sys_open("/key/with/slashes", O_RDONLY) == -1);
28611be35a1SLionel Sambuc
28711be35a1SLionel Sambuc RL(rump_sys_mkdir("/a", 0777));
28811be35a1SLionel Sambuc ATF_REQUIRE_ERRNO(ENOENT,
28911be35a1SLionel Sambuc rump_sys_open("/a/key//with/slashes", O_RDONLY) == -1);
29011be35a1SLionel Sambuc }
29111be35a1SLionel Sambuc
ATF_TP_ADD_TCS(tp)29211be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
29311be35a1SLionel Sambuc {
29411be35a1SLionel Sambuc
29511be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, reregister_reg);
29611be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, reregister_blk);
29711be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, large_blk);
29811be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, range_blk);
29911be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, key);
30011be35a1SLionel Sambuc
30111be35a1SLionel Sambuc return atf_no_error();
30211be35a1SLionel Sambuc }
303