xref: /freebsd/tools/test/stress2/misc/rename_exchange.sh (revision 9c6ed9a88d3afb8bc9aba7cf852cc36e03bcd34c)
1#!/bin/sh
2
3# Test of RENAME_EXCHANGE for tmpfs
4
5. ../default.cfg
6set -u
7prog=$(basename "$0" .sh)
8cat > /tmp/$prog.c <<EOF
9#include <sys/param.h>
10#include <sys/stat.h>
11#include <assert.h>
12#include <err.h>
13#include <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <time.h>
18#include <unistd.h>
19
20#if ! defined(AT_RENAME_EXCHANGE)
21#define AT_RENAME_EXCHANGE 0x0002
22#endif
23
24static char *dir, *f1, *f2;
25
26void
27test1(void)
28{
29	struct stat s, s1, s2;
30	time_t start;
31	char file1[1024], file2[1024];
32
33	snprintf(file1, sizeof(file1), "%s/%s", dir, f1);
34	snprintf(file2, sizeof(file2), "%s/%s", dir, f2);
35	if (stat(file1, &s1) < 0)
36		err(1, "stat(%s)", file1);
37	if (stat(file2, &s2) < 0)
38		err(1, "stat(%s)", file2);
39	assert(s1.st_size != s2.st_size);
40	start = time(NULL);
41	while (time(NULL) - start < 30) {
42		if (renameat2(AT_FDCWD, file1, AT_FDCWD, file2, RENAME_EXCHANGE) == -1)
43			err(1, "%s: rename2(%s, %s)", __func__, file1, file2);
44
45		if (stat(file1, &s) < 0)
46			err(1, "statfs(%s)", file1);
47		if (s.st_size != s2.st_size)
48			errx(1, "Got size %jd, expected %jd", (uintmax_t)s.st_size, (uintmax_t)s2.st_size);
49
50		if (renameat2(AT_FDCWD, file2, AT_FDCWD, file1, RENAME_EXCHANGE) == -1)
51			err(1, "%s: rename2(%s, %s)", __func__, file2, file1);
52	}
53}
54
55void
56test2(void)
57{
58	time_t start;
59	char cwd[1024];
60
61	if (getcwd(cwd, sizeof(cwd)) == NULL)
62		err(1, "getcwd()");
63	chdir(dir);
64	start = time(NULL);
65	while (time(NULL) - start < 30) {
66		if (renameat2(AT_FDCWD, f1, AT_FDCWD, f2, RENAME_EXCHANGE) == -1)
67			err(1, "%s: rename2(%s, %s)", __func__, f1, f2);
68
69		if (renameat2(AT_FDCWD, f2, AT_FDCWD, f1, RENAME_EXCHANGE) == -1)
70			err(1, "%s: rename2(%s, %s)", __func__, f2, f1);
71	}
72	chdir(cwd);
73}
74
75/* rename(<file>, <non existing file>) */
76void
77test3(void)
78{
79	int e;
80	char file1[1024], file2[1024];
81
82	snprintf(file1, sizeof(file1), "%s/%s", dir, f1);
83	snprintf(file2, sizeof(file2), "%s/NotThere", dir);
84	if (renameat2(AT_FDCWD, file1, AT_FDCWD, file2, RENAME_EXCHANGE) != -1)
85		err(1, "%s: rename2(%s, %s)", __func__, file1, file2);
86	e = errno;
87	if (e != ENOENT)
88		errx(1, "%s: Expected errno %i, got %d\n", __func__, ENOENT, e);
89
90	if (renameat2(AT_FDCWD, file2, AT_FDCWD, file1, RENAME_EXCHANGE) != -1)
91		err(1, "%s: rename2(%s, %s)", __func__, file2, file1);
92	e = errno;
93	if (e != ENOENT)
94		errx(1, "%s: Expected errno %i, got %d\n", __func__, ENOENT, e);
95}
96
97/* rename(<file>, <directory>) */
98void
99test4(void)
100{
101	int e;
102	char file1[1024], file2[1024];
103
104	snprintf(file1, sizeof(file1), "%s/%s", dir, f1);
105	snprintf(file2, sizeof(file2), "%s", dir);
106	if (renameat2(AT_FDCWD, file1, AT_FDCWD, file2, RENAME_EXCHANGE) != -1)
107		err(1, "%s: rename2(%s, %s)", __func__, file1, file2);
108	e = errno;
109	if (e != EINVAL)
110		errx(1, "%s: Expected errno %i, got %d\n", __func__, EINVAL, e);
111
112	if (renameat2(AT_FDCWD, file2, AT_FDCWD, file1, RENAME_EXCHANGE) != -1)
113		err(1, "%s: rename2(%s, %s)", __func__, file2, file1);
114	e = errno;
115	if (e != EINVAL)
116		errx(1, "%s: Expected errno %i, got %d\n", __func__, EINVAL, e);
117}
118
119int
120main(int argc, char *argv[])
121{
122
123	if (argc != 4) {
124		fprintf(stderr, "Usage: %s <dir> <file1> <file2>\n", argv[0]);
125		exit(1);
126	}
127	dir = argv[1];
128	f1 = argv[2];
129	f2 = argv[3];
130
131	test1();
132	test2();
133	test3();
134	test4();
135}
136EOF
137cc -o /tmp/$prog -Wall -Wextra -g -O0 /tmp/$prog.c || exit 1
138
139mount | grep -q "on $mntpoint " && umount $mntpoint
140size=2g
141mount -o size=${size}m -t tmpfs tmpfs $mntpoint
142
143../testcases/swap/swap -t 5m -i 20 > /dev/null &
144sleep 1
145
146for d in d1 d2 d3 d4 d5; do
147	mkdir $mntpoint/$d
148	echo 1  > $mntpoint/$d/f1
149	echo 22 > $mntpoint/$d/f2
150done
151cd $mntpoint
152for d in d1 d2 d3 d4 d5; do
153	/tmp/$prog $mntpoint/$d f1 f2 &
154done
155while pgrep -q $prog; do sleep .2; done
156cd -
157
158while pkill swap; do sleep .5; done
159wait
160
161umount $mntpoint
162exit 0
163