[BACK]Return to t_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / tests / fs / vfs

Annotation of src/tests/fs/vfs/t_vnops.c, Revision 1.40

1.40    ! martin      1: /*     $NetBSD: t_vnops.c,v 1.39 2014/06/03 11:56:07 njoly Exp $       */
1.1       pooka       2:
                      3: /*-
                      4:  * Copyright (c) 2010 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     17:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     18:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     19:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     20:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     21:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     22:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     23:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     24:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     25:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29: #include <sys/stat.h>
                     30: #include <sys/statvfs.h>
                     31:
1.13      pooka      32: #include <assert.h>
1.1       pooka      33: #include <atf-c.h>
                     34: #include <fcntl.h>
                     35: #include <libgen.h>
1.5       njoly      36: #include <stdlib.h>
1.13      pooka      37: #include <string.h>
1.1       pooka      38: #include <unistd.h>
                     39:
                     40: #include <rump/rump_syscalls.h>
                     41: #include <rump/rump.h>
                     42:
                     43: #include "../common/h_fsmacros.h"
                     44: #include "../../h_macros.h"
                     45:
1.11      pooka      46: #define TESTFILE "afile"
                     47:
1.29      njoly      48: #define USES_DIRS                                      \
                     49:     if (FSTYPE_SYSVBFS(tc))                            \
                     50:        atf_tc_skip("directories not supported by file system")
1.1       pooka      51:
1.7       pooka      52: #define USES_SYMLINKS                                  \
                     53:     if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc))                \
1.9       njoly      54:        atf_tc_skip("symlinks not supported by file system")
1.7       pooka      55:
1.2       pooka      56: static char *
                     57: md(char *buf, const char *base, const char *tail)
                     58: {
                     59:
                     60:        sprintf(buf, "%s/%s", base, tail);
                     61:        return buf;
                     62: }
                     63:
1.1       pooka      64: static void
                     65: lookup_simple(const atf_tc_t *tc, const char *mountpath)
                     66: {
                     67:        char pb[MAXPATHLEN], final[MAXPATHLEN];
                     68:        struct stat sb1, sb2;
                     69:
                     70:        strcpy(final, mountpath);
                     71:        sprintf(pb, "%s/../%s", mountpath, basename(final));
                     72:        if (rump_sys_stat(pb, &sb1) == -1)
                     73:                atf_tc_fail_errno("stat 1");
                     74:
                     75:        sprintf(pb, "%s/./../%s", mountpath, basename(final));
                     76:        if (rump_sys_stat(pb, &sb2) == -1)
                     77:                atf_tc_fail_errno("stat 2");
                     78:
                     79:        ATF_REQUIRE(memcmp(&sb1, &sb2, sizeof(sb1)) == 0);
                     80: }
                     81:
                     82: static void
                     83: lookup_complex(const atf_tc_t *tc, const char *mountpath)
                     84: {
                     85:        char pb[MAXPATHLEN];
                     86:        struct stat sb1, sb2;
                     87:
                     88:        USES_DIRS;
                     89:
                     90:        sprintf(pb, "%s/dir", mountpath);
                     91:        if (rump_sys_mkdir(pb, 0777) == -1)
                     92:                atf_tc_fail_errno("mkdir");
                     93:        if (rump_sys_stat(pb, &sb1) == -1)
                     94:                atf_tc_fail_errno("stat 1");
                     95:
                     96:        sprintf(pb, "%s/./dir/../././dir/.", mountpath);
                     97:        if (rump_sys_stat(pb, &sb2) == -1)
                     98:                atf_tc_fail_errno("stat 2");
                     99:
1.40    ! martin    100:        if (memcmp(&sb1, &sb2, sizeof(sb1)) != 0) {
        !           101:                printf("what\tsb1\t\tsb2\n");
        !           102:
        !           103: #define FIELD(FN)      \
        !           104:                printf(#FN "\t%lld\t%lld\n", \
        !           105:                (long long)sb1.FN, (long long)sb2.FN)
        !           106: #define TIME(FN)       \
        !           107:                printf(#FN "\t%lld.%ld\t%lld.%ld\n", \
        !           108:                (long long)sb1.FN.tv_sec, sb1.FN.tv_nsec, \
        !           109:                (long long)sb2.FN.tv_sec, sb2.FN.tv_nsec)
        !           110:
        !           111:                FIELD(st_dev);
        !           112:                FIELD(st_mode);
        !           113:                FIELD(st_ino);
        !           114:                FIELD(st_nlink);
        !           115:                FIELD(st_uid);
        !           116:                FIELD(st_gid);
        !           117:                FIELD(st_rdev);
        !           118:                TIME(st_atim);
        !           119:                TIME(st_mtim);
        !           120:                TIME(st_ctim);
        !           121:                TIME(st_birthtim);
        !           122:                FIELD(st_size);
        !           123:                FIELD(st_blocks);
        !           124:                FIELD(st_flags);
        !           125:                FIELD(st_gen);
        !           126:
        !           127: #undef FIELD
        !           128: #undef TIME
        !           129:
        !           130:                atf_tc_fail("stat results differ, see ouput for more details");
        !           131:        }
1.1       pooka     132: }
                    133:
                    134: static void
                    135: dir_simple(const atf_tc_t *tc, const char *mountpath)
                    136: {
                    137:        char pb[MAXPATHLEN];
                    138:        struct stat sb;
                    139:
                    140:        USES_DIRS;
                    141:
                    142:        /* check we can create directories */
                    143:        sprintf(pb, "%s/dir", mountpath);
                    144:        if (rump_sys_mkdir(pb, 0777) == -1)
                    145:                atf_tc_fail_errno("mkdir");
                    146:        if (rump_sys_stat(pb, &sb) == -1)
                    147:                atf_tc_fail_errno("stat new directory");
                    148:
                    149:        /* check we can remove then and that it makes them unreachable */
                    150:        if (rump_sys_rmdir(pb) == -1)
                    151:                atf_tc_fail_errno("rmdir");
                    152:        if (rump_sys_stat(pb, &sb) != -1 || errno != ENOENT)
                    153:                atf_tc_fail("ENOENT expected from stat");
                    154: }
                    155:
                    156: static void
                    157: dir_notempty(const atf_tc_t *tc, const char *mountpath)
                    158: {
                    159:        char pb[MAXPATHLEN], pb2[MAXPATHLEN];
                    160:        int fd, rv;
                    161:
                    162:        USES_DIRS;
                    163:
                    164:        /* check we can create directories */
                    165:        sprintf(pb, "%s/dir", mountpath);
                    166:        if (rump_sys_mkdir(pb, 0777) == -1)
                    167:                atf_tc_fail_errno("mkdir");
                    168:
                    169:        sprintf(pb2, "%s/dir/file", mountpath);
                    170:        fd = rump_sys_open(pb2, O_RDWR | O_CREAT, 0777);
                    171:        if (fd == -1)
                    172:                atf_tc_fail_errno("create file");
                    173:        rump_sys_close(fd);
                    174:
                    175:        rv = rump_sys_rmdir(pb);
1.34      jmmv      176:        if (FSTYPE_ZFS(tc))
                    177:                atf_tc_expect_fail("PR kern/47656: Test known to be broken");
1.1       pooka     178:        if (rv != -1 || errno != ENOTEMPTY)
                    179:                atf_tc_fail("non-empty directory removed succesfully");
                    180:
                    181:        if (rump_sys_unlink(pb2) == -1)
                    182:                atf_tc_fail_errno("cannot remove dir/file");
                    183:
                    184:        if (rump_sys_rmdir(pb) == -1)
                    185:                atf_tc_fail_errno("remove directory");
                    186: }
                    187:
