[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.20

1.20    ! pooka       1: /*     $NetBSD: t_vnops.c,v 1.19 2011/03/01 15:33:35 pooka 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.1       pooka      48: #define USES_DIRS \
                     49:     if (FSTYPE_SYSVBFS(tc)) atf_tc_skip("dirs not supported by file system")
                     50:
1.7       pooka      51: #define USES_SYMLINKS                                  \
                     52:     if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc))                \
1.9       njoly      53:        atf_tc_skip("symlinks not supported by file system")
1.7       pooka      54:
1.2       pooka      55: static char *
                     56: md(char *buf, const char *base, const char *tail)
                     57: {
                     58:
                     59:        sprintf(buf, "%s/%s", base, tail);
                     60:        return buf;
                     61: }
                     62:
1.1       pooka      63: static void
                     64: lookup_simple(const atf_tc_t *tc, const char *mountpath)
                     65: {
                     66:        char pb[MAXPATHLEN], final[MAXPATHLEN];
                     67:        struct stat sb1, sb2;
                     68:
                     69:        strcpy(final, mountpath);
                     70:        sprintf(pb, "%s/../%s", mountpath, basename(final));
                     71:        if (rump_sys_stat(pb, &sb1) == -1)
                     72:                atf_tc_fail_errno("stat 1");
                     73:
                     74:        sprintf(pb, "%s/./../%s", mountpath, basename(final));
                     75:        if (rump_sys_stat(pb, &sb2) == -1)
                     76:                atf_tc_fail_errno("stat 2");
                     77:
                     78:        ATF_REQUIRE(memcmp(&sb1, &sb2, sizeof(sb1)) == 0);
                     79: }
                     80:
                     81: static void
                     82: lookup_complex(const atf_tc_t *tc, const char *mountpath)
                     83: {
                     84:        char pb[MAXPATHLEN];
                     85:        struct stat sb1, sb2;
                     86:
                     87:        USES_DIRS;
                     88:
                     89:        sprintf(pb, "%s/dir", mountpath);
                     90:        if (rump_sys_mkdir(pb, 0777) == -1)
                     91:                atf_tc_fail_errno("mkdir");
                     92:        if (rump_sys_stat(pb, &sb1) == -1)
                     93:                atf_tc_fail_errno("stat 1");
                     94:
                     95:        sprintf(pb, "%s/./dir/../././dir/.", mountpath);
                     96:        if (rump_sys_stat(pb, &sb2) == -1)
                     97:                atf_tc_fail_errno("stat 2");
                     98:
                     99:        ATF_REQUIRE(memcmp(&sb1, &sb2, sizeof(sb1)) == 0);
                    100: }
                    101:
                    102: static void
                    103: dir_simple(const atf_tc_t *tc, const char *mountpath)
                    104: {
                    105:        char pb[MAXPATHLEN];
                    106:        struct stat sb;
                    107:
                    108:        USES_DIRS;
                    109:
                    110:        /* check we can create directories */
                    111:        sprintf(pb, "%s/dir", mountpath);
                    112:        if (rump_sys_mkdir(pb, 0777) == -1)
                    113:                atf_tc_fail_errno("mkdir");
                    114:        if (rump_sys_stat(pb, &sb) == -1)
                    115:                atf_tc_fail_errno("stat new directory");
                    116:
                    117:        /* check we can remove then and that it makes them unreachable */
                    118:        if (rump_sys_rmdir(pb) == -1)
                    119:                atf_tc_fail_errno("rmdir");
                    120:        if (rump_sys_stat(pb, &sb) != -1 || errno != ENOENT)
                    121:                atf_tc_fail("ENOENT expected from stat");
                    122: }
                    123:
                    124: static void
                    125: dir_notempty(const atf_tc_t *tc, const char *mountpath)
                    126: {
                    127:        char pb[MAXPATHLEN], pb2[MAXPATHLEN];
                    128:        int fd, rv;
                    129:
                    130:        USES_DIRS;
                    131:
                    132:        /* check we can create directories */
                    133:        sprintf(pb, "%s/dir", mountpath);
                    134:        if (rump_sys_mkdir(pb, 0777) == -1)
                    135:                atf_tc_fail_errno("mkdir");
                    136:
                    137:        sprintf(pb2, "%s/dir/file", mountpath);
                    138:        fd = rump_sys_open(pb2, O_RDWR | O_CREAT, 0777);
                    139:        if (fd == -1)
                    140:                atf_tc_fail_errno("create file");
                    141:        rump_sys_close(fd);
                    142:
                    143:        rv = rump_sys_rmdir(pb);
                    144:        if (rv != -1 || errno != ENOTEMPTY)
                    145:                atf_tc_fail("non-empty directory removed succesfully");
                    146:
                    147:        if (rump_sys_unlink(pb2) == -1)
                    148:                atf_tc_fail_errno("cannot remove dir/file");
                    149:
                    150:        if (rump_sys_rmdir(pb) == -1)
                    151:                atf_tc_fail_errno("remove directory");
                    152: }
                    153:
1.2       pooka     154: static void
1.18      pooka     155: dir_rmdirdotdot(const atf_tc_t *tc, const char *mp)
                    156: {
                    157:        char pb[MAXPATHLEN];
                    158:        int xerrno;
                    159:
                    160:        USES_DIRS;
                    161:
                    162:        FSTEST_ENTER();
                    163:        RL(rump_sys_mkdir("test", 0777));
                    164:        RL(rump_sys_chdir("test"));
                    165:
                    166:        RL(rump_sys_mkdir("subtest", 0777));
                    167:        RL(rump_sys_chdir("subtest"));
                    168:
                    169:        md(pb, mp, "test/subtest");
                    170:        RL(rump_sys_rmdir(pb));
                    171:        md(pb, mp, "test");
                    172:        RL(rump_sys_rmdir(pb));
                    173:
                    174:        if (FSTYPE_NFS(tc))
                    175:                xerrno = ESTALE;
                    176:        else
                    177:                xerrno = ENOENT;
1.19      pooka     178:        if (FSTYPE_TMPFS(tc))
                    179:                atf_tc_expect_signal(-1, "PR kern/44657");
1.18      pooka     180:        ATF_REQUIRE_ERRNO(xerrno, rump_sys_chdir("..") == -1);
                    181:        FSTEST_EXIT();
                    182: }
                    183:
                    184: static void
1.2       pooka     185: checkfile(const char *path, struct stat *refp)
                    186: {
                    187:        char buf[MAXPATHLEN];
                    188:        struct stat sb;
                    189:        static int n = 1;
                    190:
                    191:        md(buf, path, "file");
                    192:        if (rump_sys_stat(buf, &sb) == -1)
                    193:                atf_tc_fail_errno("cannot stat file %d (%s)", n, buf);
                    194:        if (memcmp(&sb, refp, sizeof(sb)) != 0)
                    195:                atf_tc_fail("stat mismatch %d", n);
                    196:        n++;
                    197: }
                    198:
                    199: static void
                    200: rename_dir(const atf_tc_t *tc, const char *mp)
                    201: {
                    202:        char pb1[MAXPATHLEN], pb2[MAXPATHLEN], pb3[MAXPATHLEN];
1.16      pooka     203:        struct stat ref, sb;
1.2       pooka     204:
1.17      pooka     205:        //if (FSTYPE_MSDOS(tc))
                    206:                //atf_tc_skip("test fails in some setups, reason unknown");
1.3       pooka     207:
1.10      pooka     208:        if (FSTYPE_RUMPFS(tc))
                    209:                atf_tc_skip("rename not supported by fs");
                    210:
1.2       pooka     211:        USES_DIRS;
                    212:
                    213:        md(pb1, mp, "dir1");
                    214:        if (rump_sys_mkdir(pb1, 0777) == -1)
                    215:                atf_tc_fail_errno("mkdir 1");
                    216:
                    217:        md(pb2, mp, "dir2");
                    218:        if (rump_sys_mkdir(pb2, 0777) == -1)
                    219:                atf_tc_fail_errno("mkdir 2");
                    220:        md(pb2, mp, "dir2/subdir");
                    221:        if (rump_sys_mkdir(pb2, 0777) == -1)
                    222:                atf_tc_fail_errno("mkdir 3");
                    223:
                    224:        md(pb3, mp, "dir1/file");
                    225:        if (rump_sys_mknod(pb3, S_IFREG | 0777, -1) == -1)
                    226:                atf_tc_fail_errno("create file");
                    227:        if (rump_sys_stat(pb3, &ref) == -1)
                    228:                atf_tc_fail_errno("stat of file");
                    229:
                    230:        /*
                    231:         * First try ops which should succeed.
                    232:         */
                    233:
                    234:        /* rename within directory */
                    235:        md(pb3, mp, "dir3");
                    236:        if (rump_sys_rename(pb1, pb3) == -1)
                    237:                atf_tc_fail_errno("rename 1");
                    238:        checkfile(pb3, &ref);
                    239:
                    240:        /* rename directory onto itself (two ways, should fail) */
                    241:        md(pb1, mp, "dir3/.");
                    242:        if (rump_sys_rename(pb1, pb3) != -1 || errno != EINVAL)
                    243:                atf_tc_fail_errno("rename 2");
                    244:        if (rump_sys_rename(pb3, pb1) != -1 || errno != EISDIR)
                    245:                atf_tc_fail_errno("rename 3");
                    246:
                    247:        checkfile(pb3, &ref);
                    248:
                    249:        /* rename father of directory into directory */
                    250:        md(pb1, mp, "dir2/dir");
                    251:        md(pb2, mp, "dir2");
                    252:        if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
                    253:                atf_tc_fail_errno("rename 4");
                    254:
                    255:        /* same for grandfather */
                    256:        md(pb1, mp, "dir2/subdir/dir2");
                    257:        if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL)
                    258:                atf_tc_fail("rename 5");
                    259:
                    260:        checkfile(pb3, &ref);
                    261:
                    262:        /* rename directory over a non-empty directory */
                    263:        if (rump_sys_rename(pb2, pb3) != -1 || errno != ENOTEMPTY)
                    264:                atf_tc_fail("rename 6");
                    265:
                    266:        /* cross-directory rename */
                    267:        md(pb1, mp, "dir3");
                    268:        md(pb2, mp, "dir2/somedir");
                    269:        if (rump_sys_rename(pb1, pb2) == -1)
                    270:                atf_tc_fail_errno("rename 7");
                    271:        checkfile(pb2, &ref);
                    272:
                    273:        /* move to parent directory */
                    274:        md(pb1, mp, "dir2/somedir/../../dir3");
                    275:        if (rump_sys_rename(pb2, pb1) == -1)
                    276:                atf_tc_fail_errno("rename 8");
                    277:        md(pb1, mp, "dir2/../dir3");
                    278:        checkfile(pb1, &ref);
                    279:
1.16      pooka     280:        /* atomic cross-directory rename */
1.2       pooka     281:        md(pb3, mp, "dir2/subdir");
                    282:        if (rump_sys_rename(pb1, pb3) == -1)
                    283:                atf_tc_fail_errno("rename 9");
                    284:        checkfile(pb3, &ref);
1.16      pooka     285:
                    286:        /* rename directory over an empty directory */
                    287:        md(pb1, mp, "parent");
                    288:        md(pb2, mp, "parent/dir1");
                    289:        md(pb3, mp, "parent/dir2");
                    290:        RL(rump_sys_mkdir(pb1, 0777));
                    291:        RL(rump_sys_mkdir(pb2, 0777));
                    292:        RL(rump_sys_mkdir(pb3, 0777));
                    293:        RL(rump_sys_rename(pb2, pb3));
                    294:
                    295:        RL(rump_sys_stat(pb1, &sb));
                    296:        ATF_CHECK_EQ(sb.st_nlink, 3);
                    297:        RL(rump_sys_rmdir(pb3));
                    298:        if (FSTYPE_TMPFS(tc))
                    299:                atf_tc_expect_signal(-1, "PR kern/44288");
                    300:        RL(rump_sys_rmdir(pb1));
1.20    ! pooka     301:
        !           302:        if (FSTYPE_MSDOS(tc))
        !           303:                atf_tc_expect_fail("PR kern/44661");
