spdk_dd: Add posix flags support
Signed-off-by: Maciej Szwed <maciej.szwed@intel.com> Change-Id: Ie051a399af6dea694faa942a412844c267500d2e Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3060 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
parent
dcd2a253f1
commit
eb1f031c88
@ -47,6 +47,8 @@
|
||||
struct spdk_dd_opts {
|
||||
char *input_file;
|
||||
char *output_file;
|
||||
char *input_file_flags;
|
||||
char *output_file_flags;
|
||||
char *input_bdev;
|
||||
char *output_bdev;
|
||||
uint64_t input_offset;
|
||||
@ -119,6 +121,24 @@ struct dd_job {
|
||||
uint64_t copy_size;
|
||||
};
|
||||
|
||||
struct dd_flags {
|
||||
char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
static struct dd_flags g_flags[] = {
|
||||
{"append", O_APPEND},
|
||||
{"direct", O_DIRECT},
|
||||
{"directory", O_DIRECTORY},
|
||||
{"dsync", O_DSYNC},
|
||||
{"noatime", O_NOATIME},
|
||||
{"noctty", O_NOCTTY},
|
||||
{"nofollow", O_NOFOLLOW},
|
||||
{"nonblock", O_NONBLOCK},
|
||||
{"sync", O_SYNC},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static struct dd_job g_job = {};
|
||||
static int g_error = 0;
|
||||
static struct timespec g_start_time;
|
||||
@ -489,14 +509,19 @@ dd_output_poll(void *ctx)
|
||||
}
|
||||
|
||||
static int
|
||||
dd_open_file(struct dd_target *target, const char *fname, uint64_t skip_blocks, bool input)
|
||||
dd_open_file(struct dd_target *target, const char *fname, int flags, uint64_t skip_blocks,
|
||||
bool input)
|
||||
{
|
||||
int flags = O_RDWR;
|
||||
flags |= O_RDWR;
|
||||
|
||||
if (input == false) {
|
||||
if (input == false && ((flags & O_DIRECTORY) == 0)) {
|
||||
flags |= O_CREAT;
|
||||
}
|
||||
|
||||
if (input == false && ((flags & O_APPEND) == 0)) {
|
||||
flags |= O_TRUNC;
|
||||
}
|
||||
|
||||
target->type = DD_TARGET_TYPE_FILE;
|
||||
target->u.aio.fd = open(fname, flags, 0600);
|
||||
if (target->u.aio.fd < 0) {
|
||||
@ -565,15 +590,48 @@ static void dd_finish(void)
|
||||
g_interrupt = true;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_flags(char *file_flags)
|
||||
{
|
||||
char *input_flag;
|
||||
int flags = 0;
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
/* Translate input flags to file open flags */
|
||||
while ((input_flag = strsep(&file_flags, ","))) {
|
||||
for (i = 0; g_flags[i].name != NULL; i++) {
|
||||
if (!strcmp(input_flag, g_flags[i].name)) {
|
||||
flags |= g_flags[i].flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == false) {
|
||||
SPDK_ERRLOG("Unknown file flag: %s\n", input_flag);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
found = false;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_run(void *arg1)
|
||||
{
|
||||
uint64_t write_size;
|
||||
uint32_t i;
|
||||
int rc;
|
||||
int rc, flags = 0;
|
||||
|
||||
if (g_opts.input_file) {
|
||||
if (dd_open_file(&g_job.input, g_opts.input_file, g_opts.input_offset, true) < 0) {
|
||||
if (g_opts.input_file_flags) {
|
||||
flags = parse_flags(g_opts.input_file_flags);
|
||||
}
|
||||
|
||||
if (dd_open_file(&g_job.input, g_opts.input_file, flags, g_opts.input_offset, true) < 0) {
|
||||
SPDK_ERRLOG("%s: %s\n", g_opts.input_file, strerror(errno));
|
||||
dd_exit(-errno);
|
||||
return;
|
||||
@ -617,7 +675,13 @@ dd_run(void *arg1)
|
||||
g_job.output.pos = g_opts.output_offset * g_opts.io_unit_size;
|
||||
|
||||
if (g_opts.output_file) {
|
||||
if (dd_open_file(&g_job.output, g_opts.output_file, g_opts.output_offset, false) < 0) {
|
||||
flags = 0;
|
||||
|
||||
if (g_opts.output_file_flags) {
|
||||
flags = parse_flags(g_opts.output_file_flags);
|
||||
}
|
||||
|
||||
if (dd_open_file(&g_job.output, g_opts.output_file, flags, g_opts.output_offset, false) < 0) {
|
||||
SPDK_ERRLOG("%s: %s\n", g_opts.output_file, strerror(errno));
|
||||
dd_exit(-errno);
|
||||
return;
|
||||
@ -681,6 +745,8 @@ dd_run(void *arg1)
|
||||
enum dd_cmdline_opts {
|
||||
DD_OPTION_IF = 0x1000,
|
||||
DD_OPTION_OF,
|
||||
DD_OPTION_IFLAGS,
|
||||
DD_OPTION_OFLAGS,
|
||||
DD_OPTION_IB,
|
||||
DD_OPTION_OB,
|
||||
DD_OPTION_SKIP,
|
||||
@ -703,6 +769,18 @@ static struct option g_cmdline_opts[] = {
|
||||
.flag = NULL,
|
||||
.val = DD_OPTION_OF,
|
||||
},
|
||||
{
|
||||
.name = "iflag",
|
||||
.has_arg = 1,
|
||||
.flag = NULL,
|
||||
.val = DD_OPTION_IFLAGS,
|
||||
},
|
||||
{
|
||||
.name = "oflag",
|
||||
.has_arg = 1,
|
||||
.flag = NULL,
|
||||
.val = DD_OPTION_OFLAGS,
|
||||
},
|
||||
{
|
||||
.name = "ib",
|
||||
.has_arg = 1,
|
||||
@ -758,11 +836,23 @@ usage(void)
|
||||
printf(" --ib Input bdev. Must specifier either --if or --ib\n");
|
||||
printf(" --of Output file. Must specify either --of or --ob.\n");
|
||||
printf(" --ob Output bdev. Must specify either --of or --ob.\n");
|
||||
printf(" --iflag Input file flags.\n");
|
||||
printf(" --oflag Onput file flags.\n");
|
||||
printf(" --bs I/O unit size (default: %" PRId64 ")\n", g_opts.io_unit_size);
|
||||
printf(" --qd Queue depth (default: %d)\n", g_opts.queue_depth);
|
||||
printf(" --count I/O unit count. The number of I/O units to copy. (default: all)\n");
|
||||
printf(" --skip Skip this many I/O units at start of input. (default: 0)\n");
|
||||
printf(" --seek Skip this many I/O units at start of output. (default: 0)\n");
|
||||
printf(" Available iflag and oflag values:\n");
|
||||
printf(" append - append mode\n");
|
||||
printf(" direct - use direct I/O for data\n");
|
||||
printf(" directory - fail unless a directory\n");
|
||||
printf(" dsync - use synchronized I/O for data\n");
|
||||
printf(" noatime - do not update access time\n");
|
||||
printf(" noctty - do not assign controlling terminal from file\n");
|
||||
printf(" nofollow - do not follow symlinks\n");
|
||||
printf(" nonblock - use non-blocking I/O\n");
|
||||
printf(" sync - use synchronized I/O for data and metadata\n");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -775,6 +865,12 @@ parse_args(int argc, char *argv)
|
||||
case DD_OPTION_OF:
|
||||
g_opts.output_file = strdup(argv);
|
||||
break;
|
||||
case DD_OPTION_IFLAGS:
|
||||
g_opts.input_file_flags = strdup(argv);
|
||||
break;
|
||||
case DD_OPTION_OFLAGS:
|
||||
g_opts.output_file_flags = strdup(argv);
|
||||
break;
|
||||
case DD_OPTION_IB:
|
||||
g_opts.input_bdev = strdup(argv);
|
||||
break;
|
||||
@ -812,6 +908,8 @@ dd_free(void)
|
||||
free(g_opts.output_file);
|
||||
free(g_opts.input_bdev);
|
||||
free(g_opts.output_bdev);
|
||||
free(g_opts.input_file_flags);
|
||||
free(g_opts.output_file_flags);
|
||||
|
||||
if (g_job.ios) {
|
||||
for (i = 0; i < g_opts.queue_depth; i++) {
|
||||
@ -875,6 +973,18 @@ main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (g_opts.output_file == NULL && g_opts.output_file_flags != NULL) {
|
||||
SPDK_ERRLOG("--oflags may be used only with --of\n");
|
||||
rc = EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (g_opts.input_file == NULL && g_opts.input_file_flags != NULL) {
|
||||
SPDK_ERRLOG("--iflags may be used only with --if\n");
|
||||
rc = EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = spdk_app_start(&opts, dd_run, NULL);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("Error occured while performing copy\n");
|
||||
|
Loading…
Reference in New Issue
Block a user