1.2       pooka     188: static void
1.18      pooka     189: dir_rmdirdotdot(const atf_tc_t *tc, const char *mp)
                    190: {
                    191:        char pb[MAXPATHLEN];
                    192:        int xerrno;
                    193:
                    194:        USES_DIRS;
                    195:
                    196:        FSTEST_ENTER();
                    197:        RL(rump_sys_mkdir("test", 0777));
                    198:        RL(rump_sys_chdir("test"));
                    199:
                    200:        RL(rump_sys_mkdir("subtest", 0777));
                    201:        RL(rump_sys_chdir("subtest"));
                    202:
                    203:        md(pb, mp, "test/subtest");
                    204:        RL(rump_sys_rmdir(pb));
                    205:        md(pb, mp, "test");
                    206:        RL(rump_sys_rmdir(pb));
                    207:
                    208:        if (FSTYPE_NFS(tc))
                    209:                xerrno = ESTALE;
                    210:        else
                    211:                xerrno = ENOENT;
                    212:        ATF_REQUIRE_ERRNO(xerrno, rump_sys_chdir("..") == -1);
                    213:        FSTEST_EXIT();
                    214: }
                    215:
                    216: static void
1.2       pooka     217: checkfile(const char *path, struct stat *refp)
                    218: {
                    219:        char buf[MAXPATHLEN];
                    220:        struct stat sb;
                    221:        static int n = 1;
                    222:
                    223:        md(buf, path, "file");
                    224:        if (rump_sys_stat(buf, &sb) == -1)
                    225:                atf_tc_fail_errno("cannot stat file %d (%s)", n, buf);
                    226:        if (memcmp(&sb, refp, sizeof(sb)) != 0)
                    227:                atf_tc_fail("stat mismatch %d", n);
                    228:        n++;
                    229: }
                    230:
                    231: static void
                    232: rename_dir(const atf_tc_t *tc, const char *mp)
                    233: {
                    234:        char pb1[MAXPATHLEN], pb2[MAXPATHLEN], pb3[MAXPATHLEN];
1.16      pooka     235:        struct stat ref, sb;
1.2       pooka     236:
1.10      pooka     237:        if (FSTYPE_RUMPFS(tc))
1.29      njoly     238:                atf_tc_skip("rename not supported by file system");
1.10      pooka     239:
1.2       pooka     240:        USES_DIRS;
                    241:
                    242:        md(pb1, mp, "dir1");
                    243:        if (rump_sys_mkdir(pb1, 0777) == -1)
                    244:                atf_tc_fail_errno("mkdir 1");
                    245:
                    246:        md(pb2, mp, "dir2");
                    247:        if (rump_sys_mkdir(pb2, 0777) == -1)
                    248:                atf_tc_fail_errno("mkdir 2");
                    249:        md(pb2, mp, "dir2/subdir");
                    250:        if (rump_sys_mkdir(pb2, 0777) == -1)
                    251:                atf_tc_fail_errno("mkdir 3");
                    252:
                    253:        md(pb3, mp, "dir1/file");
                    254:        if (rump_sys_mknod(pb3, S_IFREG | 0777, -1) == -1)
                    255:                atf_tc_fail_errno("create file");
                    256:        if (rump_sys_stat(pb3, &ref) == -1)
                    257:                atf_tc_fail_errno("stat of file");
                    258:
                    259:        /*
                    260:         * First try ops which should succeed.
                    261:         */
                    262:
                    263:        /* rename within directory */
                    264:        md(pb3, mp, "dir3");
                    265:        if (rump_sys_rename(pb1, pb3) == -1)
                    266:                atf_tc_fail_errno("rename 1");
                    267:        checkfile(pb3, &ref);
                    268:
                    269:        /* rename directory onto itself (two ways, should fail) */
                    270:        md(pb1, mp, "dir3/.");
                    271:        if (rump_sys_rename(pb1, pb3) != -1 || errno != EINVAL)
                    272:                atf_tc_fail_errno("rename 2");
1.34      jmmv      273:        if (FSTYPE_ZFS(tc))
                    274:                atf_tc_expect_fail("PR kern/47656: Test known to be broken");
1.2       pooka     275:        if (rump_sys_rename(pb3, pb1) != -1 || errno != EISDIR)
                    276:                atf_tc_fail_errno("rename 3");
                    277:
                    278:        checkfile(pb3, &ref);
                    279:
                    280:        /* rename father of directory into directory */
                    281:        md(pb1, mp, "dir2/dir");
                    282:        md(pb2, mp, "dir2");
                    283:        if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
                    284:                atf_tc_fail_errno("rename 4");
                    285:
                    286:        /* same for grandfather */
                    287:        md(pb1, mp, "dir2/subdir/dir2");
                    288:        if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
                    289:                atf_tc_fail("rename 5");
                    290:
                    291:        checkfile(pb3, &ref);
                    292:
                    293:        /* rename directory over a non-empty directory */
                    294:        if (rump_sys_rename(pb2, pb3) != -1 || errno != ENOTEMPTY)
                    295:                atf_tc_fail("rename 6");
                    296:
                    297:        /* cross-directory rename */
                    298:        md(pb1, mp, "dir3");
                    299:        md(pb2, mp, "dir2/somedir");
                    300:        if (rump_sys_rename(pb1, pb2) == -1)
                    301:                atf_tc_fail_errno("rename 7");
                    302:        checkfile(pb2, &ref);
                    303:
                    304:        /* move to parent directory */
                    305:        md(pb1, mp, "dir2/somedir/../../dir3");
                    306:        if (rump_sys_rename(pb2, pb1) == -1)
                    307:                atf_tc_fail_errno("rename 8");
                    308:        md(pb1, mp, "dir2/../dir3");
                    309:        checkfile(pb1, &ref);
                    310:
1.16      pooka     311:        /* atomic cross-directory rename */
1.2       pooka     312:        md(pb3, mp, "dir2/subdir");
                    313:        if (rump_sys_rename(pb1, pb3) == -1)
                    314:                atf_tc_fail_errno("rename 9");
                    315:        checkfile(pb3, &ref);
1.16      pooka     316:
                    317:        /* rename directory over an empty directory */
                    318:        md(pb1, mp, "parent");
                    319:        md(pb2, mp, "parent/dir1");
                    320:        md(pb3, mp, "parent/dir2");
                    321:        RL(rump_sys_mkdir(pb1, 0777));
                    322:        RL(rump_sys_mkdir(pb2, 0777));
                    323:        RL(rump_sys_mkdir(pb3, 0777));
                    324:        RL(rump_sys_rename(pb2, pb3));
                    325:
                    326:        RL(rump_sys_stat(pb1, &sb));
1.22      hannken   327:        if (! FSTYPE_MSDOS(tc))
                    328:                ATF_CHECK_EQ(sb.st_nlink, 3);
1.16      pooka     329:        RL(rump_sys_rmdir(pb3));
                    330:        RL(rump_sys_rmdir(pb1));
1.2       pooka     331: }
                    332:
                    333: static void
                    334: rename_dotdot(const atf_tc_t *tc, const char *mp)
                    335: {
                    336:
1.10      pooka     337:        if (FSTYPE_RUMPFS(tc))
1.29      njoly     338:                atf_tc_skip("rename not supported by file system");
1.10      pooka     339:
1.2       pooka     340:        USES_DIRS;
                    341:
                    342:        if (rump_sys_chdir(mp) == -1)
                    343:                atf_tc_fail_errno("chdir mountpoint");
                    344:
                    345:        if (rump_sys_mkdir("dir1", 0777) == -1)
                    346:                atf_tc_fail_errno("mkdir 1");
                    347:        if (rump_sys_mkdir("dir2", 0777) == -1)
                    348:                atf_tc_fail_errno("mkdir 2");
                    349:
                    350:        if (rump_sys_rename("dir1", "dir1/..") != -1 || errno != EINVAL)
                    351:                atf_tc_fail_errno("self-dotdot to");
                    352:
                    353:        if (rump_sys_rename("dir1/..", "sometarget") != -1 || errno != EINVAL)
                    354:                atf_tc_fail_errno("self-dotdot from");
                    355:
                    356:        if (rump_sys_rename("dir1", "dir2/..") != -1 || errno != EINVAL)
                    357:                atf_tc_fail("other-dotdot");
                    358:
                    359:        rump_sys_chdir("/");
                    360: }
                    361:
                    362: static void
                    363: rename_reg_nodir(const atf_tc_t *tc, const char *mp)
                    364: {
                    365:        bool haslinks;
                    366:        struct stat sb;
1.38      christos  367:        ino_t f1ino;
1.2       pooka     368:
1.10      pooka     369:        if (FSTYPE_RUMPFS(tc))
1.29      njoly     370:                atf_tc_skip("rename not supported by file system");
1.10      pooka     371:
1.2       pooka     372:        if (rump_sys_chdir(mp) == -1)
                    373:                atf_tc_fail_errno("chdir mountpoint");
                    374:
                    375:        if (FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))
                    376:                haslinks = false;
                    377:        else
                    378:                haslinks = true;
                    379:
                    380:        if (rump_sys_mknod("file1", S_IFREG | 0777, -1) == -1)
                    381:                atf_tc_fail_errno("create file");
                    382:        if (rump_sys_mknod("file2", S_IFREG | 0777, -1) == -1)
                    383:                atf_tc_fail_errno("create file");
                    384:
                    385:        if (rump_sys_stat("file1", &sb) == -1)
                    386:                atf_tc_fail_errno("stat");
                    387:        f1ino = sb.st_ino;
                    388:
                    389:        if (haslinks) {
                    390:                if (rump_sys_link("file1", "file_link") == -1)
                    391:                        atf_tc_fail_errno("link");
                    392:                if (rump_sys_stat("file_link", &sb) == -1)
                    393:                        atf_tc_fail_errno("stat");
                    394:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    395:                ATF_REQUIRE_EQ(sb.st_nlink, 2);
                    396:        }
                    397:
                    398:        if (rump_sys_stat("file2", &sb) == -1)
                    399:                atf_tc_fail_errno("stat");
                    400:
                    401:        if (rump_sys_rename("file1", "file3") == -1)
                    402:                atf_tc_fail_errno("rename 1");
                    403:        if (rump_sys_stat("file3", &sb) == -1)
                    404:                atf_tc_fail_errno("stat 1");
                    405:        if (haslinks) {
                    406:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    407:        }
                    408:        if (rump_sys_stat("file1", &sb) != -1 || errno != ENOENT)
                    409:                atf_tc_fail_errno("source 1");
                    410:
                    411:        if (rump_sys_rename("file3", "file2") == -1)
                    412:                atf_tc_fail_errno("rename 2");
                    413:        if (rump_sys_stat("file2", &sb) == -1)
                    414:                atf_tc_fail_errno("stat 2");
                    415:        if (haslinks) {
                    416:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    417:        }
                    418:
                    419:        if (rump_sys_stat("file3", &sb) != -1 || errno != ENOENT)
                    420:                atf_tc_fail_errno("source 2");
                    421:
                    422:        if (haslinks) {
                    423:                if (rump_sys_rename("file2", "file_link") == -1)
                    424:                        atf_tc_fail_errno("rename hardlink");
                    425:                if (rump_sys_stat("file2", &sb) != -1 || errno != ENOENT)
                    426:                        atf_tc_fail_errno("source 3");
                    427:                if (rump_sys_stat("file_link", &sb) == -1)
                    428:                        atf_tc_fail_errno("stat 2");
                    429:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    430:                ATF_REQUIRE_EQ(sb.st_nlink, 1);
                    431:        }
                    432:
