4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
24 * The purpose of this test is to check Lustre API root fd cache.
26 * The program will exit as soon as a non zero error code is returned.
35 #include <sys/ioctl.h>
40 #include <lustre/lustreapi.h>
41 #include <linux/lustre/lustre_idl.h>
43 #define ERROR(fmt, ...) \
44 fprintf(stderr, "%s: %s:%d: %s: " fmt "\n", \
45 program_invocation_short_name, __FILE__, __LINE__, \
46 __func__, ## __VA_ARGS__)
48 #define DIE(fmt, ...) \
50 ERROR(fmt, ## __VA_ARGS__); \
54 #define ASSERTF(cond, fmt, ...) \
57 DIE("assertion '%s' failed: "fmt, \
58 #cond, ## __VA_ARGS__); \
61 #define PERFORM(testfn) \
64 fprintf(stderr, "Starting test " #testfn " at %lld\n", \
65 (unsigned long long)time(NULL)); \
67 fprintf(stderr, "Finishing test " #testfn " at %lld\n", \
68 (unsigned long long)time(NULL)); \
72 /* Name of file/directory. Will be set once and will not change. */
73 static char *mainpath; /* path to file on mountpoint 1 */
74 static char *mainpath2; /* path to file on mountpoint 2 */
76 static char mnt_dir[PATH_MAX]; /* Lustre mountpoint 1 */
77 static char mnt_dir2[PATH_MAX]; /* Lustre mountpoint 2 */
78 static int mnt_fd = -1;
79 static int mnt_fd2 = -1;
81 /* Cleanup our test directory. */
82 static void cleanup(void)
86 rc = remove(mainpath);
87 ASSERTF(!rc || errno == ENOENT,
88 "Failed to unlink %s: %s", mainpath, strerror(errno));
91 #define TEST1_THR_NBR 20
92 static void *test1_thr(void *arg)
100 rc = llapi_fid2path(mnt_dir2, fidstr, path,
101 sizeof(path), &recno, &linkno);
106 /* Race on root cache at startup */
107 static void test1(void)
109 static pthread_t thread[TEST1_THR_NBR];
113 char fidstr[FID_LEN + 1];
115 fd = creat(mainpath, 00660);
116 ASSERTF(fd >= 0, "creat failed for '%s': %s",
117 mainpath, strerror(errno));
119 rc = llapi_fd2fid(fd, &fid);
120 ASSERTF(rc == 0, "llapi_fd2fid failed for '%s': %s",
121 mainpath, strerror(-rc));
124 snprintf(fidstr, sizeof(fidstr), DFID_NOBRACE, PFID(&fid));
125 for (iter = 0; iter < 100; iter++) {
126 /* reset cache on first mountpoint */
127 fd = llapi_open_by_fid(mnt_dir, &fid, O_RDONLY);
128 ASSERTF(fd >= 0, "llapi_open_by_fid for " DFID_NOBRACE ": %d",
132 /* start threads with llapi_open_by_fid() */
133 for (i = 0; i < TEST1_THR_NBR; i++)
134 pthread_create(&thread[i], NULL, &test1_thr, fidstr);
136 for (i = 0; i < TEST1_THR_NBR; i++) {
137 pthread_join(thread[i], (void **) &rc);
139 "llapi_fid2path for " DFID_NOBRACE " (iter: %d, thr:%d): %s",
140 PFID(&fid), iter, i, strerror(-rc));
145 static void usage(char *prog)
147 fprintf(stderr, "Usage: %s [-h]\n", basename(prog));
148 fprintf(stderr, "or: %s FILEPATH1 FILEPATH2\n", basename(prog));
152 static void process_args(int argc, char *argv[])
154 /* default mountpoints used */
158 if (argc > 1 && argv[1][0] == '-')
161 if (argc <= 2 || argv[1][0] == '\0' || argv[2][0] == '\0')
169 static int fill_default_paths(void)
171 static char tmp1[PATH_MAX] = "/mnt/lustre/llapi_root_test.XXXXXX";
172 static char tmp2[PATH_MAX] = "/mnt/lustre2/";
175 /* default paths needed?*/
176 if (mainpath || mainpath2)
181 fprintf(stderr, "Failed to creat %s: %s\n",
182 tmp1, strerror(errno));
187 strcat(tmp2, basename(tmp1));
195 int main(int argc, char *argv[])
201 process_args(argc, argv);
202 fill_default_paths();
205 if (strcmp(basename(mainpath), basename(mainpath2)) != 0 ||
206 strcmp(mainpath, mainpath2) == 0) {
208 "%s and %s should be the same file on 2 distinct mountpoints\n",
209 mainpath, mainpath2);
213 rc = llapi_search_mounts(mainpath, 0, mnt_dir, fsname);
215 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
220 rc = llapi_search_mounts(mainpath2, 0, mnt_dir2, fsname2);
222 fprintf(stderr, "Error: %s: not a Lustre filesystem\n",
227 if (strcmp(fsname, fsname2) != 0) {
229 "%s and %s are not on the same filesystem (%s, %s)\n",
230 mnt_dir, mnt_dir2, fsname, fsname2);
234 mnt_fd = open(mnt_dir, O_RDONLY|O_DIRECTORY);
235 ASSERTF(mnt_fd >= 0, "cannot open '%s': %s\n", mnt_dir,
238 mnt_fd2 = open(mnt_dir2, O_RDONLY|O_DIRECTORY);
239 ASSERTF(mnt_fd2 >= 0, "cannot open '%s': %s\n", mnt_dir2,
242 fprintf(stderr, "Starting: %s %s %s\n\n",
243 basename(argv[0]), mainpath, mainpath2);
245 /* Play nice with Lustre test scripts. Non-line buffered output
246 * stream under I/O redirection may appear incorrectly.
248 setvbuf(stdout, NULL, _IOLBF, 0);