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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
38 #define _GNU_SOURCE /* pull in O_DIRECTORY in bits/fcntl.h */
44 #include <sys/types.h>
48 #include <sys/ioctl.h>
52 #include <semaphore.h>
55 #include <lustre/lustre_idl.h>
56 #include <lustre/lustreapi.h>
58 #define T1 "write data before unlink\n"
59 #define T2 "write data after unlink\n"
60 char msg[] = "yabba dabba doo, I'm coming for you, I live in a shoe, I don't know what to do.\n'Bigger, bigger,and bigger yet!' cried the Creator. 'You are not yet substantial enough for my boundless intents!' And ever greater and greater the object became, until all was lost 'neath its momentus bulk.\n";
61 char *buf, *buf_align;
64 #define ALIGN_LEN 65535
67 "Usage: %s filename command-sequence\n"
68 " command-sequence items:\n"
70 " C[num] create with optional stripes\n"
72 " D open(O_DIRECTORY)\n"
75 " G gid get grouplock\n"
76 " g gid put grouplock\n"
80 " M rw mmap to EOF (must open and stat prior)\n"
83 " O open(O_CREAT|O_RDWR)\n"
84 " r[num] read [optional length]\n"
85 " R reference entire mmap-ed region\n"
89 " T[num] ftruncate [optional position, default 0]\n"
93 " V open a volatile file\n"
94 " w[num] write optional length\n"
95 " W write entire mmap-ed region\n"
98 " z[num] seek [optional position, default 0]\n"
99 " _ wait for signal\n";
101 void usr1_handler(int unused)
103 int saved_errno = errno;
106 * signal(7): POSIX.1-2004 ...requires an implementation to guarantee
107 * that the following functions can be safely called inside a signal
117 pop_arg(int argc, char *argv[])
119 static int cur_arg = 3;
124 return argv[cur_arg++];
127 struct flag_mapping {
131 {"O_RDONLY", O_RDONLY},
132 {"O_WRONLY", O_WRONLY},
134 {"O_CREAT", O_CREAT},
136 {"O_NOCTTY", O_NOCTTY},
137 {"O_TRUNC", O_TRUNC},
138 {"O_APPEND", O_APPEND},
139 {"O_NONBLOCK", O_NONBLOCK},
140 {"O_NDELAY", O_NDELAY},
143 {"O_DIRECT", O_DIRECT},
145 {"O_LARGEFILE", O_LARGEFILE},
146 {"O_DIRECTORY", O_DIRECTORY},
147 {"O_NOFOLLOW", O_NOFOLLOW},
151 int get_flags(char *data, int *rflags)
159 cloned_flags = strdup(data);
160 if (cloned_flags == NULL) {
161 fprintf(stderr, "Insufficient memory.\n");
165 for (tmp = strtok(cloned_flags, ":"); tmp;
166 tmp = strtok(NULL, ":")) {
169 size = tmp - cloned_flags;
170 for (i = 0; flag_table[i].flag != -1; i++) {
171 if (!strcmp(tmp, flag_table[i].string)){
172 flags |= flag_table[i].flag;
173 size += strlen(flag_table[i].string);
190 #define POP_ARG() (pop_arg(argc, argv))
192 int main(int argc, char **argv)
194 char *fname, *commands;
198 size_t mmap_len = 0, i;
199 unsigned char *mmap_ptr = NULL, junk = 0;
200 int rc, len, fd = -1;
209 fprintf(stderr, usage, argv[0]);
213 memset(&st, 0, sizeof(st));
214 sem_init(&sem, 0, 0);
215 /* use sigaction instead of signal to avoid SA_ONESHOT semantics */
216 sigaction(SIGUSR1, &(const struct sigaction){.sa_handler = &usr1_handler},
221 for (commands = argv[2]; *commands; commands++) {
228 len = atoi(commands+1);
230 len = 3600; /* 1 hour */
231 ts.tv_sec = time(NULL) + len;
233 while (sem_timedwait(&sem, &ts) < 0 && errno == EINTR);
236 if (close(fd) == -1) {
244 len = atoi(commands+1);
245 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
249 perror("create stripe file");
254 if (mkdir(fname, 0755) == -1) {
256 perror("mkdir(0755)");
261 fd = open(fname, O_DIRECTORY);
264 perror("open(O_DIRECTORY)");
269 if (statfs(fname, &stfs) == -1) {
277 rc = llapi_path2fid(fname, &fid);
279 rc = llapi_fd2fid(fd, &fid);
282 "llapi_path/fd2fid() on %d, rc=%d\n",
285 printf(DFID"\n", PFID(&fid));
288 gid = atoi(commands+1);
289 if (ioctl(fd, LL_IOC_GROUP_LOCK, gid) == -1) {
291 perror("ioctl(GROUP_LOCK)");
296 gid = atoi(commands+1);
297 if (ioctl(fd, LL_IOC_GROUP_UNLOCK, gid) == -1) {
299 perror("ioctl(GROUP_UNLOCK)");
307 if (symlink(fname, newfile)) {
317 if (link(fname, newfile)) {
324 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
326 perror("mknod(S_IFREG|0644, 0)");
331 if (st.st_size == 0) {
332 fprintf(stderr, "mmap without preceeding stat, or on"
333 " zero length file.\n");
336 mmap_len = st.st_size;
337 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
339 if (mmap_ptr == MAP_FAILED) {
349 if (rename (fname, newfile)) {
356 fd = open(fname, O_CREAT|O_RDWR, 0644);
359 perror("open(O_RDWR|O_CREAT)");
364 len = get_flags(commands+1, &flags);
367 fd = open(fname, flags, 0666);
369 fd = open(fname, flags);
377 len = atoi(commands+1);
381 buf = realloc(buf, len + ALIGN_LEN);
384 perror("allocating buf for read\n");
388 buf_align = (char *)((long)(buf + ALIGN_LEN) &
392 rc = read(fd, buf_align, len);
399 fprintf(stderr, "short read: %u/%u\n",
406 printf("%.*s\n", rc, buf_align);
410 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
414 if (stat(fname, &st) == -1) {
421 if (fstat(fd, &st) == -1) {
428 if (fchmod(fd, 0) == -1) {
435 len = atoi(commands+1);
436 if (ftruncate(fd, len) == -1) {
438 printf("ftruncate (%d,%d)\n", fd, len);
444 if (unlink(fname) == -1) {
451 if (munmap(mmap_ptr, mmap_len)) {
461 len = get_flags(commands + 1, &flags);
463 fd = llapi_create_volatile(fname, flags);
465 perror("llapi_create_volatile");
470 len = atoi(commands+1);
474 buf = realloc(buf, len + ALIGN_LEN);
477 perror("allocating buf for write\n");
481 buf_align = (char *)((long)(buf + ALIGN_LEN) &
483 strncpy(buf_align, msg, bufsize);
486 rc = write(fd, buf_align, len);
493 fprintf(stderr, "short write: %u/%u\n",
499 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
500 mmap_ptr[i] += junk++;
503 if (fsync(fd) == -1) {
510 if (fdatasync(fd) == -1) {
516 len = atoi(commands+1);
517 if (lseek(fd, len, SEEK_SET) == -1) {
535 fprintf(stderr, "unknown command \"%c\"\n", *commands);
536 fprintf(stderr, usage, argv[0]);