1.37      njoly     433:        ATF_CHECK_ERRNO(EFAULT, rump_sys_rename("file2", NULL) == -1);
                    434:        ATF_CHECK_ERRNO(EFAULT, rump_sys_rename(NULL, "file2") == -1);
                    435:
1.2       pooka     436:        rump_sys_chdir("/");
                    437: }
                    438:
1.5       njoly     439: static void
                    440: create_nametoolong(const atf_tc_t *tc, const char *mp)
                    441: {
                    442:        char *name;
                    443:        int fd;
                    444:        long val;
                    445:        size_t len;
                    446:
                    447:        if (rump_sys_chdir(mp) == -1)
                    448:                atf_tc_fail_errno("chdir mountpoint");
                    449:
                    450:        val = rump_sys_pathconf(".", _PC_NAME_MAX);
                    451:        if (val == -1)
                    452:                atf_tc_fail_errno("pathconf");
                    453:
                    454:        len = val + 1;
                    455:        name = malloc(len+1);
                    456:        if (name == NULL)
                    457:                atf_tc_fail_errno("malloc");
                    458:
                    459:        memset(name, 'a', len);
                    460:        *(name+len) = '\0';
                    461:
                    462:        val = rump_sys_pathconf(".", _PC_NO_TRUNC);
                    463:        if (val == -1)
                    464:                atf_tc_fail_errno("pathconf");
                    465:
                    466:        fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666);
                    467:        if (val != 0 && (fd != -1 || errno != ENAMETOOLONG))
                    468:                atf_tc_fail_errno("open");
                    469:
                    470:        if (val == 0 && rump_sys_close(fd) == -1)
                    471:                atf_tc_fail_errno("close");
                    472:        if (val == 0 && rump_sys_unlink(name) == -1)
                    473:                atf_tc_fail_errno("unlink");
                    474:
                    475:        free(name);
                    476:
                    477:        rump_sys_chdir("/");
                    478: }
                    479:
                    480: static void
