Add nr parameter to file_service_type
[fio.git] / init.c
diff --git a/init.c b/init.c
index c75bed21d670b29fae359c917af5aaed12331334..eee23359afc68d209366d7f95cb1c5242de111bf 100644 (file)
--- a/init.c
+++ b/init.c
@@ -22,7 +22,6 @@
 
 #define td_var_offset(var)     ((size_t) &((struct thread_data *)0)->var)
 
-static int str_ioengine_cb(void *, const char *);
 static int str_mem_cb(void *, const char *);
 static int str_lockmem_cb(void *, unsigned long *);
 #ifdef FIO_HAVE_IOPRIO
@@ -31,6 +30,7 @@ static int str_prioclass_cb(void *, unsigned int *);
 #endif
 static int str_exitall_cb(void);
 static int str_cpumask_cb(void *, unsigned int *);
+static int str_fst_cb(void *, const char *);
 
 #define __stringify_1(x)       #x
 #define __stringify(x)         __stringify_1(x)
@@ -80,8 +80,8 @@ static struct fio_option options[] = {
        },
        {
                .name   = "ioengine",
-               .type   = FIO_OPT_STR,
-               .cb     = str_ioengine_cb,
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = td_var_offset(ioengine),
                .help   = "IO engine to use",
                .def    = "sync",
                .posval = {
@@ -103,6 +103,7 @@ static struct fio_option options[] = {
 #ifdef FIO_HAVE_SYSLET
                          { .ival = "syslet-rw", },
 #endif
+                         { .ival = "cpuio", },
                          { .ival = "external", },
                          },
        },
@@ -190,6 +191,7 @@ static struct fio_option options[] = {
        {
                .name   = "file_service_type",
                .type   = FIO_OPT_STR,
+               .cb     = str_fst_cb,
                .off1   = td_var_offset(file_service_type),
                .help   = "How to select which file to service next",
                .def    = "roundrobin",
@@ -475,7 +477,8 @@ static struct fio_option options[] = {
                .name   = "cpuchunks",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(cpucycle),
-               .help   = "Length of the CPU burn cycles",
+               .help   = "Length of the CPU burn cycles (usecs)",
+               .def    = "50000",
        },
 #ifdef FIO_HAVE_CPU_AFFINITY
        {
@@ -774,6 +777,20 @@ static char *to_kmg(unsigned int val)
        return buf;
 }
 
+/* External engines are specified by "external:name.o") */
+static const char *get_engine_name(const char *str)
+{
+       char *p = strstr(str, ":");
+
+       if (!p)
+               return str;
+
+       p++;
+       strip_blank_front(&p);
+       strip_blank_end(p);
+       return p;
+}
+
 /*
  * Adds a job to the list of things todo. Sanitizes the various options
  * to make sure we don't have conflicts, and initializes various
@@ -786,6 +803,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        struct stat sb;
        int numjobs, i;
        struct fio_file *f;
+       const char *engine;
 
        /*
         * the def_thread is just for options, it's not a real job
@@ -793,13 +811,26 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        if (td == &def_thread)
                return 0;
 
-       assert(td->io_ops);
+       engine = get_engine_name(td->ioengine);
+       td->io_ops = load_ioengine(td, engine);
+       if (!td->io_ops) {
+               log_err("fio: failed to load engine %s\n", engine);
+               return 1;
+       }
+
+       if (td->use_thread)
+               nr_thread++;
+       else
+               nr_process++;
 
        if (td->odirect)
                td->io_ops->flags |= FIO_RAWIO;
 
+       if (!td->filename)
+               td->filename = strdup(jobname);
+
        td->filetype = FIO_TYPE_FILE;
-       if (td->filename && !lstat(td->filename, &sb)) {
+       if (!lstat(td->filename, &sb)) {
                if (S_ISBLK(sb.st_mode))
                        td->filetype = FIO_TYPE_BD;
                else if (S_ISCHR(sb.st_mode))
@@ -883,7 +914,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 
        if (!terse_output) {
                if (!job_add_num) {
-                       if (td->io_ops->flags & FIO_CPUIO)
+                       if (!strcmp(td->io_ops->name, "cpuio"))
                                fprintf(f_out, "%s: ioengine=cpu, cpuload=%u, cpucycle=%u\n", td->name, td->cpuload, td->cpucycle);
                        else {
                                char *c1, *c2, *c3, *c4;
@@ -938,7 +969,7 @@ int init_random_state(struct thread_data *td)
        int fd, num_maps, blocks, i;
        struct fio_file *f;
 
-       if (td->io_ops->flags & FIO_CPUIO)
+       if (td->io_ops->flags & FIO_DISKLESSIO)
                return 0;
 
        fd = open("/dev/urandom", O_RDONLY);
@@ -973,6 +1004,10 @@ int init_random_state(struct thread_data *td)
                        blocks = (f->real_file_size + td->rw_min_bs - 1) / td->rw_min_bs;
                        num_maps = (blocks + BLOCKS_PER_MAP-1)/ BLOCKS_PER_MAP;
                        f->file_map = malloc(num_maps * sizeof(long));
+                       if (!f->file_map) {
+                               log_err("fio: failed allocating random map. If running a large number of jobs, try the 'norandommap' option\n");
+                               return 1;
+                       }
                        f->num_maps = num_maps;
                        memset(f->file_map, 0, num_maps * sizeof(long));
                }
@@ -1015,7 +1050,7 @@ static int is_empty_or_comment(char *line)
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
  */
-static char *get_mmap_file(const char *str)
+static char *get_opt_postfix(const char *str)
 {
        char *p = strstr(str, ":");
 
@@ -1033,7 +1068,7 @@ static int str_mem_cb(void *data, const char *mem)
        struct thread_data *td = data;
 
        if (td->mem_type == MEM_MMAPHUGE || td->mem_type == MEM_MMAP) {
-               td->mmapfile = get_mmap_file(mem);
+               td->mmapfile = get_opt_postfix(mem);
                if (td->mem_type == MEM_MMAPHUGE && !td->mmapfile) {
                        log_err("fio: mmaphuge:/path/to/file\n");
                        return 1;
@@ -1043,32 +1078,6 @@ static int str_mem_cb(void *data, const char *mem)
        return 0;
 }
 
-/* External engines are specified by "external:name.o") */
-static const char *get_engine_name(const char *str)
-{
-       char *p = strstr(str, ":");
-
-       if (!p)
-               return str;
-
-       p++;
-       strip_blank_front(&p);
-       strip_blank_end(p);
-       return p;
-}
-
-static int str_ioengine_cb(void *data, const char *str)
-{
-       struct thread_data *td = data;
-       const char *name = get_engine_name(str);
-
-       td->io_ops = load_ioengine(td, name);
-       if (td->io_ops)
-               return 0;
-
-       return 1;
-}
-
 static int str_lockmem_cb(void fio_unused *data, unsigned long *val)
 {
        mlock_size = *val;
@@ -1107,6 +1116,18 @@ static int str_cpumask_cb(void *data, unsigned int *val)
        return 0;
 }
 
+static int str_fst_cb(void *data, const char *str)
+{
+       struct thread_data *td = data;
+       char *nr = get_opt_postfix(str);
+
+       td->file_service_nr = 1;
+       if (nr)
+               td->file_service_nr = atoi(nr);
+
+       return 0;
+}
+
 /*
  * This is our [ini] type file parser.
  */