1.2       pooka     304: }
                    305:
                    306: static void
                    307: rename_dotdot(const atf_tc_t *tc, const char *mp)
                    308: {
                    309:
1.10      pooka     310:        if (FSTYPE_RUMPFS(tc))
                    311:                atf_tc_skip("rename not supported by fs");
                    312:
1.2       pooka     313:        USES_DIRS;
                    314:
                    315:        if (rump_sys_chdir(mp) == -1)
                    316:                atf_tc_fail_errno("chdir mountpoint");
                    317:
                    318:        if (rump_sys_mkdir("dir1", 0777) == -1)
                    319:                atf_tc_fail_errno("mkdir 1");
                    320:        if (rump_sys_mkdir("dir2", 0777) == -1)
                    321:                atf_tc_fail_errno("mkdir 2");
                    322:
                    323:        if (rump_sys_rename("dir1", "dir1/..") != -1 || errno != EINVAL)
                    324:                atf_tc_fail_errno("self-dotdot to");
                    325:
                    326:        if (rump_sys_rename("dir1/..", "sometarget") != -1 || errno != EINVAL)
                    327:                atf_tc_fail_errno("self-dotdot from");
                    328:        atf_tc_expect_pass();
                    329:
                    330:        if (FSTYPE_TMPFS(tc)) {
                    331:                atf_tc_expect_fail("PR kern/43617");
                    332:        }
                    333:        if (rump_sys_rename("dir1", "dir2/..") != -1 || errno != EINVAL)
                    334:                atf_tc_fail("other-dotdot");
                    335:
                    336:        rump_sys_chdir("/");
                    337: }
                    338:
                    339: static void
                    340: rename_reg_nodir(const atf_tc_t *tc, const char *mp)
                    341: {
                    342:        bool haslinks;
                    343:        struct stat sb;
                    344:        ino_t f1ino, f2ino;
                    345:
1.10      pooka     346:        if (FSTYPE_RUMPFS(tc))
                    347:                atf_tc_skip("rename not supported by fs");
                    348:
1.3       pooka     349:        if (FSTYPE_MSDOS(tc))
                    350:                atf_tc_skip("test fails in some setups, reason unknown");
                    351:
1.2       pooka     352:        if (rump_sys_chdir(mp) == -1)
                    353:                atf_tc_fail_errno("chdir mountpoint");
                    354:
                    355:        if (FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))
                    356:                haslinks = false;
                    357:        else
                    358:                haslinks = true;
                    359:
                    360:        if (rump_sys_mknod("file1", S_IFREG | 0777, -1) == -1)
                    361:                atf_tc_fail_errno("create file");
                    362:        if (rump_sys_mknod("file2", S_IFREG | 0777, -1) == -1)
                    363:                atf_tc_fail_errno("create file");
                    364:
                    365:        if (rump_sys_stat("file1", &sb) == -1)
                    366:                atf_tc_fail_errno("stat");
                    367:        f1ino = sb.st_ino;
                    368:
                    369:        if (haslinks) {
                    370:                if (rump_sys_link("file1", "file_link") == -1)
                    371:                        atf_tc_fail_errno("link");
                    372:                if (rump_sys_stat("file_link", &sb) == -1)
                    373:                        atf_tc_fail_errno("stat");
                    374:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    375:                ATF_REQUIRE_EQ(sb.st_nlink, 2);
                    376:        }
                    377:
                    378:        if (rump_sys_stat("file2", &sb) == -1)
                    379:                atf_tc_fail_errno("stat");
                    380:        f2ino = sb.st_ino;
                    381:
                    382:        if (rump_sys_rename("file1", "file3") == -1)
                    383:                atf_tc_fail_errno("rename 1");
                    384:        if (rump_sys_stat("file3", &sb) == -1)
                    385:                atf_tc_fail_errno("stat 1");
                    386:        if (haslinks) {
                    387:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    388:        }
                    389:        if (rump_sys_stat("file1", &sb) != -1 || errno != ENOENT)
                    390:                atf_tc_fail_errno("source 1");
                    391:
                    392:        if (rump_sys_rename("file3", "file2") == -1)
                    393:                atf_tc_fail_errno("rename 2");
                    394:        if (rump_sys_stat("file2", &sb) == -1)
                    395:                atf_tc_fail_errno("stat 2");
                    396:        if (haslinks) {
                    397:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    398:        }
                    399:
                    400:        if (rump_sys_stat("file3", &sb) != -1 || errno != ENOENT)
                    401:                atf_tc_fail_errno("source 2");
                    402:
                    403:        if (haslinks) {
                    404:                if (rump_sys_rename("file2", "file_link") == -1)
                    405:                        atf_tc_fail_errno("rename hardlink");
                    406:                if (rump_sys_stat("file2", &sb) != -1 || errno != ENOENT)
                    407:                        atf_tc_fail_errno("source 3");
                    408:                if (rump_sys_stat("file_link", &sb) == -1)
                    409:                        atf_tc_fail_errno("stat 2");
                    410:                ATF_REQUIRE_EQ(sb.st_ino, f1ino);
                    411:                ATF_REQUIRE_EQ(sb.st_nlink, 1);
                    412:        }
                    413:
                    414:        rump_sys_chdir("/");
                    415: }
                    416:
1.5       njoly     417: static void
                    418: create_nametoolong(const atf_tc_t *tc, const char *mp)
                    419: {
                    420:        char *name;
                    421:        int fd;
                    422:        long val;
                    423:        size_t len;
                    424:
                    425:        if (rump_sys_chdir(mp) == -1)
                    426:                atf_tc_fail_errno("chdir mountpoint");
                    427:
                    428:        val = rump_sys_pathconf(".", _PC_NAME_MAX);
                    429:        if (val == -1)
                    430:                atf_tc_fail_errno("pathconf");
                    431:
                    432:        len = val + 1;
                    433:        name = malloc(len+1);
                    434:        if (name == NULL)
                    435:                atf_tc_fail_errno("malloc");
                    436:
                    437:        memset(name, 'a', len);
                    438:        *(name+len) = '\0';
                    439:
                    440:        val = rump_sys_pathconf(".", _PC_NO_TRUNC);
                    441:        if (val == -1)
                    442:                atf_tc_fail_errno("pathconf");
                    443:
                    444:        if (FSTYPE_MSDOS(tc))
                    445:                atf_tc_expect_fail("PR kern/43670");
                    446:        fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666);
                    447:        if (val != 0 && (fd != -1 || errno != ENAMETOOLONG))
                    448:                atf_tc_fail_errno("open");
                    449:
                    450:        if (val == 0 && rump_sys_close(fd) == -1)
                    451:                atf_tc_fail_errno("close");
                    452:        if (val == 0 && rump_sys_unlink(name) == -1)
                    453:                atf_tc_fail_errno("unlink");
                    454:
                    455:        free(name);
                    456:
                    457:        rump_sys_chdir("/");
                    458: }
                    459:
                    460: static void
1.14      yamt      461: create_exist(const atf_tc_t *tc, const char *mp)
                    462: {
                    463:        const char *name = "hoge";
                    464:        int fd;
                    465:
                    466:        RL(rump_sys_chdir(mp));
                    467:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666));
                    468:        RL(rump_sys_close(fd));
                    469:        RL(rump_sys_unlink(name));
                    470:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666));
                    471:        RL(rump_sys_close(fd));
                    472:        RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666));
                    473:        RL(rump_sys_close(fd));
                    474:        ATF_REQUIRE_ERRNO(EEXIST,
                    475:            (fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666)));
                    476:        RL(rump_sys_unlink(name));
                    477:        RL(rump_sys_chdir("/"));
                    478: }
                    479:
                    480: static void
1.5       njoly     481: rename_nametoolong(const atf_tc_t *tc, const char *mp)
                    482: {
                    483:        char *name;
                    484:        int res, fd;
                    485:        long val;
                    486:        size_t len;
                    487:
1.10      pooka     488:        if (FSTYPE_RUMPFS(tc))
                    489:                atf_tc_skip("rename not supported by fs");
                    490:
1.5       njoly     491:        if (rump_sys_chdir(mp) == -1)
                    492:                atf_tc_fail_errno("chdir mountpoint");
                    493:
                    494:        val = rump_sys_pathconf(".", _PC_NAME_MAX);
                    495:        if (val == -1)
                    496:                atf_tc_fail_errno("pathconf");
                    497:
                    498:        len = val + 1;
                    499:        name = malloc(len+1);
                    500:        if (name == NULL)
                    501:                atf_tc_fail_errno("malloc");
                    502:
                    503:        memset(name, 'a', len);
                    504:        *(name+len) = '\0';
                    505:
                    506:        fd = rump_sys_open("dummy", O_RDWR|O_CREAT, 0666);
                    507:        if (fd == -1)
                    508:                atf_tc_fail_errno("open");
                    509:        if (rump_sys_close(fd) == -1)
                    510:                atf_tc_fail_errno("close");
                    511:
                    512:        val = rump_sys_pathconf(".", _PC_NO_TRUNC);
                    513:        if (val == -1)
                    514:                atf_tc_fail_errno("pathconf");
                    515:
                    516:        if (FSTYPE_MSDOS(tc))
                    517:                atf_tc_expect_fail("PR kern/43670");
                    518:        res = rump_sys_rename("dummy", name);
                    519:        if (val != 0 && (res != -1 || errno != ENAMETOOLONG))
                    520:                atf_tc_fail_errno("rename");
                    521:
                    522:        if (val == 0 && rump_sys_unlink(name) == -1)
                    523:                atf_tc_fail_errno("unlink");
                    524:
                    525:        free(name);
                    526:
                    527:        rump_sys_chdir("/");
                    528: }
                    529:
1.7       pooka     530: static void
                    531: symlink_zerolen(const atf_tc_t *tc, const char *mp)
                    532: {
                    533:
                    534:        USES_SYMLINKS;
                    535:
                    536:        RL(rump_sys_chdir(mp));
1.8       pooka     537:
                    538:        if (FSTYPE_TMPFS(tc)) {
                    539:                atf_tc_expect_signal(SIGABRT, "PR kern/43843");
                    540:        }
                    541:
1.7       pooka     542:        RL(rump_sys_symlink("", "afile"));
                    543:        RL(rump_sys_chdir("/"));
                    544: }
                    545:
