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 [sun.com URL with a
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 <lustre/liblustreapi.h>
52 #define T1 "write data before unlink\n"
53 #define T2 "write data after unlink\n"
54 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";
55 char *buf, *buf_align;
60 "Usage: %s filename command-sequence\n"
61 " command-sequence items:\n"
63 " C[num] create with optional stripes\n"
65 " D open(O_DIRECTORY)\n"
69 " M rw mmap to EOF (must open and stat prior)\n"
72 " O open(O_CREAT|O_RDWR)\n"
73 " r[num] read [optional length]\n"
74 " R reference entire mmap-ed region\n"
78 " T[num] ftruncate [optional position, default 0]\n"
81 " w[num] write optional length\n"
82 " W write entire mmap-ed region\n"
85 " z[num] seek [optional position, default 0]\n"
86 " _ wait for signal\n";
88 static int usr1_received;
89 void usr1_handler(int unused)
95 pop_arg(int argc, char *argv[])
97 static int cur_arg = 3;
102 return argv[cur_arg++];
105 struct flag_mapping {
109 {"O_RDONLY", O_RDONLY},
110 {"O_WRONLY", O_WRONLY},
112 {"O_CREAT", O_CREAT},
114 {"O_NOCTTY", O_NOCTTY},
115 {"O_TRUNC", O_TRUNC},
116 {"O_APPEND", O_APPEND},
117 {"O_NONBLOCK", O_NONBLOCK},
118 {"O_NDELAY", O_NDELAY},
121 {"O_DIRECT", O_DIRECT},
123 {"O_LARGEFILE", O_LARGEFILE},
124 {"O_DIRECTORY", O_DIRECTORY},
125 {"O_NOFOLLOW", O_NOFOLLOW},
129 int get_flags(char *data, int *rflags)
137 cloned_flags = strdup(data);
138 if (cloned_flags == NULL) {
139 fprintf(stderr, "Insufficient memory.\n");
143 for (tmp = strtok(cloned_flags, ":"); tmp;
144 tmp = strtok(NULL, ":")) {
147 size = tmp - cloned_flags;
148 for (i = 0; flag_table[i].flag != -1; i++) {
149 if (!strcmp(tmp, flag_table[i].string)){
150 flags |= flag_table[i].flag;
151 size += strlen(flag_table[i].string);
168 #define POP_ARG() (pop_arg(argc, argv))
169 #define min(a,b) ((a)>(b)?(b):(a))
171 int main(int argc, char **argv)
173 char *fname, *commands;
176 size_t mmap_len = 0, i;
177 unsigned char *mmap_ptr = NULL, junk = 0;
178 int rc, len, fd = -1;
184 fprintf(stderr, usage, argv[0]);
188 signal(SIGUSR1, usr1_handler);
192 for (commands = argv[2]; *commands; commands++) {
195 if (usr1_received == 0) {
203 signal(SIGUSR1, usr1_handler);
206 if (close(fd) == -1) {
214 len = atoi(commands+1);
215 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
219 perror("create stripe file");
224 if (mkdir(fname, 0755) == -1) {
226 perror("mkdir(0755)");
231 fd = open(fname, O_DIRECTORY);
234 perror("open(O_DIRECTORY)");
242 if (symlink(fname, newfile)) {
252 if (link(fname, newfile)) {
259 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
261 perror("mknod(S_IFREG|0644, 0)");
266 mmap_len = st.st_size;
267 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
269 if (mmap_ptr == MAP_FAILED) {
279 if (rename (fname, newfile)) {
286 fd = open(fname, O_CREAT|O_RDWR, 0644);
289 perror("open(O_RDWR|O_CREAT)");
294 len = get_flags(commands+1, &flags);
296 fd = open(fname, flags);
304 len = atoi(commands+1);
308 buf = realloc(buf, len + ALIGN);
311 perror("allocating buf for read\n");
315 buf_align = (char *)((long)(buf + ALIGN) &
319 rc = read(fd, buf_align, len);
326 fprintf(stderr, "short read: %u/%u\n",
332 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
336 if (stat(fname, &st) == -1) {
343 if (fstat(fd, &st) == -1) {
350 if (fchmod(fd, 0) == -1) {
357 len = atoi(commands+1);
358 if (ftruncate(fd, len) == -1) {
360 printf("ftruncate (%d,%d)\n", fd, len);
366 if (unlink(fname) == -1) {
373 if (munmap(mmap_ptr, mmap_len)) {
383 len = atoi(commands+1);
387 buf = realloc(buf, len + ALIGN);
390 perror("allocating buf for write\n");
394 buf_align = (char *)((long)(buf + ALIGN) &
396 strncpy(buf_align, msg, bufsize);
399 rc = write(fd, buf_align, len);
406 fprintf(stderr, "short write: %u/%u\n",
412 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
413 mmap_ptr[i] += junk++;
416 if (fsync(fd) == -1) {
423 if (fdatasync(fd) == -1) {
429 len = atoi(commands+1);
430 if (lseek(fd, len, SEEK_SET) == -1) {
448 fprintf(stderr, "unknown command \"%c\"\n", *commands);
449 fprintf(stderr, usage, argv[0]);