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 memset(&st, 0, sizeof(st));
191 signal(SIGUSR1, usr1_handler);
195 for (commands = argv[2]; *commands; commands++) {
198 if (usr1_received == 0) {
206 signal(SIGUSR1, usr1_handler);
209 if (close(fd) == -1) {
217 len = atoi(commands+1);
218 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
222 perror("create stripe file");
227 if (mkdir(fname, 0755) == -1) {
229 perror("mkdir(0755)");
234 fd = open(fname, O_DIRECTORY);
237 perror("open(O_DIRECTORY)");
245 if (symlink(fname, newfile)) {
255 if (link(fname, newfile)) {
262 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
264 perror("mknod(S_IFREG|0644, 0)");
269 if (st.st_size == 0) {
270 fprintf(stderr, "mmap without preceeding stat, or on"
271 " zero length file.\n");
274 mmap_len = st.st_size;
275 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
277 if (mmap_ptr == MAP_FAILED) {
287 if (rename (fname, newfile)) {
294 fd = open(fname, O_CREAT|O_RDWR, 0644);
297 perror("open(O_RDWR|O_CREAT)");
302 len = get_flags(commands+1, &flags);
304 fd = open(fname, flags);
312 len = atoi(commands+1);
316 buf = realloc(buf, len + ALIGN);
319 perror("allocating buf for read\n");
323 buf_align = (char *)((long)(buf + ALIGN) &
327 rc = read(fd, buf_align, len);
334 fprintf(stderr, "short read: %u/%u\n",
338 printf("%.*s\n", rc, buf_align);
342 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
346 if (stat(fname, &st) == -1) {
353 if (fstat(fd, &st) == -1) {
360 if (fchmod(fd, 0) == -1) {
367 len = atoi(commands+1);
368 if (ftruncate(fd, len) == -1) {
370 printf("ftruncate (%d,%d)\n", fd, len);
376 if (unlink(fname) == -1) {
383 if (munmap(mmap_ptr, mmap_len)) {
393 len = atoi(commands+1);
397 buf = realloc(buf, len + ALIGN);
400 perror("allocating buf for write\n");
404 buf_align = (char *)((long)(buf + ALIGN) &
406 strncpy(buf_align, msg, bufsize);
409 rc = write(fd, buf_align, len);
416 fprintf(stderr, "short write: %u/%u\n",
422 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
423 mmap_ptr[i] += junk++;
426 if (fsync(fd) == -1) {
433 if (fdatasync(fd) == -1) {
439 len = atoi(commands+1);
440 if (lseek(fd, len, SEEK_SET) == -1) {
458 fprintf(stderr, "unknown command \"%c\"\n", *commands);
459 fprintf(stderr, usage, argv[0]);