1.11      pooka     546: static void
                    547: attrs(const atf_tc_t *tc, const char *mp)
                    548: {
                    549:        struct stat sb, sb2;
                    550:        struct timeval tv[2];
                    551:        int fd;
                    552:
                    553:        FSTEST_ENTER();
                    554:        RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
                    555:        RL(rump_sys_close(fd));
                    556:        RL(rump_sys_stat(TESTFILE, &sb));
                    557:        if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
                    558:                RL(rump_sys_chown(TESTFILE, 1, 2));
                    559:                sb.st_uid = 1;
                    560:                sb.st_gid = 2;
                    561:                RL(rump_sys_chmod(TESTFILE, 0123));
                    562:                sb.st_mode = (sb.st_mode & ~ACCESSPERMS) | 0123;
                    563:        }
                    564:
                    565:        tv[0].tv_sec = 1000000000; /* need something >1980 for msdosfs */
                    566:        tv[0].tv_usec = 1;
                    567:        tv[1].tv_sec = 1000000002; /* need even seconds for msdosfs */
                    568:        tv[1].tv_usec = 3;
                    569:        RL(rump_sys_utimes(TESTFILE, tv));
                    570:        RL(rump_sys_utimes(TESTFILE, tv)); /* XXX: utimes & birthtime */
                    571:        sb.st_atimespec.tv_sec = 1000000000;
                    572:        sb.st_atimespec.tv_nsec = 1000;
                    573:        sb.st_mtimespec.tv_sec = 1000000002;
                    574:        sb.st_mtimespec.tv_nsec = 3000;
                    575:
                    576:        RL(rump_sys_stat(TESTFILE, &sb2));
                    577: #define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a)
                    578:        if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
                    579:                CHECK(st_uid);
                    580:                CHECK(st_gid);
                    581:                CHECK(st_mode);
                    582:        }
                    583:        if (!FSTYPE_MSDOS(tc)) {
                    584:                /* msdosfs has only access date, not time */
                    585:                CHECK(st_atimespec.tv_sec);
                    586:        }
                    587:        CHECK(st_mtimespec.tv_sec);
                    588:        if (!(FSTYPE_EXT2FS(tc) || FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) {
                    589:                CHECK(st_atimespec.tv_nsec);
                    590:                CHECK(st_mtimespec.tv_nsec);
                    591:        }
                    592: #undef  CHECK
                    593:
                    594:        FSTEST_EXIT();
                    595: }
                    596:
1.12      kefren    597: static void
                    598: fcntl_lock(const atf_tc_t *tc, const char *mp)
                    599: {
                    600:        int fd, fd2;
                    601:        struct flock l;
                    602:        struct lwp *lwp1, *lwp2;
                    603:
                    604:        FSTEST_ENTER();
                    605:        l.l_pid = 0;
                    606:        l.l_start = l.l_len = 1024;
                    607:        l.l_type = F_RDLCK | F_WRLCK;
                    608:        l.l_whence = SEEK_END;
                    609:
                    610:        lwp1 = rump_pub_lwproc_curlwp();
                    611:        RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755));
                    612:        RL(rump_sys_ftruncate(fd, 8192));
                    613:
                    614:        /* PR kern/43321 */
                    615:        RL(rump_sys_fcntl(fd, F_SETLK, &l));
                    616:
                    617:        /* Next, we fork and try to lock the same area */
                    618:        RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
                    619:        lwp2 = rump_pub_lwproc_curlwp();
                    620:        RL(fd2 = rump_sys_open(TESTFILE, O_RDWR, 0));
                    621:        ATF_REQUIRE_ERRNO(EAGAIN, rump_sys_fcntl(fd2, F_SETLK, &l));
                    622:
                    623:        /* Switch back and unlock... */
                    624:        rump_pub_lwproc_switch(lwp1);
                    625:        l.l_type = F_UNLCK;
                    626:        RL(rump_sys_fcntl(fd, F_SETLK, &l));
                    627:
                    628:        /* ... and try to lock again */
                    629:        rump_pub_lwproc_switch(lwp2);
                    630:        l.l_type = F_RDLCK | F_WRLCK;
                    631:        RL(rump_sys_fcntl(fd2, F_SETLK, &l));
                    632:
                    633:        RL(rump_sys_close(fd2));
                    634:        rump_pub_lwproc_releaselwp();
                    635:
                    636:        RL(rump_sys_close(fd));
                    637:
                    638:        FSTEST_EXIT();
                    639: }
                    640:
1.13      pooka     641: static int
                    642: flock_compare(const void *p, const void *q)
                    643: {
                    644:        int a = ((const struct flock *)p)->l_start;
                    645:        int b = ((const struct flock *)q)->l_start;
                    646:        return a < b ? -1 : (a > b ? 1 : 0);
                    647: }
                    648:
                    649: static void
                    650: fcntl_getlock_pids(const atf_tc_t *tc, const char *mp)
                    651: {
                    652:        /* test non-overlaping ranges */
                    653:        struct flock expect[4];
                    654:        const struct flock lock[4] = {
                    655:                { 0, 2, 0, F_WRLCK, SEEK_SET },
                    656:                { 2, 1, 0, F_WRLCK, SEEK_SET },
                    657:                { 7, 5, 0, F_WRLCK, SEEK_SET },
                    658:                { 4, 3, 0, F_WRLCK, SEEK_SET },
                    659:        };
                    660:
                    661:        int fd[4];
                    662:        struct lwp *lwp[4];
                    663:        pid_t prevpid = 0;
                    664:
                    665:        unsigned int i, j;
                    666:        const off_t sz = 8192;
                    667:        int omode  = 0755;
                    668:        int oflags = O_RDWR | O_CREAT;
                    669:
                    670:        memcpy(expect, lock, sizeof(lock));
                    671:        qsort(expect, __arraycount(expect), sizeof(expect[0]), &flock_compare);
                    672:
                    673:        FSTEST_ENTER();
                    674:
                    675:        /*
                    676:         * First, we create 4 processes and let each lock a range of the
                    677:         * file.  Note that the third and fourth processes lock in
                    678:         * "reverse" order, i.e. the greater pid locks a range before
                    679:         * the lesser pid.
                    680:         */
                    681:        for(i = 0; i < __arraycount(lwp); i++) {
                    682:                RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
                    683:
                    684:                lwp[i] = rump_pub_lwproc_curlwp();
                    685:                assert(rump_sys_getpid() > prevpid);
                    686:                prevpid = rump_sys_getpid();
                    687:
                    688:                RL(fd[i] = rump_sys_open(TESTFILE, oflags, omode));
                    689:                oflags = O_RDWR;
                    690:                omode  = 0;
                    691:
                    692:                RL(rump_sys_ftruncate(fd[i], sz));
                    693:                RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i]));
                    694:        }
                    695:
                    696:        atf_tc_expect_fail("PR kern/44494");
                    697:        /*
                    698:         * In the context of each pid , do GETLK for a readlock from
                    699:         * i = [0,__arraycount(locks)].  If we try to lock from the same
                    700:         * start offset as the lock our current process holds, check
                    701:         * that we fail on the offset of the next lock ("else if" branch).
                    702:         * Otherwise, expect to get a lock for the current offset
                    703:         * ("if" branch).  The "else" branch is purely for the last
                    704:         * process where we expect no blocking locks.
                    705:         */
                    706:        for(i = 0; i < __arraycount(lwp); i++) {
                    707:                rump_pub_lwproc_switch(lwp[i]);
                    708:
                    709:                for(j = 0; j < __arraycount(lwp); j++) {
                    710:                        struct flock l;
                    711:                        l = expect[j];
                    712:                        l.l_len = sz;
                    713:                        l.l_type = F_RDLCK;
                    714:
                    715:                        RL(rump_sys_fcntl(fd[i], F_GETLK, &l));
                    716:
                    717:                        if(expect[j].l_start != lock[i].l_start) {
                    718:                                /*
                    719:                                 * lock set by another process
                    720:                                 */
                    721:                                ATF_CHECK(l.l_type != F_UNLCK);
                    722:                                ATF_CHECK_EQ(l.l_start, expect[j].l_start);
                    723:                                ATF_CHECK_EQ(l.l_len,   expect[j].l_len);
                    724:                        } else if (j != __arraycount(lwp) - 1) {
                    725:                                /*
                    726:                                 * lock set by the current process
                    727:                                 */
                    728:                                ATF_CHECK(l.l_type != F_UNLCK);
                    729:                                ATF_CHECK_EQ(l.l_start, expect[j+1].l_start);
                    730:                                ATF_CHECK_EQ(l.l_len,   expect[j+1].l_len);
                    731:                        } else {
                    732:                                /*
                    733:                                 * there are no other locks after the
                    734:                                 * current process lock
                    735:                                 */
                    736:                                ATF_CHECK_EQ(l.l_type,   F_UNLCK);
                    737:                                ATF_CHECK_EQ(l.l_start,  expect[j].l_start);
                    738:                                ATF_CHECK_EQ(l.l_len,    sz);
                    739:                                ATF_CHECK_EQ(l.l_pid,    expect[j].l_pid);
                    740:                                ATF_CHECK_EQ(l.l_whence, expect[j].l_whence);
                    741:                        }
                    742:                }
                    743:        }
                    744:
                    745:        /*
                    746:         * Release processes.  This also releases the fds and locks
                    747:         * making fs unmount possible
                    748:         */
                    749:        for(i = 0; i < __arraycount(lwp); i++) {
                    750:                rump_pub_lwproc_switch(lwp[i]);
                    751:                rump_pub_lwproc_releaselwp();
                    752:        }
                    753:
                    754:        FSTEST_EXIT();
                    755: }
                    756:
