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"
82 " w[num] write optional length\n"
83 " W write entire mmap-ed region\n"
86 " z[num] seek [optional position, default 0]\n"
87 " _ wait for signal\n";
89 static int usr1_received;
90 void usr1_handler(int unused)
96 pop_arg(int argc, char *argv[])
98 static int cur_arg = 3;
103 return argv[cur_arg++];
106 struct flag_mapping {
110 {"O_RDONLY", O_RDONLY},
111 {"O_WRONLY", O_WRONLY},
113 {"O_CREAT", O_CREAT},
115 {"O_NOCTTY", O_NOCTTY},
116 {"O_TRUNC", O_TRUNC},
117 {"O_APPEND", O_APPEND},
118 {"O_NONBLOCK", O_NONBLOCK},
119 {"O_NDELAY", O_NDELAY},
122 {"O_DIRECT", O_DIRECT},
124 {"O_LARGEFILE", O_LARGEFILE},
125 {"O_DIRECTORY", O_DIRECTORY},
126 {"O_NOFOLLOW", O_NOFOLLOW},
130 int get_flags(char *data, int *rflags)
138 cloned_flags = strdup(data);
139 if (cloned_flags == NULL) {
140 fprintf(stderr, "Insufficient memory.\n");
144 for (tmp = strtok(cloned_flags, ":"); tmp;
145 tmp = strtok(NULL, ":")) {
148 size = tmp - cloned_flags;
149 for (i = 0; flag_table[i].flag != -1; i++) {
150 if (!strcmp(tmp, flag_table[i].string)){
151 flags |= flag_table[i].flag;
152 size += strlen(flag_table[i].string);
169 #define POP_ARG() (pop_arg(argc, argv))
170 #define min(a,b) ((a)>(b)?(b):(a))
172 int main(int argc, char **argv)
174 char *fname, *commands;
177 size_t mmap_len = 0, i;
178 unsigned char *mmap_ptr = NULL, junk = 0;
179 int rc, len, fd = -1;
185 fprintf(stderr, usage, argv[0]);
189 signal(SIGUSR1, usr1_handler);
193 for (commands = argv[2]; *commands; commands++) {
196 if (usr1_received == 0) {
204 signal(SIGUSR1, usr1_handler);
207 if (close(fd) == -1) {
215 len = atoi(commands+1);
216 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
220 perror("create stripe file");
225 if (mkdir(fname, 0755) == -1) {
227 perror("mkdir(0755)");
232 fd = open(fname, O_DIRECTORY);
235 perror("open(O_DIRECTORY)");
243 if (symlink(fname, newfile)) {
253 if (link(fname, newfile)) {
260 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
262 perror("mknod(S_IFREG|0644, 0)");
267 mmap_len = st.st_size;
268 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
270 if (mmap_ptr == MAP_FAILED) {
280 if (rename (fname, newfile)) {
287 fd = open(fname, O_CREAT|O_RDWR, 0644);
290 perror("open(O_RDWR|O_CREAT)");
295 len = get_flags(commands+1, &flags);
297 fd = open(fname, flags);
305 len = atoi(commands+1);
309 buf = realloc(buf, len + ALIGN);
312 perror("allocating buf for read\n");
316 buf_align = (char *)((long)(buf + ALIGN) &
320 rc = read(fd, buf_align, len);
327 fprintf(stderr, "short read: %u/%u\n",
333 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
337 if (stat(fname, &st) == -1) {
344 if (fstat(fd, &st) == -1) {
351 if (fchmod(fd, 0) == -1) {
358 len = atoi(commands+1);
359 if (ftruncate(fd, len) == -1) {
361 printf("ftruncate (%d,%d)\n", fd, len);
367 if (unlink(fname) == -1) {
374 if (munmap(mmap_ptr, mmap_len)) {
384 len = atoi(commands+1);
388 buf = realloc(buf, len + ALIGN);
391 perror("allocating buf for write\n");
395 buf_align = (char *)((long)(buf + ALIGN) &
397 strncpy(buf_align, msg, bufsize);
400 rc = write(fd, buf_align, len);
407 fprintf(stderr, "short write: %u/%u\n",
413 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
414 mmap_ptr[i] += junk++;
417 if (fsync(fd) == -1) {
424 if (fdatasync(fd) == -1) {
430 len = atoi(commands+1);
431 if (lseek(fd, len, SEEK_SET) == -1) {
449 fprintf(stderr, "unknown command \"%c\"\n", *commands);
450 fprintf(stderr, usage, argv[0]);