make vfs & filesystems use failable copying
[minix3.git] / test / test55.c
blob2c8cdc1ff74be020132356f029829d0de8418b82
1 /* Tests for statvfs(2) call family */
2 #include <sys/statvfs.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <assert.h>
6 #include <fcntl.h>
7 #include <err.h>
8 #include <unistd.h>
9 #define TRIALS 10
10 #define SIZE 65536
11 #define FSMAX 64
13 int max_error = 3;
14 #include "common.h"
16 int do_getvfsstat(struct statvfs *buf, size_t bufsz, int flags, int count);
17 void compare_statvfs(struct statvfs *st1, struct statvfs *st2);
18 void test55a(void);
19 void test55b(void);
21 int subtest;
22 char filename[] = "statvfs_test_XXXXXX";
24 static void create_file(void)
26 char buf[SIZE]={0};
27 char *p;
28 ssize_t ntowrite, nwritten;
29 int fd;
31 subtest = 2;
32 if ((fd = mkstemp(filename)) < 0) e(1);
34 ntowrite = SIZE;
35 p = &buf[0];
36 while (ntowrite > 0) {
37 if ((nwritten = write(fd, p, ntowrite)) < 0) e(2);
38 p += nwritten;
39 ntowrite -= nwritten;
42 if (close(fd) < 0) e(3);
45 void test55a(void)
47 struct statvfs stats;
48 unsigned long f_bsize, f_bsize_new;
49 unsigned long f_frsize, f_frsize_new;
50 fsblkcnt_t f_blocks, f_blocks_new;
51 fsblkcnt_t f_bfree, f_bfree_new;
52 fsblkcnt_t f_bavail, f_bavail_new;
53 fsfilcnt_t f_files, f_files_new;
54 fsfilcnt_t f_ffree, f_ffree_new;
55 fsfilcnt_t f_favail, f_favail_new;
56 unsigned long f_fsid, f_fsid_new;
57 unsigned long f_flag, f_flag_new;
58 unsigned long f_namemax, f_namemax_new;
60 subtest = 1;
62 if (statvfs(".", &stats) < 0) e(1);
64 f_bsize = stats.f_bsize ;
65 f_frsize = stats.f_frsize ;
66 f_blocks = stats.f_blocks ;
67 f_bfree = stats.f_bfree ;
68 f_bavail = stats.f_bavail ;
69 f_files = stats.f_files ;
70 f_ffree = stats.f_ffree ;
71 f_favail = stats.f_favail ;
72 f_fsid = stats.f_fsid ;
73 f_flag = stats.f_flag ;
74 f_namemax = stats.f_namemax;
76 create_file();
78 if (statvfs(".", &stats) < 0) e(2);
79 if (unlink(filename) < 0) e(3);
81 f_bsize_new = stats.f_bsize ;
82 f_frsize_new = stats.f_frsize ;
83 f_blocks_new = stats.f_blocks ;
84 f_bfree_new = stats.f_bfree ;
85 f_bavail_new = stats.f_bavail ;
86 f_files_new = stats.f_files ;
87 f_ffree_new = stats.f_ffree ;
88 f_favail_new = stats.f_favail ;
89 f_fsid_new = stats.f_fsid ;
90 f_flag_new = stats.f_flag ;
91 f_namemax_new = stats.f_namemax;
93 if (!((f_bsize == f_bsize_new) &&
94 (f_frsize == f_frsize_new) &&
95 (f_blocks == f_blocks_new) &&
96 (f_bfree > f_bfree_new) &&
97 (f_bavail > f_bavail_new) &&
98 (f_files == f_files_new) &&
99 (f_ffree == f_ffree_new + 1) &&
100 (f_favail == f_favail_new + 1) &&
101 (f_fsid == f_fsid_new) &&
102 (f_flag == f_flag_new) &&
103 (f_namemax == f_namemax_new))) {
104 e(4);
108 int do_getvfsstat(struct statvfs *buf, size_t bufsz, int flags, int count)
110 int i, j;
112 if (getvfsstat(buf, bufsz, flags) != count) e(101);
114 /* All file system identifiers should be unique. */
115 for (i = 0; i < count - 1; i++) {
116 for (j = i + 1; j < count; j++) {
117 if (buf[i].f_fsid == buf[j].f_fsid) e(102);
118 if (!memcmp(&buf[i].f_fsidx, &buf[j].f_fsidx,
119 sizeof(buf[j].f_fsidx))) e(103);
123 /* Expect one root file system. */
124 j = -1;
125 for (i = 0; i < count; i++) {
126 if (!strcmp(buf[i].f_mntonname, "/")) {
127 if (j != -1) e(104);
128 j = i;
131 if (j == -1) e(105);
133 return j;
136 void compare_statvfs(struct statvfs *st1, struct statvfs *st2)
138 int i;
140 /* The structures should basically be identical, but a background
141 * process calling statvfs for some reason might screw things up.
142 * Thus, we only compare fields that we know should be identical.
143 * For the strings, we use memcmp rather than strcmp to ensure that
144 * no garbage is left in the fields.
146 if (st1->f_flag != st2->f_flag) e(201);
147 if (st1->f_bsize != st2->f_bsize) e(202);
148 if (st1->f_frsize != st2->f_frsize) e(203);
149 if (st1->f_iosize != st2->f_iosize) e(204);
151 if (st1->f_fsid != st2->f_fsid) e(205);
152 if (memcmp(&st1->f_fsidx, &st2->f_fsidx, sizeof(st1->f_fsidx))) e(206);
154 if (st1->f_namemax != st2->f_namemax) e(207);
155 if (st1->f_owner != st2->f_owner) e(208);
157 for (i = 0; i < sizeof(st1->f_spare) / sizeof(st1->f_spare[0]); i++) {
158 if (st1->f_spare[i] != 0) e(209);
159 if (st2->f_spare[i] != 0) e(210);
162 if (memcmp(st1->f_fstypename, st2->f_fstypename,
163 sizeof(st1->f_fstypename))) e(211);
164 if (memcmp(st1->f_mntonname, st2->f_mntonname,
165 sizeof(st1->f_mntonname))) e(212);
166 if (memcmp(st1->f_mntfromname, st2->f_mntfromname,
167 sizeof(st1->f_mntfromname))) e(213);
170 void test55b(void)
172 static struct statvfs buf[FSMAX];
173 struct statvfs rootbuf;
174 int count, root;
176 subtest = 2;
178 count = getvfsstat(NULL, 0, ST_WAIT);
179 if (count < 2) e(1); /* we have at least the root FS and ProcFS */
180 if (count > FSMAX) e(2);
182 if (getvfsstat(buf, 0, ST_WAIT) != 0) e(3);
183 if (getvfsstat(buf, sizeof(buf[0]) - 1, ST_WAIT) != 0) e(4);
184 if (getvfsstat(buf, sizeof(buf[0]), ST_WAIT) != 1) e(5);
185 if (getvfsstat(buf, sizeof(buf[0]) + 1, ST_WAIT) != 1) e(6);
186 if (getvfsstat(buf, sizeof(buf[0]) * 2, ST_WAIT) != 2) e(7);
188 /* We assume that nothing is being un/mounted right now. */
189 root = do_getvfsstat(buf, sizeof(buf), ST_WAIT, count);
191 /* Compare cached and uncached copies. */
192 if (statvfs1("/", &rootbuf, ST_NOWAIT) != 0) e(13);
193 compare_statvfs(&buf[root], &rootbuf);
195 /* Do the same again, but now the other way around. */
196 rootbuf = buf[root];
197 root = do_getvfsstat(buf, sizeof(buf), ST_NOWAIT, count);
198 compare_statvfs(&buf[root], &rootbuf);
201 int main(int argc, char **argv)
203 int i;
205 start(55);
207 for(i = 0; i < TRIALS; i++) {
208 test55a();
209 test55b();
212 quit();
213 return(-1);