1.15      pooka     757: static void
                    758: access_simple(const atf_tc_t *tc, const char *mp)
                    759: {
                    760:        int fd;
                    761:        int tmode;
                    762:
                    763:        FSTEST_ENTER();
                    764:        RL(fd = rump_sys_open("tfile", O_CREAT | O_RDWR, 0777));
                    765:        RL(rump_sys_close(fd));
                    766:
                    767: #define ALLACC (F_OK | X_OK | W_OK | R_OK)
                    768:        if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc))
                    769:                tmode = F_OK;
                    770:        else
                    771:                tmode = ALLACC;
                    772:
                    773:        RL(rump_sys_access("tfile", tmode));
                    774:
                    775:        /* PR kern/44648 */
                    776:        ATF_REQUIRE_ERRNO(EINVAL, rump_sys_access("tfile", ALLACC+1) == -1);
                    777: #undef ALLACC
                    778:        FSTEST_EXIT();
                    779: }
                    780:
1.1       pooka     781: ATF_TC_FSAPPLY(lookup_simple, "simple lookup (./.. on root)");
                    782: ATF_TC_FSAPPLY(lookup_complex, "lookup of non-dot entries");
                    783: ATF_TC_FSAPPLY(dir_simple, "mkdir/rmdir");
                    784: ATF_TC_FSAPPLY(dir_notempty, "non-empty directories cannot be removed");
1.18      pooka     785: ATF_TC_FSAPPLY(dir_rmdirdotdot, "remove .. and try to cd out");
1.2       pooka     786: ATF_TC_FSAPPLY(rename_dir, "exercise various directory renaming ops");
                    787: ATF_TC_FSAPPLY(rename_dotdot, "rename dir ..");
                    788: ATF_TC_FSAPPLY(rename_reg_nodir, "rename regular files, no subdirectories");
1.5       njoly     789: ATF_TC_FSAPPLY(create_nametoolong, "create file with name too long");
1.14      yamt      790: ATF_TC_FSAPPLY(create_exist, "create with O_EXCL");
1.5       njoly     791: ATF_TC_FSAPPLY(rename_nametoolong, "rename to file with name too long");
1.7       pooka     792: ATF_TC_FSAPPLY(symlink_zerolen, "symlink with 0-len target");
1.11      pooka     793: ATF_TC_FSAPPLY(attrs, "check setting attributes works");
1.12      kefren    794: ATF_TC_FSAPPLY(fcntl_lock, "check fcntl F_SETLK");
1.13      pooka     795: ATF_TC_FSAPPLY(fcntl_getlock_pids,"fcntl F_GETLK w/ many procs, PR kern/44494");
1.15      pooka     796: ATF_TC_FSAPPLY(access_simple, "access(2)");
1.1       pooka     797:
                    798: ATF_TP_ADD_TCS(tp)
                    799: {
                    800:
                    801:        ATF_TP_FSAPPLY(lookup_simple);
                    802:        ATF_TP_FSAPPLY(lookup_complex);
                    803:        ATF_TP_FSAPPLY(dir_simple);
                    804:        ATF_TP_FSAPPLY(dir_notempty);
1.18      pooka     805:        ATF_TP_FSAPPLY(dir_rmdirdotdot);
1.2       pooka     806:        ATF_TP_FSAPPLY(rename_dir);
                    807:        ATF_TP_FSAPPLY(rename_dotdot);
                    808:        ATF_TP_FSAPPLY(rename_reg_nodir);
1.5       njoly     809:        ATF_TP_FSAPPLY(create_nametoolong);
1.14      yamt      810:        ATF_TP_FSAPPLY(create_exist);
1.5       njoly     811:        ATF_TP_FSAPPLY(rename_nametoolong);
1.7       pooka     812:        ATF_TP_FSAPPLY(symlink_zerolen);
1.11      pooka     813:        ATF_TP_FSAPPLY(attrs);
1.12      kefren    814:        ATF_TP_FSAPPLY(fcntl_lock);
1.13      pooka     815:        ATF_TP_FSAPPLY(fcntl_getlock_pids);
1.15      pooka     816:        ATF_TP_FSAPPLY(access_simple);
1.1       pooka     817:
                    818:        return atf_no_error();
                    819: }

CVSweb <webmaster@jp.NetBSD.org>