endif
DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
-CPPFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(DEBUGFLAGS)
+CPPFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INTERNAL $(DEBUGFLAGS)
OPTFLAGS= -O3 -g -ffast-math
CFLAGS = -std=gnu99 -Wwrite-strings -Wall -Wdeclaration-after-statement $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS)
LIBS += -lm $(EXTLIBS)
cconv.c lib/prio_tree.c json.c lib/zipf.c lib/axmap.c \
lib/lfsr.c gettime-thread.c helpers.c lib/flist_sort.c \
lib/hweight.c lib/getrusage.c idletime.c td_error.c \
- profiles/tiobench.c profiles/act.c io_u_queue.c
+ profiles/tiobench.c profiles/act.c io_u_queue.c filelock.c
ifdef CONFIG_64BIT_LLP64
CFLAGS += -DBITS_PER_LONG=32
ifndef CONFIG_INET_ATON
SOURCE += lib/inet_aton.c
endif
+ ifdef CONFIG_GFAPI
+ SOURCE += engines/glusterfs.c
+ SOURCE += engines/glusterfs_sync.c
+ SOURCE += engines/glusterfs_async.c
+ ifdef CONFIG_GF_FADVISE
+ CFLAGS += "-DGFAPI_USE_FADVISE"
+ endif
+ endif
ifeq ($(CONFIG_TARGET_OS), Linux)
SOURCE += diskutil.c fifo.c blktrace.c cgroup.c trim.c engines/sg.c \
$(QUIET_LINK)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_LFSR_TEST_OBJS) $(LIBS)
clean: FORCE
- -rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) core.* core gfio FIO-VERSION-FILE *.d config-host.mak config-host.h
+ -rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) core.* core gfio FIO-VERSION-FILE *.d lib/*.d crc/*.d engines/*.d profiles/*.d t/*.d config-host.mak config-host.h
distclean: clean FORCE
- @rm -f cscope.out
+ @rm -f cscope.out fio.pdf fio_generate_plots.pdf fio2gnuplot.pdf
cscope:
@cscope -b -R
tools/plot/fio2gnuplot.1:
@cat tools/plot/fio2gnuplot.manpage | txt2man -t fio2gnuplot > tools/plot/fio2gnuplot.1
+doc: tools/plot/fio2gnuplot.1
+ @man -t ./fio.1 | ps2pdf - fio.pdf
+ @man -t tools/fio_generate_plots.1 | ps2pdf - fio_generate_plots.pdf
+ @man -t tools/plot/fio2gnuplot.1 | ps2pdf - fio2gnuplot.pdf
+
install: $(PROGS) $(SCRIPTS) tools/plot/fio2gnuplot.1 FORCE
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
$(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
echo "sched_setaffinity(3 arg) $linux_3arg_affinity"
echo "sched_setaffinity(2 arg) $linux_2arg_affinity"
-##########################################
-# CPU_COUNT test
-cpu_count="no"
-cat > $TMPC << EOF
-#include <sched.h>
-int main(int argc, char **argv)
-{
- cpu_set_t mask;
- return CPU_COUNT(&mask);
-}
-EOF
-if compile_prog "" "" "cpu_count"; then
- cpu_count="yes"
-fi
-echo "CPU_COUNT $cpu_count"
-
##########################################
# clock_gettime probe
clock_gettime="no"
echo "Rados Block Device engine $rbd"
##########################################
+# Check whether we have setvbuf
+setvbuf="no"
+cat > $TMPC << EOF
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+ FILE *f = NULL;
+ char buf[80];
+ setvbuf(f, buf, _IOFBF, sizeof(buf));
+ return 0;
+}
+EOF
+if compile_prog "" "" "setvbuf"; then
+ setvbuf="yes"
+fi
+echo "setvbuf $setvbuf"
+
+ # check for gfapi
+ gfapi="no"
+ cat > $TMPC << EOF
+ #include <glusterfs/api/glfs.h>
+
+ int main(int argc, char **argv)
+ {
+
+ glfs_t *g = glfs_new("foo");
+
+ return 0;
+ }
+ EOF
+ if compile_prog "" "-lgfapi -lglusterfs" "gfapi"; then
+ LIBS="-lgfapi -lglusterfs $LIBS"
+ gfapi="yes"
+ fi
+ echo "Gluster API engine $gfapi"
+
+ ##########################################
+ # check for gfapi fadvise support
+ gf_fadvise="no"
+ cat > $TMPC << EOF
+ #include <glusterfs/api/glfs.h>
+
+ int main(int argc, char **argv)
+ {
+ struct glfs_fd *fd;
+ int ret = glfs_fadvise(fd, 0, 0, 1);
+
+ return 0;
+ }
+ EOF
+
+ if compile_prog "" "-lgfapi -lglusterfs" "gfapi"; then
+ gf_fadvise="yes"
+ fi
+ echo "Gluster API use fadvise $gf_fadvise"
+
+##########################################
+# Check if we support stckf on s390
+s390_z196_facilities="no"
+cat > $TMPC << EOF
+#define STFLE_BITS_Z196 45 /* various z196 facilities ... */
+int main(int argc, char **argv)
+{
+ /* We want just 1 double word to be returned. */
+ register unsigned long reg0 asm("0") = 0;
+ unsigned long stfle_bits;
+ asm volatile(".machine push" "\n\t"
+ ".machine \"z9-109\"" "\n\t"
+ "stfle %0" "\n\t"
+ ".machine pop" "\n"
+ : "=QS" (stfle_bits), "+d" (reg0)
+ : : "cc");
+
+ if ((stfle_bits & (1UL << (63 - STFLE_BITS_Z196))) != 0)
+ return 0;
+ else
+ return -1;
+}
+EOF
+if compile_prog "" "" "s390_z196_facilities"; then
+ $TMPE
+ if [[ $? -eq 0 ]]; then
+ s390_z196_facilities="yes"
+ fi
+fi
+echo "s390_z196_facilities $s390_z196_facilities"
#############################################################################
if test "$wordsize" = "64" ; then
if test "$rbd" = "yes" ; then
output_sym "CONFIG_RBD"
fi
-if test "$cpu_count" = "yes" ; then
- output_sym "CONFIG_CPU_COUNT"
+if test "$setvbuf" = "yes" ; then
+ output_sym "CONFIG_SETVBUF"
+fi
+if test "$s390_z196_facilities" = "yes" ; then
+ output_sym "CONFIG_S390_Z196_FACILITIES"
+ CFLAGS="$CFLAGS -march=z9-109"
fi
+ if test "$gfapi" = "yes" ; then
+ output_sym "CONFIG_GFAPI"
+ fi
+ if test "$gf_fadvise" = "yes" ; then
+ output_sym "CONFIG_GF_FADVISE"
+ fi
echo "LIBS+=$LIBS" >> $config_host_mak
echo "CFLAGS+=$CFLAGS" >> $config_host_mak
divided between the available files for the job. If not set, fio will use the
full size of the given files or devices. If the files do not exist, size
must be given. It is also possible to give size as a percentage between 1 and
-100. If size=20% is given, fio will use 20% of the full size of the given files
-or devices.
+100. If size=20% is given, fio will use 20% of the full size of the given
+files or devices.
+.TP
+.BI io_limit \fR=\fPint
+Normally fio operates within the region set by \fBsize\fR, which means that
+the \fBsize\fR option sets both the region and size of IO to be performed.
+Sometimes that is not what you want. With this option, it is possible to
+define just the amount of IO that fio should do. For instance, if \fBsize\fR
+is set to 20G and \fBio_limit\fR is set to 5G, fio will perform IO within
+the first 20G but exit when 5G have been done.
.TP
.BI fill_device \fR=\fPbool "\fR,\fB fill_fs" \fR=\fPbool
Sets size to something really large and waits for ENOSPC (no space left on
IO engine supporting direct access to Ceph Rados Block Devices (RBD) via librbd
without the need to use the kernel rbd driver. This ioengine defines engine specific
options.
+ .TP
+ .B gfapi
+ Using Glusterfs libgfapi sync interface to direct access to Glusterfs volumes without
+ having to go through FUSE. This ioengine defines engine specific
+ options.
+ .TP
+ .B gfapi_async
+ Using Glusterfs libgfapi async interface to direct access to Glusterfs volumes without
+ having to go through FUSE. This ioengine defines engine specific
+ options.
.RE
.P
.RE
.BI ioscheduler \fR=\fPstr
Attempt to switch the device hosting the file to the specified I/O scheduler.
.TP
-.BI cpuload \fR=\fPint
-If the job is a CPU cycle-eater, attempt to use the specified percentage of
-CPU cycles.
-.TP
-.BI cpuchunks \fR=\fPint
-If the job is a CPU cycle-eater, split the load into cycles of the
-given time in milliseconds.
-.TP
.BI disk_util \fR=\fPbool
Generate disk utilization statistics if the platform supports it. Default: true.
.TP
.BI (cpu)cpuchunks \fR=\fPint
Split the load into cycles of the given time. In microseconds.
.TP
+.BI (cpu)exit_on_io_done \fR=\fPbool
+Detect when IO threads are done, then exit.
+.TP
.BI (libaio)userspace_reap
Normally, with the libaio engine in use, fio will use
the io_getevents system call to reap newly returned events.
} else {
error[i] = atoi(fname);
if (error[i] < 0)
- error[i] = error[i];
+ error[i] = -error[i];
}
if (!error[i]) {
log_err("Unknown error %s, please use number value \n",
td->o.continue_on_error |= 1 << etype;
td->o.ignore_error_nr[etype] = i;
td->o.ignore_error[etype] = error;
- }
+ } else
+ free(error);
+
return 0;
}
{
struct thread_data *td = data;
struct thread_options *o = &td->o;
- char *nr = get_opt_postfix(str);
+ char *nr;
if (parse_dryrun())
return 0;
o->ddir_seq_nr = 1;
o->ddir_seq_add = 0;
+ nr = get_opt_postfix(str);
if (!nr)
return 0;
static int str_numa_cpunodes_cb(void *data, char *input)
{
struct thread_data *td = data;
+ struct bitmask *verify_bitmask;
if (parse_dryrun())
return 0;
* numa_allocate_nodemask(), so it should be freed by
* numa_free_nodemask().
*/
- td->o.numa_cpunodesmask = numa_parse_nodestring(input);
- if (td->o.numa_cpunodesmask == NULL) {
+ verify_bitmask = numa_parse_nodestring(input);
+ if (verify_bitmask == NULL) {
log_err("fio: numa_parse_nodestring failed\n");
td_verror(td, 1, "str_numa_cpunodes_cb");
return 1;
}
+ numa_free_nodemask(verify_bitmask);
+ td->o.numa_cpunodes = strdup(input);
td->o.numa_cpumask_set = 1;
return 0;
}
{ "default", "prefer", "bind", "interleave", "local", NULL };
int i;
char *nodelist;
+ struct bitmask *verify_bitmask;
if (parse_dryrun())
return 0;
break;
case MPOL_INTERLEAVE:
case MPOL_BIND:
- td->o.numa_memnodesmask = numa_parse_nodestring(nodelist);
- if (td->o.numa_memnodesmask == NULL) {
+ verify_bitmask = numa_parse_nodestring(nodelist);
+ if (verify_bitmask == NULL) {
log_err("fio: numa_parse_nodestring failed\n");
td_verror(td, 1, "str_numa_memnodes_cb");
return 1;
}
+ td->o.numa_memnodes = strdup(nodelist);
+ numa_free_nodemask(verify_bitmask);
+
break;
case MPOL_LOCAL:
case MPOL_DEFAULT:
.help = "fallocate() file based engine",
},
#endif
+ #ifdef CONFIG_GFAPI
+ { .ival = "gfapi",
+ .help = "Glusterfs libgfapi(sync) based engine"
+ },
+ { .ival = "gfapi_async",
+ .help = "Glusterfs libgfapi(async) based engine"
+ },
+ #endif
+
{ .ival = "external",
.help = "Load external engine (append name)",
},
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_INVALID,
},
+ {
+ .name = "io_limit",
+ .lname = "IO Limit",
+ .type = FIO_OPT_STR_VAL,
+ .off1 = td_var_offset(io_limit),
+ .interval = 1024 * 1024,
+ .category = FIO_OPT_C_IO,
+ .group = FIO_OPT_G_INVALID,
+ },
{
.name = "fill_device",
.lname = "Fill device",
return NULL;
ret = fread(&buf[tmp - str], 1, 128 - (tmp - str), f);
- if (ret <= 0)
+ if (ret <= 0) {
+ pclose(f);
return NULL;
+ }
pclose(f);
buf[(tmp - str) + ret - 1] = '\0';