1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
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>
50 #include <libcfs/libcfs.h>
51 #include <lustre/liblustreapi.h>
53 #define T1 "write data before unlink\n"
54 #define T2 "write data after unlink\n"
55 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";
56 char *buf, *buf_align;
61 "Usage: %s filename command-sequence\n"
62 " command-sequence items:\n"
64 " C[num] create with optional stripes\n"
66 " D open(O_DIRECTORY)\n"
70 " M rw mmap to EOF (must open and stat prior)\n"
73 " O open(O_CREAT|O_RDWR)\n"
74 " r[num] read [optional length]\n"
75 " R reference entire mmap-ed region\n"
79 " T[num] ftruncate [optional position, default 0]\n"
83 " w[num] write optional length\n"
84 " W write entire mmap-ed region\n"
87 " z[num] seek [optional position, default 0]\n"
88 " _ wait for signal\n";
90 static int usr1_received;
91 void usr1_handler(int unused)
97 pop_arg(int argc, char *argv[])
99 static int cur_arg = 3;
104 return argv[cur_arg++];
107 struct flag_mapping {
111 {"O_RDONLY", O_RDONLY},
112 {"O_WRONLY", O_WRONLY},
114 {"O_CREAT", O_CREAT},
116 {"O_NOCTTY", O_NOCTTY},
117 {"O_TRUNC", O_TRUNC},
118 {"O_APPEND", O_APPEND},
119 {"O_NONBLOCK", O_NONBLOCK},
120 {"O_NDELAY", O_NDELAY},
123 {"O_DIRECT", O_DIRECT},
125 {"O_LARGEFILE", O_LARGEFILE},
126 {"O_DIRECTORY", O_DIRECTORY},
127 {"O_NOFOLLOW", O_NOFOLLOW},
131 int get_flags(char *data, int *rflags)
139 cloned_flags = strdup(data);
140 if (cloned_flags == NULL) {
141 fprintf(stderr, "Insufficient memory.\n");
145 for (tmp = strtok(cloned_flags, ":"); tmp;
146 tmp = strtok(NULL, ":")) {
149 size = tmp - cloned_flags;
150 for (i = 0; flag_table[i].flag != -1; i++) {
151 if (!strcmp(tmp, flag_table[i].string)){
152 flags |= flag_table[i].flag;
153 size += strlen(flag_table[i].string);
170 #define POP_ARG() (pop_arg(argc, argv))
171 #define min(a,b) ((a)>(b)?(b):(a))
173 int main(int argc, char **argv)
175 char *fname, *commands;
178 size_t mmap_len = 0, i;
179 unsigned char *mmap_ptr = NULL, junk = 0;
180 int rc, len, fd = -1;
186 fprintf(stderr, usage, argv[0]);
190 signal(SIGUSR1, usr1_handler);
194 for (commands = argv[2]; *commands; commands++) {
197 if (usr1_received == 0) {
205 signal(SIGUSR1, usr1_handler);
208 if (close(fd) == -1) {
216 len = atoi(commands+1);
217 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
221 perror("create stripe file");
226 if (mkdir(fname, 0755) == -1) {
228 perror("mkdir(0755)");
233 fd = open(fname, O_DIRECTORY);
236 perror("open(O_DIRECTORY)");
244 if (symlink(fname, newfile)) {
254 if (link(fname, newfile)) {
261 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
263 perror("mknod(S_IFREG|0644, 0)");
268 mmap_len = st.st_size;
269 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
271 if (mmap_ptr == MAP_FAILED) {
281 if (rename (fname, newfile)) {
288 fd = open(fname, O_CREAT|O_RDWR, 0644);
291 perror("open(O_RDWR|O_CREAT)");
296 len = get_flags(commands+1, &flags);
298 fd = open(fname, flags);
306 len = atoi(commands+1);
310 buf = realloc(buf, len + ALIGN);
313 perror("allocating buf for read\n");
317 buf_align = (char *)((long)(buf + ALIGN) &
321 rc = read(fd, buf_align, len);
328 fprintf(stderr, "short read: %u/%u\n",
332 printf("%.*s\n", rc, buf_align);
336 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
340 if (stat(fname, &st) == -1) {
347 if (fstat(fd, &st) == -1) {
354 if (fchmod(fd, 0) == -1) {
361 len = atoi(commands+1);
362 if (ftruncate(fd, len) == -1) {
364 printf("ftruncate (%d,%d)\n", fd, len);
370 if (unlink(fname) == -1) {
377 if (munmap(mmap_ptr, mmap_len)) {
387 len = atoi(commands+1);
391 buf = realloc(buf, len + ALIGN);
394 perror("allocating buf for write\n");
398 buf_align = (char *)((long)(buf + ALIGN) &
400 strncpy(buf_align, msg, bufsize);
403 rc = write(fd, buf_align, len);
410 fprintf(stderr, "short write: %u/%u\n",
416 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
417 mmap_ptr[i] += junk++;
420 if (fsync(fd) == -1) {
427 if (fdatasync(fd) == -1) {
433 len = atoi(commands+1);
434 if (lseek(fd, len, SEEK_SET) == -1) {
452 fprintf(stderr, "unknown command \"%c\"\n", *commands);
453 fprintf(stderr, usage, argv[0]);