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 (c) 2003, 2010, Oracle and/or its affiliates. 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>
51 #include <semaphore.h>
52 #include <libcfs/libcfs.h>
53 #include <lustre/liblustreapi.h>
55 #define T1 "write data before unlink\n"
56 #define T2 "write data after unlink\n"
57 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";
58 char *buf, *buf_align;
64 "Usage: %s filename command-sequence\n"
65 " command-sequence items:\n"
67 " C[num] create with optional stripes\n"
69 " D open(O_DIRECTORY)\n"
71 " G gid get grouplock\n"
72 " g gid put grouplock\n"
76 " M rw mmap to EOF (must open and stat prior)\n"
79 " O open(O_CREAT|O_RDWR)\n"
80 " r[num] read [optional length]\n"
81 " R reference entire mmap-ed region\n"
85 " T[num] ftruncate [optional position, default 0]\n"
89 " w[num] write optional length\n"
90 " W write entire mmap-ed region\n"
93 " z[num] seek [optional position, default 0]\n"
94 " _ wait for signal\n";
96 void usr1_handler(int unused)
98 int saved_errno = errno;
101 * signal(7): POSIX.1-2004 ...requires an implementation to guarantee
102 * that the following functions can be safely called inside a signal
112 pop_arg(int argc, char *argv[])
114 static int cur_arg = 3;
119 return argv[cur_arg++];
122 struct flag_mapping {
126 {"O_RDONLY", O_RDONLY},
127 {"O_WRONLY", O_WRONLY},
129 {"O_CREAT", O_CREAT},
131 {"O_NOCTTY", O_NOCTTY},
132 {"O_TRUNC", O_TRUNC},
133 {"O_APPEND", O_APPEND},
134 {"O_NONBLOCK", O_NONBLOCK},
135 {"O_NDELAY", O_NDELAY},
138 {"O_DIRECT", O_DIRECT},
140 {"O_LARGEFILE", O_LARGEFILE},
141 {"O_DIRECTORY", O_DIRECTORY},
142 {"O_NOFOLLOW", O_NOFOLLOW},
146 int get_flags(char *data, int *rflags)
154 cloned_flags = strdup(data);
155 if (cloned_flags == NULL) {
156 fprintf(stderr, "Insufficient memory.\n");
160 for (tmp = strtok(cloned_flags, ":"); tmp;
161 tmp = strtok(NULL, ":")) {
164 size = tmp - cloned_flags;
165 for (i = 0; flag_table[i].flag != -1; i++) {
166 if (!strcmp(tmp, flag_table[i].string)){
167 flags |= flag_table[i].flag;
168 size += strlen(flag_table[i].string);
185 #define POP_ARG() (pop_arg(argc, argv))
187 int main(int argc, char **argv)
189 char *fname, *commands;
193 size_t mmap_len = 0, i;
194 unsigned char *mmap_ptr = NULL, junk = 0;
195 int rc, len, fd = -1;
202 fprintf(stderr, usage, argv[0]);
206 memset(&st, 0, sizeof(st));
207 sem_init(&sem, 0, 0);
208 /* use sigaction instead of signal to avoid SA_ONESHOT semantics */
209 sigaction(SIGUSR1, &(const struct sigaction){.sa_handler = &usr1_handler},
214 for (commands = argv[2]; *commands; commands++) {
221 while (sem_wait(&sem) == -1 && errno == EINTR);
224 if (close(fd) == -1) {
232 len = atoi(commands+1);
233 fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644,
237 perror("create stripe file");
242 if (mkdir(fname, 0755) == -1) {
244 perror("mkdir(0755)");
249 fd = open(fname, O_DIRECTORY);
252 perror("open(O_DIRECTORY)");
257 if (statfs(fname, &stfs) == -1) {
264 gid = atoi(commands+1);
265 if (ioctl(fd, LL_IOC_GROUP_LOCK, gid) == -1) {
267 perror("ioctl(GROUP_LOCK)");
272 gid = atoi(commands+1);
273 if (ioctl(fd, LL_IOC_GROUP_UNLOCK, gid) == -1) {
275 perror("ioctl(GROUP_UNLOCK)");
283 if (symlink(fname, newfile)) {
293 if (link(fname, newfile)) {
300 if (mknod(fname, S_IFREG | 0644, 0) == -1) {
302 perror("mknod(S_IFREG|0644, 0)");
307 if (st.st_size == 0) {
308 fprintf(stderr, "mmap without preceeding stat, or on"
309 " zero length file.\n");
312 mmap_len = st.st_size;
313 mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
315 if (mmap_ptr == MAP_FAILED) {
325 if (rename (fname, newfile)) {
332 fd = open(fname, O_CREAT|O_RDWR, 0644);
335 perror("open(O_RDWR|O_CREAT)");
340 len = get_flags(commands+1, &flags);
343 fd = open(fname, flags, 0666);
345 fd = open(fname, flags);
353 len = atoi(commands+1);
357 buf = realloc(buf, len + ALIGN);
360 perror("allocating buf for read\n");
364 buf_align = (char *)((long)(buf + ALIGN) &
368 rc = read(fd, buf_align, len);
375 fprintf(stderr, "short read: %u/%u\n",
379 printf("%.*s\n", rc, buf_align);
383 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
387 if (stat(fname, &st) == -1) {
394 if (fstat(fd, &st) == -1) {
401 if (fchmod(fd, 0) == -1) {
408 len = atoi(commands+1);
409 if (ftruncate(fd, len) == -1) {
411 printf("ftruncate (%d,%d)\n", fd, len);
417 if (unlink(fname) == -1) {
424 if (munmap(mmap_ptr, mmap_len)) {
434 len = atoi(commands+1);
438 buf = realloc(buf, len + ALIGN);
441 perror("allocating buf for write\n");
445 buf_align = (char *)((long)(buf + ALIGN) &
447 strncpy(buf_align, msg, bufsize);
450 rc = write(fd, buf_align, len);
457 fprintf(stderr, "short write: %u/%u\n",
463 for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
464 mmap_ptr[i] += junk++;
467 if (fsync(fd) == -1) {
474 if (fdatasync(fd) == -1) {
480 len = atoi(commands+1);
481 if (lseek(fd, len, SEEK_SET) == -1) {
499 fprintf(stderr, "unknown command \"%c\"\n", *commands);
500 fprintf(stderr, usage, argv[0]);