1.14      yamt      481: create_exist(const atf_tc_t *tc, const char *mp)
                    482: {
                    483:        const char *name = "hoge";
                    484:        int fd;
                    485:
                    486:        RL(rump_sys_chdir(mp));
                    487:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666));
                    488:        RL(rump_sys_close(fd));
                    489:        RL(rump_sys_unlink(name));
                    490:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666));
                    491:        RL(rump_sys_close(fd));
                    492:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666));
                    493:        RL(rump_sys_close(fd));
                    494:        ATF_REQUIRE_ERRNO(EEXIST,
                    495:            (fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666)));
                    496:        RL(rump_sys_unlink(name));
                    497:        RL(rump_sys_chdir("/"));
                    498: }
                    499:
                    500: static void
1.5       njoly     501: rename_nametoolong(const atf_tc_t *tc, const char *mp)
                    502: {
                    503:        char *name;
                    504:        int res, fd;
                    505:        long val;
                    506:        size_t len;
                    507:
1.10      pooka     508:        if (FSTYPE_RUMPFS(tc))
1.29      njoly     509:                atf_tc_skip("rename not supported by file system");
1.10      pooka     510:
1.5       njoly     511:        if (rump_sys_chdir(mp) == -1)
                    512:                atf_tc_fail_errno("chdir mountpoint");
                    513:
                    514:        val = rump_sys_pathconf(".", _PC_NAME_MAX);
                    515:        if (val == -1)
                    516:                atf_tc_fail_errno("pathconf");
                    517:
                    518:        len = val + 1;
                    519:        name = malloc(len+1);
                    520:        if (name == NULL)
                    521:                atf_tc_fail_errno("malloc");
                    522:
                    523:        memset(name, 'a', len);
                    524:        *(name+len) = '\0';
                    525:
                    526:        fd = rump_sys_open("dummy", O_RDWR|O_CREAT, 0666);
                    527:        if (fd == -1)
                    528:                atf_tc_fail_errno("open");
                    529:        if (rump_sys_close(fd) == -1)
                    530:                atf_tc_fail_errno("close");
                    531:
                    532:        val = rump_sys_pathconf(".", _PC_NO_TRUNC);
                    533:        if (val == -1)
                    534:                atf_tc_fail_errno("pathconf");
                    535:
                    536:        res = rump_sys_rename("dummy", name);
                    537:        if (val != 0 && (res != -1 || errno != ENAMETOOLONG))
                    538:                atf_tc_fail_errno("rename");
                    539:
                    540:        if (val == 0 && rump_sys_unlink(name) == -1)
                    541:                atf_tc_fail_errno("unlink");
                    542:
                    543:        free(name);
                    544:
                    545:        rump_sys_chdir("/");
                    546: }
                    547:
1.7       pooka     548: static void
                    549: symlink_zerolen(const atf_tc_t *tc, const char *mp)
                    550: {
                    551:
                    552:        USES_SYMLINKS;
                    553:
                    554:        RL(rump_sys_chdir(mp));
1.8       pooka     555:
1.7       pooka     556:        RL(rump_sys_symlink("", "afile"));
                    557:        RL(rump_sys_chdir("/"));
                    558: }
                    559:
1.11      pooka     560: static void
1.28      riastrad  561: symlink_root(const atf_tc_t *tc, const char *mp)
                    562: {
                    563:
                    564:        USES_SYMLINKS;
                    565:
                    566:        RL(rump_sys_chdir(mp));
                    567:        RL(rump_sys_symlink("/", "foo"));
                    568:        RL(rump_sys_chdir("foo"));
                    569: }
                    570:
                    571: static void
1.11      pooka     572: attrs(const atf_tc_t *tc, const char *mp)
                    573: {
                    574:        struct stat sb, sb2;
                    575:        struct timeval tv[2];
                    576:        int fd;
                    577:
                    578:        FSTEST_ENTER();
                    579:        RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
                    580:        RL(rump_sys_close(fd));
                    581:        RL(rump_sys_stat(TESTFILE, &sb));
                    582:        if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
                    583:                RL(rump_sys_chown(TESTFILE, 1, 2));
                    584:                sb.st_uid = 1;
                    585:                sb.st_gid = 2;
                    586:                RL(rump_sys_chmod(TESTFILE, 0123));
                    587:                sb.st_mode = (sb.st_mode & ~ACCESSPERMS) | 0123;
                    588:        }
                    589:
                    590:        tv[0].tv_sec = 1000000000; /* need something >1980 for msdosfs */
                    591:        tv[0].tv_usec = 1;
                    592:        tv[1].tv_sec = 1000000002; /* need even seconds for msdosfs */
                    593:        tv[1].tv_usec = 3;
                    594:        RL(rump_sys_utimes(TESTFILE, tv));
                    595:        RL(rump_sys_utimes(TESTFILE, tv)); /* XXX: utimes & birthtime */
                    596:        sb.st_atimespec.tv_sec = 1000000000;
                    597:        sb.st_atimespec.tv_nsec = 1000;
                    598:        sb.st_mtimespec.tv_sec = 1000000002;
                    599:        sb.st_mtimespec.tv_nsec = 3000;
                    600:
                    601:        RL(rump_sys_stat(TESTFILE, &sb2));
                    602: #define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a)
1.34      jmmv      603:        if (FSTYPE_ZFS(tc))
                    604:                atf_tc_expect_fail("PR kern/47656: Test known to be broken");
1.11      pooka     605:        if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
                    606:                CHECK(st_uid);
                    607:                CHECK(st_gid);
                    608:                CHECK(st_mode);
                    609:        }
                    610:        if (!FSTYPE_MSDOS(tc)) {
                    611:                /* msdosfs has only access date, not time */
                    612:                CHECK(st_atimespec.tv_sec);
                    613:        }
                    614:        CHECK(st_mtimespec.tv_sec);
1.27      uch       615:        if (!(FSTYPE_EXT2FS(tc) || FSTYPE_MSDOS(tc) ||
                    616:              FSTYPE_SYSVBFS(tc) || FSTYPE_V7FS(tc))) {
1.11      pooka     617:                CHECK(st_atimespec.tv_nsec);
                    618:                CHECK(st_mtimespec.tv_nsec);
                    619:        }
                    620: #undef  CHECK
                    621:
                    622:        FSTEST_EXIT();
                    623: }
                    624:
1.12      kefren    625: static void
                    626: fcntl_lock(const atf_tc_t *tc, const char *mp)
                    627: {
                    628:        int fd, fd2;
                    629:        struct flock l;
                    630:        struct lwp *lwp1, *lwp2;
                    631:
                    632:        FSTEST_ENTER();
                    633:        l.l_pid = 0;
                    634:        l.l_start = l.l_len = 1024;
                    635:        l.l_type = F_RDLCK | F_WRLCK;
                    636:        l.l_whence = SEEK_END;
                    637:
                    638:        lwp1 = rump_pub_lwproc_curlwp();
                    639:        RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
                    640:        RL(rump_sys_ftruncate(fd, 8192));
                    641:
                    642:        /* PR kern/43321 */
1.34      jmmv      643:        if (FSTYPE_ZFS(tc))
                    644:                atf_tc_expect_fail("PR kern/47656: Test known to be broken");
1.12      kefren    645:        RL(rump_sys_fcntl(fd, F_SETLK, &l));
                    646:
                    647:        /* Next, we fork and try to lock the same area */
                    648:        RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
                    649:        lwp2 = rump_pub_lwproc_curlwp();
                    650:        RL(fd2 = rump_sys_open(TESTFILE, O_RDWR, 0));
                    651:        ATF_REQUIRE_ERRNO(EAGAIN, rump_sys_fcntl(fd2, F_SETLK, &l));
                    652:
                    653:        /* Switch back and unlock... */
                    654:        rump_pub_lwproc_switch(lwp1);
                    655:        l.l_type = F_UNLCK;
                    656:        RL(rump_sys_fcntl(fd, F_SETLK, &l));
                    657:
                    658:        /* ... and try to lock again */
                    659:        rump_pub_lwproc_switch(lwp2);
                    660:        l.l_type = F_RDLCK | F_WRLCK;
                    661:        RL(rump_sys_fcntl(fd2, F_SETLK, &l));
                    662:
                    663:        RL(rump_sys_close(fd2));
                    664:        rump_pub_lwproc_releaselwp();
                    665:
                    666:        RL(rump_sys_close(fd));
                    667:
                    668:        FSTEST_EXIT();
                    669: }
                    670:
1.13      pooka     671: static int
                    672: flock_compare(const void *p, const void *q)
                    673: {
                    674:        int a = ((const struct flock *)p)->l_start;
                    675:        int b = ((const struct flock *)q)->l_start;
                    676:        return a < b ? -1 : (a > b ? 1 : 0);
                    677: }
                    678:
1.26      alnsn     679: /*
                    680:  * Find all locks set by fcntl_getlock_pids test
                    681:  * using GETLK for a range [start, start+end], and,
                    682:  * if there is a blocking lock, recursively find
                    683:  * all locks to the left (toward the beginning of
                    684:  * a file) and to the right of the lock.
                    685:  * The function also understands "until end of file"
                    686:  * convention when len==0.
                    687:  */
                    688: static unsigned int
                    689: fcntl_getlocks(int fildes, off_t start, off_t len,
                    690:     struct flock *lock, struct flock *end)
                    691: {
                    692:        unsigned int rv = 0;
                    693:        const struct flock l = { start, len, 0, F_RDLCK, SEEK_SET };
                    694:
                    695:        if (lock == end)
                    696:                return rv;
                    697:
                    698:        RL(rump_sys_fcntl(fildes, F_GETLK, &l));
                    699:
                    700:        if (l.l_type == F_UNLCK)
                    701:                return rv;
                    702:
                    703:        *lock++ = l;
                    704:        rv += 1;
                    705:
                    706:        ATF_REQUIRE(l.l_whence == SEEK_SET);
                    707:
                    708:        if (l.l_start > start) {
                    709:                unsigned int n =
                    710:                    fcntl_getlocks(fildes, start, l.l_start - start, lock, end);
                    711:                rv += n;
                    712:                lock += n;
                    713:                if (lock == end)
                    714:                        return rv;
                    715:        }
                    716:
                    717:        if (l.l_len == 0) /* does l spans until the end? */
                    718:                return rv;
                    719:
                    720:        if (len == 0) /* are we looking for locks until the end? */ {
                    721:                rv += fcntl_getlocks(fildes, l.l_start + l.l_len, len, lock, end);
                    722:        } else if (l.l_start + l.l_len < start + len) {
                    723:                len -= l.l_start + l.l_len - start;
                    724:                rv += fcntl_getlocks(fildes, l.l_start + l.l_len, len, lock, end);
                    725:        }
                    726:
                    727:        return rv;
                    728: }
                    729:
