The following changes since commit e90391eb56d81a2cc175c50caf6b4e5abbdb6142: filesetup: set TD_SETTING_UP runstate when laying out files (2013-04-13 20:40:53 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Aaron Carroll (1): README: quick note on how to cross compile Bruce Cran (1): Update the examples filenames in the Windows installer. Dmitry Monakhov (1): fio: fix segfault on 32bits platforms Jens Axboe (3): eta: improve output for threads sitting in TD_SETTING_UP log: add printf() attribute to log_*() functions Fixup bad logging types Otavio Salvador (1): ARM: Use generic assembly nop and barrier code for armv6 README | 5 ++++ arch/arch-arm.h | 4 ++- backend.c | 2 +- client.c | 4 ++- engines/e4defrag.c | 2 +- engines/mmap.c | 2 +- eta.c | 15 ++++++++--- filesetup.c | 3 +- gettime.c | 9 ++++--- idletime.c | 2 +- io_u.c | 3 +- log.h | 6 ++-- os/windows/dobuild.cmd | 2 +- os/windows/examples.wxs | 60 +++++++++++++++++++++++----------------------- os/windows/install.wxs | 3 +- server.c | 5 ++- server.h | 2 +- stat.c | 53 +++++++++++++++++++++++++--------------- stat.h | 1 + 19 files changed, 108 insertions(+), 75 deletions(-) --- Diff of recent changes: diff --git a/README b/README index 7df6306..3782570 100644 --- a/README +++ b/README @@ -96,6 +96,11 @@ For gfio, you need gtk 2.18 or newer and associated glib threads and cairo. gfio isn't built automatically, it needs to be enabled with a --enable-gfio option to configure. +To build FIO with a cross-compiler: + $ make clean + $ make CROSS_COMPILE=/path/to/toolchain/prefix +Configure will attempt to determine the target platform automatically. + Windows ------- diff --git a/arch/arch-arm.h b/arch/arch-arm.h index 658b688..7cd9502 100644 --- a/arch/arch-arm.h +++ b/arch/arch-arm.h @@ -18,7 +18,9 @@ #define __NR_sys_vmsplice 343 #endif -#if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__) +#if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) \ + || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__) \ + || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) #define nop __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t") #define read_barrier() __asm__ __volatile__ ("" : : : "memory") #define write_barrier() __asm__ __volatile__ ("" : : : "memory") diff --git a/backend.c b/backend.c index 119c4f9..1c4484b 100644 --- a/backend.c +++ b/backend.c @@ -835,7 +835,7 @@ sync_done: check_update_rusage(td); if (td->trim_entries) - log_err("fio: %d trim entries leaked?\n", td->trim_entries); + log_err("fio: %lu trim entries leaked?\n", td->trim_entries); if (td->o.fill_device && td->error == ENOSPC) { td->error = 0; diff --git a/client.c b/client.c index 13e84f6..155eb72 100644 --- a/client.c +++ b/client.c @@ -887,6 +887,7 @@ static void convert_jobs_eta(struct jobs_eta *je) je->nr_running = le32_to_cpu(je->nr_running); je->nr_ramp = le32_to_cpu(je->nr_ramp); je->nr_pending = le32_to_cpu(je->nr_pending); + je->nr_setting_up = le32_to_cpu(je->nr_setting_up); je->files_open = le32_to_cpu(je->files_open); for (i = 0; i < DDIR_RWDIR_CNT; i++) { @@ -912,6 +913,7 @@ void fio_client_sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je) dst->nr_running += je->nr_running; dst->nr_ramp += je->nr_ramp; dst->nr_pending += je->nr_pending; + dst->nr_setting_up += je->nr_setting_up; dst->files_open += je->files_open; for (i = 0; i < DDIR_RWDIR_CNT; i++) { @@ -955,7 +957,7 @@ static void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd) } if (!reply) { - log_err("fio: client: unable to find matching tag (%lx)\n", cmd->tag); + log_err("fio: client: unable to find matching tag (%llx)\n", (unsigned long long) cmd->tag); return; } diff --git a/engines/e4defrag.c b/engines/e4defrag.c index d9ddf75..4d87f67 100644 --- a/engines/e4defrag.c +++ b/engines/e4defrag.c @@ -92,7 +92,7 @@ static int fio_e4defrag_init(struct thread_data *td) ed->donor_fd = open(donor_name, O_CREAT|O_WRONLY, 0644); if (ed->donor_fd < 0) { td_verror(td, ed->donor_fd, "io_queue_init"); - log_err("Can't open donor file %s err:%d", ed->donor_fd); + log_err("Can't open donor file %s err:%d", donor_name, ed->donor_fd); free(ed); return 1; } diff --git a/engines/mmap.c b/engines/mmap.c index c1aff5b..8c04a19 100644 --- a/engines/mmap.c +++ b/engines/mmap.c @@ -187,7 +187,7 @@ static int fio_mmapio_init(struct thread_data *td) if ((td->o.rw_min_bs & page_mask) && (o->odirect || o->fsync_blocks || o->fdatasync_blocks)) { log_err("fio: mmap options dictate a minimum block size of " - "%lu bytes\n", page_size); + "%llu bytes\n", (unsigned long long) page_size); return 1; } diff --git a/eta.c b/eta.c index 769ac14..9fc6e27 100644 --- a/eta.c +++ b/eta.c @@ -186,6 +186,7 @@ static int thread_eta(struct thread_data *td) eta_sec = td->o.timeout + done_secs - elapsed; } else if (td->runstate == TD_NOT_CREATED || td->runstate == TD_CREATED || td->runstate == TD_INITIALIZED + || td->runstate == TD_SETTING_UP || td->runstate == TD_RAMP || td->runstate == TD_PRE_READING) { int t_eta = 0, r_eta = 0; @@ -349,9 +350,10 @@ int calc_thread_status(struct jobs_eta *je, int force) } else if (td->runstate == TD_RAMP) { je->nr_running++; je->nr_ramp++; - } else if (td->runstate == TD_SETTING_UP) + } else if (td->runstate == TD_SETTING_UP) { je->nr_running++; - else if (td->runstate < TD_RUNNING) + je->nr_setting_up++; + } else if (td->runstate < TD_RUNNING) je->nr_pending++; if (je->elapsed_sec >= 3) @@ -361,7 +363,7 @@ int calc_thread_status(struct jobs_eta *je, int force) check_str_update(td); - if (td->runstate > TD_RAMP) { + if (td->runstate > TD_SETTING_UP) { int ddir; for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++) { @@ -471,8 +473,13 @@ void display_thread_status(struct jobs_eta *je) if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running) strcpy(perc_str, "-.-% done"); else { + double mult = 100.0; + + if (je->nr_setting_up && je->nr_running) + mult *= (1.0 - (double) je->nr_setting_up / (double) je->nr_running); + eta_good = 1; - perc *= 100.0; + perc *= mult; sprintf(perc_str, "%3.1f%% done", perc); } diff --git a/filesetup.c b/filesetup.c index 37ea752..9f186fb 100644 --- a/filesetup.c +++ b/filesetup.c @@ -355,7 +355,8 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) if (f->file_offset > f->real_file_size) { log_err("%s: offset extends end (%llu > %llu)\n", td->o.name, - f->file_offset, f->real_file_size); + (unsigned long long) f->file_offset, + (unsigned long long) f->real_file_size); return 1; } diff --git a/gettime.c b/gettime.c index 8b3e1e5..1a0f827 100644 --- a/gettime.c +++ b/gettime.c @@ -578,7 +578,7 @@ int fio_monotonic_clocktest(void) free(threads); if (failed) { - log_err("Clocksource test: %u threads failed\n", failed); + log_err("Clocksource test: %lu threads failed\n", failed); goto err; } @@ -595,9 +595,10 @@ int fio_monotonic_clocktest(void) if (prev->tsc > this->tsc) { uint64_t diff = prev->tsc - this->tsc; - log_info("cs: CPU clock mismatch (diff=%lu):\n", diff); - log_info("\t CPU%3lu: TSC=%lu, SEQ=%lu\n", prev->cpu, prev->tsc, prev->seq); - log_info("\t CPU%3lu: TSC=%lu, SEQ=%lu\n", this->cpu, this->tsc, this->seq); + log_info("cs: CPU clock mismatch (diff=%llu):\n", + (unsigned long long) diff); + log_info("\t CPU%3u: TSC=%llu, SEQ=%u\n", prev->cpu, (unsigned long long) prev->tsc, prev->seq); + log_info("\t CPU%3u: TSC=%llu, SEQ=%u\n", this->cpu, (unsigned long long) this->tsc, this->seq); failed++; } diff --git a/idletime.c b/idletime.c index 244723f..d4d665a 100644 --- a/idletime.c +++ b/idletime.c @@ -406,7 +406,7 @@ int fio_idle_prof_parse_opt(const char *args) ipc.opt = IDLE_PROF_OPT_PERCPU; return 0; } else { - log_err("fio: incorrect idle-prof option\n", args); + log_err("fio: incorrect idle-prof option: %s\n", args); return -1; } #else diff --git a/io_u.c b/io_u.c index 7941a6d..19ef7b9 100644 --- a/io_u.c +++ b/io_u.c @@ -314,8 +314,7 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u, else if (b != -1ULL) io_u->offset = b * td->o.ba[ddir]; else { - log_err("fio: bug in offset generation: offset=%llu, b=%llu\n", - offset, b); + log_err("fio: bug in offset generation: offset=%llu, b=%llu\n", (unsigned long long) offset, (unsigned long long) b); ret = 1; } } diff --git a/log.h b/log.h index ad9d08b..25f92f9 100644 --- a/log.h +++ b/log.h @@ -7,9 +7,9 @@ extern FILE *f_out; extern FILE *f_err; -extern int log_err(const char *format, ...); -extern int log_info(const char *format, ...); -extern int log_local(const char *format, ...); +extern int log_err(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2))); +extern int log_info(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2))); +extern int log_local(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2))); extern int log_valist(const char *str, va_list); extern int log_local_buf(const char *buf, size_t); diff --git a/os/windows/dobuild.cmd b/os/windows/dobuild.cmd index cbbe2cb..166578a 100644 --- a/os/windows/dobuild.cmd +++ b/os/windows/dobuild.cmd @@ -20,5 +20,5 @@ if not defined FIO_ARCH ( @if ERRORLEVEL 1 goto end "%WIX%bin\candle" -nologo -arch %FIO_ARCH% examples.wxs @if ERRORLEVEL 1 goto end -"%WIX%bin\light" -nologo install.wixobj examples.wixobj -ext WixUIExtension -out %FIO_VERSION%-%FIO_ARCH%.msi +"%WIX%bin\light" -nologo -sice:61 install.wixobj examples.wixobj -ext WixUIExtension -out %FIO_VERSION%-%FIO_ARCH%.msi :end \ No newline at end of file diff --git a/os/windows/examples.wxs b/os/windows/examples.wxs index 7717309..644799d 100755 --- a/os/windows/examples.wxs +++ b/os/windows/examples.wxs @@ -3,73 +3,73 @@ <Fragment> <DirectoryRef Id="examples"> <Component> - <File Source="..\..\examples\1mbs_clients" /> + <File Source="..\..\examples\1mbs_clients.fio" /> </Component> <Component> - <File Source="..\..\examples\aio-read" /> + <File Source="..\..\examples\aio-read.fio" /> </Component> <Component> - <File Source="..\..\examples\disk-zone-profile" /> + <File Source="..\..\examples\disk-zone-profile.fio" /> </Component> <Component> - <File Source="..\..\examples\fsx" /> + <File Source="..\..\examples\fsx.fio" /> </Component> <Component> - <File Source="..\..\examples\iometer-file-access-server" /> + <File Source="..\..\examples\iometer-file-access-server.fio" /> </Component> <Component> - <File Source="..\..\examples\netio" /> + <File Source="..\..\examples\netio.fio" /> </Component> <Component> - <File Source="..\..\examples\ssd-test" /> + <File Source="..\..\examples\ssd-test.fio" /> </Component> <Component> - <File Source="..\..\examples\surface-scan" /> + <File Source="..\..\examples\surface-scan.fio" /> </Component> <Component> - <File Source="..\..\examples\tiobench-example" /> + <File Source="..\..\examples\tiobench-example.fio" /> </Component> <Component> - <File Source="..\..\examples\null" /> + <File Source="..\..\examples\null.fio" /> </Component> <Component> - <File Source="..\..\examples\flow" /> + <File Source="..\..\examples\flow.fio" /> </Component> <Component> - <File Source="..\..\examples\cpuio" /> + <File Source="..\..\examples\cpuio.fio" /> </Component> <Component> - <File Source="..\..\examples\falloc" /> + <File Source="..\..\examples\falloc.fio" /> </Component> <Component> - <File Source="..\..\examples\fusion-aw-sync.ini" /> + <File Source="..\..\examples\fusion-aw-sync.fio" /> </Component> <Component> <File Source="..\..\examples\ssd-steadystate.fio" /> </Component> <Component> - <File Source="..\..\examples\zipf" /> + <File Source="..\..\examples\zipf.fio" /> </Component> </DirectoryRef> </Fragment> <Fragment> <ComponentGroup Id="examples"> - <ComponentRef Id="_1mbs_clients" /> - <ComponentRef Id="aio_read" /> - <ComponentRef Id="disk_zone_profile" /> - <ComponentRef Id="fsx" /> - <ComponentRef Id="iometer_file_access_server" /> - <ComponentRef Id="netio" /> - <ComponentRef Id="ssd_test" /> - <ComponentRef Id="surface_scan" /> - <ComponentRef Id="tiobench_example" /> - <ComponentRef Id="null" /> - <ComponentRef Id="flow" /> - <ComponentRef Id="cpuio" /> - <ComponentRef Id="falloc" /> - <ComponentRef Id="fusion_aw_sync.ini" /> + <ComponentRef Id="_1mbs_clients.fio" /> + <ComponentRef Id="aio_read.fio" /> + <ComponentRef Id="disk_zone_profile.fio" /> + <ComponentRef Id="fsx.fio" /> + <ComponentRef Id="iometer_file_access_server.fio" /> + <ComponentRef Id="netio.fio" /> + <ComponentRef Id="ssd_test.fio" /> + <ComponentRef Id="surface_scan.fio" /> + <ComponentRef Id="tiobench_example.fio" /> + <ComponentRef Id="null.fio" /> + <ComponentRef Id="flow.fio" /> + <ComponentRef Id="cpuio.fio" /> + <ComponentRef Id="falloc.fio" /> + <ComponentRef Id="fusion_aw_sync.fio" /> <ComponentRef Id="ssd_steadystate.fio" /> - <ComponentRef Id="zipf" /> + <ComponentRef Id="zipf.fio" /> </ComponentGroup> </Fragment> </Wix> diff --git a/os/windows/install.wxs b/os/windows/install.wxs index 1494a64..378fed6 100755 --- a/os/windows/install.wxs +++ b/os/windows/install.wxs @@ -70,6 +70,7 @@ <UIRef Id="WixUI_Minimal"/> - <MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of the application is already installed."/> + <MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of the application is already installed." + AllowSameVersionUpgrades="yes"/> </Product> </Wix> diff --git a/server.c b/server.c index 884ff8e..3d31cbf 100644 --- a/server.c +++ b/server.c @@ -681,6 +681,7 @@ static int handle_send_eta_cmd(struct fio_net_cmd *cmd) je->nr_running = cpu_to_le32(je->nr_running); je->nr_ramp = cpu_to_le32(je->nr_ramp); je->nr_pending = cpu_to_le32(je->nr_pending); + je->nr_setting_up = cpu_to_le32(je->nr_setting_up); je->files_open = cpu_to_le32(je->files_open); for (i = 0; i < DDIR_RWDIR_CNT; i++) { @@ -1466,7 +1467,7 @@ int fio_server_parse_string(const char *str, char **ptr, int *is_sock, host++; lport = atoi(host); if (!lport || lport > 65535) { - log_err("fio: bad server port %u\n", port); + log_err("fio: bad server port %u\n", lport); return 1; } /* no hostname given, we are done */ @@ -1484,7 +1485,7 @@ int fio_server_parse_string(const char *str, char **ptr, int *is_sock, portp++; lport = atoi(portp); if (!lport || lport > 65535) { - log_err("fio: bad server port %u\n", port); + log_err("fio: bad server port %u\n", lport); return 1; } } diff --git a/server.h b/server.h index 478c283..46745aa 100644 --- a/server.h +++ b/server.h @@ -38,7 +38,7 @@ struct fio_net_cmd_reply { }; enum { - FIO_SERVER_VER = 22, + FIO_SERVER_VER = 23, FIO_SERVER_MAX_FRAGMENT_PDU = 1024, diff --git a/stat.c b/stat.c index 66bea0a..3db0612 100644 --- a/stat.c +++ b/stat.c @@ -282,7 +282,9 @@ void show_group_stats(struct group_run_stats *rs) log_info("%s: io=%s, aggrb=%s/s, minb=%s/s, maxb=%s/s," " mint=%llumsec, maxt=%llumsec\n", rs->unified_rw_rep ? " MIXED" : ddir_str[i], - p1, p2, p3, p4, rs->min_run[i], rs->max_run[i]); + p1, p2, p3, p4, + (unsigned long long) rs->min_run[i], + (unsigned long long) rs->max_run[i]); free(p1); free(p2); @@ -385,7 +387,8 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts, log_info(" %s: io=%s, bw=%s/s, iops=%s, runt=%6llumsec\n", rs->unified_rw_rep ? "mixed" : ddir_str[ddir], - io_p, bw_p, iops_p, ts->runtime[ddir]); + io_p, bw_p, iops_p, + (unsigned long long) ts->runtime[ddir]); free(io_p); free(bw_p); @@ -544,8 +547,11 @@ void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs) sys_cpu = 0; } - log_info(" cpu : usr=%3.2f%%, sys=%3.2f%%, ctx=%lu, majf=%lu," - " minf=%lu\n", usr_cpu, sys_cpu, ts->ctx, ts->majf, ts->minf); + log_info(" cpu : usr=%3.2f%%, sys=%3.2f%%, ctx=%llu," + " majf=%llu, minf=%llu\n", usr_cpu, sys_cpu, + (unsigned long long) ts->ctx, + (unsigned long long) ts->majf, + (unsigned long long) ts->minf); stat_calc_dist(ts->io_u_map, ddir_rw_sum(ts->total_io_u), io_u_dist); log_info(" IO depths : 1=%3.1f%%, 2=%3.1f%%, 4=%3.1f%%, 8=%3.1f%%," @@ -566,15 +572,17 @@ void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs) io_u_dist[1], io_u_dist[2], io_u_dist[3], io_u_dist[4], io_u_dist[5], io_u_dist[6]); - log_info(" issued : total=r=%lu/w=%lu/d=%lu," - " short=r=%lu/w=%lu/d=%lu\n", - ts->total_io_u[0], ts->total_io_u[1], - ts->total_io_u[2], - ts->short_io_u[0], ts->short_io_u[1], - ts->short_io_u[2]); + log_info(" issued : total=r=%llu/w=%llu/d=%llu," + " short=r=%llu/w=%llu/d=%llu\n", + (unsigned long long) ts->total_io_u[0], + (unsigned long long) ts->total_io_u[1], + (unsigned long long) ts->total_io_u[2], + (unsigned long long) ts->short_io_u[0], + (unsigned long long) ts->short_io_u[1], + (unsigned long long) ts->short_io_u[2]); if (ts->continue_on_error) { - log_info(" errors : total=%lu, first_error=%d/<%s>\n", - ts->total_err_count, + log_info(" errors : total=%llu, first_error=%d/<%s>\n", + (unsigned long long)ts->total_err_count, ts->first_error, strerror(ts->first_error)); } @@ -600,8 +608,9 @@ static void show_ddir_status_terse(struct thread_stat *ts, iops = (1000 * (uint64_t) ts->total_io_u[ddir]) / runt; } - log_info(";%llu;%llu;%llu;%llu", ts->io_bytes[ddir] >> 10, bw, iops, - ts->runtime[ddir]); + log_info(";%llu;%llu;%llu;%llu", + (unsigned long long) ts->io_bytes[ddir] >> 10, bw, iops, + (unsigned long long) ts->runtime[ddir]); if (calc_lat(&ts->slat_stat[ddir], &min, &max, &mean, &dev)) log_info(";%lu;%lu;%f;%f", min, max, mean, dev); @@ -787,8 +796,10 @@ static void show_thread_status_terse_v2(struct thread_stat *ts, sys_cpu = 0; } - log_info(";%f%%;%f%%;%lu;%lu;%lu", usr_cpu, sys_cpu, ts->ctx, ts->majf, - ts->minf); + log_info(";%f%%;%f%%;%llu;%llu;%llu", usr_cpu, sys_cpu, + (unsigned long long) ts->ctx, + (unsigned long long) ts->majf, + (unsigned long long) ts->minf); /* Calc % distribution of IO depths, usecond, msecond latency */ stat_calc_dist(ts->io_u_map, ddir_rw_sum(ts->total_io_u), io_u_dist); @@ -808,7 +819,7 @@ static void show_thread_status_terse_v2(struct thread_stat *ts, log_info(";%3.2f%%", io_u_lat_m[i]); /* Additional output if continue_on_error set - default off*/ if (ts->continue_on_error) - log_info(";%lu;%d", ts->total_err_count, ts->first_error); + log_info(";%llu;%d", (unsigned long long) ts->total_err_count, ts->first_error); log_info("\n"); /* Additional output if description is set */ @@ -849,8 +860,10 @@ static void show_thread_status_terse_v3_v4(struct thread_stat *ts, sys_cpu = 0; } - log_info(";%f%%;%f%%;%lu;%lu;%lu", usr_cpu, sys_cpu, ts->ctx, ts->majf, - ts->minf); + log_info(";%f%%;%f%%;%llu;%llu;%llu", usr_cpu, sys_cpu, + (unsigned long long) ts->ctx, + (unsigned long long) ts->majf, + (unsigned long long) ts->minf); /* Calc % distribution of IO depths, usecond, msecond latency */ stat_calc_dist(ts->io_u_map, ddir_rw_sum(ts->total_io_u), io_u_dist); @@ -874,7 +887,7 @@ static void show_thread_status_terse_v3_v4(struct thread_stat *ts, /* Additional output if continue_on_error set - default off*/ if (ts->continue_on_error) - log_info(";%lu;%d", ts->total_err_count, ts->first_error); + log_info(";%llu;%d", (unsigned long long) ts->total_err_count, ts->first_error); /* Additional output if description is set */ if (strlen(ts->description)) diff --git a/stat.h b/stat.h index 76a71d4..0125f57 100644 --- a/stat.h +++ b/stat.h @@ -181,6 +181,7 @@ struct jobs_eta { uint32_t nr_running; uint32_t nr_ramp; uint32_t nr_pending; + uint32_t nr_setting_up; uint32_t files_open; uint32_t m_rate[DDIR_RWDIR_CNT], t_rate[DDIR_RWDIR_CNT]; uint32_t m_iops[DDIR_RWDIR_CNT], t_iops[DDIR_RWDIR_CNT]; -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html