* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2012, Whamcloud, Inc.
+ * Copyright (c) 2014, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <stdlib.h>
#include <unistd.h>
-#include <libcfs/libcfs.h>
#include <lustre/lustreapi.h>
#define ACT_NONE 0
#define ACT_SEEK 4
#define ACT_READHOLE 8
#define ACT_VERIFY 16
+#define ACT_OUTPUT 32
void usage()
{
- printf("usage: rwv -f filename <-r|-w> [-a] [-z] [-d] [-v]"
- "[-s offset] -n iovcnt SIZE1 SIZE2 SIZE3...\n");
- printf("-a append IO (O_APPEND)\n");
- printf("-r file read (O_RDONLY)\n");
- printf("-w file write (O_WRONLY)\n");
- printf("-s set the start pos of the read/write test\n");
- printf("-z test for read hitting hole\n");
- printf("-d create flags (O_LOV_DELAY_CREATE)\n");
- printf("-v verify the data content of read\n");
+ printf("usage: rwv -f filename <-r|-w> [-a] [-z] [-d] [-v]");
+ printf(" [-s offset] [-o[outf]] -n iovcnt SIZE1 SIZE2 SIZE3...\n");
+ printf("-a append IO (O_APPEND)\n");
+ printf("-r file read (O_RDONLY)\n");
+ printf("-w file write (O_WRONLY)\n");
+ printf("-s set the start pos of the read/write test\n");
+ printf("-z test for read hitting hole\n");
+ printf("-d create flags (O_LOV_DELAY_CREATE)\n");
+ printf("-v verify the data content of read\n");
+ printf("-o write the file content of read to an optional file\n");
}
int data_verify(struct iovec *iov, int iovcnt, char c)
int flags = 0;
int iovcnt = 0;
int act = ACT_NONE;
+ int out_fd = -1;
char pad = 0xba;
char *end;
char *fname = "FILE";
struct iovec *iov;
off64_t offset = 0;
- while ((c = getopt(argc, argv, "f:n:s:rwahvdz")) != -1) {
+ while ((c = getopt(argc, argv, "f:n:s:rwahvdzo::")) != -1) {
switch (c) {
case 'f':
fname = optarg;
return 1;
}
break;
- case 'w':
- act |= ACT_WRITE;
- break;
- case 'r':
- act |= ACT_READ;
- break;
+ case 'w':
+ act |= ACT_WRITE;
+ flags |= O_WRONLY | O_CREAT;
+ break;
+ case 'r':
+ act |= ACT_READ;
+ flags |= O_RDONLY;
+ break;
case 'a':
flags |= O_APPEND;
break;
case 'v':
act |= ACT_VERIFY;
break;
+ case 'o':
+ act |= ACT_OUTPUT;
+ if (optarg != NULL)
+ out_fd = open(optarg, O_WRONLY|O_CREAT, 0644);
+ else
+ out_fd = fileno(stdout);
+ break;
case 'h':
usage();
break;
return 1;
}
+ if (act & ACT_OUTPUT && (!(act & ACT_READ) || out_fd < 0)) {
+ printf("-o not in read mode or cannot open the output file");
+ return 1;
+ }
+
if (argc - optind < iovcnt) {
printf("Not enough parameters for iov size\n");
return 1;
iv->iov_len = strtoul(argv[optind++], &end, 0);
if (*end) {
printf("Error iov size\n");
- GOTO(out, rc = 1);
+ rc = 1;
+ goto out;
}
iv->iov_base = mmap(NULL, iv->iov_len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, 0, 0);
if (iv->iov_base == MAP_FAILED) {
printf("No memory %s\n", strerror(errno));
- GOTO(out, rc = 1);
+ rc = 1;
+ goto out;
}
if (act & ACT_WRITE)
memset(iv->iov_base, pad, iv->iov_len);
len += iv->iov_len;
}
- fd = open(fname, O_LARGEFILE | O_RDWR | O_CREAT | flags, 0644);
- if (fd == -1) {
- printf("Cannot open %s:%s\n", fname, strerror(errno));
- return 1;
- }
+ fd = open(fname, O_LARGEFILE | flags, 0644);
+ if (fd == -1) {
+ printf("Cannot open %s:%s\n", fname, strerror(errno));
+ return 1;
+ }
- if ((act & ACT_SEEK) && (lseek64(fd, offset, SEEK_SET) < 0)) {
- printf("Cannot seek %s\n", strerror(errno));
- GOTO(out, rc == 1);
- }
+ if ((act & ACT_SEEK) && (lseek64(fd, offset, SEEK_SET) < 0)) {
+ printf("Cannot seek %s\n", strerror(errno));
+ rc = 1;
+ goto out;
+ }
if (act & ACT_WRITE) {
rc = writev(fd, iov, iovcnt);
if (rc != len) {
printf("Write error: %s (rc = %d, len = %ld)\n",
strerror(errno), rc, len);
- GOTO(out, rc = 1);
+ rc = 1;
+ goto out;
}
} else if (act & ACT_READ) {
rc = readv(fd, iov, iovcnt);
if (rc != len) {
printf("Read error: %s rc = %d\n", strerror(errno), rc);
- GOTO(out, rc = 1);
+ rc = 1;
+ goto out;
}
/* It should return zeroed buf if the read hits hole.*/
if (((act & ACT_READHOLE) || (act & ACT_VERIFY)) &&
- data_verify(iov, iovcnt, pad))
- GOTO(out, rc = 1);
+ data_verify(iov, iovcnt, pad)) {
+ rc = 1;
+ goto out;
+ }
+
+ if (act & ACT_OUTPUT) {
+ rc = writev(out_fd, iov, iovcnt);
+ if (rc != len) {
+ printf("write error: %s rc = %d\n",
+ strerror(errno), rc);
+ rc = 1;
+ goto out;
+ }
+ }
}
rc = 0;
out:
if (iov)
free(iov);
+ if (out_fd >= 0)
+ close(out_fd);
return rc;
}