1.13      pooka     730: static void
                    731: fcntl_getlock_pids(const atf_tc_t *tc, const char *mp)
                    732: {
                    733:        /* test non-overlaping ranges */
                    734:        struct flock expect[4];
                    735:        const struct flock lock[4] = {
                    736:                { 0, 2, 0, F_WRLCK, SEEK_SET },
                    737:                { 2, 1, 0, F_WRLCK, SEEK_SET },
                    738:                { 7, 5, 0, F_WRLCK, SEEK_SET },
                    739:                { 4, 3, 0, F_WRLCK, SEEK_SET },
                    740:        };
                    741:
1.26      alnsn     742:     /* Add extra element to make sure recursion does't stop at array end */
                    743:        struct flock result[5];
                    744:
                    745:        /* Add 5th process */
                    746:        int fd[5];
                    747:        pid_t pid[5];
                    748:        struct lwp *lwp[5];
1.13      pooka     749:
                    750:        unsigned int i, j;
                    751:        const off_t sz = 8192;
                    752:        int omode  = 0755;
                    753:        int oflags = O_RDWR | O_CREAT;
                    754:
                    755:        memcpy(expect, lock, sizeof(lock));
                    756:
                    757:        FSTEST_ENTER();
                    758:
                    759:        /*
                    760:         * First, we create 4 processes and let each lock a range of the
                    761:         * file.  Note that the third and fourth processes lock in
                    762:         * "reverse" order, i.e. the greater pid locks a range before
                    763:         * the lesser pid.
1.26      alnsn     764:         * Then, we create 5th process which doesn't lock anything.
1.13      pooka     765:         */
1.26      alnsn     766:        for (i = 0; i < __arraycount(lwp); i++) {
1.13      pooka     767:                RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
                    768:
                    769:                lwp[i] = rump_pub_lwproc_curlwp();
1.26      alnsn     770:                pid[i] = rump_sys_getpid();
1.13      pooka     771:
                    772:                RL(fd[i] = rump_sys_open(TESTFILE, oflags, omode));
                    773:                oflags = O_RDWR;
                    774:                omode  = 0;
                    775:
                    776:                RL(rump_sys_ftruncate(fd[i], sz));
1.26      alnsn     777:
1.34      jmmv      778:                if (FSTYPE_ZFS(tc))
                    779:                        atf_tc_expect_fail("PR kern/47656: Test known to be "
                    780:                            "broken");
1.26      alnsn     781:                if (i < __arraycount(lock)) {
                    782:                        RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i]));
                    783:                        expect[i].l_pid = pid[i];
                    784:                }
1.13      pooka     785:        }
                    786:
1.26      alnsn     787:        qsort(expect, __arraycount(expect), sizeof(expect[0]), &flock_compare);
                    788:
1.13      pooka     789:        /*
1.26      alnsn     790:         * In the context of each process, recursively find all locks
                    791:         * that would block the current process. Processes 1-4 don't
                    792:         * see their own lock, we insert it to simplify checks.
                    793:         * Process 5 sees all 4 locks.
1.13      pooka     794:         */
1.26      alnsn     795:        for (i = 0; i < __arraycount(lwp); i++) {
                    796:                unsigned int nlocks;
                    797:
1.13      pooka     798:                rump_pub_lwproc_switch(lwp[i]);
                    799:
1.26      alnsn     800:                memset(result, 0, sizeof(result));
                    801:                nlocks = fcntl_getlocks(fd[i], 0, sz,
                    802:                    result, result + __arraycount(result));
                    803:
                    804:                if (i < __arraycount(lock)) {
                    805:                        ATF_REQUIRE(nlocks < __arraycount(result));
                    806:                        result[nlocks] = lock[i];
                    807:                        result[nlocks].l_pid = pid[i];
                    808:                        nlocks++;
                    809:                }
                    810:
                    811:                ATF_CHECK_EQ(nlocks, __arraycount(expect));
                    812:
                    813:                qsort(result, nlocks, sizeof(result[0]), &flock_compare);
                    814:
                    815:                for (j = 0; j < nlocks; j++) {
                    816:                        ATF_CHECK_EQ(result[j].l_start,  expect[j].l_start );
                    817:                        ATF_CHECK_EQ(result[j].l_len,    expect[j].l_len   );
                    818:                        ATF_CHECK_EQ(result[j].l_pid,    expect[j].l_pid   );
                    819:                        ATF_CHECK_EQ(result[j].l_type,   expect[j].l_type  );
                    820:                        ATF_CHECK_EQ(result[j].l_whence, expect[j].l_whence);
1.13      pooka     821:                }
                    822:        }
                    823:
                    824:        /*
                    825:         * Release processes.  This also releases the fds and locks
                    826:         * making fs unmount possible
                    827:         */
1.26      alnsn     828:        for (i = 0; i < __arraycount(lwp); i++) {
1.13      pooka     829:                rump_pub_lwproc_switch(lwp[i]);
                    830:                rump_pub_lwproc_releaselwp();
                    831:        }
                    832:
                    833:        FSTEST_EXIT();
                    834: }
                    835:
1.15      pooka     836: static void
                    837: access_simple(const atf_tc_t *tc, const char *mp)
                    838: {
                    839:        int fd;
                    840:        int tmode;
                    841:
                    842:        FSTEST_ENTER();
                    843:        RL(fd = rump_sys_open("tfile", O_CREAT | O_RDWR, 0777));
                    844:        RL(rump_sys_close(fd));
                    845:
                    846: #define ALLACC (F_OK | X_OK | W_OK | R_OK)
                    847:        if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc))
                    848:                tmode = F_OK;
                    849:        else
                    850:                tmode = ALLACC;
                    851:
                    852:        RL(rump_sys_access("tfile", tmode));
                    853:
                    854:        /* PR kern/44648 */
                    855:        ATF_REQUIRE_ERRNO(EINVAL, rump_sys_access("tfile", ALLACC+1) == -1);
                    856: #undef ALLACC
                    857:        FSTEST_EXIT();
                    858: }
                    859:
1.30      njoly     860: static void
                    861: read_directory(const atf_tc_t *tc, const char *mp)
                    862: {
                    863:        char buf[1024];
                    864:        int fd, res;
                    865:        ssize_t size;
                    866:
                    867:        FSTEST_ENTER();
                    868:        fd = rump_sys_open(".", O_DIRECTORY | O_RDONLY, 0777);
                    869:        ATF_REQUIRE(fd != -1);
                    870:
                    871:        size = rump_sys_pread(fd, buf, sizeof(buf), 0);
                    872:        ATF_CHECK(size != -1 || errno == EISDIR);
                    873:        size = rump_sys_read(fd, buf, sizeof(buf));
                    874:        ATF_CHECK(size != -1 || errno == EISDIR);
                    875:
                    876:        res = rump_sys_close(fd);
                    877:        ATF_REQUIRE(res != -1);
                    878:        FSTEST_EXIT();
                    879: }
                    880:
1.39      njoly     881: static void
                    882: lstat_symlink(const atf_tc_t *tc, const char *mp)
                    883: {
                    884:        const char *src, *dst;
                    885:        int res;
                    886:        struct stat st;
                    887:
                    888:        USES_SYMLINKS;
                    889:        FSTEST_ENTER();
                    890:
                    891:        src = "source";
                    892:        dst = "destination";
                    893:
                    894:        res = rump_sys_symlink(src, dst);
                    895:        ATF_REQUIRE(res != -1);
                    896:        res = rump_sys_lstat(dst, &st);
                    897:        ATF_REQUIRE(res != -1);
                    898:
                    899:        ATF_CHECK(S_ISLNK(st.st_mode) != 0);
                    900:        ATF_CHECK(st.st_size == (off_t)strlen(src));
                    901:
                    902:        FSTEST_EXIT();
                    903: }
                    904:
1.1       pooka     905: ATF_TC_FSAPPLY(lookup_simple, "simple lookup (./.. on root)");
                    906: ATF_TC_FSAPPLY(lookup_complex, "lookup of non-dot entries");
                    907: ATF_TC_FSAPPLY(dir_simple, "mkdir/rmdir");
                    908: ATF_TC_FSAPPLY(dir_notempty, "non-empty directories cannot be removed");
1.31      christos  909: ATF_TC_FSAPPLY(dir_rmdirdotdot, "remove .. and try to cd out (PR kern/44657)");
                    910: ATF_TC_FSAPPLY(rename_dir, "exercise various directory renaming ops "
                    911: "(PR kern/44288)");
                    912: ATF_TC_FSAPPLY(rename_dotdot, "rename dir .. (PR kern/43617)");
1.2       pooka     913: ATF_TC_FSAPPLY(rename_reg_nodir, "rename regular files, no subdirectories");
1.5       njoly     914: ATF_TC_FSAPPLY(create_nametoolong, "create file with name too long");
1.14      yamt      915: ATF_TC_FSAPPLY(create_exist, "create with O_EXCL");
1.5       njoly     916: ATF_TC_FSAPPLY(rename_nametoolong, "rename to file with name too long");
1.7       pooka     917: ATF_TC_FSAPPLY(symlink_zerolen, "symlink with 0-len target");
1.28      riastrad  918: ATF_TC_FSAPPLY(symlink_root, "symlink to root directory");
1.11      pooka     919: ATF_TC_FSAPPLY(attrs, "check setting attributes works");
1.12      kefren    920: ATF_TC_FSAPPLY(fcntl_lock, "check fcntl F_SETLK");
1.13      pooka     921: ATF_TC_FSAPPLY(fcntl_getlock_pids,"fcntl F_GETLK w/ many procs, PR kern/44494");
1.15      pooka     922: ATF_TC_FSAPPLY(access_simple, "access(2)");
1.30      njoly     923: ATF_TC_FSAPPLY(read_directory, "read(2) on directories");
1.39      njoly     924: ATF_TC_FSAPPLY(lstat_symlink, "lstat(2) values for symbolic links");
1.1       pooka     925:
                    926: ATF_TP_ADD_TCS(tp)
                    927: {
                    928:
                    929:        ATF_TP_FSAPPLY(lookup_simple);
                    930:        ATF_TP_FSAPPLY(lookup_complex);
                    931:        ATF_TP_FSAPPLY(dir_simple);
                    932:        ATF_TP_FSAPPLY(dir_notempty);
1.18      pooka     933:        ATF_TP_FSAPPLY(dir_rmdirdotdot);
1.2       pooka     934:        ATF_TP_FSAPPLY(rename_dir);
                    935:        ATF_TP_FSAPPLY(rename_dotdot);
                    936:        ATF_TP_FSAPPLY(rename_reg_nodir);
1.5       njoly     937:        ATF_TP_FSAPPLY(create_nametoolong);
1.14      yamt      938:        ATF_TP_FSAPPLY(create_exist);
1.5       njoly     939:        ATF_TP_FSAPPLY(rename_nametoolong);
1.7       pooka     940:        ATF_TP_FSAPPLY(symlink_zerolen);
1.28      riastrad  941:        ATF_TP_FSAPPLY(symlink_root);
1.11      pooka     942:        ATF_TP_FSAPPLY(attrs);
1.12      kefren    943:        ATF_TP_FSAPPLY(fcntl_lock);
1.13      pooka     944:        ATF_TP_FSAPPLY(fcntl_getlock_pids);
1.15      pooka     945:        ATF_TP_FSAPPLY(access_simple);
1.30      njoly     946:        ATF_TP_FSAPPLY(read_directory);
1.39      njoly     947:        ATF_TP_FSAPPLY(lstat_symlink);
1.1       pooka     948:
                    949:        return atf_no_error();
                    950: }

CVSweb <webmaster@jp.NetBSD.org>