All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: Recent changes
       [not found] <20110127050004.1AE9737A304@kernel.dk>
@ 2011-01-27  8:51 ` Bruce Cran
  2011-01-27  9:08   ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Bruce Cran @ 2011-01-27  8:51 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio

On Thu, 27 Jan 2011 06:00:04 +0100 (CET)
Jens Axboe <jaxboe@fusionio.com> wrote:

> +#define POSIX_MADV_DONTNEED	MADV_DONTNEED
> +#define POSIX_MADV_SEQUENTIAL	MADV_SEQUENTIAL
> +#define POSIX_MADV_RANDOM	MADV_RANDOM

These are already defined on OpenSolaris 2009.06 and cause redefinition
warnings.

-- 
Bruce Cran


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-01-27  8:51 ` Recent changes Bruce Cran
@ 2011-01-27  9:08   ` Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-27  9:08 UTC (permalink / raw)
  To: Bruce Cran; +Cc: fio

On 2011-01-27 09:51, Bruce Cran wrote:
> On Thu, 27 Jan 2011 06:00:04 +0100 (CET)
> Jens Axboe <jaxboe@fusionio.com> wrote:
> 
>> +#define POSIX_MADV_DONTNEED	MADV_DONTNEED
>> +#define POSIX_MADV_SEQUENTIAL	MADV_SEQUENTIAL
>> +#define POSIX_MADV_RANDOM	MADV_RANDOM
> 
> These are already defined on OpenSolaris 2009.06 and cause redefinition
> warnings.

I wonder why that was broken on Solaris, I'll add an ifdef check.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2012-04-14  6:45         ` Danny Kukawka
@ 2012-04-14 14:47           ` Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2012-04-14 14:47 UTC (permalink / raw)
  To: Danny Kukawka; +Cc: fio

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 2012-04-14 08:45, Danny Kukawka wrote:
> Am 06.04.2012 19:44, schrieb Jens Axboe:
>> On 2012-04-06 11:40, Danny Kukawka wrote:
>>> Am 06.04.2012 15:31, schrieb Jens Axboe:
>>>> On 2012-04-05 22:29, Danny Kukawka wrote:
>>>>> Am 06.04.2012 06:00, schrieb Jens Axboe:
>>>>>> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
>>>>>>
>>>>>>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
>>>>>>
>>>>>> are available in the git repository at:
>>>>>>   git://git.kernel.dk/fio.git master
>>>>>>
>>>>>> Jens Axboe (1):
>>>>>>       group reporting: fix bad values of min/max
>>>>>
>>>>> Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
>>>>> work for me.
>>>>>
>>>>> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
>>>>> --bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0
>>>>>
>>>>> still prints:
>>>>>
>>>>> READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
>>>>> mint=600232msec, maxt=600232msec
>>>>
>>>> Since that's still off by 1.024, are you absolutely sure you are running
>>>> the right version of fio?
>>
>>> I used git snapshot with latest commit
>>> ddb754dbb54a8174080f753c85ff56a7ffca3957, but I can recheck if needed.
>>
>> Yes, please re-check, it should not be happening and I don't see it
>> here.
>>
> 
> I checked again with 8423bd1106a0 and I still see the same problem:
> 
> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
>     --bs=4m --rw=write --iodepth=128 --ioengine=libaio
>     --filename=$TEST_TARGET --output=$DIR/fio1-write-4m-rbd
> 
> Run status group 0 (all jobs):
>   WRITE: io=51200MB, aggrb=20080KB/s, minb=20080KB/s, maxb=20080KB/s,
> mint=2610946msec, maxt=2610946msec

I'm confused on what you think is an issue? From the above, fio
transferred 51200MB, which is 52428800KB. The runtime was 2610.946s,
which gives us a throughput of 20080.38KB/sec. Which is what fio
reports. aggrb/minb/maxb are identical, which was the original bug.

What am I missing?

- -- 
Jens Axboe

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBCAAGBQJPiY3oAAoJEPfTWPspceCm7TIP/jCGLv0L6Th7T4FosTrCC0bm
U9jUDWkNo+b4n+87FLTmX6rxXenNN/NbGYJHaCE8A+FnWyDLihhEAslMD9mqn7OA
66EWir/HrbzikQ6mF9fMPDWCLLNKVV+eVORmrN3Ne6y6d3luH5RiMFKOfWmdbhv2
cHhVpDx5hfGF+tvRcPy/NIOkl7gNszOqF2ili9wP+aTokp+2jF7rVK9pw7KfA9jG
IPrt2oC6hIr6+6v8xekZRgEH61R/Gsq6T0Tf0dJtEMMNhcspEpXZbKCf1xV8+22W
HmYsjVJysIPEn0KCnPzE+DtDEF/rInbYvlTuOcJS1ugMt/AGOWtQm9OprIQTQsc+
T0lMQ4lVEzxmcvy3dMs2pnTL0pdWOAVfNXGopVpd1jV0jI1uBvsZyW2sBpiVn7nA
10GB6Y97Cm+ap9oaP+nnxRgLjmHrDpbgSFnRt6CFUnD+6xp2iV8Bo7qA06e0ABwT
IFpeHW57OhhR+zIMqNqsldvsuuPB8PKWxvi0eH7YBuDKk/XoD91Im9iYJRxjbvBQ
xN7hpjeWFQap4OLPERKDoTYBcJ4NdYaM9UdXPsmazc4T28K2tmxtzcIrkalj1Ryn
d6B0FoQRWZlPYk3c7NbDKcz49llC08zdptNffMP2g8fKzgGxzTY/oAgiET6JqK/o
dSMKbZgMjfK2iNGUjLR9
=Mpll
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2012-04-06 17:44       ` Jens Axboe
@ 2012-04-14  6:45         ` Danny Kukawka
  2012-04-14 14:47           ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Danny Kukawka @ 2012-04-14  6:45 UTC (permalink / raw)
  To: fio; +Cc: Jens Axboe

[-- Attachment #1: Type: text/plain, Size: 1885 bytes --]

Am 06.04.2012 19:44, schrieb Jens Axboe:
> On 2012-04-06 11:40, Danny Kukawka wrote:
>> Am 06.04.2012 15:31, schrieb Jens Axboe:
>>> On 2012-04-05 22:29, Danny Kukawka wrote:
>>>> Am 06.04.2012 06:00, schrieb Jens Axboe:
>>>>> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
>>>>>
>>>>>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
>>>>>
>>>>> are available in the git repository at:
>>>>>   git://git.kernel.dk/fio.git master
>>>>>
>>>>> Jens Axboe (1):
>>>>>       group reporting: fix bad values of min/max
>>>>
>>>> Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
>>>> work for me.
>>>>
>>>> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
>>>> --bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0
>>>>
>>>> still prints:
>>>>
>>>> READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
>>>> mint=600232msec, maxt=600232msec
>>>
>>> Since that's still off by 1.024, are you absolutely sure you are running
>>> the right version of fio?
> 
>> I used git snapshot with latest commit
>> ddb754dbb54a8174080f753c85ff56a7ffca3957, but I can recheck if needed.
> 
> Yes, please re-check, it should not be happening and I don't see it
> here.
> 

I checked again with 8423bd1106a0 and I still see the same problem:

fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
    --bs=4m --rw=write --iodepth=128 --ioengine=libaio
    --filename=$TEST_TARGET --output=$DIR/fio1-write-4m-rbd

Run status group 0 (all jobs):
  WRITE: io=51200MB, aggrb=20080KB/s, minb=20080KB/s, maxb=20080KB/s,
mint=2610946msec, maxt=2610946msec

Danny
-- 
Danny Kukawka
 SUSE LINUX Products GmbH
  Maxfeldstrasse 5, D-90409 Nuremberg, Germany
  GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 316 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2012-04-06 17:40     ` Danny Kukawka
@ 2012-04-06 17:44       ` Jens Axboe
  2012-04-14  6:45         ` Danny Kukawka
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2012-04-06 17:44 UTC (permalink / raw)
  To: Danny Kukawka; +Cc: fio

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 2012-04-06 11:40, Danny Kukawka wrote:
> Am 06.04.2012 15:31, schrieb Jens Axboe:
>> On 2012-04-05 22:29, Danny Kukawka wrote:
>>> Am 06.04.2012 06:00, schrieb Jens Axboe:
>>>> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
>>>>
>>>>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
>>>>
>>>> are available in the git repository at:
>>>>   git://git.kernel.dk/fio.git master
>>>>
>>>> Jens Axboe (1):
>>>>       group reporting: fix bad values of min/max
>>>
>>> Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
>>> work for me.
>>>
>>> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
>>> --bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0
>>>
>>> still prints:
>>>
>>> READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
>>> mint=600232msec, maxt=600232msec
>>
>> Since that's still off by 1.024, are you absolutely sure you are running
>> the right version of fio?
> 
> I used git snapshot with latest commit
> ddb754dbb54a8174080f753c85ff56a7ffca3957, but I can recheck if needed.

Yes, please re-check, it should not be happening and I don't see it
here.

- -- 
Jens Axboe

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBCAAGBQJPfyuUAAoJEPfTWPspceCmP1UQAKTo9AeqpSSz7x3VIuHFAQRJ
wv6aNitw0MMc/oWnH40UtcJgAaa19UFYBQxK6NwTCsyjbpqnG+V+lw3OQ1LKuKvj
NyBomGFSQTm6hIa6I6+WyxinR3Ahs8RiMipm4/fJjFZHsNSLd1j6Owm8quT51/YU
GmH7PytAgpJ/fU9jtH1OssZgvwAeoE9NKLL4UHxTrJaCVZLRc/BMUO+vVKsQCcWb
mEC12yK9jJ3oRYF0DYT5boFkrfBA2FSIQFAm36pvlJ7HjiFqDLBxzli//wqvqW5k
z3MlFBGjaFx7q5URRmcHZehkVn5BNnOCnaTRPav5j1B9UEnmEQ6WLK76zBSf9qsM
qnz6ReE89PZF1UdNOzzLl4KEaystJNv5402y0LIaqiNzKK6jK+aDDy09Hw/2JgJm
OnT7EbCK423eLcTA9avVJcRetQ9/0Ay06l/+vHUabmD+iXIDel4BCkN04FaWA+by
D5S9aJCi1pYk+QAygj5V2+2b2Vwv00T13785nQwRVfKBU2gQ+n43dEjLG0sjYkq1
OMnZMhUuCFGhdTHrtyM7pSJjcqEUPLf2OOY1jdHm2PGijdHGSNwCvs94aZtM9/KR
Vh03rzKtGzpPcfvnVTVxJ5F4qpUguR5Fk0tB/r4DMAyufn350vO7sag6iM4WQY8O
J8L3brrFqhkSdYvTtJpi
=FEpB
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2012-04-06 13:31   ` Jens Axboe
@ 2012-04-06 17:40     ` Danny Kukawka
  2012-04-06 17:44       ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Danny Kukawka @ 2012-04-06 17:40 UTC (permalink / raw)
  To: fio; +Cc: Jens Axboe

[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]

Am 06.04.2012 15:31, schrieb Jens Axboe:
> On 2012-04-05 22:29, Danny Kukawka wrote:
>> Am 06.04.2012 06:00, schrieb Jens Axboe:
>>> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
>>>
>>>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
>>>
>>> are available in the git repository at:
>>>   git://git.kernel.dk/fio.git master
>>>
>>> Jens Axboe (1):
>>>       group reporting: fix bad values of min/max
>>
>> Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
>> work for me.
>>
>> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
>> --bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0
>>
>> still prints:
>>
>> READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
>> mint=600232msec, maxt=600232msec
> 
> Since that's still off by 1.024, are you absolutely sure you are running
> the right version of fio?

I used git snapshot with latest commit
ddb754dbb54a8174080f753c85ff56a7ffca3957, but I can recheck if needed.

Danny
-- 
Danny Kukawka
 SUSE LINUX Products GmbH
  Maxfeldstrasse 5, D-90409 Nuremberg, Germany
  GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 316 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2012-04-06  4:29 ` Danny Kukawka
@ 2012-04-06 13:31   ` Jens Axboe
  2012-04-06 17:40     ` Danny Kukawka
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2012-04-06 13:31 UTC (permalink / raw)
  To: Danny Kukawka; +Cc: fio

On 2012-04-05 22:29, Danny Kukawka wrote:
> Am 06.04.2012 06:00, schrieb Jens Axboe:
>> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
>>
>>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
>>
>> are available in the git repository at:
>>   git://git.kernel.dk/fio.git master
>>
>> Jens Axboe (1):
>>       group reporting: fix bad values of min/max
> 
> Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
> work for me.
> 
> fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
> --bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0
> 
> still prints:
> 
> READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
> mint=600232msec, maxt=600232msec

Since that's still off by 1.024, are you absolutely sure you are running
the right version of fio?

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
       [not found] <20120406040004.1BF99484001@kernel.dk>
@ 2012-04-06  4:29 ` Danny Kukawka
  2012-04-06 13:31   ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Danny Kukawka @ 2012-04-06  4:29 UTC (permalink / raw)
  To: fio; +Cc: Jens Axboe

[-- Attachment #1: Type: text/plain, Size: 892 bytes --]

Am 06.04.2012 06:00, schrieb Jens Axboe:
> The following changes since commit 885ac623a4f154007efa49266bb381bcbc60f1e6:
> 
>   iolog: remove assert in io_u overlap (2012-04-04 14:11:58 -0600)
> 
> are available in the git repository at:
>   git://git.kernel.dk/fio.git master
> 
> Jens Axboe (1):
>       group reporting: fix bad values of min/max

Should this fix also the minb/maxb and mint/maxt ? If so, it doesn't
work for me.

fio --name=fio1-write-4m-rbd --direct=1 --size=50g --group_reporting
--bs=4m --rw=write --iodepth=128 --ioengine=libaio --filename=/dev/rbd0

still prints:

READ: io=65260MB, aggrb=111334KB/s, minb=114006KB/s, maxb=114006KB/s,
mint=600232msec, maxt=600232msec

Danny
-- 
Danny Kukawka
 SUSE LINUX Products GmbH
  Maxfeldstrasse 5, D-90409 Nuremberg, Germany
  GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 316 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (99 preceding siblings ...)
  2012-02-02  5:00 ` Jens Axboe
@ 2012-02-28  5:00 ` Jens Axboe
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2012-02-28  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit f6d38abde41a7b18808dcdab393f05d6300d16c3:

  Fix compiler warnings (2012-02-01 13:17:57 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      blktrace 1.0.5

Vasily Tarasov (1):
      Too small arrays for file names

 blkparse.c |    4 ++--
 blktrace.h |    3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index b0b88c3..a7ff0f7 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.0.4";
+static char blkparse_version[] = "1.0.5";
 
 struct skip_info {
 	unsigned long start, end;
@@ -2839,7 +2839,7 @@ int main(int argc, char *argv[])
 			ofp = fdopen(STDOUT_FILENO, "w");
 			mode = _IOLBF;
 		} else {
-			char ofname[128];
+			char ofname[PATH_MAX];
 
 			snprintf(ofname, sizeof(ofname) - 1, "%s", output_name);
 			ofp = fopen(ofname, "w");
diff --git a/blktrace.h b/blktrace.h
index 8b3e031..5da6dbc 100644
--- a/blktrace.h
+++ b/blktrace.h
@@ -2,6 +2,7 @@
 #define BLKTRACE_H
 
 #include <stdio.h>
+#include <limits.h>
 #include <byteswap.h>
 #include <endian.h>
 
@@ -44,7 +45,7 @@ struct per_cpu_info {
 
 	int fd;
 	int fdblock;
-	char fname[128];
+	char fname[PATH_MAX];
 
 	struct io_stats io_stats;
 

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (98 preceding siblings ...)
  2012-02-01  5:00 ` Jens Axboe
@ 2012-02-02  5:00 ` Jens Axboe
  2012-02-28  5:00 ` Jens Axboe
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2012-02-02  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 7f0062f7b893a80afbe0e43f5db157c7bc1a01f9:

  blktrace 1.0.4 (2012-01-31 10:53:21 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Eric Sandeen (10):
      Check setvbuf return value
      Fix potential array overrun in act_to_str
      Free pdu_buff on bad pdu path in process()
      Close stream in 'I' switch handling
      Remove extraneous malloc in find_input routines
      Fix several leaks on error paths
      btt: close devmap file after processing
      blkparse: initialize cpu_map
      blktrace: remove unused variable
      avoid string overflows

Jens Axboe (1):
      Fix compiler warnings

 blkparse.c          |    5 ++++-
 blkrawverify.c      |    3 ++-
 blktrace.c          |   27 +++++++++++++++++++--------
 btreplay/btrecord.c |    2 +-
 btreplay/btreplay.c |    2 +-
 btt/aqd.c           |    2 ++
 btt/bno_dump.c      |    5 +++--
 btt/devmap.c        |    1 +
 btt/plat.c          |    2 ++
 btt/proc.c          |    3 +--
 btt/seek.c          |   20 +++++++++-----------
 btt/trace_queue.c   |    2 +-
 12 files changed, 46 insertions(+), 28 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 0f8d135..b0b88c3 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -562,7 +562,9 @@ static struct process_pid_map *add_ppm_hash(pid_t pid, const char *name)
 		ppm = malloc(sizeof(*ppm));
 		memset(ppm, 0, sizeof(*ppm));
 		ppm->pid = pid;
-		strcpy(ppm->comm, name);
+		memset(ppm->comm, 0, sizeof(ppm->comm));
+		strncpy(ppm->comm, name, sizeof(ppm->comm));
+		ppm->comm[sizeof(ppm->comm) - 1] = '\0';
 		ppm->hash_next = ppm_hash_table[hash_idx];
 		ppm_hash_table[hash_idx] = ppm;
 	}
@@ -1962,6 +1964,7 @@ static int check_cpu_map(struct per_dev_info *pdi)
 	 * create a map of the cpus we have traces for
 	 */
 	cpu_map = malloc(pdi->cpu_map_max / sizeof(long));
+	memset(cpu_map, 0, sizeof(*cpu_map));
 	n = rb_first(&rb_sort_root);
 	while (n) {
 		__t = rb_entry(n, struct trace, rb_node);
diff --git a/blkrawverify.c b/blkrawverify.c
index b6ceb9d..ed5d258 100644
--- a/blkrawverify.c
+++ b/blkrawverify.c
@@ -87,7 +87,7 @@ static char *act_to_str(__u32 action)
 	unsigned int act = action & 0xffff;
 	unsigned int trace = (action >> BLK_TC_SHIFT) & 0xffff;
 
-	if (act <= N_ACTS) {
+	if (act < N_ACTS) {
 		sprintf(buf, "%s ", acts[act].string);
 		for (i = 0; i < N_TRACES; i++)
 			if (trace & (1 << i)) {
@@ -201,6 +201,7 @@ static int process(FILE **fp, char *devname, char *file, unsigned int cpu)
 			if (n = 0) {
 				INC_BAD("bad pdu");
 				nbad_seq++;
+				free(pdu_buf);
 				break;
 			}
 			free(pdu_buf);
diff --git a/blktrace.c b/blktrace.c
index b14daf2..89aaaac 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -872,8 +872,9 @@ static int net_send_header(int fd, int cpu, char *buts_name, int len)
 	memset(&hdr, 0, sizeof(hdr));
 
 	hdr.magic = BLK_IO_TRACE_MAGIC;
+	memset(hdr.buts_name, 0, sizeof(hdr.buts_name));
 	strncpy(hdr.buts_name, buts_name, sizeof(hdr.buts_name));
-	hdr.buts_name[sizeof(hdr.buts_name)-1] = '\0';
+	hdr.buts_name[sizeof(hdr.buts_name) - 1] = '\0';
 	hdr.cpu = cpu;
 	hdr.max_cpus = ncpus;
 	hdr.len = len;
@@ -981,7 +982,9 @@ retry:
 		}
 
 		memcpy(&addr->sin_addr, hent->h_addr, 4);
-		strcpy(hostname, hent->h_name);
+		memset(hostname, 0, sizeof(hostname));
+		strncpy(hostname, hent->h_name, sizeof(hostname));
+		hostname[sizeof(hostname) - 1] = '\0';
 	}
 
 	return 0;
@@ -1728,11 +1731,10 @@ static int handle_pfds_netclient(struct tracer *tp, int nevs, int force_read)
 {
 	struct stat sb;
 	int i, nentries = 0;
-	struct pdc_stats *sp;
 	struct pollfd *pfd = tp->pfds;
 	struct io_info *iop = tp->ios;
 
-	for (i = 0; i < ndevs; i++, pfd++, iop++, sp++) {
+	for (i = 0; i < ndevs; i++, pfd++, iop++) {
 		if (pfd->revents & POLLIN || force_read) {
 			if (fstat(iop->ifd, &sb) < 0) {
 				perror(iop->ifn);
@@ -2076,9 +2078,13 @@ static int handle_args(int argc, char *argv[])
 				return 1;
 			}
 
-			while (fscanf(ifp, "%s\n", dev_line) = 1)
-				if (add_devpath(dev_line) != 0)
+			while (fscanf(ifp, "%s\n", dev_line) = 1) {
+				if (add_devpath(dev_line) != 0) {
+					fclose(ifp);
 					return 1;
+				}
+			}
+			fclose(ifp);
 			break;
 		}
 
@@ -2128,7 +2134,9 @@ static int handle_args(int argc, char *argv[])
 			break;
 		case 'h':
 			net_mode = Net_client;
-			strcpy(hostname, optarg);
+			memset(hostname, 0, sizeof(hostname));
+			strncpy(hostname, optarg, sizeof(hostname));
+			hostname[sizeof(hostname) - 1] = '\0';
 			break;
 		case 'l':
 			net_mode = Net_server;
@@ -2183,7 +2191,10 @@ static int handle_args(int argc, char *argv[])
 		piped_output = 1;
 		handle_pfds = handle_pfds_entries;
 		pfp = stdout;
-		setvbuf(pfp, NULL, _IONBF, 0);
+		if (setvbuf(pfp, NULL, _IONBF, 0)) {
+			perror("setvbuf stdout");
+			return 1;
+		}
 	} else
 		handle_pfds = handle_pfds_file;
 	return 0;
diff --git a/btreplay/btrecord.c b/btreplay/btrecord.c
index 88ab806..3646257 100644
--- a/btreplay/btrecord.c
+++ b/btreplay/btrecord.c
@@ -365,7 +365,7 @@ static void find_input_files(char *idir)
 	}
 
 	while ((ent = readdir(dir)) != NULL) {
-		char *p, *dsf = malloc(256);
+		char *p, *dsf;
 
 		if (strstr(ent->d_name, ".blktrace.") = NULL)
 			continue;
diff --git a/btreplay/btreplay.c b/btreplay/btreplay.c
index f4f5aa0..20494e0 100644
--- a/btreplay/btreplay.c
+++ b/btreplay/btreplay.c
@@ -596,7 +596,7 @@ static void find_input_devs(char *idir)
 	}
 
 	while ((ent = readdir(dir)) != NULL) {
-		char *p, *dsf = malloc(256);
+		char *p, *dsf;
 
 		if (strstr(ent->d_name, ".replay.") = NULL)
 			continue;
diff --git a/btt/aqd.c b/btt/aqd.c
index 3bb6f85..17ab15b 100644
--- a/btt/aqd.c
+++ b/btt/aqd.c
@@ -43,6 +43,8 @@ void *aqd_alloc(struct d_info *dip)
 	sprintf(oname, "%s_%s_aqd.dat", aqd_name, dip->dip_name);
 	if ((ap->fp = my_fopen(oname, "w")) = NULL) {
 		perror(oname);
+		free(oname);
+		free(ap);
 		return NULL;
 	}
 	add_file(ap->fp, oname);
diff --git a/btt/bno_dump.c b/btt/bno_dump.c
index 02f3811..00c9ac2 100644
--- a/btt/bno_dump.c
+++ b/btt/bno_dump.c
@@ -31,9 +31,10 @@ static FILE *bno_dump_open(struct d_info *dip, char rwc)
 
 	oname = malloc(strlen(bno_dump_name) + strlen(dip->dip_name) + 32);
 	sprintf(oname, "%s_%s_%c.dat", bno_dump_name, dip->dip_name, rwc);
-	if ((fp = my_fopen(oname, "w")) = NULL)
+	if ((fp = my_fopen(oname, "w")) = NULL) {
 		perror(oname);
-	else
+		free(oname);
+	} else
 		add_file(fp, oname);
 	return fp;
 }
diff --git a/btt/devmap.c b/btt/devmap.c
index 9c0348b..0553a9e 100644
--- a/btt/devmap.c
+++ b/btt/devmap.c
@@ -76,6 +76,7 @@ int dev_map_read(char *fname)
 			break;
 	}
 
+	fclose(fp);
 	return 0;
 }
 
diff --git a/btt/plat.c b/btt/plat.c
index e7b7dde..dff7115 100644
--- a/btt/plat.c
+++ b/btt/plat.c
@@ -42,6 +42,8 @@ void *plat_alloc(struct d_info *dip, char *post)
 	sprintf(oname, "%s%s_plat.dat", dip->dip_name, post);
 	if ((pp->fp = my_fopen(oname, "w")) = NULL) {
 		perror(oname);
+		free(oname);
+		free(pp);
 		return NULL;
 	}
 	add_file(pp->fp, oname);
diff --git a/btt/proc.c b/btt/proc.c
index aac49cb..eb44c3d 100644
--- a/btt/proc.c
+++ b/btt/proc.c
@@ -238,9 +238,8 @@ void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg)
 		__foreach(root_name.rb_node, f, arg);
 	else {
 		struct p_info *pip;
-		char *exe, *p, *next, *exes_save = strdup(exes);
+		char *exe, *next, *exes_save = strdup(exes);
 
-		p = exes_save;
 		while (exes_save != NULL) {
 			exe = exes_save;
 			if ((next = strchr(exes_save, ',')) != NULL) {
diff --git a/btt/seek.c b/btt/seek.c
index abdb0ee..52f6a21 100644
--- a/btt/seek.c
+++ b/btt/seek.c
@@ -51,9 +51,10 @@ static FILE *seek_open(char *str, char rw)
 
 	oname = malloc(strlen(seek_name) + strlen(str) + 32);
 	sprintf(oname, "%s_%s_%c.dat", seek_name, str, rw);
-	if ((fp = my_fopen(oname, "w")) = NULL)
+	if ((fp = my_fopen(oname, "w")) = NULL) {
 		perror(oname);
-	else
+		free(oname);
+	} else
 		add_file(fp, oname);
 
 	return fp;
@@ -99,18 +100,14 @@ static void __destroy(struct rb_node *n)
 
 static void sps_emit(struct seeki *sip)
 {
-	double tstamp, s_p_s;
+	double s_p_s;
 	struct sps_bkt *sps = &sip->sps;
 	double delta = sps->t_last - sps->t_start;
 
-	if ((sps->nseeks = 1) || (delta < DBL_EPSILON)) {
+	if ((sps->nseeks = 1) || (delta < DBL_EPSILON))
 		s_p_s = (double)(sps->nseeks);
-		tstamp = sps->t_start;
-	} else {
-
+	else
 		s_p_s = (double)(sps->nseeks) / delta;
-		tstamp = sps->t_start + (delta / 2);
-	}
 
 	fprintf(sip->sps_fp, "%15.9lf %.2lf\n", sps->t_start, s_p_s);
 
@@ -226,9 +223,10 @@ void *seeki_alloc(struct d_info *dip, char *post)
 
 		oname = malloc(strlen(sps_name) + strlen(dip->dip_name) + 32);
 		sprintf(oname, "%s_%s.dat", sps_name, dip->dip_name);
-		if ((sip->sps_fp = my_fopen(oname, "w")) = NULL)
+		if ((sip->sps_fp = my_fopen(oname, "w")) = NULL) {
 			perror(oname);
-		else
+			free(oname);
+		} else
 			add_file(sip->sps_fp, oname);
 	} else
 		sip->sps_fp = NULL;
diff --git a/btt/trace_queue.c b/btt/trace_queue.c
index 82c5760..8edcd90 100644
--- a/btt/trace_queue.c
+++ b/btt/trace_queue.c
@@ -33,7 +33,7 @@ static void handle_queue(struct io *q_iop)
 		update_lq(&last_q, &all_avgs.q2q, q_iop->t.time);
 	}
 
-	q_iop->i_time = q_iop->g_time = q_iop->i_time = q_iop->m_time +	q_iop->i_time = q_iop->g_time = q_iop->c_time = q_iop->m_time  						q_iop->d_time = (__u64)-1;
 	q_iop->dip->n_qs++;
 

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (97 preceding siblings ...)
  2011-08-12  4:00 ` Jens Axboe
@ 2012-02-01  5:00 ` Jens Axboe
  2012-02-02  5:00 ` Jens Axboe
  2012-02-28  5:00 ` Jens Axboe
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2012-02-01  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 0abccbcb5d1a538028ffcb3869d646d29bf5812b:

  blktrace 1.0.3 (2011-08-11 12:49:08 +0200)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Jens Axboe (2):
      Merge branch 'master' of ssh://brick.kernel.dk/data/git/blktrace
      blktrace 1.0.4

Mikulas Patocka (1):
      Fix for realloc bug and wrong error logging

 blkparse.c |    2 +-
 blktrace.c |    9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 169d491..0f8d135 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.0.3";
+static char blkparse_version[] = "1.0.4";
 
 struct skip_info {
 	unsigned long start, end;
diff --git a/blktrace.c b/blktrace.c
index 72866e2..b14daf2 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -1330,7 +1330,7 @@ static struct trace_buf *tb_combine(struct trace_buf *prev,
 		 * the whole structures, as the other fields
 		 * are "static".
 		 */
-		prev = realloc(prev->buf, sizeof(*prev) + tot_len);
+		prev = realloc(prev, sizeof(*prev) + tot_len);
 		prev->buf = (void *)(prev + 1);
 	}
 
@@ -2155,12 +2155,17 @@ static int handle_args(int argc, char *argv[])
 		return 1;
 	}
 
-	if (statfs(debugfs_path, &st) < 0 || st.f_type != (long)DEBUGFS_TYPE) {
+	if (statfs(debugfs_path, &st) < 0) {
 		fprintf(stderr, "Invalid debug path %s: %d/%s\n",
 			debugfs_path, errno, strerror(errno));
 		return 1;
 	}
 
+	if (st.f_type != (long)DEBUGFS_TYPE) {
+		fprintf(stderr, "Debugfs is not mounted at %s\n", debugfs_path);
+		return 1;
+	}
+
 	if (act_mask_tmp != 0)
 		act_mask = act_mask_tmp;
 

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
@ 2011-10-14  4:00 Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-10-14  4:00 UTC (permalink / raw)
  To: fio

The following changes since commit 15b87723551b424d0db4c53577b567e670c7d4d8:

  Fix bad random offset generation for file map (2011-10-12 09:46:01 +0200)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Bruce Cran (2):
      Fix compile on FreeBSD
      Fix Windows issue with socklen_t

Jens Axboe (183):
      Start of client/server
      Hide things not appropriate behind is_backend
      Use poll() for connect loop
      Close listen socket when done
      Properly log errors in server
      Add start of client, start of real protocol
      Start of functional client
      Server logging cleanup/functionality
      Use length guarded sprintf functions
      Pass more arguments to fio_init_net_cmd()
      server: debug fixes
      crc16: use void * as the argument
      Reinstate double logging if f_err != stderr
      server: switch to 16-bit crc
      server: serial is a 64-bit field
      client: fix error in logging output
      server: quit client when job run is complete
      server: ensure payload larger than max is broken into pieces
      client: initial support for multiple connections
      client: continue support for multiple connections
      server: exit gracefully on ctrl-c
      client: re-setup poll fd array in case a client disappears
      Add FD_NET debugging value
      server/client: add FD_NET debug clues
      Fixup some bad file naming
      server: malloc/free fix
      Style fixup
      server: make struct group_run_stats network transfer friendly
      server: initial support for daemonizing
      server: start conversion of data structures to network friendly types
      client: don't setup shared mem area for just the frontend
      server: endianness bug and exit command
      server: unify shm setup
      Move stat_io_bytes/time to thread_data
      Move getrusage() out of thread_stat
      Allocate thread_stat name arrays statically
      server: transmit status as structures, not text
      client: fixup quit
      Add type checking to 16/32/64 endianness converters
      server: package defrag fix
      Add TODO list
      Abstract out calculation of ETA from display of ETA
      server: add ETA as a specific command
      server: send network copy of run_str[]
      server: attempt to handle client ctrl-c
      server: fix typos in conversion
      poll: break on EINTR without complaining
      server: remove some debug statements
      server: silence mem debug warning
      client: handle connection failure
      server: error handling and probe command
      client: probe command support
      server: idle loop support
      parser: use logging infrastructure
      server: fix for non zero appended strings
      Style fixup
      server: initial support for command line passing
      server: send return quit when asked to leave
      client: improve poll() loop
      server: improve exit handling
      client: improve handling of non-newline text strings
      server: add a few more debug logging statements
      Fix bad indexing of options
      server: more debug dumping
      Move endianness check to OS parts
      log: needs stdarg include for va_list
      HPUX endianness
      Wider endianness support
      More endianness for platforms
      Need signal.h for sigaction()
      server: fix sk typo and add endian type to probe
      server: log where connection is coming from
      server: cast sockaddr_in for accept()
      Update TODO
      Generic endianness typo
      server: log locally if connection isn't up yet
      Finalize (?) byte swap/endian stuff
      server: portability fixups
      log: don't use vsyslog
      Add fio_socklen_t
      Assume AIX is big endian
      AIX fixes
      Remove endianness TODO, should be done now
      Add IEEE 754 pack and unpack helpers
      Change network transmitted doubles to fio_fp64_t IEEE 754 type
      Merge branch 'master' into client-server
      Print usage if no arguments are given
      t/stest: add log.o smaller helper
      Re-enable -O2 optimization
      Add IEEE 754 test case
      Remove float conversion from TODO
      Fio 1.99
      Fix warnings about unused fwrite() return value
      client: prefix server text messages with <hostname>
      Endian sanity check
      Move endian support out of server.h
      Add support for write_iops_log
      client: check and error out on exceeding number of command line args to pass
      parser: always use the fio logging instead of stderr/stdout
      client: ensure that cmd line arguments are always run
      server: send quit if we don't add a job
      client: disconnect on read failure
      client: improve handling of multiple clients
      server: require poll before fio_net_recv_cmd()
      server: quit on !block and backend exit
      Fio 1.99.1
      Only print usage() on error
      Correctly handle multiple clients for various command line arguments
      Add jhash (Jenkins hash) and use that for file names
      client: add hashes for fd/name lookups
      net: support for unix domain sockets
      Add support for client/server connection over unix domain sockets
      Remember to close sockets on error
      Update TODO
      server: fix += -> + typo
      Unify client/server argument
      server: fix bad interpretation of local socket binding
      Remember to clear client cookie
      Split version into separate include fio
      client: remove leftover debug printf()
      server: increase default max pdu length to 1024
      Fio 1.99.2
      Poll server idle loop any time the main status thread sleeps
      client: fix mem leak
      Pass arch/os in probe
      server: ensure to set proper port
      client: don't clear client->addr after it's been set
      server: properly configure port without argument
      client: pretty up probe output
      Makefile: move -rdynamic to linking flag
      Fix warning when clang is used as the compiler
      Makefile: use -O3 by default
      Fio 1.99.3
      client: used hostname passed back in probe as log prefix
      Add protocol support for an arbitrary number of command line arguments
      Update TODO
      client: fix jobs_eta conversion typo
      client: sum running ETA of jobs
      client/server: request ETA instead of having the server send it automatically
      init: typo, remove -> remote.
      client: track pending ETA requests
      client/server: few select speedups
      Abstract out and export summation of thread_stats
      client: properly assign client eta in flight
      server: write pid file for backgrounded server to specified file
      server: improve pidfile and log handling
      client: duplicate arguments to "empty" clients
      server: fread() - check <= 0 return value
      Fio 1.99.4
      client/server: track and handle command timeouts
      server: assume PID is dead on ESRCH
      server: error handling fixes
      client: display summed total of all clients when all stats have been received
      client: dec sum_stat_clients if one a client is disconnected
      client/server: fix ptr <-> uint64_t casting warnings on 32-bit builds
      server: include 32/64-bit in probe
      client: cleanup bit printing
      Fix off-by-one in jobs_eta allocation
      Merge branch 'master' into client-server
      Correct Windows fio version
      Fix clat percentile display
      Pretty up clat percentile display so it's actually readable
      Be a bit more defensive in clat percentile calc and display
      server: fix bug in converting/storing clat percentiles
      Fio 1.99.5
      Remove extra \n before printing run status
      Enable completion latency percentiles by default
      Disable clat percentiles if gtod_reduce=1 is set
      Adapt clat percentiles for min/max values
      client/server: add support for passing disk_util structures
      Break double loop on end-of-clat percentiles
      Silence uninitialized mem warning on disk_util send
      Update TODO
      Add IOPS to terse output
      Don't output version for terse output
      Add completion latency percentiles to terse output format
      Add disk utilization to terse format output
      Move IEEE754 support code to lib/
      Check string length of ts->description, not value
      Fio 1.99.6
      Update man page
      Man page typo
      Only print ts->description if set for non-terse output

Martin Steigerwald (1):
      Escape minus signs in manpage to fix lintian warning:

 HOWTO                  |   29 ++-
 Makefile               |   32 +-
 README                 |   69 +++-
 SERVER-TODO            |    2 +
 arch/arch-alpha.h      |    2 +-
 arch/arch-arm.h        |    2 +-
 arch/arch-generic.h    |    2 +-
 arch/arch-hppa.h       |    2 +-
 arch/arch-ia64.h       |    2 +-
 arch/arch-mips.h       |    2 +-
 arch/arch-ppc.h        |    2 +-
 arch/arch-s390.h       |    2 +-
 arch/arch-sh.h         |    2 +-
 arch/arch-sparc.h      |    2 +-
 arch/arch-sparc64.h    |    2 +-
 arch/arch-x86.h        |    2 +-
 arch/arch-x86_64.h     |    2 +-
 arch/arch.h            |    4 +-
 client.c               |  995 ++++++++++++++++++++++++++++++++++++++++++
 crc/crc16.c            |    5 +-
 crc/crc16.h            |    2 +-
 debug.c                |    4 +-
 debug.h                |    1 +
 diskutil.c             |  194 +++++----
 diskutil.h             |   40 ++-
 engines/net.c          |  209 +++++++--
 eta.c                  |  163 ++++---
 examples/netio         |    9 +-
 filehash.c             |    4 +-
 fio.1                  |  128 +++++-
 fio.c                  |  261 +++++++++---
 fio.h                  |  216 ++--------
 fio_generate_plots     |   18 +
 fio_version.h          |    8 +
 hash.h                 |   77 ++++
 init.c                 |  429 +++++++++++++------
 io_u.c                 |    5 +-
 iolog.c                |  541 +++++++++++++++++++++++
 iolog.h                |   14 +-
 lib/ieee754.c          |   84 ++++
 lib/ieee754.h          |   20 +
 log.c                  |  574 +++----------------------
 log.h                  |   20 +-
 options.c              |   49 ++-
 os/os-aix.h            |   13 +
 os/os-freebsd.h        |   14 +
 os/os-hpux.h           |   14 +
 os/os-linux.h          |   19 +-
 os/os-mac.h            |   16 +
 os/os-netbsd.h         |   13 +
 os/os-solaris.h        |   13 +
 os/os-windows.h        |   11 +
 os/os.h                |   82 ++++
 os/windows/install.wxs |    4 +-
 os/windows/version.h   |   10 +-
 parse.c                |  107 +++---
 server.c               | 1134 ++++++++++++++++++++++++++++++++++++++++++++++++
 server.h               |  144 ++++++
 stat.c                 |  494 ++++++++++++++-------
 stat.h                 |  201 +++++++++
 t/ieee754.c            |   21 +
 t/log.c                |   15 +
 62 files changed, 5162 insertions(+), 1395 deletions(-)
 create mode 100644 SERVER-TODO
 create mode 100644 client.c
 create mode 100644 fio_version.h
 create mode 100644 iolog.c
 create mode 100644 lib/ieee754.c
 create mode 100644 lib/ieee754.h
 create mode 100644 server.c
 create mode 100644 server.h
 create mode 100644 stat.h
 create mode 100644 t/ieee754.c
 create mode 100644 t/log.c

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index cc2df9b..a8d5197 100644
--- a/HOWTO
+++ b/HOWTO
@@ -267,7 +267,7 @@ filename=str	Fio normally makes up a filename based on the job name,
 		files between threads in a job or several jobs, specify
 		a filename for each of them to override the default. If
 		the ioengine used is 'net', the filename is the host, port,
-		and protocol to use in the format of =host/port/protocol.
+		and protocol to use in the format of =host,port,protocol.
 		See ioengine=net for more. If the ioengine is file based, you
 		can specify a number of files by separating the names with a
 		':' colon. So if you wanted a job to open /dev/sda and /dev/sdb
@@ -864,6 +864,9 @@ exitall		When one job finishes, terminate the rest. The default is
 bwavgtime=int	Average the calculated bandwidth over the given time. Value
 		is specified in milliseconds.
 
+iopsavgtime=int	Average the calculated IOPS over the given time. Value
+		is specified in milliseconds.
+
 create_serialize=bool	If true, serialize the file creating for the jobs.
 			This may be handy to avoid interleaving of data
 			files, which may greatly depend on the filesystem
@@ -1104,6 +1107,9 @@ write_lat_log=str Same as write_bw_log, except that this option stores io
 		and foo_lat.log. This helps fio_generate_plot fine the logs
 		automatically.
 
+write_bw_log=str If given, write an IOPS log of the jobs in this job
+		file. See write_bw_log.
+
 lockmem=int	Pin down the specified amount of memory with mlock(2). Can
 		potentially be used instead of removing memory or booting
 		with less memory to simulate a smaller amount of memory.
@@ -1356,25 +1362,42 @@ Split up, the format is as follows:
 
 	version, jobname, groupid, error
 	READ status:
-		Total IO (KB), bandwidth (KB/sec), runtime (msec)
+		Total IO (KB), bandwidth (KB/sec), IOPS, runtime (msec)
 		Submission latency: min, max, mean, deviation
 		Completion latency: min, max, mean, deviation
+		Completion latency percentiles: 20 fields (see below)
 		Total latency: min, max, mean, deviation
 		Bw: min, max, aggregate percentage of total, mean, deviation
 	WRITE status:
-		Total IO (KB), bandwidth (KB/sec), runtime (msec)
+		Total IO (KB), bandwidth (KB/sec), IOPS, runtime (msec)
 		Submission latency: min, max, mean, deviation
 		Completion latency: min, max, mean, deviation
+		Completion latency percentiles: 20 fields (see below)
 		Total latency: min, max, mean, deviation
 		Bw: min, max, aggregate percentage of total, mean, deviation
 	CPU usage: user, system, context switches, major faults, minor faults
 	IO depths: <=1, 2, 4, 8, 16, 32, >=64
 	IO latencies microseconds: <=2, 4, 10, 20, 50, 100, 250, 500, 750, 1000
 	IO latencies milliseconds: <=2, 4, 10, 20, 50, 100, 250, 500, 750, 1000, 2000, >=2000
+	Disk utilization: Disk name, Read ios, write ios,
+			  Read merges, write merges,
+			  Read ticks, write ticks,
+			  Read in-queue time, write in-queue time,
+			  Disk utilization percentage
 	Additional Info (dependant on continue_on_error, default off): total # errors, first error code 
 	
 	Additional Info (dependant on description being set): Text description
 
+Completion latency percentiles can be a grouping of up to 20 sets, so
+for the terse output fio writes all of them. Each field will look like this:
+
+	1.00%=6112
+
+which is the Xth percentile, and the usec latency associated with it.
+
+For disk utilization, all disks used by fio are shown. So for each disk
+there will be a disk utilization section.
+
 
 8.0 Trace file format
 ---------------------
diff --git a/Makefile b/Makefile
index 85942a0..6a3f85b 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC	= gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
 CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
 	$(DEBUGFLAGS)
-OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
+OPTFLAGS= -O3 -fno-omit-frame-pointer -g $(EXTFLAGS)
 CFLAGS	= -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS)
 LIBS	= -lm $(EXTLIBS)
 PROGS	= fio
@@ -12,9 +12,9 @@ UNAME  := $(shell uname)
 SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
 		eta.c verify.c memory.c io_u.c parse.c mutex.c options.c \
 		rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \
-		lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
+		lib/num2str.c lib/ieee754.c $(wildcard crc/*.c) engines/cpu.c \
 		engines/mmap.c engines/sync.c engines/null.c engines/net.c \
-		memalign.c
+		memalign.c server.c client.c iolog.c
 
 ifeq ($(UNAME), Linux)
   SOURCE += diskutil.c fifo.c blktrace.c helpers.c cgroup.c trim.c \
@@ -22,7 +22,7 @@ ifeq ($(UNAME), Linux)
 		engines/splice.c engines/syslet-rw.c engines/guasi.c \
 		engines/binject.c engines/rdma.c profiles/tiobench.c
   LIBS += -lpthread -ldl -lrt -laio
-  CFLAGS += -rdynamic
+  LDFLAGS += -rdynamic
 endif
 ifeq ($(UNAME), SunOS)
   SOURCE += fifo.c lib/strsep.c helpers.c engines/posixaio.c \
@@ -33,12 +33,12 @@ endif
 ifeq ($(UNAME), FreeBSD)
   SOURCE += helpers.c engines/posixaio.c
   LIBS	 += -lpthread -lrt
-  CFLAGS += -rdynamic
+  LDFLAGS += -rdynamic
 endif
 ifeq ($(UNAME), NetBSD)
   SOURCE += helpers.c engines/posixaio.c
   LIBS	 += -lpthread -lrt
-  CFLAGS += -rdynamic
+  LDFLAGS += -rdynamic
 endif
 ifeq ($(UNAME), AIX)
   SOURCE += fifo.c helpers.c lib/getopt_long.c engines/posixaio.c
@@ -63,9 +63,16 @@ endif
 
 OBJS = $(SOURCE:.c=.o)
 
-T_OBJS = t/stest.o
-T_OBJS += mutex.o smalloc.o
-T_PROGS = t/stest
+T_SMALLOC_OBJS = t/stest.o
+T_SMALLOC_OBJS += mutex.o smalloc.o t/log.o
+T_SMALLOC_PROGS = t/stest
+
+T_IEEE_OBJS = t/ieee754.o
+T_IEEE_OBJS += ieee754.o
+T_IEEE_PROGS = t/ieee754
+
+T_OBJS = $(T_SMALLOC_OBJS)
+T_OBJS += $(T_IEEE_OBJS)
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
@@ -84,8 +91,11 @@ all: .depend $(PROGS) $(SCRIPTS)
 .c.o: .depend
 	$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
 
-t/stest: $(T_OBJS)
-	$(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_OBJS) $(LIBS) $(LDFLAGS)
+t/stest: $(T_SMALLOC_OBJS)
+	$(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_SMALLOC_OBJS) $(LIBS) $(LDFLAGS)
+
+t/ieee754: $(T_IEEE_OBJS)
+	$(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_IEEE_OBJS) $(LIBS) $(LDFLAGS)
 
 fio: $(OBJS)
 	$(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
diff --git a/README b/README
index 0eac41f..26b5909 100644
--- a/README
+++ b/README
@@ -133,23 +133,25 @@ $ fio
 	--debug			Enable some debugging options (see below)
 	--output		Write output to file
 	--timeout		Runtime in seconds
-	--latency-log	Generate per-job latency logs
-	--bandwidth-log	Generate per-job bandwidth logs
+	--latency-log		Generate per-job latency logs
+	--bandwidth-log		Generate per-job bandwidth logs
 	--minimal		Minimal (terse) output
 	--version		Print version info and exit
 	--terse-version=type	Terse version output format
 	--help			Print this page
-	--cmdhelp=cmd	Print command help, "all" for all of them
+	--cmdhelp=cmd		Print command help, "all" for all of them
 	--showcmd		Turn a job file into command line options
 	--readonly		Turn on safety read-only checks, preventing
-					writes
+				writes
 	--eta=when		When ETA estimate should be printed
-					May be "always", "never" or "auto"
-	--section=name	Only run specified section in job file. Multiple
-				sections can be specified.
+				May be "always", "never" or "auto"
+	--section=name		Only run specified section in job file.
+				Multiple sections can be specified.
 	--alloc-size=kb	Set smalloc pool to this size in kb (def 1024)
 	--warnings-fatal Fio parser warnings are fatal
 	--max-jobs		Maximum number of threads/processes to support
+	--server=args		Start backend server. See Client/Server section.
+	--client=host		Connect to specified backend.
 
 
 Any parameters following the options will be assumed to be job files,
@@ -315,6 +317,59 @@ The job file parameters are:
 
 
 
+Client/server
+------------
+
+Normally you would run fio as a stand-alone application on the machine
+where the IO workload should be generated. However, it is also possible to
+run the frontend and backend of fio separately. This makes it possible to
+have a fio server running on the machine(s) where the IO workload should
+be running, while controlling it from another machine.
+
+To start the server, you would do:
+
+fio --server=args
+
+on that machine, where args defines what fio listens to. The arguments
+are of the form 'type:hostname or IP:port'. 'type' is either 'ip' for
+TCP/IP, or 'sock' for a local unix domain socket. 'hostname' is either
+a hostname or IP address, and 'port' is the port to listen to (only valid
+for TCP/IP, not a local socket). Some examples:
+
+1) fio --server
+
+   Start a fio server, listening on all interfaces on the default port (8765).
+
+2) fio --server=ip:hostname:4444
+
+   Start a fio server, listening on IP belonging to hostname and on port 4444.
+
+3) fio --server=:4444
+
+   Start a fio server, listening on all interfaces on port 4444.
+
+4) fio --server=1.2.3.4
+
+   Start a fio server, listening on IP 1.2.3.4 on the default port.
+
+5) fio --server=sock:/tmp/fio.sock
+
+   Start a fio server, listening on the local socket /tmp/fio.sock.
+
+When a server is running, you can connect to it from a client. The client
+is run with:
+
+fio --local-args --client=server --remote-args <job file(s)>
+
+where --local-args are arguments that are local to the client where it is
+running, 'server' is the connect string, and --remote-args and <job file(s)>
+are sent to the server. The 'server' string follows the same format as it
+does on the server side, to allow IP/hostname/socket and port strings.
+You can connect to multiple clients as well, to do that you could run:
+
+fio --client=server2 --client=server2 <job file(s)>
+
+
 Platforms
 ---------
 
diff --git a/SERVER-TODO b/SERVER-TODO
new file mode 100644
index 0000000..b988405
--- /dev/null
+++ b/SERVER-TODO
@@ -0,0 +1,2 @@
+- Collate ETA output from multiple connections into 1
+- If group_reporting is set, collate final output from multiple connections
diff --git a/arch/arch-alpha.h b/arch/arch-alpha.h
index e8132a0..c0f784f 100644
--- a/arch/arch-alpha.h
+++ b/arch/arch-alpha.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_ALPHA_H
 #define ARCH_ALPHA_H
 
-#define ARCH	(arch_alpha)
+#define FIO_ARCH	(arch_alpha)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		442
diff --git a/arch/arch-arm.h b/arch/arch-arm.h
index b0cfd80..658b688 100644
--- a/arch/arch-arm.h
+++ b/arch/arch-arm.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_ARM_H
 #define ARCH_ARM_H
 
-#define ARCH	(arch_arm)
+#define FIO_ARCH	(arch_arm)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		314
diff --git a/arch/arch-generic.h b/arch/arch-generic.h
index c7b0ca0..a0b71f8 100644
--- a/arch/arch-generic.h
+++ b/arch/arch-generic.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_GENERIC_H
 #define ARCH_GENERIC_H
 
-#define ARCH	(arch_generic)
+#define FIO_ARCH	(arch_generic)
 
 #define nop			do { } while (0)
 #define read_barrier()		__asm__ __volatile__("": : :"memory")
diff --git a/arch/arch-hppa.h b/arch/arch-hppa.h
index c865a89..c1c079e 100644
--- a/arch/arch-hppa.h
+++ b/arch/arch-hppa.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_HPPA_H
 #define ARCH_HPPA_H
 
-#define ARCH	(arch_hppa)
+#define FIO_ARCH	(arch_hppa)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		267
diff --git a/arch/arch-ia64.h b/arch/arch-ia64.h
index 056f636..f4464c4 100644
--- a/arch/arch-ia64.h
+++ b/arch/arch-ia64.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_IA64_H
 #define ARCH_IA64_H
 
-#define ARCH	(arch_ia64)
+#define FIO_ARCH	(arch_ia64)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		1274
diff --git a/arch/arch-mips.h b/arch/arch-mips.h
index 759d3a9..0b781d1 100644
--- a/arch/arch-mips.h
+++ b/arch/arch-mips.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_MIPS64_H
 #define ARCH_MIPS64_H
 
-#define ARCH	(arch_mips)
+#define FIO_ARCH	(arch_mips)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		314
diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h
index d495a1b..b790a55 100644
--- a/arch/arch-ppc.h
+++ b/arch/arch-ppc.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_PPC_H
 #define ARCH_PPH_H
 
-#define ARCH	(arch_ppc)
+#define FIO_ARCH	(arch_ppc)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		273
diff --git a/arch/arch-s390.h b/arch/arch-s390.h
index 0647750..fe51791 100644
--- a/arch/arch-s390.h
+++ b/arch/arch-s390.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_S390_H
 #define ARCH_S390_H
 
-#define ARCH	(arch_s390)
+#define FIO_ARCH	(arch_s390)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		282
diff --git a/arch/arch-sh.h b/arch/arch-sh.h
index f5f313d..9acbbbe 100644
--- a/arch/arch-sh.h
+++ b/arch/arch-sh.h
@@ -3,7 +3,7 @@
 #ifndef ARCH_SH_H
 #define ARCH_SH_H
 
-#define ARCH	(arch_sh)
+#define FIO_ARCH	(arch_sh)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set	288
diff --git a/arch/arch-sparc.h b/arch/arch-sparc.h
index cd552ab..fe47b80 100644
--- a/arch/arch-sparc.h
+++ b/arch/arch-sparc.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_SPARC_H
 #define ARCH_SPARC_H
 
-#define ARCH	(arch_sparc)
+#define FIO_ARCH	(arch_sparc)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		196
diff --git a/arch/arch-sparc64.h b/arch/arch-sparc64.h
index 332cf91..e793ae5 100644
--- a/arch/arch-sparc64.h
+++ b/arch/arch-sparc64.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_SPARC64_H
 #define ARCH_SPARC64_H
 
-#define ARCH	(arch_sparc64)
+#define FIO_ARCH	(arch_sparc64)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		196
diff --git a/arch/arch-x86.h b/arch/arch-x86.h
index 2e803cb..1ededd8 100644
--- a/arch/arch-x86.h
+++ b/arch/arch-x86.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_X86_H
 #define ARCH_X86_H
 
-#define ARCH	(arch_i386)
+#define FIO_ARCH	(arch_i386)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		289
diff --git a/arch/arch-x86_64.h b/arch/arch-x86_64.h
index f2dcf49..29e681f 100644
--- a/arch/arch-x86_64.h
+++ b/arch/arch-x86_64.h
@@ -1,7 +1,7 @@
 #ifndef ARCH_X86_64_h
 #define ARCH_X86_64_h
 
-#define ARCH	(arch_x86_64)
+#define FIO_ARCH	(arch_x86_64)
 
 #ifndef __NR_ioprio_set
 #define __NR_ioprio_set		251
diff --git a/arch/arch.h b/arch/arch.h
index d598652..4ad49a4 100644
--- a/arch/arch.h
+++ b/arch/arch.h
@@ -8,7 +8,7 @@
 #endif
 
 enum {
-	arch_x86_64,
+	arch_x86_64 = 1,
 	arch_i386,
 	arch_ppc,
 	arch_ia64,
@@ -21,6 +21,8 @@ enum {
 	arch_hppa,
 
 	arch_generic,
+
+	arch_nr,
 };
 
 enum {
diff --git a/client.c b/client.c
new file mode 100644
index 0000000..c72f034
--- /dev/null
+++ b/client.c
@@ -0,0 +1,995 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+
+#include "fio.h"
+#include "server.h"
+#include "flist.h"
+#include "hash.h"
+
+struct client_eta {
+	struct jobs_eta eta;
+	unsigned int pending;
+};
+
+struct fio_client {
+	struct flist_head list;
+	struct flist_head hash_list;
+	struct flist_head arg_list;
+	struct sockaddr_in addr;
+	struct sockaddr_un addr_un;
+	char *hostname;
+	int port;
+	int fd;
+
+	char *name;
+
+	int state;
+
+	int skip_newline;
+	int is_sock;
+	int disk_stats_shown;
+
+	struct flist_head eta_list;
+	struct client_eta *eta_in_flight;
+
+	struct flist_head cmd_list;
+
+	uint16_t argc;
+	char **argv;
+};
+
+static struct timeval eta_tv;
+
+enum {
+	Client_created		= 0,
+	Client_connected	= 1,
+	Client_started		= 2,
+	Client_stopped		= 3,
+	Client_exited		= 4,
+};
+
+static FLIST_HEAD(client_list);
+static FLIST_HEAD(eta_list);
+
+static FLIST_HEAD(arg_list);
+
+static struct thread_stat client_ts;
+static struct group_run_stats client_gs;
+static int sum_stat_clients;
+static int sum_stat_nr;
+
+#define FIO_CLIENT_HASH_BITS	7
+#define FIO_CLIENT_HASH_SZ	(1 << FIO_CLIENT_HASH_BITS)
+#define FIO_CLIENT_HASH_MASK	(FIO_CLIENT_HASH_SZ - 1)
+static struct flist_head client_hash[FIO_CLIENT_HASH_SZ];
+
+static int handle_client(struct fio_client *client);
+static void dec_jobs_eta(struct client_eta *eta);
+
+static void fio_client_add_hash(struct fio_client *client)
+{
+	int bucket = hash_long(client->fd, FIO_CLIENT_HASH_BITS);
+
+	bucket &= FIO_CLIENT_HASH_MASK;
+	flist_add(&client->hash_list, &client_hash[bucket]);
+}
+
+static void fio_client_remove_hash(struct fio_client *client)
+{
+	if (!flist_empty(&client->hash_list))
+		flist_del_init(&client->hash_list);
+}
+
+static void fio_init fio_client_hash_init(void)
+{
+	int i;
+
+	for (i = 0; i < FIO_CLIENT_HASH_SZ; i++)
+		INIT_FLIST_HEAD(&client_hash[i]);
+}
+
+static struct fio_client *find_client_by_fd(int fd)
+{
+	int bucket = hash_long(fd, FIO_CLIENT_HASH_BITS) & FIO_CLIENT_HASH_MASK;
+	struct fio_client *client;
+	struct flist_head *entry;
+
+	flist_for_each(entry, &client_hash[bucket]) {
+		client = flist_entry(entry, struct fio_client, hash_list);
+
+		if (client->fd == fd)
+			return client;
+	}
+
+	return NULL;
+}
+
+static void remove_client(struct fio_client *client)
+{
+	dprint(FD_NET, "client: removed <%s>\n", client->hostname);
+	flist_del(&client->list);
+
+	fio_client_remove_hash(client);
+
+	if (!flist_empty(&client->eta_list)) {
+		flist_del_init(&client->eta_list);
+		dec_jobs_eta(client->eta_in_flight);
+	}
+
+	free(client->hostname);
+	if (client->argv)
+		free(client->argv);
+	if (client->name)
+		free(client->name);
+
+	free(client);
+	nr_clients--;
+	sum_stat_clients--;
+}
+
+static void __fio_client_add_cmd_option(struct fio_client *client,
+					const char *opt)
+{
+	int index;
+
+	index = client->argc++;
+	client->argv = realloc(client->argv, sizeof(char *) * client->argc);
+	client->argv[index] = strdup(opt);
+	dprint(FD_NET, "client: add cmd %d: %s\n", index, opt);
+}
+
+void fio_client_add_cmd_option(void *cookie, const char *opt)
+{
+	struct fio_client *client = cookie;
+	struct flist_head *entry;
+
+	if (!client || !opt)
+		return;
+
+	__fio_client_add_cmd_option(client, opt);
+
+	/*
+	 * Duplicate arguments to shared client group
+	 */
+	flist_for_each(entry, &arg_list) {
+		client = flist_entry(entry, struct fio_client, arg_list);
+
+		__fio_client_add_cmd_option(client, opt);
+	}
+}
+
+int fio_client_add(const char *hostname, void **cookie)
+{
+	struct fio_client *existing = *cookie;
+	struct fio_client *client;
+
+	if (existing) {
+		/*
+		 * We always add our "exec" name as the option, hence 1
+		 * means empty.
+		 */
+		if (existing->argc == 1)
+			flist_add_tail(&existing->arg_list, &arg_list);
+		else {
+			while (!flist_empty(&arg_list))
+				flist_del_init(arg_list.next);
+		}
+	}
+
+	client = malloc(sizeof(*client));
+	memset(client, 0, sizeof(*client));
+
+	INIT_FLIST_HEAD(&client->list);
+	INIT_FLIST_HEAD(&client->hash_list);
+	INIT_FLIST_HEAD(&client->arg_list);
+	INIT_FLIST_HEAD(&client->eta_list);
+	INIT_FLIST_HEAD(&client->cmd_list);
+
+	if (fio_server_parse_string(hostname, &client->hostname,
+					&client->is_sock, &client->port,
+					&client->addr.sin_addr))
+		return -1;
+
+	client->fd = -1;
+
+	__fio_client_add_cmd_option(client, "fio");
+
+	flist_add(&client->list, &client_list);
+	nr_clients++;
+	dprint(FD_NET, "client: added <%s>\n", client->hostname);
+	*cookie = client;
+	return 0;
+}
+
+static int fio_client_connect_ip(struct fio_client *client)
+{
+	int fd;
+
+	client->addr.sin_family = AF_INET;
+	client->addr.sin_port = htons(client->port);
+
+	fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (fd < 0) {
+		log_err("fio: socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	if (connect(fd, (struct sockaddr *) &client->addr, sizeof(client->addr)) < 0) {
+		log_err("fio: connect: %s\n", strerror(errno));
+		log_err("fio: failed to connect to %s:%u\n", client->hostname,
+								client->port);
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+static int fio_client_connect_sock(struct fio_client *client)
+{
+	struct sockaddr_un *addr = &client->addr_un;
+	fio_socklen_t len;
+	int fd;
+
+	memset(addr, 0, sizeof(*addr));
+	addr->sun_family = AF_UNIX;
+	strcpy(addr->sun_path, client->hostname);
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd < 0) {
+		log_err("fio: socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
+	if (connect(fd, (struct sockaddr *) addr, len) < 0) {
+		log_err("fio: connect; %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+static int fio_client_connect(struct fio_client *client)
+{
+	int fd;
+
+	dprint(FD_NET, "client: connect to host %s\n", client->hostname);
+
+	if (client->is_sock)
+		fd = fio_client_connect_sock(client);
+	else
+		fd = fio_client_connect_ip(client);
+
+	dprint(FD_NET, "client: %s connected %d\n", client->hostname, fd);
+
+	if (fd < 0)
+		return 1;
+
+	client->fd = fd;
+	fio_client_add_hash(client);
+	client->state = Client_connected;
+	return 0;
+}
+
+void fio_clients_terminate(void)
+{
+	struct flist_head *entry;
+	struct fio_client *client;
+
+	dprint(FD_NET, "client: terminate clients\n");
+
+	flist_for_each(entry, &client_list) {
+		client = flist_entry(entry, struct fio_client, list);
+
+		fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_QUIT, 0, NULL);
+	}
+}
+
+static void sig_int(int sig)
+{
+	dprint(FD_NET, "client: got signal %d\n", sig);
+	fio_clients_terminate();
+}
+
+static void client_signal_handler(void)
+{
+	struct sigaction act;
+
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = sig_int;
+	act.sa_flags = SA_RESTART;
+	sigaction(SIGINT, &act, NULL);
+
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = sig_int;
+	act.sa_flags = SA_RESTART;
+	sigaction(SIGTERM, &act, NULL);
+}
+
+static void probe_client(struct fio_client *client)
+{
+	dprint(FD_NET, "client: send probe\n");
+
+	fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_PROBE, 0, &client->cmd_list);
+}
+
+static int send_client_cmd_line(struct fio_client *client)
+{
+	struct cmd_single_line_pdu *cslp;
+	struct cmd_line_pdu *clp;
+	unsigned long offset;
+	unsigned int *lens;
+	void *pdu;
+	size_t mem;
+	int i, ret;
+
+	dprint(FD_NET, "client: send cmdline %d\n", client->argc);
+
+	lens = malloc(client->argc * sizeof(unsigned int));
+
+	/*
+	 * Find out how much mem we need
+	 */
+	for (i = 0, mem = 0; i < client->argc; i++) {
+		lens[i] = strlen(client->argv[i]) + 1;
+		mem += lens[i];
+	}
+
+	/*
+	 * We need one cmd_line_pdu, and argc number of cmd_single_line_pdu
+	 */
+	mem += sizeof(*clp) + (client->argc * sizeof(*cslp));
+
+	pdu = malloc(mem);
+	clp = pdu;
+	offset = sizeof(*clp);
+
+	for (i = 0; i < client->argc; i++) {
+		uint16_t arg_len = lens[i];
+
+		cslp = pdu + offset;
+		strcpy((char *) cslp->text, client->argv[i]);
+		cslp->len = cpu_to_le16(arg_len);
+		offset += sizeof(*cslp) + arg_len;
+	}
+
+	free(lens);
+	clp->lines = cpu_to_le16(client->argc);
+	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOBLINE, pdu, mem, 0);
+	free(pdu);
+	return ret;
+}
+
+int fio_clients_connect(void)
+{
+	struct fio_client *client;
+	struct flist_head *entry, *tmp;
+	int ret;
+
+	dprint(FD_NET, "client: connect all\n");
+
+	client_signal_handler();
+
+	flist_for_each_safe(entry, tmp, &client_list) {
+		client = flist_entry(entry, struct fio_client, list);
+
+		ret = fio_client_connect(client);
+		if (ret) {
+			remove_client(client);
+			continue;
+		}
+
+		probe_client(client);
+
+		if (client->argc > 1)
+			send_client_cmd_line(client);
+	}
+
+	return !nr_clients;
+}
+
+/*
+ * Send file contents to server backend. We could use sendfile(), but to remain
+ * more portable lets just read/write the darn thing.
+ */
+static int fio_client_send_ini(struct fio_client *client, const char *filename)
+{
+	struct stat sb;
+	char *p, *buf;
+	off_t len;
+	int fd, ret;
+
+	dprint(FD_NET, "send ini %s to %s\n", filename, client->hostname);
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		log_err("fio: job file <%s> open: %s\n", filename, strerror(errno));
+		return 1;
+	}
+
+	if (fstat(fd, &sb) < 0) {
+		log_err("fio: job file stat: %s\n", strerror(errno));
+		close(fd);
+		return 1;
+	}
+
+	buf = malloc(sb.st_size);
+
+	len = sb.st_size;
+	p = buf;
+	do {
+		ret = read(fd, p, len);
+		if (ret > 0) {
+			len -= ret;
+			if (!len)
+				break;
+			p += ret;
+			continue;
+		} else if (!ret)
+			break;
+		else if (errno == EAGAIN || errno == EINTR)
+			continue;
+	} while (1);
+
+	if (len) {
+		log_err("fio: failed reading job file %s\n", filename);
+		close(fd);
+		free(buf);
+		return 1;
+	}
+
+	ret = fio_net_send_cmd(client->fd, FIO_NET_CMD_JOB, buf, sb.st_size, 0);
+	free(buf);
+	close(fd);
+	return ret;
+}
+
+int fio_clients_send_ini(const char *filename)
+{
+	struct fio_client *client;
+	struct flist_head *entry, *tmp;
+
+	flist_for_each_safe(entry, tmp, &client_list) {
+		client = flist_entry(entry, struct fio_client, list);
+
+		if (fio_client_send_ini(client, filename))
+			remove_client(client);
+	}
+
+	return !nr_clients;
+}
+
+static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
+{
+	dst->max_val	= le64_to_cpu(src->max_val);
+	dst->min_val	= le64_to_cpu(src->min_val);
+	dst->samples	= le64_to_cpu(src->samples);
+
+	/*
+	 * Floats arrive as IEEE 754 encoded uint64_t, convert back to double
+	 */
+	dst->mean.u.f	= fio_uint64_to_double(le64_to_cpu(dst->mean.u.i));
+	dst->S.u.f	= fio_uint64_to_double(le64_to_cpu(dst->S.u.i));
+}
+
+static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
+{
+	int i, j;
+
+	dst->error	= le32_to_cpu(src->error);
+	dst->groupid	= le32_to_cpu(src->groupid);
+	dst->pid	= le32_to_cpu(src->pid);
+	dst->members	= le32_to_cpu(src->members);
+
+	for (i = 0; i < 2; i++) {
+		convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]);
+		convert_io_stat(&dst->slat_stat[i], &src->slat_stat[i]);
+		convert_io_stat(&dst->lat_stat[i], &src->lat_stat[i]);
+		convert_io_stat(&dst->bw_stat[i], &src->bw_stat[i]);
+	}
+
+	dst->usr_time		= le64_to_cpu(src->usr_time);
+	dst->sys_time		= le64_to_cpu(src->sys_time);
+	dst->ctx		= le64_to_cpu(src->ctx);
+	dst->minf		= le64_to_cpu(src->minf);
+	dst->majf		= le64_to_cpu(src->majf);
+	dst->clat_percentiles	= le64_to_cpu(src->clat_percentiles);
+
+	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
+		fio_fp64_t *fps = &src->percentile_list[i];
+		fio_fp64_t *fpd = &dst->percentile_list[i];
+
+		fpd->u.f = fio_uint64_to_double(le64_to_cpu(fps->u.i));
+	}
+
+	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
+		dst->io_u_map[i]	= le32_to_cpu(src->io_u_map[i]);
+		dst->io_u_submit[i]	= le32_to_cpu(src->io_u_submit[i]);
+		dst->io_u_complete[i]	= le32_to_cpu(src->io_u_complete[i]);
+	}
+
+	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
+		dst->io_u_lat_u[i]	= le32_to_cpu(src->io_u_lat_u[i]);
+		dst->io_u_lat_m[i]	= le32_to_cpu(src->io_u_lat_m[i]);
+	}
+
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
+			dst->io_u_plat[i][j] = le32_to_cpu(src->io_u_plat[i][j]);
+
+	for (i = 0; i < 3; i++) {
+		dst->total_io_u[i]	= le64_to_cpu(src->total_io_u[i]);
+		dst->short_io_u[i]	= le64_to_cpu(src->short_io_u[i]);
+	}
+
+	dst->total_submit	= le64_to_cpu(src->total_submit);
+	dst->total_complete	= le64_to_cpu(src->total_complete);
+
+	for (i = 0; i < 2; i++) {
+		dst->io_bytes[i]	= le64_to_cpu(src->io_bytes[i]);
+		dst->runtime[i]		= le64_to_cpu(src->runtime[i]);
+	}
+
+	dst->total_run_time	= le64_to_cpu(src->total_run_time);
+	dst->continue_on_error	= le16_to_cpu(src->continue_on_error);
+	dst->total_err_count	= le64_to_cpu(src->total_err_count);
+	dst->first_error	= le32_to_cpu(src->first_error);
+	dst->kb_base		= le32_to_cpu(src->kb_base);
+}
+
+static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		dst->max_run[i]		= le64_to_cpu(src->max_run[i]);
+		dst->min_run[i]		= le64_to_cpu(src->min_run[i]);
+		dst->max_bw[i]		= le64_to_cpu(src->max_bw[i]);
+		dst->min_bw[i]		= le64_to_cpu(src->min_bw[i]);
+		dst->io_kb[i]		= le64_to_cpu(src->io_kb[i]);
+		dst->agg[i]		= le64_to_cpu(src->agg[i]);
+	}
+
+	dst->kb_base	= le32_to_cpu(src->kb_base);
+	dst->groupid	= le32_to_cpu(src->groupid);
+}
+
+static void handle_ts(struct fio_net_cmd *cmd)
+{
+	struct cmd_ts_pdu *p = (struct cmd_ts_pdu *) cmd->payload;
+
+	convert_ts(&p->ts, &p->ts);
+	convert_gs(&p->rs, &p->rs);
+
+	show_thread_status(&p->ts, &p->rs);
+
+	if (sum_stat_clients == 1)
+		return;
+
+	sum_thread_stats(&client_ts, &p->ts, sum_stat_nr);
+	sum_group_stats(&client_gs, &p->rs);
+
+	client_ts.members++;
+	client_ts.groupid = p->ts.groupid;
+
+	if (++sum_stat_nr == sum_stat_clients) {
+		strcpy(client_ts.name, "All clients");
+		show_thread_status(&client_ts, &client_gs);
+	}
+}
+
+static void handle_gs(struct fio_net_cmd *cmd)
+{
+	struct group_run_stats *gs = (struct group_run_stats *) cmd->payload;
+
+	convert_gs(gs, gs);
+	show_group_stats(gs);
+}
+
+static void convert_agg(struct disk_util_agg *agg)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		agg->ios[i]	= le32_to_cpu(agg->ios[i]);
+		agg->merges[i]	= le32_to_cpu(agg->merges[i]);
+		agg->sectors[i]	= le64_to_cpu(agg->sectors[i]);
+		agg->ticks[i]	= le32_to_cpu(agg->ticks[i]);
+	}
+
+	agg->io_ticks		= le32_to_cpu(agg->io_ticks);
+	agg->time_in_queue	= le32_to_cpu(agg->time_in_queue);
+	agg->slavecount		= le32_to_cpu(agg->slavecount);
+	agg->max_util.u.f	= __le64_to_cpu(fio_uint64_to_double(agg->max_util.u.i));
+}
+
+static void convert_dus(struct disk_util_stat *dus)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		dus->ios[i]	= le32_to_cpu(dus->ios[i]);
+		dus->merges[i]	= le32_to_cpu(dus->merges[i]);
+		dus->sectors[i]	= le64_to_cpu(dus->sectors[i]);
+		dus->ticks[i]	= le32_to_cpu(dus->ticks[i]);
+	}
+
+	dus->io_ticks		= le32_to_cpu(dus->io_ticks);
+	dus->time_in_queue	= le32_to_cpu(dus->time_in_queue);
+	dus->msec		= le64_to_cpu(dus->msec);
+}
+
+static void handle_du(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+	struct cmd_du_pdu *du = (struct cmd_du_pdu *) cmd->payload;
+
+	convert_dus(&du->dus);
+	convert_agg(&du->agg);
+
+	if (!client->disk_stats_shown) {
+		client->disk_stats_shown = 1;
+		log_info("\nDisk stats (read/write):\n");
+	}
+
+	print_disk_util(&du->dus, &du->agg, terse_output);
+}
+
+static void convert_jobs_eta(struct jobs_eta *je)
+{
+	int i;
+
+	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->files_open		= le32_to_cpu(je->files_open);
+	je->m_rate		= le32_to_cpu(je->m_rate);
+	je->t_rate		= le32_to_cpu(je->t_rate);
+	je->m_iops		= le32_to_cpu(je->m_iops);
+	je->t_iops		= le32_to_cpu(je->t_iops);
+
+	for (i = 0; i < 2; i++) {
+		je->rate[i]	= le32_to_cpu(je->rate[i]);
+		je->iops[i]	= le32_to_cpu(je->iops[i]);
+	}
+
+	je->elapsed_sec		= le64_to_cpu(je->elapsed_sec);
+	je->eta_sec		= le64_to_cpu(je->eta_sec);
+}
+
+static void sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
+{
+	int i;
+
+	dst->nr_running		+= je->nr_running;
+	dst->nr_ramp		+= je->nr_ramp;
+	dst->nr_pending		+= je->nr_pending;
+	dst->files_open		+= je->files_open;
+	dst->m_rate		+= je->m_rate;
+	dst->t_rate		+= je->t_rate;
+	dst->m_iops		+= je->m_iops;
+	dst->t_iops		+= je->t_iops;
+
+	for (i = 0; i < 2; i++) {
+		dst->rate[i]	+= je->rate[i];
+		dst->iops[i]	+= je->iops[i];
+	}
+
+	dst->elapsed_sec	+= je->elapsed_sec;
+
+	if (je->eta_sec > dst->eta_sec)
+		dst->eta_sec = je->eta_sec;
+}
+
+static void dec_jobs_eta(struct client_eta *eta)
+{
+	if (!--eta->pending) {
+		display_thread_status(&eta->eta);
+		free(eta);
+	}
+}
+
+static void remove_reply_cmd(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+	struct fio_net_int_cmd *icmd = NULL;
+	struct flist_head *entry;
+
+	flist_for_each(entry, &client->cmd_list) {
+		icmd = flist_entry(entry, struct fio_net_int_cmd, list);
+
+		if (cmd->tag == (uintptr_t) icmd)
+			break;
+
+		icmd = NULL;
+	}
+
+	if (!icmd) {
+		log_err("fio: client: unable to find matching tag\n");
+		return;
+	}
+
+	flist_del(&icmd->list);
+	cmd->tag = icmd->saved_tag;
+	free(icmd);
+}
+
+static void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+	struct jobs_eta *je = (struct jobs_eta *) cmd->payload;
+	struct client_eta *eta = (struct client_eta *) (uintptr_t) cmd->tag;
+
+	dprint(FD_NET, "client: got eta tag %p, %d\n", eta, eta->pending);
+
+	assert(client->eta_in_flight == eta);
+
+	client->eta_in_flight = NULL;
+	flist_del_init(&client->eta_list);
+
+	convert_jobs_eta(je);
+	sum_jobs_eta(&eta->eta, je);
+	dec_jobs_eta(eta);
+}
+
+static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd)
+{
+	struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload;
+	const char *os, *arch;
+	char bit[16];
+
+	os = fio_get_os_string(probe->os);
+	if (!os)
+		os = "unknown";
+
+	arch = fio_get_arch_string(probe->arch);
+	if (!arch)
+		os = "unknown";
+
+	sprintf(bit, "%d-bit", probe->bpp * 8);
+
+	log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%u.%u.%u\n",
+		probe->hostname, probe->bigendian, bit, os, arch,
+		probe->fio_major, probe->fio_minor, probe->fio_patch);
+
+	if (!client->name)
+		client->name = strdup((char *) probe->hostname);
+}
+
+static int handle_client(struct fio_client *client)
+{
+	struct fio_net_cmd *cmd;
+
+	dprint(FD_NET, "client: handle %s\n", client->hostname);
+
+	cmd = fio_net_recv_cmd(client->fd);
+	if (!cmd)
+		return 0;
+
+	dprint(FD_NET, "client: got cmd op %s from %s\n",
+				fio_server_op(cmd->opcode), client->hostname);
+
+	switch (cmd->opcode) {
+	case FIO_NET_CMD_QUIT:
+		remove_client(client);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_TEXT: {
+		const char *buf = (const char *) cmd->payload;
+		const char *name;
+		int fio_unused ret;
+
+		name = client->name ? client->name : client->hostname;
+
+		if (!client->skip_newline)
+			fprintf(f_out, "<%s> ", name);
+		ret = fwrite(buf, cmd->pdu_len, 1, f_out);
+		fflush(f_out);
+		client->skip_newline = strchr(buf, '\n') == NULL;
+		free(cmd);
+		break;
+		}
+	case FIO_NET_CMD_DU:
+		handle_du(client, cmd);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_TS:
+		handle_ts(cmd);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_GS:
+		handle_gs(cmd);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_ETA:
+		remove_reply_cmd(client, cmd);
+		handle_eta(client, cmd);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_PROBE:
+		remove_reply_cmd(client, cmd);
+		handle_probe(client, cmd);
+		free(cmd);
+		break;
+	case FIO_NET_CMD_START:
+		client->state = Client_started;
+		free(cmd);
+		break;
+	case FIO_NET_CMD_STOP:
+		client->state = Client_stopped;
+		free(cmd);
+		break;
+	default:
+		log_err("fio: unknown client op: %s\n", fio_server_op(cmd->opcode));
+		free(cmd);
+		break;
+	}
+
+	return 1;
+}
+
+static void request_client_etas(void)
+{
+	struct fio_client *client;
+	struct flist_head *entry;
+	struct client_eta *eta;
+	int skipped = 0;
+
+	dprint(FD_NET, "client: request eta (%d)\n", nr_clients);
+
+	eta = malloc(sizeof(*eta));
+	memset(&eta->eta, 0, sizeof(eta->eta));
+	eta->pending = nr_clients;
+
+	flist_for_each(entry, &client_list) {
+		client = flist_entry(entry, struct fio_client, list);
+
+		if (!flist_empty(&client->eta_list)) {
+			skipped++;
+			continue;
+		}
+
+		assert(!client->eta_in_flight);
+		flist_add_tail(&client->eta_list, &eta_list);
+		client->eta_in_flight = eta;
+		fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_SEND_ETA,
+					(uintptr_t) eta, &client->cmd_list);
+	}
+
+	while (skipped--)
+		dec_jobs_eta(eta);
+
+	dprint(FD_NET, "client: requested eta tag %p\n", eta);
+}
+
+static int client_check_cmd_timeout(struct fio_client *client,
+				    struct timeval *now)
+{
+	struct fio_net_int_cmd *cmd;
+	struct flist_head *entry, *tmp;
+	int ret = 0;
+
+	flist_for_each_safe(entry, tmp, &client->cmd_list) {
+		cmd = flist_entry(entry, struct fio_net_int_cmd, list);
+
+		if (mtime_since(&cmd->tv, now) < FIO_NET_CLIENT_TIMEOUT)
+			continue;
+
+		log_err("fio: client %s, timeout on cmd %s\n", client->hostname,
+						fio_server_op(cmd->cmd.opcode));
+		flist_del(&cmd->list);
+		free(cmd);
+		ret = 1;
+	}
+
+	return flist_empty(&client->cmd_list) && ret;
+}
+
+static int fio_client_timed_out(void)
+{
+	struct fio_client *client;
+	struct flist_head *entry, *tmp;
+	struct timeval tv;
+	int ret = 0;
+
+	gettimeofday(&tv, NULL);
+
+	flist_for_each_safe(entry, tmp, &client_list) {
+		client = flist_entry(entry, struct fio_client, list);
+
+		if (flist_empty(&client->cmd_list))
+			continue;
+
+		if (!client_check_cmd_timeout(client, &tv))
+			continue;
+
+		log_err("fio: client %s timed out\n", client->hostname);
+		remove_client(client);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+int fio_handle_clients(void)
+{
+	struct fio_client *client;
+	struct flist_head *entry;
+	struct pollfd *pfds;
+	int i, ret = 0;
+
+	gettimeofday(&eta_tv, NULL);
+
+	pfds = malloc(nr_clients * sizeof(struct pollfd));
+
+	sum_stat_clients = nr_clients;
+	init_thread_stat(&client_ts);
+	init_group_run_stat(&client_gs);
+
+	while (!exit_backend && nr_clients) {
+		i = 0;
+		flist_for_each(entry, &client_list) {
+			client = flist_entry(entry, struct fio_client, list);
+
+			pfds[i].fd = client->fd;
+			pfds[i].events = POLLIN;
+			i++;
+		}
+
+		assert(i == nr_clients);
+
+		do {
+			struct timeval tv;
+
+			gettimeofday(&tv, NULL);
+			if (mtime_since(&eta_tv, &tv) >= 900) {
+				request_client_etas();
+				memcpy(&eta_tv, &tv, sizeof(tv));
+
+				if (fio_client_timed_out())
+					break;
+			}
+
+			ret = poll(pfds, nr_clients, 100);
+			if (ret < 0) {
+				if (errno == EINTR)
+					continue;
+				log_err("fio: poll clients: %s\n", strerror(errno));
+				break;
+			} else if (!ret)
+				continue;
+		} while (ret <= 0);
+
+		for (i = 0; i < nr_clients; i++) {
+			if (!(pfds[i].revents & POLLIN))
+				continue;
+
+			client = find_client_by_fd(pfds[i].fd);
+			if (!client) {
+				log_err("fio: unknown client fd %d\n", pfds[i].fd);
+				continue;
+			}
+			if (!handle_client(client)) {
+				log_info("client: host=%s disconnected\n",
+						client->hostname);
+				remove_client(client);
+			}
+		}
+	}
+
+	free(pfds);
+	return 0;
+}
diff --git a/crc/crc16.c b/crc/crc16.c
index ac7983a..d9c4e49 100644
--- a/crc/crc16.c
+++ b/crc/crc16.c
@@ -43,11 +43,12 @@ unsigned short const crc16_table[256] = {
 	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
 };
 
-unsigned short crc16(unsigned char const *buffer, unsigned int len)
+unsigned short crc16(const void *buffer, unsigned int len)
 {
+	const unsigned char *cp = (const unsigned char *) buffer;
 	unsigned short crc = 0;
 
 	while (len--)
-		crc = crc16_byte(crc, *buffer++);
+		crc = crc16_byte(crc, *cp++);
 	return crc;
 }
diff --git a/crc/crc16.h b/crc/crc16.h
index 841378d..6c078a4 100644
--- a/crc/crc16.h
+++ b/crc/crc16.h
@@ -17,7 +17,7 @@
 
 extern unsigned short const crc16_table[256];
 
-extern unsigned short crc16(const unsigned char *buffer, unsigned int len);
+extern unsigned short crc16(const void *buffer, unsigned int len);
 
 static inline unsigned short crc16_byte(unsigned short crc,
 					const unsigned char data)
diff --git a/debug.c b/debug.c
index 013cd53..5e98063 100644
--- a/debug.c
+++ b/debug.c
@@ -16,8 +16,8 @@ void __dprint(int type, const char *str, ...)
 	    && pid != *fio_debug_jobp)
 		return;
 
-	log_info("%-8s ", debug_levels[type].name);
-	log_info("%-5u ", (int) pid);
+	log_local("%-8s ", debug_levels[type].name);
+	log_local("%-5u ", (int) pid);
 
 	va_start(args, str);
 	log_valist(str, args);
diff --git a/debug.h b/debug.h
index 3473d6f..af71d62 100644
--- a/debug.h
+++ b/debug.h
@@ -18,6 +18,7 @@ enum {
 	FD_MUTEX,
 	FD_PROFILE,
 	FD_TIME,
+	FD_NET,
 	FD_DEBUG_MAX,
 };
 
diff --git a/diskutil.c b/diskutil.c
index 9fc3095..24e1782 100644
--- a/diskutil.c
+++ b/diskutil.c
@@ -14,7 +14,7 @@
 static int last_majdev, last_mindev;
 static struct disk_util *last_du;
 
-static struct flist_head disk_list = FLIST_HEAD_INIT(disk_list);
+FLIST_HEAD(disk_list);
 
 static struct disk_util *__init_per_file_disk_util(struct thread_data *td,
 		int majdev, int mindev, char *path);
@@ -33,13 +33,13 @@ static void disk_util_free(struct disk_util *du)
 	}
 	
 	fio_mutex_remove(du->lock);
-	sfree(du->name);
 	sfree(du);
 }
 
 static int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus)
 {
 	unsigned in_flight;
+	unsigned long long sectors[2];
 	char line[256];
 	FILE *f;
 	char *p;
@@ -60,13 +60,15 @@ static int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus)
 	dprint(FD_DISKUTIL, "%s: %s", du->path, p);
 
 	ret = sscanf(p, "%u %u %llu %u %u %u %llu %u %u %u %u\n", &dus->ios[0],
-					&dus->merges[0], &dus->sectors[0],
+					&dus->merges[0], &sectors[0],
 					&dus->ticks[0], &dus->ios[1],
-					&dus->merges[1], &dus->sectors[1],
+					&dus->merges[1], &sectors[1],
 					&dus->ticks[1], &in_flight,
 					&dus->io_ticks, &dus->time_in_queue);
 	fclose(f);
 	dprint(FD_DISKUTIL, "%s: stat read ok? %d\n", du->path, ret == 1);
+	dus->sectors[0] = sectors[0];
+	dus->sectors[1] = sectors[1];
 	return ret != 11;
 }
 
@@ -95,7 +97,7 @@ static void update_io_tick_disk(struct disk_util *du)
 	dus->time_in_queue += (__dus.time_in_queue - ldus->time_in_queue);
 
 	fio_gettime(&t, NULL);
-	du->msec += mtime_since(&du->time, &t);
+	dus->msec += mtime_since(&du->time, &t);
 	memcpy(&du->time, &t, sizeof(t));
 	memcpy(ldus, &__dus, sizeof(__dus));
 }
@@ -265,7 +267,7 @@ static struct disk_util *disk_util_add(struct thread_data *td, int majdev,
 	memset(du, 0, sizeof(*du));
 	INIT_FLIST_HEAD(&du->list);
 	sprintf(du->path, "%s/stat", path);
-	du->name = smalloc_strdup(basename(path));
+	strncpy((char *) du->dus.name, basename(path), FIO_DU_NAME_SZ);
 	du->sysfs_root = path;
 	du->major = majdev;
 	du->minor = mindev;
@@ -277,15 +279,15 @@ static struct disk_util *disk_util_add(struct thread_data *td, int majdev,
 	flist_for_each(entry, &disk_list) {
 		__du = flist_entry(entry, struct disk_util, list);
 
-		dprint(FD_DISKUTIL, "found %s in list\n", __du->name);
+		dprint(FD_DISKUTIL, "found %s in list\n", __du->dus.name);
 
-		if (!strcmp(du->name, __du->name)) {
+		if (!strcmp((char *) du->dus.name, (char *) __du->dus.name)) {
 			disk_util_free(du);
 			return __du;
 		}
 	}
 
-	dprint(FD_DISKUTIL, "add %s to list\n", du->name);
+	dprint(FD_DISKUTIL, "add %s to list\n", du->dus.name);
 
 	fio_gettime(&du->time, NULL);
 	get_io_ticks(du, &du->last_dus);
@@ -451,108 +453,136 @@ void init_disk_util(struct thread_data *td)
 		f->du = __init_disk_util(td, f);
 }
 
+static void show_agg_stats(struct disk_util_agg *agg, int terse)
+{
+	if (!agg->slavecount)
+		return;
+
+	if (!terse) {
+		log_info(", aggrios=%u/%u, aggrmerge=%u/%u, aggrticks=%u/%u,"
+				" aggrin_queue=%u, aggrutil=%3.2f%%",
+				agg->ios[0] / agg->slavecount,
+				agg->ios[1] / agg->slavecount,
+				agg->merges[0] / agg->slavecount,
+				agg->merges[1] / agg->slavecount,
+				agg->ticks[0] / agg->slavecount,
+				agg->ticks[1] / agg->slavecount,
+				agg->time_in_queue / agg->slavecount,
+				agg->max_util.u.f);
+	} else {
+		log_info("slaves;%u;%u;%u;%u;%u;%u;%u;%3.2f%%",
+				agg->ios[0] / agg->slavecount,
+				agg->ios[1] / agg->slavecount,
+				agg->merges[0] / agg->slavecount,
+				agg->merges[1] / agg->slavecount,
+				agg->ticks[0] / agg->slavecount,
+				agg->ticks[1] / agg->slavecount,
+				agg->time_in_queue / agg->slavecount,
+				agg->max_util.u.f);
+	}
+}
+
 static void aggregate_slaves_stats(struct disk_util *masterdu)
 {
+	struct disk_util_agg *agg = &masterdu->agg;
 	struct disk_util_stat *dus;
 	struct flist_head *entry;
 	struct disk_util *slavedu;
-	double util, max_util = 0;
-	int slavecount = 0;
-
-	unsigned merges[2] = { 0, };
-	unsigned ticks[2] = { 0, };
-	unsigned time_in_queue = { 0, };
-	unsigned long long sectors[2] = { 0, };
-	unsigned ios[2] = { 0, };
+	double util;
 
 	flist_for_each(entry, &masterdu->slaves) {
 		slavedu = flist_entry(entry, struct disk_util, slavelist);
 		dus = &slavedu->dus;
-		ios[0] += dus->ios[0];
-		ios[1] += dus->ios[1];
-		merges[0] += dus->merges[0];
-		merges[1] += dus->merges[1];
-		sectors[0] += dus->sectors[0];
-		sectors[1] += dus->sectors[1];
-		ticks[0] += dus->ticks[0];
-		ticks[1] += dus->ticks[1];
-		time_in_queue += dus->time_in_queue;
-		++slavecount;
-
-		util = (double) (100 * dus->io_ticks / (double) slavedu->msec);
+		agg->ios[0] += dus->ios[0];
+		agg->ios[1] += dus->ios[1];
+		agg->merges[0] += dus->merges[0];
+		agg->merges[1] += dus->merges[1];
+		agg->sectors[0] += dus->sectors[0];
+		agg->sectors[1] += dus->sectors[1];
+		agg->ticks[0] += dus->ticks[0];
+		agg->ticks[1] += dus->ticks[1];
+		agg->time_in_queue += dus->time_in_queue;
+		agg->slavecount++;
+
+		util = (double) (100 * dus->io_ticks / (double) slavedu->dus.msec);
 		/* System utilization is the utilization of the
 		 * component with the highest utilization.
 		 */
-		if (util > max_util)
-			max_util = util;
+		if (util > agg->max_util.u.f)
+			agg->max_util.u.f = util;
 
 	}
 
-	if (max_util > 100.0)
-		max_util = 100.0;
+	if (agg->max_util.u.f > 100.0)
+		agg->max_util.u.f = 100.0;
+}
 
-	log_info(", aggrios=%u/%u, aggrmerge=%u/%u, aggrticks=%u/%u,"
-			" aggrin_queue=%u, aggrutil=%3.2f%%",
-			ios[0]/slavecount, ios[1]/slavecount,
-			merges[0]/slavecount, merges[1]/slavecount,
-			ticks[0]/slavecount, ticks[1]/slavecount,
-			time_in_queue/slavecount, max_util);
+void free_disk_util(void)
+{
+	struct disk_util *du;
 
+	while (!flist_empty(&disk_list)) {
+		du = flist_entry(disk_list.next, struct disk_util, list);
+		flist_del(&du->list);
+		disk_util_free(du);
+	}
+
+	last_majdev = last_mindev = -1;
 }
 
-void show_disk_util(void)
+void print_disk_util(struct disk_util_stat *dus, struct disk_util_agg *agg,
+		     int terse)
 {
-	struct disk_util_stat *dus;
-	struct flist_head *entry, *next;
-	struct disk_util *du;
 	double util;
 
-	if (flist_empty(&disk_list))
-		return;
+	util = (double) 100 * dus->io_ticks / (double) dus->msec;
+	if (util > 100.0)
+		util = 100.0;
 
-	log_info("\nDisk stats (read/write):\n");
-
-	flist_for_each(entry, &disk_list) {
-		du = flist_entry(entry, struct disk_util, list);
-		dus = &du->dus;
-
-		util = (double) 100 * du->dus.io_ticks / (double) du->msec;
-		if (util > 100.0)
-			util = 100.0;
-
-		/* If this node is the slave of a master device, as
-		 * happens in case of software RAIDs, inward-indent
-		 * this stats line to reflect a master-slave
-		 * relationship. Because the master device gets added
-		 * before the slave devices, we can safely assume that
-		 * the master's stats line has been displayed in a
-		 * previous iteration of this loop.
-		 */
-		if (!flist_empty(&du->slavelist))
-			log_info("  ");
+	if (agg->slavecount)
+		log_info("  ");
 
+	if (!terse) {
 		log_info("  %s: ios=%u/%u, merge=%u/%u, ticks=%u/%u, "
-			 "in_queue=%u, util=%3.2f%%", du->name,
-						dus->ios[0], dus->ios[1],
-						dus->merges[0], dus->merges[1],
-						dus->ticks[0], dus->ticks[1],
-						dus->time_in_queue, util);
-
-		/* If the device has slaves, aggregate the stats for
-		 * those slave devices also.
-		 */
-		if (!flist_empty(&du->slaves))
-			aggregate_slaves_stats(du);
-
-		log_info("\n");
+			 "in_queue=%u, util=%3.2f%%", dus->name,
+					dus->ios[0], dus->ios[1],
+					dus->merges[0], dus->merges[1],
+					dus->ticks[0], dus->ticks[1],
+					dus->time_in_queue, util);
+	} else {
+		log_info(";%s;%u;%u;%u;%u;%lu;%lu;%u;%u;%u;%u;%3.2f%%",
+					dus->name, dus->ios[0], dus->ios[1],
+					dus->merges[0], dus->merges[1],
+					dus->ticks[0], dus->ticks[1],
+					dus->time_in_queue, util);
 	}
 
 	/*
-	 * now free the list
+	 * If the device has slaves, aggregate the stats for
+	 * those slave devices also.
 	 */
-	flist_for_each_safe(entry, next, &disk_list) {
-		flist_del(entry);
+	if (agg->slavecount)
+		show_agg_stats(agg, terse);
+
+	if (!terse)
+		log_info("\n");
+}
+
+void show_disk_util(int terse)
+{
+	struct flist_head *entry;
+	struct disk_util *du;
+
+	if (flist_empty(&disk_list))
+		return;
+
+	if (!terse)
+		log_info("\nDisk stats (read/write):\n");
+
+	flist_for_each(entry, &disk_list) {
 		du = flist_entry(entry, struct disk_util, list);
-		disk_util_free(du);
+
+		aggregate_slaves_stats(du);
+		print_disk_util(&du->dus, &du->agg, terse);
 	}
 }
diff --git a/diskutil.h b/diskutil.h
index dc89cc5..5a9b079 100644
--- a/diskutil.h
+++ b/diskutil.h
@@ -1,16 +1,31 @@
 #ifndef FIO_DISKUTIL_H
 #define FIO_DISKUTIL_H
 
+#define FIO_DU_NAME_SZ		64
+
 /*
  * Disk utils as read in /sys/block/<dev>/stat
  */
 struct disk_util_stat {
-	unsigned ios[2];
-	unsigned merges[2];
-	unsigned long long sectors[2];
-	unsigned ticks[2];
-	unsigned io_ticks;
-	unsigned time_in_queue;
+	uint8_t name[FIO_DU_NAME_SZ];
+	uint32_t ios[2];
+	uint32_t merges[2];
+	uint64_t sectors[2];
+	uint32_t ticks[2];
+	uint32_t io_ticks;
+	uint32_t time_in_queue;
+	uint64_t msec;
+};
+
+struct disk_util_agg {
+	uint32_t ios[2];
+	uint32_t merges[2];
+	uint64_t sectors[2];
+	uint32_t ticks[2];
+	uint32_t io_ticks;
+	uint32_t time_in_queue;
+	uint32_t slavecount;
+	fio_fp64_t max_util;
 };
 
 /*
@@ -31,6 +46,8 @@ struct disk_util {
 	struct disk_util_stat dus;
 	struct disk_util_stat last_dus;
 
+	struct disk_util_agg agg;
+
 	/* For software raids, this entry maintains pointers to the
 	 * entries for the slave devices. The disk_util entries for
 	 * the slaves devices should primarily be maintained through
@@ -40,7 +57,6 @@ struct disk_util {
 	 */
 	struct flist_head slaves;
 
-	unsigned long msec;
 	struct timeval time;
 
 	struct fio_mutex *lock;
@@ -76,15 +92,21 @@ static inline void disk_util_dec(struct disk_util *du)
 
 #define DISK_UTIL_MSEC	(250)
 
+extern struct flist_head disk_list;
+
 /*
  * disk util stuff
  */
 #ifdef FIO_HAVE_DISK_UTIL
-extern void show_disk_util(void);
+extern void print_disk_util(struct disk_util_stat *, struct disk_util_agg *, int terse);
+extern void show_disk_util(int terse);
+extern void free_disk_util(void);
 extern void init_disk_util(struct thread_data *);
 extern void update_io_ticks(void);
 #else
-#define show_disk_util()
+#define print_disk_util(dus, agg, terse)
+#define show_disk_util(terse)
+#define free_disk_util()
 #define init_disk_util(td)
 #define update_io_ticks()
 #endif
diff --git a/engines/net.c b/engines/net.c
index 6866ba2..d6821a4 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -14,7 +14,9 @@
 #include <netdb.h>
 #include <sys/poll.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 
 #include "../fio.h"
 
@@ -22,10 +24,11 @@ struct netio_data {
 	int listenfd;
 	int send_to_net;
 	int use_splice;
-	int net_protocol;
+	int type;
 	int pipes[2];
 	char host[64];
 	struct sockaddr_in addr;
+	struct sockaddr_un addr_un;
 };
 
 struct udp_close_msg {
@@ -36,6 +39,10 @@ struct udp_close_msg {
 enum {
 	FIO_LINK_CLOSE = 0x89,
 	FIO_LINK_CLOSE_MAGIC = 0x6c696e6b,
+
+	FIO_TYPE_TCP	= 1,
+	FIO_TYPE_UDP	= 2,
+	FIO_TYPE_UNIX	= 3,
 };
 
 /*
@@ -226,7 +233,7 @@ static int fio_netio_send(struct thread_data *td, struct io_u *io_u)
 	int ret, flags = OS_MSG_DONTWAIT;
 
 	do {
-		if (nd->net_protocol == IPPROTO_UDP) {
+		if (nd->type == FIO_TYPE_UDP) {
 			struct sockaddr *to = (struct sockaddr *) &nd->addr;
 
 			ret = sendto(io_u->file->fd, io_u->xfer_buf,
@@ -279,12 +286,8 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
 	int ret, flags = OS_MSG_DONTWAIT;
 
 	do {
-		if (nd->net_protocol == IPPROTO_UDP) {
-#ifdef __hpux
-			int len = sizeof(nd->addr);
-#else
-			socklen_t len = sizeof(nd->addr);
-#endif
+		if (nd->type == FIO_TYPE_UDP) {
+			fio_socklen_t len = sizeof(nd->addr);
 			struct sockaddr *from = (struct sockaddr *) &nd->addr;
 
 			ret = recvfrom(io_u->file->fd, io_u->xfer_buf,
@@ -318,12 +321,14 @@ static int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
 	fio_ro_check(td, io_u);
 
 	if (io_u->ddir == DDIR_WRITE) {
-		if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP)
+		if (!nd->use_splice || nd->type == FIO_TYPE_UDP ||
+		    nd->type == FIO_TYPE_UNIX) 
 			ret = fio_netio_send(td, io_u);
 		else
 			ret = fio_netio_splice_out(td, io_u);
 	} else if (io_u->ddir == DDIR_READ) {
-		if (!nd->use_splice || nd->net_protocol == IPPROTO_UDP)
+		if (!nd->use_splice || nd->type == FIO_TYPE_UDP ||
+		    nd->type == FIO_TYPE_UDP)
 			ret = fio_netio_recv(td, io_u);
 		else
 			ret = fio_netio_splice_in(td, io_u);
@@ -354,25 +359,50 @@ static int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
 static int fio_netio_connect(struct thread_data *td, struct fio_file *f)
 {
 	struct netio_data *nd = td->io_ops->data;
-	int type;
+	int type, domain;
 
-	if (nd->net_protocol == IPPROTO_TCP)
+	if (nd->type == FIO_TYPE_TCP) {
+		domain = AF_INET;
 		type = SOCK_STREAM;
-	else
+	} else if (nd->type == FIO_TYPE_UDP) {
+		domain = AF_INET;
 		type = SOCK_DGRAM;
+	} else if (nd->type == FIO_TYPE_UNIX) {
+		domain = AF_UNIX;
+		type = SOCK_STREAM;
+	} else {
+		log_err("fio: bad network type %d\n", nd->type);
+		f->fd = -1;
+		return 1;
+	}
 
-	f->fd = socket(AF_INET, type, nd->net_protocol);
+	f->fd = socket(domain, type, 0);
 	if (f->fd < 0) {
 		td_verror(td, errno, "socket");
 		return 1;
 	}
 
-	if (nd->net_protocol == IPPROTO_UDP)
+	if (nd->type == FIO_TYPE_UDP)
 		return 0;
+	else if (nd->type == FIO_TYPE_TCP) {
+		fio_socklen_t len = sizeof(nd->addr);
 
-	if (connect(f->fd, (struct sockaddr *) &nd->addr, sizeof(nd->addr)) < 0) {
-		td_verror(td, errno, "connect");
-		return 1;
+		if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
+			td_verror(td, errno, "connect");
+			close(f->fd);
+			return 1;
+		}
+	} else {
+		struct sockaddr_un *addr = &nd->addr_un;
+		fio_socklen_t len;
+
+		len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
+
+		if (connect(f->fd, (struct sockaddr *) addr, len) < 0) {
+			td_verror(td, errno, "connect");
+			close(f->fd);
+			return 1;
+		}
 	}
 
 	return 0;
@@ -381,13 +411,9 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f)
 static int fio_netio_accept(struct thread_data *td, struct fio_file *f)
 {
 	struct netio_data *nd = td->io_ops->data;
-#ifdef __hpux
-	int socklen = sizeof(nd->addr);
-#else
-	socklen_t socklen = sizeof(nd->addr);
-#endif
+	fio_socklen_t socklen = sizeof(nd->addr);
 
-	if (nd->net_protocol == IPPROTO_UDP) {
+	if (nd->type == FIO_TYPE_UDP) {
 		f->fd = nd->listenfd;
 		return 0;
 	}
@@ -408,10 +434,16 @@ static int fio_netio_accept(struct thread_data *td, struct fio_file *f)
 
 static int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
 {
+	int ret;
+
 	if (td_read(td))
-		return fio_netio_accept(td, f);
+		ret = fio_netio_accept(td, f);
 	else
-		return fio_netio_connect(td, f);
+		ret = fio_netio_connect(td, f);
+
+	if (ret)
+		f->fd = -1;
+	return ret;
 }
 
 static void fio_netio_udp_close(struct thread_data *td, struct fio_file *f)
@@ -438,14 +470,14 @@ static int fio_netio_close_file(struct thread_data *td, struct fio_file *f)
 	 * If this is an UDP connection, notify the receiver that we are
 	 * closing down the link
 	 */
-	if (nd->net_protocol == IPPROTO_UDP)
+	if (nd->type == FIO_TYPE_UDP)
 		fio_netio_udp_close(td, f);
 
 	return generic_close_file(td, f);
 }
 
-static int fio_netio_setup_connect(struct thread_data *td, const char *host,
-				   unsigned short port)
+static int fio_netio_setup_connect_inet(struct thread_data *td,
+					const char *host, unsigned short port)
 {
 	struct netio_data *nd = td->io_ops->data;
 
@@ -467,17 +499,72 @@ static int fio_netio_setup_connect(struct thread_data *td, const char *host,
 	return 0;
 }
 
-static int fio_netio_setup_listen(struct thread_data *td, short port)
+static int fio_netio_setup_connect_unix(struct thread_data *td,
+					const char *path)
+{
+	struct netio_data *nd = td->io_ops->data;
+	struct sockaddr_un *soun = &nd->addr_un;
+
+	soun->sun_family = AF_UNIX;
+	strcpy(soun->sun_path, path);
+	return 0;
+}
+
+static int fio_netio_setup_connect(struct thread_data *td, const char *host,
+				   unsigned short port)
+{
+	struct netio_data *nd = td->io_ops->data;
+
+	if (nd->type == FIO_TYPE_UDP || nd->type == FIO_TYPE_TCP)
+		return fio_netio_setup_connect_inet(td, host, port);
+	else
+		return fio_netio_setup_connect_unix(td, host);
+}
+
+static int fio_netio_setup_listen_unix(struct thread_data *td, const char *path)
+{
+	struct netio_data *nd = td->io_ops->data;
+	struct sockaddr_un *addr = &nd->addr_un;
+	mode_t mode;
+	int len, fd;
+
+	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (fd < 0) {
+		log_err("fio: socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	mode = umask(000);
+
+	memset(addr, 0, sizeof(*addr));
+	addr->sun_family = AF_UNIX;
+	strcpy(addr->sun_path, path);
+	unlink(path);
+
+	len = sizeof(addr->sun_family) + strlen(path) + 1;
+
+	if (bind(fd, (struct sockaddr *) addr, len) < 0) {
+		log_err("fio: bind: %s\n", strerror(errno));
+		close(fd);
+		return -1;
+	}
+
+	umask(mode);
+	nd->listenfd = fd;
+	return 0;
+}
+
+static int fio_netio_setup_listen_inet(struct thread_data *td, short port)
 {
 	struct netio_data *nd = td->io_ops->data;
 	int fd, opt, type;
 
-	if (nd->net_protocol == IPPROTO_TCP)
+	if (nd->type == FIO_TYPE_TCP)
 		type = SOCK_STREAM;
 	else
 		type = SOCK_DGRAM;
 
-	fd = socket(AF_INET, type, nd->net_protocol);
+	fd = socket(AF_INET, type, 0);
 	if (fd < 0) {
 		td_verror(td, errno, "socket");
 		return 1;
@@ -503,12 +590,33 @@ static int fio_netio_setup_listen(struct thread_data *td, short port)
 		td_verror(td, errno, "bind");
 		return 1;
 	}
-	if (nd->net_protocol == IPPROTO_TCP && listen(fd, 1) < 0) {
+
+	nd->listenfd = fd;
+	return 0;
+}
+
+static int fio_netio_setup_listen(struct thread_data *td, const char *path,
+				  short port)
+{
+	struct netio_data *nd = td->io_ops->data;
+	int ret;
+
+	if (nd->type == FIO_TYPE_UDP || nd->type == FIO_TYPE_TCP)
+		ret = fio_netio_setup_listen_inet(td, port);
+	else
+		ret = fio_netio_setup_listen_unix(td, path);
+
+	if (ret)
+		return ret;
+	if (nd->type == FIO_TYPE_UDP)
+		return 0;
+
+	if (listen(nd->listenfd, 10) < 0) {
 		td_verror(td, errno, "listen");
+		nd->listenfd = -1;
 		return 1;
 	}
 
-	nd->listenfd = fd;
 	return 0;
 }
 
@@ -531,7 +639,7 @@ static int fio_netio_init(struct thread_data *td)
 
 	strcpy(buf, td->o.filename);
 
-	sep = strchr(buf, '/');
+	sep = strchr(buf, ',');
 	if (!sep)
 		goto bad_host;
 
@@ -543,31 +651,34 @@ static int fio_netio_init(struct thread_data *td)
 
 	modep = NULL;
 	portp = sep;
-	sep = strchr(portp, '/');
+	sep = strchr(portp, ',');
 	if (sep) {
 		*sep = '\0';
 		modep = sep + 1;
 	}
-		
-	port = strtol(portp, NULL, 10);
-	if (!port || port > 65535)
+
+	if (!strncmp("tcp", modep, strlen(modep)) ||
+	    !strncmp("TCP", modep, strlen(modep)))
+		nd->type = FIO_TYPE_TCP;
+	else if (!strncmp("udp", modep, strlen(modep)) ||
+		 !strncmp("UDP", modep, strlen(modep)))
+		nd->type = FIO_TYPE_UDP;
+	else if (!strncmp("unix", modep, strlen(modep)) ||
+		 !strncmp("UNIX", modep, strlen(modep)))
+		nd->type = FIO_TYPE_UNIX;
+	else
 		goto bad_host;
 
-	if (modep) {
-		if (!strncmp("tcp", modep, strlen(modep)) ||
-		    !strncmp("TCP", modep, strlen(modep)))
-			nd->net_protocol = IPPROTO_TCP;
-		else if (!strncmp("udp", modep, strlen(modep)) ||
-			 !strncmp("UDP", modep, strlen(modep)))
-			nd->net_protocol = IPPROTO_UDP;
-		else
+	if (nd->type != FIO_TYPE_UNIX) {
+		port = strtol(portp, NULL, 10);
+		if (!port || port > 65535)
 			goto bad_host;
 	} else
-		nd->net_protocol = IPPROTO_TCP;
+		port = 0;
 
 	if (td_read(td)) {
 		nd->send_to_net = 0;
-		ret = fio_netio_setup_listen(td, port);
+		ret = fio_netio_setup_listen(td, host, port);
 	} else {
 		nd->send_to_net = 1;
 		ret = fio_netio_setup_connect(td, host, port);
diff --git a/eta.c b/eta.c
index d93bf1a..6118d1a 100644
--- a/eta.c
+++ b/eta.c
@@ -230,32 +230,28 @@ static void calc_iops(unsigned long mtime, unsigned long long *io_iops,
  * Print status of the jobs we know about. This includes rate estimates,
  * ETA, thread state, etc.
  */
-void print_thread_status(void)
+int calc_thread_status(struct jobs_eta *je, int force)
 {
-	unsigned long elapsed = (mtime_since_genesis() + 999) / 1000;
-	int i, nr_ramp, nr_running, nr_pending, t_rate, m_rate;
-	int t_iops, m_iops, files_open;
 	struct thread_data *td;
-	char eta_str[128];
-	double perc = 0.0;
-	unsigned long long io_bytes[2], io_iops[2];
-	unsigned long rate_time, disp_time, bw_avg_time, *eta_secs, eta_sec;
+	int i;
+	unsigned long rate_time, disp_time, bw_avg_time, *eta_secs;
+	unsigned long long io_bytes[2];
+	unsigned long long io_iops[2];
 	struct timeval now;
 
 	static unsigned long long rate_io_bytes[2];
 	static unsigned long long disp_io_bytes[2];
 	static unsigned long long disp_io_iops[2];
 	static struct timeval rate_prev_time, disp_prev_time;
-	static unsigned int rate[2], iops[2];
-	static int linelen_last;
-	static int eta_good;
 	int i2p = 0;
 
-	if (temp_stall_ts || terse_output || eta_print == FIO_ETA_NEVER)
-		return;
+	if (!force) {
+		if (temp_stall_ts || terse_output || eta_print == FIO_ETA_NEVER)
+			return 0;
 
-	if (!isatty(STDOUT_FILENO) && (eta_print != FIO_ETA_ALWAYS))
-		return;
+		if (!isatty(STDOUT_FILENO) && (eta_print != FIO_ETA_ALWAYS))
+			return 0;
+	}
 
 	if (!rate_io_bytes[0] && !rate_io_bytes[1])
 		fill_start_time(&rate_prev_time);
@@ -265,32 +261,31 @@ void print_thread_status(void)
 	eta_secs = malloc(thread_number * sizeof(unsigned long));
 	memset(eta_secs, 0, thread_number * sizeof(unsigned long));
 
+	je->elapsed_sec = (mtime_since_genesis() + 999) / 1000;
+
 	io_bytes[0] = io_bytes[1] = 0;
 	io_iops[0] = io_iops[1] = 0;
-	nr_pending = nr_running = t_rate = m_rate = t_iops = m_iops = 0;
-	nr_ramp = 0;
 	bw_avg_time = ULONG_MAX;
-	files_open = 0;
 	for_each_td(td, i) {
 		if (td->o.bw_avg_time < bw_avg_time)
 			bw_avg_time = td->o.bw_avg_time;
 		if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING
 		    || td->runstate == TD_FSYNCING
 		    || td->runstate == TD_PRE_READING) {
-			nr_running++;
-			t_rate += td->o.rate[0] + td->o.rate[1];
-			m_rate += td->o.ratemin[0] + td->o.ratemin[1];
-			t_iops += td->o.rate_iops[0] + td->o.rate_iops[1];
-			m_iops += td->o.rate_iops_min[0] +
+			je->nr_running++;
+			je->t_rate += td->o.rate[0] + td->o.rate[1];
+			je->m_rate += td->o.ratemin[0] + td->o.ratemin[1];
+			je->t_iops += td->o.rate_iops[0] + td->o.rate_iops[1];
+			je->m_iops += td->o.rate_iops_min[0] +
 					td->o.rate_iops_min[1];
-			files_open += td->nr_open_files;
+			je->files_open += td->nr_open_files;
 		} else if (td->runstate == TD_RAMP) {
-			nr_running++;
-			nr_ramp++;
+			je->nr_running++;
+			je->nr_ramp++;
 		} else if (td->runstate < TD_RUNNING)
-			nr_pending++;
+			je->nr_pending++;
 
-		if (elapsed >= 3)
+		if (je->elapsed_sec >= 3)
 			eta_secs[i] = thread_eta(td);
 		else
 			eta_secs[i] = INT_MAX;
@@ -306,37 +301,32 @@ void print_thread_status(void)
 	}
 
 	if (exitall_on_terminate)
-		eta_sec = INT_MAX;
+		je->eta_sec = INT_MAX;
 	else
-		eta_sec = 0;
+		je->eta_sec = 0;
 
 	for_each_td(td, i) {
 		if (!i2p && is_power_of_2(td->o.kb_base))
 			i2p = 1;
 		if (exitall_on_terminate) {
-			if (eta_secs[i] < eta_sec)
-				eta_sec = eta_secs[i];
+			if (eta_secs[i] < je->eta_sec)
+				je->eta_sec = eta_secs[i];
 		} else {
-			if (eta_secs[i] > eta_sec)
-				eta_sec = eta_secs[i];
+			if (eta_secs[i] > je->eta_sec)
+				je->eta_sec = eta_secs[i];
 		}
 	}
 
 	free(eta_secs);
 
-	if (eta_sec != INT_MAX && elapsed) {
-		perc = (double) elapsed / (double) (elapsed + eta_sec);
-		eta_to_str(eta_str, eta_sec);
-	}
-
 	fio_gettime(&now, NULL);
 	rate_time = mtime_since(&rate_prev_time, &now);
 
 	if (write_bw_log && rate_time > bw_avg_time && !in_ramp_time(td)) {
-		calc_rate(rate_time, io_bytes, rate_io_bytes, rate);
+		calc_rate(rate_time, io_bytes, rate_io_bytes, je->rate);
 		memcpy(&rate_prev_time, &now, sizeof(now));
-		add_agg_sample(rate[DDIR_READ], DDIR_READ, 0);
-		add_agg_sample(rate[DDIR_WRITE], DDIR_WRITE, 0);
+		add_agg_sample(je->rate[DDIR_READ], DDIR_READ, 0);
+		add_agg_sample(je->rate[DDIR_WRITE], DDIR_WRITE, 0);
 	}
 
 	disp_time = mtime_since(&disp_prev_time, &now);
@@ -344,35 +334,55 @@ void print_thread_status(void)
 	/*
 	 * Allow a little slack, the target is to print it every 1000 msecs
 	 */
-	if (disp_time < 900)
-		return;
+	if (!force && disp_time < 900)
+		return 0;
 
-	calc_rate(disp_time, io_bytes, disp_io_bytes, rate);
-	calc_iops(disp_time, io_iops, disp_io_iops, iops);
+	calc_rate(disp_time, io_bytes, disp_io_bytes, je->rate);
+	calc_iops(disp_time, io_iops, disp_io_iops, je->iops);
 
 	memcpy(&disp_prev_time, &now, sizeof(now));
 
-	if (!nr_running && !nr_pending)
-		return;
+	if (!force && !je->nr_running && !je->nr_pending)
+		return 0;
+
+	je->nr_threads = thread_number;
+	memcpy(je->run_str, run_str, thread_number * sizeof(char));
+
+	return 1;
+}
 
-	printf("Jobs: %d (f=%d)", nr_running, files_open);
-	if (m_rate || t_rate) {
+void display_thread_status(struct jobs_eta *je)
+{
+	static int linelen_last;
+	static int eta_good;
+	char output[512], *p = output;
+	char eta_str[128];
+	double perc = 0.0;
+	int i2p = 0;
+
+	if (je->eta_sec != INT_MAX && je->elapsed_sec) {
+		perc = (double) je->elapsed_sec / (double) (je->elapsed_sec + je->eta_sec);
+		eta_to_str(eta_str, je->eta_sec);
+	}
+
+	p += sprintf(p, "Jobs: %d (f=%d)", je->nr_running, je->files_open);
+	if (je->m_rate || je->t_rate) {
 		char *tr, *mr;
 
-		mr = num2str(m_rate, 4, 0, i2p);
-		tr = num2str(t_rate, 4, 0, i2p);
-		printf(", CR=%s/%s KB/s", tr, mr);
+		mr = num2str(je->m_rate, 4, 0, i2p);
+		tr = num2str(je->t_rate, 4, 0, i2p);
+		p += sprintf(p, ", CR=%s/%s KB/s", tr, mr);
 		free(tr);
 		free(mr);
-	} else if (m_iops || t_iops)
-		printf(", CR=%d/%d IOPS", t_iops, m_iops);
-	if (eta_sec != INT_MAX && nr_running) {
+	} else if (je->m_iops || je->t_iops)
+		p += sprintf(p, ", CR=%d/%d IOPS", je->t_iops, je->m_iops);
+	if (je->eta_sec != INT_MAX && je->nr_running) {
 		char perc_str[32];
 		char *iops_str[2];
 		char *rate_str[2];
 		int l;
 
-		if ((!eta_sec && !eta_good) || nr_ramp == nr_running)
+		if ((!je->eta_sec && !eta_good) || je->nr_ramp == je->nr_running)
 			strcpy(perc_str, "-.-% done");
 		else {
 			eta_good = 1;
@@ -380,17 +390,18 @@ void print_thread_status(void)
 			sprintf(perc_str, "%3.1f%% done", perc);
 		}
 
-		rate_str[0] = num2str(rate[0], 5, 10, i2p);
-		rate_str[1] = num2str(rate[1], 5, 10, i2p);
+		rate_str[0] = num2str(je->rate[0], 5, 10, i2p);
+		rate_str[1] = num2str(je->rate[1], 5, 10, i2p);
 
-		iops_str[0] = num2str(iops[0], 4, 1, 0);
-		iops_str[1] = num2str(iops[1], 4, 1, 0);
+		iops_str[0] = num2str(je->iops[0], 4, 1, 0);
+		iops_str[1] = num2str(je->iops[1], 4, 1, 0);
 
-		l = printf(": [%s] [%s] [%s/%s /s] [%s/%s iops] [eta %s]",
-				 run_str, perc_str, rate_str[0], rate_str[1],
-				 iops_str[0], iops_str[1], eta_str);
+		l = sprintf(p, ": [%s] [%s] [%s/%s /s] [%s/%s iops] [eta %s]",
+				je->run_str, perc_str, rate_str[0],
+				rate_str[1], iops_str[0], iops_str[1], eta_str);
+		p += l;
 		if (l >= 0 && l < linelen_last)
-			printf("%*s", linelen_last - l, "");
+			p += sprintf(p, "%*s", linelen_last - l, "");
 		linelen_last = l;
 
 		free(rate_str[0]);
@@ -398,10 +409,30 @@ void print_thread_status(void)
 		free(iops_str[0]);
 		free(iops_str[1]);
 	}
-	printf("\r");
+	p += sprintf(p, "\r");
+
+	printf("%s", output);
 	fflush(stdout);
 }
 
+void print_thread_status(void)
+{
+	struct jobs_eta *je;
+	size_t size;
+
+	if (!thread_number)
+		return;
+
+	size = sizeof(*je) + thread_number * sizeof(char) + 1;
+	je = malloc(size);
+	memset(je, 0, size);
+
+	if (calc_thread_status(je, 0))
+		display_thread_status(je);
+
+	free(je);
+}
+
 void print_status_init(int thr_number)
 {
 	run_str[thr_number] = 'P';
diff --git a/examples/netio b/examples/netio
index 2aa0928..5b07468 100644
--- a/examples/netio
+++ b/examples/netio
@@ -1,8 +1,12 @@
 # Example network job, just defines two clients that send/recv data
 [global]
 ioengine=net
-#the below defaults to a tcp connection, add /udp at the end for udp
-filename=localhost/8888
+#this would use UDP over localhost, port 8888
+#filename=localhost,8888,udp
+#this would use a local domain socket /tmp/fio.sock
+#filename=/tmp/fio.sock,,unix
+#TCP, port 8888, localhost
+filename=localhost,8888,tcp
 bs=4k
 size=10g
 #set the below option to enable end-to-end data integrity tests
@@ -12,4 +16,5 @@ size=10g
 rw=read
 
 [sender]
+startdelay=1
 rw=write
diff --git a/filehash.c b/filehash.c
index 1df7db0..1bb1eb2 100644
--- a/filehash.c
+++ b/filehash.c
@@ -3,7 +3,7 @@
 
 #include "fio.h"
 #include "flist.h"
-#include "crc/crc16.h"
+#include "hash.h"
 
 #define HASH_BUCKETS	512
 #define HASH_MASK	(HASH_BUCKETS - 1)
@@ -15,7 +15,7 @@ static struct fio_mutex *hash_lock;
 
 static unsigned short hash(const char *name)
 {
-	return crc16((const unsigned char *) name, strlen(name)) & HASH_MASK;
+	return jhash(name, strlen(name), 0) & HASH_MASK;
 }
 
 void remove_file_hash(struct fio_file *f)
diff --git a/fio.1 b/fio.1
index 513caa9..2473b44 100644
--- a/fio.1
+++ b/fio.1
@@ -12,6 +12,11 @@ The typical use of fio is to write a job file matching the I/O load
 one wants to simulate.
 .SH OPTIONS
 .TP
+.BI \-\-debug \fR=\fPtype
+Enable verbose tracing of various fio actions. May be `all' for all types
+or individual types separated by a comma (eg \-\-debug=io,file). `help' will
+list all available tracing options.
+.TP
 .BI \-\-output \fR=\fPfilename
 Write output to \fIfilename\fR.
 .TP
@@ -27,6 +32,18 @@ Generate per-job bandwidth logs.
 .B \-\-minimal
 Print statistics in a terse, semicolon-delimited format.
 .TP
+.B \-\-version
+Display version information and exit.
+.TP
+.BI \-\-terse\-version \fR=\fPversion
+Set terse version output format.
+.TP
+.B \-\-help
+Display usage information and exit.
+.TP
+.BI \-\-cmdhelp \fR=\fPcommand
+Print help information for \fIcommand\fR.  May be `all' for all commands.
+.TP
 .BI \-\-showcmd \fR=\fPjobfile
 Convert \fIjobfile\fR to a set of command-line options.
 .TP
@@ -37,25 +54,29 @@ Enable read-only safety checks.
 Specifies when real-time ETA estimate should be printed.  \fIwhen\fR may
 be one of `always', `never' or `auto'.
 .TP
+.BI \-\-readonly
+Turn on safety read-only checks, preventing any attempted write.
+.TP
 .BI \-\-section \fR=\fPsec
-Only run section \fIsec\fR from job file.
+Only run section \fIsec\fR from job file. Multiple of these options can be given, adding more sections to run.
 .TP
-.BI \-\-cmdhelp \fR=\fPcommand
-Print help information for \fIcommand\fR.  May be `all' for all commands.
+.BI \-\-alloc\-size \fR=\fPkb
+Set the internal smalloc pool size to \fIkb\fP kilobytes.
 .TP
-.BI \-\-debug \fR=\fPtype
-Enable verbose tracing of various fio actions. May be `all' for all types
-or individual types separated by a comma (eg \-\-debug=io,file). `help' will
-list all available tracing options.
+.BI \-\-warnings\-fatal
+All fio parser warnings are fatal, causing fio to exit with an error.
 .TP
-.B \-\-help
-Display usage information and exit.
+.BI \-\-max\-jobs \fR=\fPnr
+Set the maximum allowed number of jobs (threads/processes) to suport.
 .TP
-.B \-\-version
-Display version information and exit.
+.BI \-\-server \fR=\fPargs
+Start a backend server, with \fIargs\fP specifying what to listen to. See client/server section.
+.TP
+.BI \-\-daemonize \fR=\fPpidfile
+Background a fio server, writing the pid to the given pid file.
 .TP
-.B \-\-terse\-version\fR=\fPtype
-Terse version output format
+.BI \-\-client \fR=\fPhost
+Instead of running the jobs locally, send and run them on the given host.
 .SH "JOB FILE FORMAT"
 Job files are in `ini' format. They consist of one or more
 job definitions, which begin with a job name in square brackets and
@@ -416,8 +437,9 @@ itself and for debugging and testing purposes.
 .TP
 .B net
 Transfer over the network.  \fBfilename\fR must be set appropriately to
-`\fIhost\fR/\fIport\fR' regardless of data direction.  If receiving, only the
-\fIport\fR argument is used.
+`\fIhost\fR,\fIport\fR,\fItype\fR' regardless of data direction. \fItype\fR
+is one of \fBtcp\fR, \fBudp\fR, or \fBunix\fR. For UNIX domain sockets,
+the \fIhost\fR parameter is a file system path.
 .TP
 .B netsplice
 Like \fBnet\fR, but uses \fIsplice\fR\|(2) and \fIvmsplice\fR\|(2) to map data
@@ -673,6 +695,10 @@ Terminate all jobs when one finishes.  Default: wait for each job to finish.
 Average bandwidth calculations over the given time in milliseconds.  Default:
 500ms.
 .TP
+.BI iopsavgtime \fR=\fPint
+Average IOPS calculations over the given time in milliseconds.  Default:
+500ms.
+.TP
 .BI create_serialize \fR=\fPbool
 If true, serialize file creation for the jobs.  Default: true.
 .TP
@@ -845,6 +871,11 @@ Same as \fBwrite_bw_log\fR, but writes I/O completion latencies.  If no
 filename is given with this option, the default filename of "jobname_type.log"
 is used. Even if the filename is given, fio will still append the type of log.
 .TP
+.BI write_iops_log \fR=\fPstr
+Same as \fBwrite_bw_log\fR, but writes IOPS. If no filename is given with this
+option, the default filename of "jobname_type.log" is used. Even if the
+filename is given, fio will still append the type of log.
+.TP
 .BI disable_lat \fR=\fPbool
 Disable measurements of total latency numbers. Useful only for cutting
 back the number of calls to gettimeofday, as that does impact performance at
@@ -1094,7 +1125,7 @@ change.  The fields are:
 .P
 Read status:
 .RS
-.B Total I/O \fR(KB)\fP, bandwidth \fR(KB/s)\fP, runtime \fR(ms)\fP
+.B Total I/O \fR(KB)\fP, bandwidth \fR(KB/s)\fP, IOPS, runtime \fR(ms)\fP
 .P
 Submission latency:
 .RS
@@ -1104,6 +1135,10 @@ Completion latency:
 .RS
 .B min, max, mean, standard deviation
 .RE
+Completion latency percentiles (20 fields):
+.RS
+.B Xth percentile=usec
+.RE
 Total latency:
 .RS
 .B min, max, mean, standard deviation
@@ -1116,7 +1151,7 @@ Bandwidth:
 .P
 Write status:
 .RS
-.B Total I/O \fR(KB)\fP, bandwidth \fR(KB/s)\fP, runtime \fR(ms)\fP
+.B Total I/O \fR(KB)\fP, bandwidth \fR(KB/s)\fP, IOPS, runtime \fR(ms)\fP
 .P
 Submission latency:
 .RS
@@ -1126,6 +1161,10 @@ Completion latency:
 .RS
 .B min, max, mean, standard deviation
 .RE
+Completion latency percentiles (20 fields):
+.RS
+.B Xth percentile=usec
+.RE
 Total latency:
 .RS
 .B min, max, mean, standard deviation
@@ -1158,6 +1197,11 @@ Milliseconds:
 .RE
 .RE
 .P
+Disk utilization (1 for each disk used):
+.RS
+.B name, read ios, write ios, read merges, write merges, read ticks, write ticks, read in-queue time, write in-queue time, disk utilization percentage
+.RE
+.P
 Error Info (dependent on continue_on_error, default off):
 .RS
 .B total # errors, first error code 
@@ -1165,7 +1209,57 @@ Error Info (dependent on continue_on_error, default off):
 .P
 .B text description (if provided in config - appears on newline)
 .RE
+.SH CLIENT / SERVER
+Normally you would run fio as a stand-alone application on the machine
+where the IO workload should be generated. However, it is also possible to
+run the frontend and backend of fio separately. This makes it possible to
+have a fio server running on the machine(s) where the IO workload should
+be running, while controlling it from another machine.
+
+To start the server, you would do:
+
+\fBfio \-\-server=args\fR
+
+on that machine, where args defines what fio listens to. The arguments
+are of the form 'type:hostname or IP:port'. 'type' is either 'ip' for
+TCP/IP, or 'sock' for a local unix domain socket. 'hostname' is either
+a hostname or IP address, and 'port' is the port to listen to (only valid
+for TCP/IP, not a local socket). Some examples:
+
+1) fio --server
+
+   Start a fio server, listening on all interfaces on the default port (8765).
+
+2) fio --server=ip:hostname:4444
+
+   Start a fio server, listening on IP belonging to hostname and on port 4444.
+
+3) fio --server=:4444
+
+   Start a fio server, listening on all interfaces on port 4444.
+
+4) fio --server=1.2.3.4
+
+   Start a fio server, listening on IP 1.2.3.4 on the default port.
+
+5) fio --server=sock:/tmp/fio.sock
+
+   Start a fio server, listening on the local socket /tmp/fio.sock.
+
+When a server is running, you can connect to it from a client. The client
+is run with:
+
+fio --local-args --client=server --remote-args <job file(s)>
+
+where --local-args are arguments that are local to the client where it is
+running, 'server' is the connect string, and --remote-args and <job file(s)>
+are sent to the server. The 'server' string follows the same format as it
+does on the server side, to allow IP/hostname/socket and port strings.
+You can connect to multiple clients as well, to do that you could run:
+
+fio --client=server2 --client=server2 <job file(s)>
 .SH AUTHORS
+
 .B fio
 was written by Jens Axboe <jens.axboe@oracle.com>,
 now Jens Axboe <jaxboe@fusionio.com>.
diff --git a/fio.c b/fio.c
index b492889..e5d3bbf 100644
--- a/fio.c
+++ b/fio.c
@@ -46,6 +46,7 @@
 #include "profile.h"
 #include "lib/rand.h"
 #include "memalign.h"
+#include "server.h"
 
 unsigned long page_mask;
 unsigned long page_size;
@@ -61,6 +62,13 @@ int shm_id = 0;
 int temp_stall_ts;
 unsigned long done_secs = 0;
 
+/*
+ * Just expose an empty list, if the OS does not support disk util stats
+ */
+#ifndef FIO_HAVE_DISK_UTIL
+FLIST_HEAD(disk_list);
+#endif
+
 static struct fio_mutex *startup_mutex;
 static struct fio_mutex *writeout_mutex;
 static volatile int fio_abort;
@@ -74,9 +82,52 @@ unsigned long arch_flags = 0;
 
 struct io_log *agg_io_log[2];
 
-#define TERMINATE_ALL		(-1)
 #define JOB_START_TIMEOUT	(5 * 1000)
 
+static const char *fio_os_strings[os_nr] = {
+	"Invalid",
+	"Linux",
+	"AIX",
+	"FreeBSD",
+	"HP-UX",
+	"OSX",
+	"NetBSD",
+	"Solaris",
+	"Windows"
+};
+
+static const char *fio_arch_strings[arch_nr] = {
+	"Invalid",
+	"x86-64",
+	"x86",
+	"ppc",
+	"ia64",
+	"s390",
+	"alpha",
+	"sparc",
+	"sparc64",
+	"arm",
+	"sh",
+	"hppa",
+	"generic"
+};
+
+const char *fio_get_os_string(int nr)
+{
+	if (nr < os_nr)
+		return fio_os_strings[nr];
+
+	return NULL;
+}
+
+const char *fio_get_arch_string(int nr)
+{
+	if (nr < arch_nr)
+		return fio_arch_strings[nr];
+
+	return NULL;
+}
+
 void td_set_runstate(struct thread_data *td, int runstate)
 {
 	if (td->runstate == runstate)
@@ -87,7 +138,7 @@ void td_set_runstate(struct thread_data *td, int runstate)
 	td->runstate = runstate;
 }
 
-static void terminate_threads(int group_id)
+void fio_terminate_threads(int group_id)
 {
 	struct thread_data *td;
 	int i;
@@ -121,10 +172,15 @@ static void terminate_threads(int group_id)
 static void sig_int(int sig)
 {
 	if (threads) {
-		log_info("\nfio: terminating on signal %d\n", sig);
-		fflush(stdout);
-		exit_value = 128;
-		terminate_threads(TERMINATE_ALL);
+		if (is_backend)
+			fio_server_got_signal(sig);
+		else {
+			log_info("\nfio: terminating on signal %d\n", sig);
+			fflush(stdout);
+			exit_value = 128;
+		}
+
+		fio_terminate_threads(TERMINATE_ALL);
 	}
 }
 
@@ -137,7 +193,9 @@ static void *disk_thread_main(void *data)
 		if (!threads)
 			break;
 		update_io_ticks();
-		print_thread_status();
+
+		if (!is_backend)
+			print_thread_status();
 	}
 
 	return NULL;
@@ -178,6 +236,13 @@ static void set_sig_handlers(void)
 	act.sa_handler = sig_int;
 	act.sa_flags = SA_RESTART;
 	sigaction(SIGTERM, &act, NULL);
+
+	if (is_backend) {
+		memset(&act, 0, sizeof(act));
+		act.sa_handler = sig_int;
+		act.sa_flags = SA_RESTART;
+		sigaction(SIGPIPE, &act, NULL);
+	}
 }
 
 /*
@@ -205,7 +270,7 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now,
 	if (mtime_since(&td->start, now) < 2000)
 		return 0;
 
-	iops += td->io_blocks[ddir];
+	iops += td->this_io_blocks[ddir];
 	bytes += td->this_io_bytes[ddir];
 	ratemin += td->o.ratemin[ddir];
 	rate_iops += td->o.rate_iops[ddir];
@@ -744,7 +809,7 @@ sync_done:
 		if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
 			if (check_min_rate(td, &comp_time, bytes_done)) {
 				if (exitall_on_terminate)
-					terminate_threads(td->groupid);
+					fio_terminate_threads(td->groupid);
 				td_verror(td, EIO, "check_min_rate");
 				break;
 			}
@@ -972,8 +1037,10 @@ static int keep_running(struct thread_data *td)
 
 static void reset_io_counters(struct thread_data *td)
 {
-	td->ts.stat_io_bytes[0] = td->ts.stat_io_bytes[1] = 0;
+	td->stat_io_bytes[0] = td->stat_io_bytes[1] = 0;
 	td->this_io_bytes[0] = td->this_io_bytes[1] = 0;
+	td->stat_io_blocks[0] = td->stat_io_blocks[1] = 0;
+	td->this_io_blocks[0] = td->this_io_blocks[1] = 0;
 	td->zone_bytes = 0;
 	td->rate_bytes[0] = td->rate_bytes[1] = 0;
 	td->rate_blocks[0] = td->rate_blocks[1] = 0;
@@ -1167,19 +1234,17 @@ static void *thread_main(void *data)
 	}
 
 	fio_gettime(&td->epoch, NULL);
-	getrusage(RUSAGE_SELF, &td->ts.ru_start);
+	getrusage(RUSAGE_SELF, &td->ru_start);
 
 	clear_state = 0;
 	while (keep_running(td)) {
 		fio_gettime(&td->start, NULL);
-		memcpy(&td->ts.stat_sample_time[0], &td->start,
-				sizeof(td->start));
-		memcpy(&td->ts.stat_sample_time[1], &td->start,
-				sizeof(td->start));
+		memcpy(&td->bw_sample_time, &td->start, sizeof(td->start));
+		memcpy(&td->iops_sample_time, &td->start, sizeof(td->start));
 		memcpy(&td->tv_cache, &td->start, sizeof(td->start));
 
 		if (td->o.ratemin[0] || td->o.ratemin[1])
-			memcpy(&td->lastrate, &td->ts.stat_sample_time,
+			memcpy(&td->lastrate, &td->bw_sample_time,
 							sizeof(td->lastrate));
 
 		if (clear_state)
@@ -1228,40 +1293,48 @@ static void *thread_main(void *data)
 	td->ts.io_bytes[1] = td->io_bytes[1];
 
 	fio_mutex_down(writeout_mutex);
-	if (td->ts.bw_log) {
+	if (td->bw_log) {
 		if (td->o.bw_log_file) {
-			finish_log_named(td, td->ts.bw_log,
+			finish_log_named(td, td->bw_log,
 						td->o.bw_log_file, "bw");
 		} else
-			finish_log(td, td->ts.bw_log, "bw");
+			finish_log(td, td->bw_log, "bw");
 	}
-	if (td->ts.lat_log) {
+	if (td->lat_log) {
 		if (td->o.lat_log_file) {
-			finish_log_named(td, td->ts.lat_log,
+			finish_log_named(td, td->lat_log,
 						td->o.lat_log_file, "lat");
 		} else
-			finish_log(td, td->ts.lat_log, "lat");
+			finish_log(td, td->lat_log, "lat");
 	}
-	if (td->ts.slat_log) {
+	if (td->slat_log) {
 		if (td->o.lat_log_file) {
-			finish_log_named(td, td->ts.slat_log,
+			finish_log_named(td, td->slat_log,
 						td->o.lat_log_file, "slat");
 		} else
-			finish_log(td, td->ts.slat_log, "slat");
+			finish_log(td, td->slat_log, "slat");
 	}
-	if (td->ts.clat_log) {
+	if (td->clat_log) {
 		if (td->o.lat_log_file) {
-			finish_log_named(td, td->ts.clat_log,
+			finish_log_named(td, td->clat_log,
 						td->o.lat_log_file, "clat");
 		} else
-			finish_log(td, td->ts.clat_log, "clat");
+			finish_log(td, td->clat_log, "clat");
 	}
+	if (td->iops_log) {
+		if (td->o.iops_log_file) {
+			finish_log_named(td, td->iops_log,
+						td->o.iops_log_file, "iops");
+		} else
+			finish_log(td, td->iops_log, "iops");
+	}
+
 	fio_mutex_up(writeout_mutex);
 	if (td->o.exec_postrun)
 		exec_string(td->o.exec_postrun);
 
 	if (exitall_on_terminate)
-		terminate_threads(td->groupid);
+		fio_terminate_threads(td->groupid);
 
 err:
 	if (td->error)
@@ -1415,7 +1488,7 @@ reaped:
 	}
 
 	if (*nr_running == cputhreads && !pending && realthreads)
-		terminate_threads(TERMINATE_ALL);
+		fio_terminate_threads(TERMINATE_ALL);
 }
 
 static void *gtod_thread_main(void *data)
@@ -1477,6 +1550,8 @@ static void run_threads(void)
 	if (fio_gtod_offload && fio_start_gtod_thread())
 		return;
 
+	set_sig_handlers();
+
 	if (!terse_output) {
 		log_info("Starting ");
 		if (nr_thread)
@@ -1492,8 +1567,6 @@ static void run_threads(void)
 		fflush(stdout);
 	}
 
-	set_sig_handlers();
-
 	todo = thread_number;
 	nr_running = 0;
 	nr_started = 0;
@@ -1609,7 +1682,7 @@ static void run_threads(void)
 			dprint(FD_MUTEX, "wait on startup_mutex\n");
 			if (fio_mutex_down_timeout(startup_mutex, 10)) {
 				log_err("fio: job startup hung? exiting.\n");
-				terminate_threads(TERMINATE_ALL);
+				fio_terminate_threads(TERMINATE_ALL);
 				fio_abort = 1;
 				nr_started--;
 				break;
@@ -1677,48 +1750,31 @@ static void run_threads(void)
 
 		reap_threads(&nr_running, &t_rate, &m_rate);
 
-		if (todo)
-			usleep(100000);
+		if (todo) {
+			if (is_backend)
+				fio_server_idle_loop();
+			else
+				usleep(100000);
+		}
 	}
 
 	while (nr_running) {
 		reap_threads(&nr_running, &t_rate, &m_rate);
-		usleep(10000);
+
+		if (is_backend)
+			fio_server_idle_loop();
+		else
+			usleep(10000);
 	}
 
 	update_io_ticks();
 	fio_unpin_memory();
 }
 
-int main(int argc, char *argv[], char *envp[])
+int exec_run(void)
 {
-	long ps;
-
-	arch_init(envp);
-
-	sinit();
-
-	/*
-	 * We need locale for number printing, if it isn't set then just
-	 * go with the US format.
-	 */
-	if (!getenv("LC_NUMERIC"))
-		setlocale(LC_NUMERIC, "en_US");
-
-	ps = sysconf(_SC_PAGESIZE);
-	if (ps < 0) {
-		log_err("Failed to get page size\n");
-		return 1;
-	}
-
-	page_size = ps;
-	page_mask = ps - 1;
-
-	fio_keywords_init();
-
-	if (parse_options(argc, argv))
-		return 1;
-
+	if (nr_clients)
+		return fio_handle_clients();
 	if (exec_profile && load_profile(exec_profile))
 		return 1;
 
@@ -1762,3 +1818,80 @@ int main(int argc, char *argv[], char *envp[])
 	fio_mutex_remove(writeout_mutex);
 	return exit_value;
 }
+
+void reset_fio_state(void)
+{
+	groupid = 0;
+	thread_number = 0;
+	nr_process = 0;
+	nr_thread = 0;
+	done_secs = 0;
+}
+
+static int endian_check(void)
+{
+	union {
+		uint8_t c[8];
+		uint64_t v;
+	} u;
+	int le = 0, be = 0;
+
+	u.v = 0x12;
+	if (u.c[7] == 0x12)
+		be = 1;
+	else if (u.c[0] == 0x12)
+		le = 1;
+
+#if defined(FIO_LITTLE_ENDIAN)
+	if (be)
+		return 1;
+#elif defined(FIO_BIG_ENDIAN)
+	if (le)
+		return 1;
+#else
+	return 1;
+#endif
+
+	if (!le && !be)
+		return 1;
+
+	return 0;
+}
+
+int main(int argc, char *argv[], char *envp[])
+{
+	long ps;
+
+	if (endian_check()) {
+		log_err("fio: endianness settings appear wrong.\n");
+		log_err("fio: please report this to fio@vger.kernel.org\n");
+		return 1;
+	}
+
+	arch_init(envp);
+
+	sinit();
+
+	/*
+	 * We need locale for number printing, if it isn't set then just
+	 * go with the US format.
+	 */
+	if (!getenv("LC_NUMERIC"))
+		setlocale(LC_NUMERIC, "en_US");
+
+	ps = sysconf(_SC_PAGESIZE);
+	if (ps < 0) {
+		log_err("Failed to get page size\n");
+		return 1;
+	}
+
+	page_size = ps;
+	page_mask = ps - 1;
+
+	fio_keywords_init();
+
+	if (parse_options(argc, argv))
+		return 1;
+
+	return exec_run();
+}
diff --git a/fio.h b/fio.h
index 022ba57..04963cd 100644
--- a/fio.h
+++ b/fio.h
@@ -35,6 +35,8 @@ struct thread_data;
 #include "time.h"
 #include "lib/getopt.h"
 #include "lib/rand.h"
+#include "server.h"
+#include "stat.h"
 
 #ifdef FIO_HAVE_GUASI
 #include <guasi.h>
@@ -44,14 +46,6 @@ struct thread_data;
 #include <sys/asynch.h>
 #endif
 
-struct group_run_stats {
-	unsigned long long max_run[2], min_run[2];
-	unsigned long long max_bw[2], min_bw[2];
-	unsigned long long io_kb[2];
-	unsigned long long agg[2];
-	unsigned int kb_base;
-};
-
 /*
  * What type of allocation to use for io buffers
  */
@@ -71,172 +65,6 @@ enum {
 	RW_SEQ_IDENT,
 };
 
-/*
- * How many depth levels to log
- */
-#define FIO_IO_U_MAP_NR	7
-#define FIO_IO_U_LAT_U_NR 10
-#define FIO_IO_U_LAT_M_NR 12
-
-/*
- * Aggregate clat samples to report percentile(s) of them.
- *
- * EXECUTIVE SUMMARY
- *
- * FIO_IO_U_PLAT_BITS determines the maximum statistical error on the
- * value of resulting percentiles. The error will be approximately
- * 1/2^(FIO_IO_U_PLAT_BITS+1) of the value.
- *
- * FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the maximum
- * range being tracked for latency samples. The maximum value tracked
- * accurately will be 2^(GROUP_NR + PLAT_BITS -1) microseconds.
- *
- * FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the memory
- * requirement of storing those aggregate counts. The memory used will
- * be (FIO_IO_U_PLAT_GROUP_NR * 2^FIO_IO_U_PLAT_BITS) * sizeof(int)
- * bytes.
- *
- * FIO_IO_U_PLAT_NR is the total number of buckets.
- *
- * DETAILS
- *
- * Suppose the clat varies from 0 to 999 (usec), the straightforward
- * method is to keep an array of (999 + 1) buckets, in which a counter
- * keeps the count of samples which fall in the bucket, e.g.,
- * {[0],[1],...,[999]}. However this consumes a huge amount of space,
- * and can be avoided if an approximation is acceptable.
- *
- * One such method is to let the range of the bucket to be greater
- * than one. This method has low accuracy when the value is small. For
- * example, let the buckets be {[0,99],[100,199],...,[900,999]}, and
- * the represented value of each bucket be the mean of the range. Then
- * a value 0 has an round-off error of 49.5. To improve on this, we
- * use buckets with non-uniform ranges, while bounding the error of
- * each bucket within a ratio of the sample value. A simple example
- * would be when error_bound = 0.005, buckets are {
- * {[0],[1],...,[99]}, {[100,101],[102,103],...,[198,199]},..,
- * {[900,909],[910,919]...}  }. The total range is partitioned into
- * groups with different ranges, then buckets with uniform ranges. An
- * upper bound of the error is (range_of_bucket/2)/value_of_bucket
- *
- * For better efficiency, we implement this using base two. We group
- * samples by their Most Significant Bit (MSB), extract the next M bit
- * of them as an index within the group, and discard the rest of the
- * bits.
- *
- * E.g., assume a sample 'x' whose MSB is bit n (starting from bit 0),
- * and use M bit for indexing
- *
- *        | n |    M bits   | bit (n-M-1) ... bit 0 |
- *
- * Because x is at least 2^n, and bit 0 to bit (n-M-1) is at most
- * (2^(n-M) - 1), discarding bit 0 to (n-M-1) makes the round-off
- * error
- *
- *           2^(n-M)-1    2^(n-M)    1
- *      e <= --------- <= ------- = ---
- *             2^n          2^n     2^M
- *
- * Furthermore, we use "mean" of the range to represent the bucket,
- * the error e can be lowered by half to 1 / 2^(M+1). By using M bits
- * as the index, each group must contains 2^M buckets.
- *
- * E.g. Let M (FIO_IO_U_PLAT_BITS) be 6
- *      Error bound is 1/2^(6+1) = 0.0078125 (< 1%)
- *
- *	Group	MSB	#discarded	range of		#buckets
- *			error_bits	value
- *	----------------------------------------------------------------
- *	0*	0~5	0		[0,63]			64
- *	1*	6	0		[64,127]		64
- *	2	7	1		[128,255]		64
- *	3	8	2		[256,511]		64
- *	4	9	3		[512,1023]		64
- *	...	...	...		[...,...]		...
- *	18	23	17		[8838608,+inf]**	64
- *
- *  * Special cases: when n < (M-1) or when n == (M-1), in both cases,
- *    the value cannot be rounded off. Use all bits of the sample as
- *    index.
- *
- *  ** If a sample's MSB is greater than 23, it will be counted as 23.
- */
-
-#define FIO_IO_U_PLAT_BITS 6
-#define FIO_IO_U_PLAT_VAL (1 << FIO_IO_U_PLAT_BITS)
-#define FIO_IO_U_PLAT_GROUP_NR 19
-#define FIO_IO_U_PLAT_NR (FIO_IO_U_PLAT_GROUP_NR * FIO_IO_U_PLAT_VAL)
-#define FIO_IO_U_LIST_MAX_LEN 20 /* The size of the default and user-specified
-					list of percentiles */
-
-#define MAX_PATTERN_SIZE 512
-
-struct thread_stat {
-	char *name;
-	char *verror;
-	int error;
-	int groupid;
-	pid_t pid;
-	char *description;
-	int members;
-
-	struct io_log *slat_log;
-	struct io_log *clat_log;
-	struct io_log *lat_log;
-	struct io_log *bw_log;
-
-	/*
-	 * bandwidth and latency stats
-	 */
-	struct io_stat clat_stat[2];		/* completion latency */
-	struct io_stat slat_stat[2];		/* submission latency */
-	struct io_stat lat_stat[2];		/* total latency */
-	struct io_stat bw_stat[2];		/* bandwidth stats */
-
-	unsigned long long stat_io_bytes[2];
-	struct timeval stat_sample_time[2];
-
-	/*
-	 * fio system usage accounting
-	 */
-	struct rusage ru_start;
-	struct rusage ru_end;
-	unsigned long usr_time;
-	unsigned long sys_time;
-	unsigned long ctx;
-	unsigned long minf, majf;
-
-	/*
-	 * IO depth and latency stats
-	 */
-	unsigned int clat_percentiles;
-	double* percentile_list;
-
-	unsigned int io_u_map[FIO_IO_U_MAP_NR];
-	unsigned int io_u_submit[FIO_IO_U_MAP_NR];
-	unsigned int io_u_complete[FIO_IO_U_MAP_NR];
-	unsigned int io_u_lat_u[FIO_IO_U_LAT_U_NR];
-	unsigned int io_u_lat_m[FIO_IO_U_LAT_M_NR];
-	unsigned int io_u_plat[2][FIO_IO_U_PLAT_NR];
-	unsigned long total_io_u[3];
-	unsigned long short_io_u[3];
-	unsigned long total_submit;
-	unsigned long total_complete;
-
-	unsigned long long io_bytes[2];
-	unsigned long long runtime[2];
-	unsigned long total_run_time;
-
-	/*
-	 * IO Error related stats
-	 */
-	unsigned continue_on_error;
-	unsigned long total_err_count;
-	int first_error;
-
-	unsigned int kb_base;
-};
-
 struct bssplit {
 	unsigned int bs;
 	unsigned char perc;
@@ -307,6 +135,7 @@ struct thread_options {
 	unsigned int use_os_rand;
 	unsigned int write_lat_log;
 	unsigned int write_bw_log;
+	unsigned int write_iops_log;
 	unsigned int norandommap;
 	unsigned int softrandommap;
 	unsigned int bs_unaligned;
@@ -325,6 +154,7 @@ struct thread_options {
 	unsigned long long ramp_time;
 	unsigned int overwrite;
 	unsigned int bw_avg_time;
+	unsigned int iops_avg_time;
 	unsigned int loops;
 	unsigned long long zone_size;
 	unsigned long long zone_skip;
@@ -365,12 +195,13 @@ struct thread_options {
 	unsigned long long trim_backlog;
 	unsigned int clat_percentiles;
 	unsigned int overwrite_plist;
-	double percentile_list[FIO_IO_U_LIST_MAX_LEN];
+	fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
 
 	char *read_iolog_file;
 	char *write_iolog_file;
 	char *bw_log_file;
 	char *lat_log_file;
+	char *iops_log_file;
 	char *replay_redirect;
 
 	/*
@@ -418,8 +249,6 @@ struct thread_options {
 	unsigned int userspace_libaio_reap;
 };
 
-#define FIO_VERROR_SIZE	128
-
 /*
  * This describes a single thread/process executing a fio job.
  */
@@ -430,6 +259,22 @@ struct thread_data {
 	int thread_number;
 	int groupid;
 	struct thread_stat ts;
+
+	struct io_log *slat_log;
+	struct io_log *clat_log;
+	struct io_log *lat_log;
+	struct io_log *bw_log;
+	struct io_log *iops_log;
+
+	uint64_t stat_io_bytes[2];
+	struct timeval bw_sample_time;
+
+	uint64_t stat_io_blocks[2];
+	struct timeval iops_sample_time;
+
+	struct rusage ru_start;
+	struct rusage ru_end;
+
 	struct fio_file **files;
 	unsigned int files_size;
 	unsigned int files_index;
@@ -523,6 +368,7 @@ struct thread_data {
 
 	unsigned long io_issues[2];
 	unsigned long long io_blocks[2];
+	unsigned long long this_io_blocks[2];
 	unsigned long long io_bytes[2];
 	unsigned long long io_skip_bytes;
 	unsigned long long this_io_bytes[2];
@@ -632,6 +478,9 @@ enum {
 #define td_vmsg(td, err, msg, func)	\
 	__td_verror((td), (err), (msg), (func))
 
+#define __fio_stringify_1(x)	#x
+#define __fio_stringify(x)	__fio_stringify_1(x)
+
 extern int exitall_on_terminate;
 extern int thread_number;
 extern int nr_process, nr_thread;
@@ -650,6 +499,10 @@ extern int fio_gtod_cpu;
 extern enum fio_cs fio_clock_source;
 extern int warnings_fatal;
 extern int terse_version;
+extern int is_backend;
+extern int nr_clients;
+extern int log_syslog;
+extern const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN];
 
 extern struct thread_data *threads;
 
@@ -690,6 +543,10 @@ static inline int should_fsync(struct thread_data *td)
  * Init/option functions
  */
 extern int __must_check parse_options(int, char **);
+extern int parse_jobs_ini(char *, int, int);
+extern int parse_cmd_line(int, char **);
+extern int exec_run(void);
+extern void reset_fio_state(void);
 extern int fio_options_parse(struct thread_data *, char **, int);
 extern void fio_keywords_init(void);
 extern int fio_cmd_option_parse(struct thread_data *, const char *, char *);
@@ -731,6 +588,8 @@ enum {
 };
 
 extern void td_set_runstate(struct thread_data *, int);
+#define TERMINATE_ALL		(-1)
+extern void fio_terminate_threads(int);
 
 /*
  * Memory helpers
@@ -842,4 +701,7 @@ static inline void td_io_u_free_notify(struct thread_data *td)
 		pthread_cond_signal(&td->free_cond);
 }
 
+extern const char *fio_get_arch_string(int);
+extern const char *fio_get_os_string(int);
+
 #endif
diff --git a/fio_generate_plots b/fio_generate_plots
index 21d7c6a..4285415 100755
--- a/fio_generate_plots
+++ b/fio_generate_plots
@@ -43,6 +43,24 @@ if [ "$PLOT_LINE"x != "x" ]; then
 fi
 
 PLOT_LINE=""
+for i in *iops.log; do
+	if [ ! -r $i ]; then
+		continue
+	fi
+	PT=$(echo $i | sed s/_iops.log//g)
+	if [ "$PLOT_LINE"x != "x" ]; then
+		PLOT_LINE=$PLOT_LINE", "
+	fi
+
+	PLOT_LINE=$PLOT_LINE"'$i' title '$PT' with lines"
+done
+
+if [ "$PLOT_LINE"x != "x" ]; then
+	echo Making bw logs
+	echo "set title 'IOPS - $TITLE'; set xlabel 'time (msec)'; set ylabel 'IOPS'; set terminal png size $XRES,$YRES; set output '$TITLE-IOPS.png'; plot " $PLOT_LINE | $GNUPLOT -
+fi
+
+PLOT_LINE=""
 for i in *slat.log; do
 	if [ ! -r $i ]; then
 		continue
diff --git a/fio_version.h b/fio_version.h
new file mode 100644
index 0000000..3008c64
--- /dev/null
+++ b/fio_version.h
@@ -0,0 +1,8 @@
+#ifndef FIO_VERSION_H
+#define FIO_VERSION_H
+
+#define FIO_MAJOR	1
+#define FIO_MINOR	99
+#define FIO_PATCH	6
+
+#endif
diff --git a/hash.h b/hash.h
index 73f961b..0c3cdda 100644
--- a/hash.h
+++ b/hash.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_HASH_H
 #define _LINUX_HASH_H
 
+#include <inttypes.h>
 #include "arch/arch.h"
 
 /* Fast hashing routine for a long.
@@ -59,4 +60,80 @@ static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
 {
 	return hash_long((unsigned long)ptr, bits);
 }
+
+/*
+ * Bob Jenkins jhash
+ */
+
+#define JHASH_INITVAL	GOLDEN_RATIO_PRIME
+
+static inline uint32_t rol32(uint32_t word, uint32_t shift)
+{
+	return (word << shift) | (word >> (32 - shift));
+}
+
+/* __jhash_mix -- mix 3 32-bit values reversibly. */
+#define __jhash_mix(a, b, c)			\
+{						\
+	a -= c;  a ^= rol32(c, 4);  c += b;	\
+	b -= a;  b ^= rol32(a, 6);  a += c;	\
+	c -= b;  c ^= rol32(b, 8);  b += a;	\
+	a -= c;  a ^= rol32(c, 16); c += b;	\
+	b -= a;  b ^= rol32(a, 19); a += c;	\
+	c -= b;  c ^= rol32(b, 4);  b += a;	\
+}
+
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a, b, c)			\
+{						\
+	c ^= b; c -= rol32(b, 14);		\
+	a ^= c; a -= rol32(c, 11);		\
+	b ^= a; b -= rol32(a, 25);		\
+	c ^= b; c -= rol32(b, 16);		\
+	a ^= c; a -= rol32(c, 4);		\
+	b ^= a; b -= rol32(a, 14);		\
+	c ^= b; c -= rol32(b, 24);		\
+}
+
+static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval)
+{
+	const uint8_t *k = key;
+	uint32_t a, b, c;
+
+	/* Set up the internal state */
+	a = b = c = JHASH_INITVAL + length + initval;
+
+	/* All but the last block: affect some 32 bits of (a,b,c) */
+	while (length > 12) {
+		a += *k;
+		b += *(k + 4);
+		c += *(k + 8);
+		__jhash_mix(a, b, c);
+		length -= 12;
+		k += 12;
+	}
+
+	/* Last block: affect all 32 bits of (c) */
+	/* All the case statements fall through */
+	switch (length) {
+	case 12: c += (uint32_t) k[11] << 24;
+	case 11: c += (uint32_t) k[10] << 16;
+	case 10: c += (uint32_t) k[9] << 8;
+	case 9:  c += k[8];
+	case 8:  b += (uint32_t) k[7] << 24;
+	case 7:  b += (uint32_t) k[6] << 16;
+	case 6:  b += (uint32_t) k[5] << 8;
+	case 5:  b += k[4];
+	case 4:  a += (uint32_t) k[3] << 24;
+	case 3:  a += (uint32_t) k[2] << 16;
+	case 2:  a += (uint32_t) k[1] << 8;
+	case 1:  a += k[0];
+		 __jhash_final(a, b, c);
+	case 0: /* Nothing left to add */
+		break;
+	}
+
+	return c;
+}
+
 #endif /* _LINUX_HASH_H */
diff --git a/init.c b/init.c
index 0435dd0..5bea948 100644
--- a/init.c
+++ b/init.c
@@ -19,10 +19,20 @@
 #include "filehash.h"
 #include "verify.h"
 #include "profile.h"
+#include "server.h"
 
 #include "lib/getopt.h"
 
-static char fio_version_string[] = "fio 1.59";
+#include "fio_version.h"
+
+#if FIO_PATCH > 0
+static char fio_version_string[] =	__fio_stringify(FIO_MAJOR) "."	\
+					__fio_stringify(FIO_MINOR) "."	\
+					__fio_stringify(FIO_PATCH);
+#else
+static char fio_version_string[] =	__fio_stringify(FIO_MAJOR) "."	\
+					__fio_stringify(FIO_MINOR);
+#endif
 
 #define FIO_RANDSEED		(0xb1899bedUL)
 
@@ -45,6 +55,9 @@ int nr_job_sections = 0;
 char *exec_profile = NULL;
 int warnings_fatal = 0;
 int terse_version = 2;
+int is_backend = 0;
+int nr_clients = 0;
+int log_syslog = 0;
 
 int write_bw_log = 0;
 int read_only = 0;
@@ -58,6 +71,27 @@ unsigned int fio_debug_jobno = -1;
 unsigned int *fio_debug_jobp = NULL;
 
 static char cmd_optstr[256];
+static int did_arg;
+
+const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN] = {
+	{ .u.f	=  1.0 },
+	{ .u.f	=  5.0 },
+	{ .u.f	= 10.0 },
+	{ .u.f	= 20.0 },
+	{ .u.f	= 30.0 },
+	{ .u.f	= 40.0 },
+	{ .u.f	= 50.0 },
+	{ .u.f	= 60.0 },
+	{ .u.f	= 70.0 },
+	{ .u.f	= 80.0 },
+	{ .u.f	= 90.0 },
+	{ .u.f	= 95.0 },
+	{ .u.f	= 99.0 },
+	{ .u.f	= 99.5 },
+	{ .u.f	= 99.9 },
+};
+
+#define FIO_CLIENT_FLAG		(1 << 16)
 
 /*
  * Command line options. These will contain the above, plus a few
@@ -67,106 +101,178 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
 	{
 		.name		= (char *) "output",
 		.has_arg	= required_argument,
-		.val		= 'o',
+		.val		= 'o' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "timeout",
 		.has_arg	= required_argument,
-		.val		= 't',
+		.val		= 't' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "latency-log",
 		.has_arg	= required_argument,
-		.val		= 'l',
+		.val		= 'l' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "bandwidth-log",
 		.has_arg	= required_argument,
-		.val		= 'b',
+		.val		= 'b' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "minimal",
 		.has_arg	= optional_argument,
-		.val		= 'm',
+		.val		= 'm' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "version",
 		.has_arg	= no_argument,
-		.val		= 'v',
+		.val		= 'v' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "help",
 		.has_arg	= no_argument,
-		.val		= 'h',
+		.val		= 'h' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "cmdhelp",
 		.has_arg	= optional_argument,
-		.val		= 'c',
+		.val		= 'c' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "showcmd",
 		.has_arg	= no_argument,
-		.val		= 's',
+		.val		= 's' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "readonly",
 		.has_arg	= no_argument,
-		.val		= 'r',
+		.val		= 'r' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "eta",
 		.has_arg	= required_argument,
-		.val		= 'e',
+		.val		= 'e' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "debug",
 		.has_arg	= required_argument,
-		.val		= 'd',
+		.val		= 'd' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "section",
 		.has_arg	= required_argument,
-		.val		= 'x',
+		.val		= 'x' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "alloc-size",
 		.has_arg	= required_argument,
-		.val		= 'a',
+		.val		= 'a' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "profile",
 		.has_arg	= required_argument,
-		.val		= 'p',
+		.val		= 'p' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "warnings-fatal",
 		.has_arg	= no_argument,
-		.val		= 'w',
+		.val		= 'w' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "max-jobs",
 		.has_arg	= required_argument,
-		.val		= 'j',
+		.val		= 'j' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "terse-version",
 		.has_arg	= required_argument,
-		.val		= 'V',
+		.val		= 'V' | FIO_CLIENT_FLAG,
+	},
+	{
+		.name		= (char *) "server",
+		.has_arg	= optional_argument,
+		.val		= 'S',
+	},
+	{	.name		= (char *) "daemonize",
+		.has_arg	= required_argument,
+		.val		= 'D',
+	},
+	{
+		.name		= (char *) "client",
+		.has_arg	= required_argument,
+		.val		= 'C',
 	},
 	{
 		.name		= NULL,
 	},
 };
 
-FILE *get_f_out()
+static void free_shm(void)
 {
-	return f_out;
+	struct shmid_ds sbuf;
+
+	if (threads) {
+		void *tp = threads;
+
+		threads = NULL;
+		file_hash_exit();
+		fio_debug_jobp = NULL;
+		shmdt(tp);
+		shmctl(shm_id, IPC_RMID, &sbuf);
+	}
+
+	scleanup();
 }
 
-FILE *get_f_err()
+/*
+ * The thread area is shared between the main process and the job
+ * threads/processes. So setup a shared memory segment that will hold
+ * all the job info. We use the end of the region for keeping track of
+ * open files across jobs, for file sharing.
+ */
+static int setup_thread_area(void)
 {
-	return f_err;
+	void *hash;
+
+	if (threads)
+		return 0;
+
+	/*
+	 * 1024 is too much on some machines, scale max_jobs if
+	 * we get a failure that looks like too large a shm segment
+	 */
+	do {
+		size_t size = max_jobs * sizeof(struct thread_data);
+
+		size += file_hash_size;
+		size += sizeof(unsigned int);
+
+		shm_id = shmget(0, size, IPC_CREAT | 0600);
+		if (shm_id != -1)
+			break;
+		if (errno != EINVAL) {
+			perror("shmget");
+			break;
+		}
+
+		max_jobs >>= 1;
+	} while (max_jobs);
+
+	if (shm_id == -1)
+		return 1;
+
+	threads = shmat(shm_id, NULL, 0);
+	if (threads == (void *) -1) {
+		perror("shmat");
+		return 1;
+	}
+
+	memset(threads, 0, max_jobs * sizeof(struct thread_data));
+	hash = (void *) threads + max_jobs * sizeof(struct thread_data);
+	fio_debug_jobp = (void *) hash + file_hash_size;
+	*fio_debug_jobp = -1;
+	file_hash_init(hash);
+	return 0;
 }
 
 /*
@@ -178,6 +284,10 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent)
 
 	if (global)
 		return &def_thread;
+	if (setup_thread_area()) {
+		log_err("error: failed to setup shm segment\n");
+		return NULL;
+	}
 	if (thread_number >= max_jobs) {
 		log_err("error: maximum number of jobs (%d) reached.\n",
 				max_jobs);
@@ -627,9 +737,9 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 
 	td->ts.clat_percentiles = td->o.clat_percentiles;
 	if (td->o.overwrite_plist)
-		td->ts.percentile_list = td->o.percentile_list;
+		memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
 	else
-		td->ts.percentile_list = NULL;
+		memcpy(td->ts.percentile_list, def_percentile_list, sizeof(def_percentile_list));
 
 	td->ts.clat_stat[0].min_val = td->ts.clat_stat[1].min_val = ULONG_MAX;
 	td->ts.slat_stat[0].min_val = td->ts.slat_stat[1].min_val = ULONG_MAX;
@@ -652,12 +762,14 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 		goto err;
 
 	if (td->o.write_lat_log) {
-		setup_log(&td->ts.lat_log);
-		setup_log(&td->ts.slat_log);
-		setup_log(&td->ts.clat_log);
+		setup_log(&td->lat_log);
+		setup_log(&td->slat_log);
+		setup_log(&td->clat_log);
 	}
 	if (td->o.write_bw_log)
-		setup_log(&td->ts.bw_log);
+		setup_log(&td->bw_log);
+	if (td->o.write_iops_log)
+		setup_log(&td->iops_log);
 
 	if (!td->o.name)
 		td->o.name = strdup(jobname);
@@ -800,7 +912,7 @@ static int is_empty_or_comment(char *line)
 /*
  * This is our [ini] type file parser.
  */
-static int parse_jobs_ini(char *file, int stonewall_flag)
+int parse_jobs_ini(char *file, int is_buf, int stonewall_flag)
 {
 	unsigned int global;
 	struct thread_data *td;
@@ -814,14 +926,18 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 	char **opts;
 	int i, alloc_opts, num_opts;
 
-	if (!strcmp(file, "-"))
-		f = stdin;
-	else
-		f = fopen(file, "r");
+	if (is_buf)
+		f = NULL;
+	else {
+		if (!strcmp(file, "-"))
+			f = stdin;
+		else
+			f = fopen(file, "r");
 
-	if (!f) {
-		perror("fopen job file");
-		return 1;
+		if (!f) {
+			perror("fopen job file");
+			return 1;
+		}
 	}
 
 	string = malloc(4096);
@@ -843,7 +959,10 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 		 * haven't handled.
 		 */
 		if (!skip_fgets) {
-			p = fgets(string, 4095, f);
+			if (is_buf)
+				p = strsep(&file, "\n");
+			else
+				p = fgets(string, 4095, f);
 			if (!p)
 				break;
 		}
@@ -897,7 +1016,14 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 		num_opts = 0;
 		memset(opts, 0, alloc_opts * sizeof(char *));
 
-		while ((p = fgets(string, 4096, f)) != NULL) {
+		while (1) {
+			if (is_buf)
+				p = strsep(&file, "\n");
+			else
+				p = fgets(string, 4096, f);
+			if (!p)
+				break;
+
 			if (is_empty_or_comment(p))
 				continue;
 
@@ -950,7 +1076,7 @@ static int parse_jobs_ini(char *file, int stonewall_flag)
 	free(string);
 	free(name);
 	free(opts);
-	if (f != stdin)
+	if (!is_buf && f != stdin)
 		fclose(f);
 	return ret;
 }
@@ -969,75 +1095,9 @@ static int fill_def_thread(void)
 	return 0;
 }
 
-static void free_shm(void)
-{
-	struct shmid_ds sbuf;
-
-	if (threads) {
-		void *tp = threads;
-
-		threads = NULL;
-		file_hash_exit();
-		fio_debug_jobp = NULL;
-		shmdt(tp);
-		shmctl(shm_id, IPC_RMID, &sbuf);
-	}
-
-	scleanup();
-}
-
-/*
- * The thread area is shared between the main process and the job
- * threads/processes. So setup a shared memory segment that will hold
- * all the job info. We use the end of the region for keeping track of
- * open files across jobs, for file sharing.
- */
-static int setup_thread_area(void)
-{
-	void *hash;
-
-	/*
-	 * 1024 is too much on some machines, scale max_jobs if
-	 * we get a failure that looks like too large a shm segment
-	 */
-	do {
-		size_t size = max_jobs * sizeof(struct thread_data);
-
-		size += file_hash_size;
-		size += sizeof(unsigned int);
-
-		shm_id = shmget(0, size, IPC_CREAT | 0600);
-		if (shm_id != -1)
-			break;
-		if (errno != EINVAL) {
-			perror("shmget");
-			break;
-		}
-
-		max_jobs >>= 1;
-	} while (max_jobs);
-
-	if (shm_id == -1)
-		return 1;
-
-	threads = shmat(shm_id, NULL, 0);
-	if (threads == (void *) -1) {
-		perror("shmat");
-		return 1;
-	}
-
-	memset(threads, 0, max_jobs * sizeof(struct thread_data));
-	hash = (void *) threads + max_jobs * sizeof(struct thread_data);
-	fio_debug_jobp = (void *) hash + file_hash_size;
-	*fio_debug_jobp = -1;
-	file_hash_init(hash);
-	atexit(free_shm);
-	return 0;
-}
-
 static void usage(const char *name)
 {
-	printf("%s\n", fio_version_string);
+	printf("fio %s\n", fio_version_string);
 	printf("%s [options] [job options] <job file(s)>\n", name);
 	printf("\t--debug=options\tEnable debug logging\n");
 	printf("\t--output\tWrite output to file\n");
@@ -1060,6 +1120,9 @@ static void usage(const char *name)
 		" (def 1024)\n");
 	printf("\t--warnings-fatal Fio parser warnings are fatal\n");
 	printf("\t--max-jobs\tMaximum number of threads/processes to support\n");
+	printf("\t--server=args\tStart a backend fio server\n");
+	printf("\t--daemonize=pidfile Background fio server, write pid to file\n");
+	printf("\t--client=hostname Talk to remote backend fio server at hostname\n");
 	printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
 	printf("\n                   Jens Axboe <jaxboe@fusionio.com>\n");
 }
@@ -1079,6 +1142,7 @@ struct debug_level debug_levels[] = {
 	{ .name = "mutex",	.shift = FD_MUTEX },
 	{ .name	= "profile",	.shift = FD_PROFILE },
 	{ .name = "time",	.shift = FD_TIME },
+	{ .name = "net",	.shift = FD_NET },
 	{ .name = NULL, },
 };
 
@@ -1163,13 +1227,51 @@ static void fio_options_fill_optstring(void)
 	ostr[c] = '\0';
 }
 
-static int parse_cmd_line(int argc, char *argv[])
+static int client_flag_set(char c)
+{
+	int i;
+
+	i = 0;
+	while (l_opts[i].name) {
+		int val = l_opts[i].val;
+
+		if (c == (val & 0xff))
+			return (val & FIO_CLIENT_FLAG);
+
+		i++;
+	}
+
+	return 0;
+}
+
+void parse_cmd_client(void *client, char *opt)
+{
+	fio_client_add_cmd_option(client, opt);
+}
+
+int parse_cmd_line(int argc, char *argv[])
 {
 	struct thread_data *td = NULL;
 	int c, ini_idx = 0, lidx, ret = 0, do_exit = 0, exit_val = 0;
 	char *ostr = cmd_optstr;
+	void *pid_file = NULL;
+	void *cur_client = NULL;
+	int backend = 0;
+
+	/*
+	 * Reset optind handling, since we may call this multiple times
+	 * for the backend.
+	 */
+	optind = 1;
 
 	while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) {
+		did_arg = 1;
+
+		if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
+			parse_cmd_client(cur_client, argv[optind - 1]);
+			c &= ~FIO_CLIENT_FLAG;
+		}
+
 		switch (c) {
 		case 'a':
 			smalloc_pool_size = atoi(optarg);
@@ -1195,10 +1297,17 @@ static int parse_cmd_line(int argc, char *argv[])
 			terse_output = 1;
 			break;
 		case 'h':
-			usage(argv[0]);
-			exit(0);
+			if (!cur_client) {
+				usage(argv[0]);
+				do_exit++;
+			}
+			break;
 		case 'c':
-			exit(fio_show_option_help(optarg));
+			if (!cur_client) {
+				fio_show_option_help(optarg);
+				do_exit++;
+			}
+			break;
 		case 's':
 			dump_cmdline = 1;
 			break;
@@ -1206,11 +1315,14 @@ static int parse_cmd_line(int argc, char *argv[])
 			read_only = 1;
 			break;
 		case 'v':
-			log_info("%s\n", fio_version_string);
-			exit(0);
+			if (!cur_client) {
+				log_info("fio %s\n", fio_version_string);
+				do_exit++;
+			}
+			break;
 		case 'V':
 			terse_version = atoi(optarg);
-			if (terse_version != 2) {
+			if (terse_version != 3) {
 				log_err("fio: bad terse version format\n");
 				exit_val = 1;
 				do_exit++;
@@ -1284,22 +1396,64 @@ static int parse_cmd_line(int argc, char *argv[])
 				exit_val = 1;
 			}
 			break;
+		case 'S':
+			if (nr_clients) {
+				log_err("fio: can't be both client and server\n");
+				do_exit++;
+				exit_val = 1;
+				break;
+			}
+			if (optarg)
+				fio_server_set_arg(optarg);
+			is_backend = 1;
+			backend = 1;
+			break;
+		case 'D':
+			pid_file = strdup(optarg);
+			break;
+		case 'C':
+			if (is_backend) {
+				log_err("fio: can't be both client and server\n");
+				do_exit++;
+				exit_val = 1;
+				break;
+			}
+			if (fio_client_add(optarg, &cur_client)) {
+				log_err("fio: failed adding client %s\n", optarg);
+				do_exit++;
+				exit_val = 1;
+				break;
+			}
+			break;
 		default:
 			do_exit++;
 			exit_val = 1;
 			break;
 		}
+		if (do_exit)
+			break;
+	}
+
+	if (do_exit) {
+		if (exit_val && !(is_backend || nr_clients))
+			exit(exit_val);
 	}
 
-	if (do_exit)
-		exit(exit_val);
+	if (nr_clients && fio_clients_connect()) {
+		do_exit++;
+		exit_val = 1;
+		return -1;
+	}
+
+	if (is_backend && backend)
+		return fio_start_server(pid_file);
 
 	if (td) {
 		if (!ret)
 			ret = add_job(td, td->o.name ?: "fio", 0);
 	}
 
-	while (optind < argc) {
+	while (!ret && optind < argc) {
 		ini_idx++;
 		ini_file = realloc(ini_file, ini_idx * sizeof(char *));
 		ini_file[ini_idx - 1] = strdup(argv[optind]);
@@ -1319,19 +1473,27 @@ int parse_options(int argc, char *argv[])
 	fio_options_fill_optstring();
 	fio_options_dup_and_init(l_opts);
 
-	if (setup_thread_area())
-		return 1;
+	atexit(free_shm);
+
 	if (fill_def_thread())
 		return 1;
 
 	job_files = parse_cmd_line(argc, argv);
 
-	for (i = 0; i < job_files; i++) {
-		if (fill_def_thread())
-			return 1;
-		if (parse_jobs_ini(ini_file[i], i))
-			return 1;
-		free(ini_file[i]);
+	if (job_files > 0) {
+		for (i = 0; i < job_files; i++) {
+			if (fill_def_thread())
+				return 1;
+			if (nr_clients) {
+				if (fio_clients_send_ini(ini_file[i]))
+					return 1;
+				free(ini_file[i]);
+			} else if (!is_backend) {
+				if (parse_jobs_ini(ini_file[i], 0, i))
+					return 1;
+				free(ini_file[i]);
+			}
+		}
 	}
 
 	free(ini_file);
@@ -1342,10 +1504,19 @@ int parse_options(int argc, char *argv[])
 			return 0;
 		if (exec_profile)
 			return 0;
+		if (is_backend || nr_clients)
+			return 0;
+		if (did_arg)
+			return 0;
 
 		log_err("No jobs(s) defined\n\n");
-		usage(argv[0]);
-		return 1;
+
+		if (!did_arg) {
+			usage(argv[0]);
+			return 1;
+		}
+
+		return 0;
 	}
 
 	if (def_thread.o.gtod_offload) {
@@ -1354,6 +1525,8 @@ int parse_options(int argc, char *argv[])
 		fio_gtod_cpu = def_thread.o.gtod_cpu;
 	}
 
-	log_info("%s\n", fio_version_string);
+	if (!terse_output)
+		log_info("fio %s\n", fio_version_string);
+
 	return 0;
 }
diff --git a/io_u.c b/io_u.c
index 4dcb1fc..d1f66a9 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1293,6 +1293,8 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
 
 	if (!td->o.disable_bw)
 		add_bw_sample(td, idx, bytes, &icd->time);
+
+	add_iops_sample(td, idx, &icd->time);
 }
 
 static void io_completed(struct thread_data *td, struct io_u *io_u,
@@ -1332,6 +1334,7 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
 		int ret;
 
 		td->io_blocks[idx]++;
+		td->this_io_blocks[idx]++;
 		td->io_bytes[idx] += bytes;
 		td->this_io_bytes[idx] += bytes;
 
@@ -1347,7 +1350,7 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
 			}
 		}
 
-		if (ramp_time_over(td)) {
+		if (ramp_time_over(td) && td->runstate == TD_RUNNING) {
 			account_io_completion(td, io_u, icd, idx, bytes);
 
 			if (__should_check_rate(td, idx)) {
diff --git a/iolog.c b/iolog.c
new file mode 100644
index 0000000..f962864
--- /dev/null
+++ b/iolog.c
@@ -0,0 +1,541 @@
+/*
+ * Code related to writing an iolog of what a thread is doing, and to
+ * later read that back and replay
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <assert.h>
+#include "flist.h"
+#include "fio.h"
+#include "verify.h"
+#include "trim.h"
+
+static const char iolog_ver2[] = "fio version 2 iolog";
+
+void queue_io_piece(struct thread_data *td, struct io_piece *ipo)
+{
+	flist_add_tail(&ipo->list, &td->io_log_list);
+	td->total_io_size += ipo->len;
+}
+
+void log_io_u(struct thread_data *td, struct io_u *io_u)
+{
+	const char *act[] = { "read", "write", "sync", "datasync",
+				"sync_file_range", "wait", "trim" };
+
+	assert(io_u->ddir <= 6);
+
+	if (!td->o.write_iolog_file)
+		return;
+
+	fprintf(td->iolog_f, "%s %s %llu %lu\n", io_u->file->file_name,
+						act[io_u->ddir], io_u->offset,
+						io_u->buflen);
+}
+
+void log_file(struct thread_data *td, struct fio_file *f,
+	      enum file_log_act what)
+{
+	const char *act[] = { "add", "open", "close" };
+
+	assert(what < 3);
+
+	if (!td->o.write_iolog_file)
+		return;
+
+
+	/*
+	 * this happens on the pre-open/close done before the job starts
+	 */
+	if (!td->iolog_f)
+		return;
+
+	fprintf(td->iolog_f, "%s %s\n", f->file_name, act[what]);
+}
+
+static void iolog_delay(struct thread_data *td, unsigned long delay)
+{
+	unsigned long usec = utime_since_now(&td->last_issue);
+
+	if (delay < usec)
+		return;
+
+	delay -= usec;
+
+	/*
+	 * less than 100 usec delay, just regard it as noise
+	 */
+	if (delay < 100)
+		return;
+
+	usec_sleep(td, delay);
+}
+
+static int ipo_special(struct thread_data *td, struct io_piece *ipo)
+{
+	struct fio_file *f;
+	int ret;
+
+	/*
+	 * Not a special ipo
+	 */
+	if (ipo->ddir != DDIR_INVAL)
+		return 0;
+
+	f = td->files[ipo->fileno];
+
+	switch (ipo->file_action) {
+	case FIO_LOG_OPEN_FILE:
+		ret = td_io_open_file(td, f);
+		if (!ret)
+			break;
+		td_verror(td, ret, "iolog open file");
+		return -1;
+	case FIO_LOG_CLOSE_FILE:
+		td_io_close_file(td, f);
+		break;
+	case FIO_LOG_UNLINK_FILE:
+		unlink(f->file_name);
+		break;
+	default:
+		log_err("fio: bad file action %d\n", ipo->file_action);
+		break;
+	}
+
+	return 1;
+}
+
+int read_iolog_get(struct thread_data *td, struct io_u *io_u)
+{
+	struct io_piece *ipo;
+	unsigned long elapsed;
+	
+	while (!flist_empty(&td->io_log_list)) {
+		int ret;
+
+		ipo = flist_entry(td->io_log_list.next, struct io_piece, list);
+		flist_del(&ipo->list);
+		remove_trim_entry(td, ipo);
+
+		ret = ipo_special(td, ipo);
+		if (ret < 0) {
+			free(ipo);
+			break;
+		} else if (ret > 0) {
+			free(ipo);
+			continue;
+		}
+
+		io_u->ddir = ipo->ddir;
+		if (ipo->ddir != DDIR_WAIT) {
+			io_u->offset = ipo->offset;
+			io_u->buflen = ipo->len;
+			io_u->file = td->files[ipo->fileno];
+			get_file(io_u->file);
+			dprint(FD_IO, "iolog: get %llu/%lu/%s\n", io_u->offset,
+						io_u->buflen, io_u->file->file_name);
+			if (ipo->delay)
+				iolog_delay(td, ipo->delay);
+		} else {
+			elapsed = mtime_since_genesis();
+			if (ipo->delay > elapsed)
+				usec_sleep(td, (ipo->delay - elapsed) * 1000);
+				
+		}
+
+		free(ipo);
+		
+		if (io_u->ddir != DDIR_WAIT)
+			return 0;
+	}
+
+	td->done = 1;
+	return 1;
+}
+
+void prune_io_piece_log(struct thread_data *td)
+{
+	struct io_piece *ipo;
+	struct rb_node *n;
+
+	while ((n = rb_first(&td->io_hist_tree)) != NULL) {
+		ipo = rb_entry(n, struct io_piece, rb_node);
+		rb_erase(n, &td->io_hist_tree);
+		remove_trim_entry(td, ipo);
+		td->io_hist_len--;
+		free(ipo);
+	}
+
+	while (!flist_empty(&td->io_hist_list)) {
+		ipo = flist_entry(td->io_hist_list.next, struct io_piece, list);
+		flist_del(&ipo->list);
+		remove_trim_entry(td, ipo);
+		td->io_hist_len--;
+		free(ipo);
+	}
+}
+
+/*
+ * log a successful write, so we can unwind the log for verify
+ */
+void log_io_piece(struct thread_data *td, struct io_u *io_u)
+{
+	struct rb_node **p, *parent;
+	struct io_piece *ipo, *__ipo;
+
+	ipo = malloc(sizeof(struct io_piece));
+	init_ipo(ipo);
+	ipo->file = io_u->file;
+	ipo->offset = io_u->offset;
+	ipo->len = io_u->buflen;
+
+	if (io_u_should_trim(td, io_u)) {
+		flist_add_tail(&ipo->trim_list, &td->trim_list);
+		td->trim_entries++;
+	}
+
+	/*
+	 * We don't need to sort the entries, if:
+	 *
+	 *	Sequential writes, or
+	 *	Random writes that lay out the file as it goes along
+	 *
+	 * For both these cases, just reading back data in the order we
+	 * wrote it out is the fastest.
+	 *
+	 * One exception is if we don't have a random map AND we are doing
+	 * verifies, in that case we need to check for duplicate blocks and
+	 * drop the old one, which we rely on the rb insert/lookup for
+	 * handling.
+	 */
+	if ((!td_random(td) || !td->o.overwrite) &&
+	      (file_randommap(td, ipo->file) || td->o.verify == VERIFY_NONE)) {
+		INIT_FLIST_HEAD(&ipo->list);
+		flist_add_tail(&ipo->list, &td->io_hist_list);
+		ipo->flags |= IP_F_ONLIST;
+		td->io_hist_len++;
+		return;
+	}
+
+	RB_CLEAR_NODE(&ipo->rb_node);
+
+	/*
+	 * Sort the entry into the verification list
+	 */
+restart:
+	p = &td->io_hist_tree.rb_node;
+	parent = NULL;
+	while (*p) {
+		parent = *p;
+
+		__ipo = rb_entry(parent, struct io_piece, rb_node);
+		if (ipo->file < __ipo->file)
+			p = &(*p)->rb_left;
+		else if (ipo->file > __ipo->file)
+			p = &(*p)->rb_right;
+		else if (ipo->offset < __ipo->offset)
+			p = &(*p)->rb_left;
+		else if (ipo->offset > __ipo->offset)
+			p = &(*p)->rb_right;
+		else {
+			assert(ipo->len == __ipo->len);
+			td->io_hist_len--;
+			rb_erase(parent, &td->io_hist_tree);
+			remove_trim_entry(td, __ipo);
+			free(__ipo);
+			goto restart;
+		}
+	}
+
+	rb_link_node(&ipo->rb_node, parent, p);
+	rb_insert_color(&ipo->rb_node, &td->io_hist_tree);
+	ipo->flags |= IP_F_ONRB;
+	td->io_hist_len++;
+}
+
+void write_iolog_close(struct thread_data *td)
+{
+	fflush(td->iolog_f);
+	fclose(td->iolog_f);
+	free(td->iolog_buf);
+	td->iolog_f = NULL;
+	td->iolog_buf = NULL;
+}
+
+/*
+ * Read version 2 iolog data. It is enhanced to include per-file logging,
+ * syncs, etc.
+ */
+static int read_iolog2(struct thread_data *td, FILE *f)
+{
+	unsigned long long offset;
+	unsigned int bytes;
+	int reads, writes, waits, fileno = 0, file_action = 0; /* stupid gcc */
+	char *fname, *act;
+	char *str, *p;
+	enum fio_ddir rw;
+
+	free_release_files(td);
+
+	/*
+	 * Read in the read iolog and store it, reuse the infrastructure
+	 * for doing verifications.
+	 */
+	str = malloc(4096);
+	fname = malloc(256+16);
+	act = malloc(256+16);
+
+	reads = writes = waits = 0;
+	while ((p = fgets(str, 4096, f)) != NULL) {
+		struct io_piece *ipo;
+		int r;
+
+		r = sscanf(p, "%256s %256s %llu %u", fname, act, &offset,
+									&bytes);
+		if (r == 4) {
+			/*
+			 * Check action first
+			 */
+			if (!strcmp(act, "wait"))
+				rw = DDIR_WAIT;
+			else if (!strcmp(act, "read"))
+				rw = DDIR_READ;
+			else if (!strcmp(act, "write"))
+				rw = DDIR_WRITE;
+			else if (!strcmp(act, "sync"))
+				rw = DDIR_SYNC;
+			else if (!strcmp(act, "datasync"))
+				rw = DDIR_DATASYNC;
+			else if (!strcmp(act, "trim"))
+				rw = DDIR_TRIM;
+			else {
+				log_err("fio: bad iolog file action: %s\n",
+									act);
+				continue;
+			}
+		} else if (r == 2) {
+			rw = DDIR_INVAL;
+			if (!strcmp(act, "add")) {
+				td->o.nr_files++;
+				fileno = add_file(td, fname);
+				file_action = FIO_LOG_ADD_FILE;
+				continue;
+			} else if (!strcmp(act, "open")) {
+				fileno = get_fileno(td, fname);
+				file_action = FIO_LOG_OPEN_FILE;
+			} else if (!strcmp(act, "close")) {
+				fileno = get_fileno(td, fname);
+				file_action = FIO_LOG_CLOSE_FILE;
+			} else {
+				log_err("fio: bad iolog file action: %s\n",
+									act);
+				continue;
+			}
+		} else {
+			log_err("bad iolog2: %s", p);
+			continue;
+		}
+
+		if (rw == DDIR_READ)
+			reads++;
+		else if (rw == DDIR_WRITE) {
+			/*
+			 * Don't add a write for ro mode
+			 */
+			if (read_only)
+				continue;
+			writes++;
+		} else if (rw == DDIR_WAIT) {
+			waits++;
+		} else if (rw == DDIR_INVAL) {
+		} else if (!ddir_sync(rw)) {
+			log_err("bad ddir: %d\n", rw);
+			continue;
+		}
+
+		/*
+		 * Make note of file
+		 */
+		ipo = malloc(sizeof(*ipo));
+		init_ipo(ipo);
+		ipo->ddir = rw;
+		if (rw == DDIR_WAIT) {
+			ipo->delay = offset;
+		} else {
+			ipo->offset = offset;
+			ipo->len = bytes;
+			if (bytes > td->o.max_bs[rw])
+				td->o.max_bs[rw] = bytes;
+			ipo->fileno = fileno;
+			ipo->file_action = file_action;
+		}
+			
+		queue_io_piece(td, ipo);
+	}
+
+	free(str);
+	free(act);
+	free(fname);
+
+	if (writes && read_only) {
+		log_err("fio: <%s> skips replay of %d writes due to"
+			" read-only\n", td->o.name, writes);
+		writes = 0;
+	}
+
+	if (!reads && !writes && !waits)
+		return 1;
+	else if (reads && !writes)
+		td->o.td_ddir = TD_DDIR_READ;
+	else if (!reads && writes)
+		td->o.td_ddir = TD_DDIR_WRITE;
+	else
+		td->o.td_ddir = TD_DDIR_RW;
+
+	return 0;
+}
+
+/*
+ * open iolog, check version, and call appropriate parser
+ */
+static int init_iolog_read(struct thread_data *td)
+{
+	char buffer[256], *p;
+	FILE *f;
+	int ret;
+
+	f = fopen(td->o.read_iolog_file, "r");
+	if (!f) {
+		perror("fopen read iolog");
+		return 1;
+	}
+
+	p = fgets(buffer, sizeof(buffer), f);
+	if (!p) {
+		td_verror(td, errno, "iolog read");
+		log_err("fio: unable to read iolog\n");
+		fclose(f);
+		return 1;
+	}
+
+	/*
+	 * version 2 of the iolog stores a specific string as the
+	 * first line, check for that
+	 */
+	if (!strncmp(iolog_ver2, buffer, strlen(iolog_ver2)))
+		ret = read_iolog2(td, f);
+	else {
+		log_err("fio: iolog version 1 is no longer supported\n");
+		ret = 1;
+	}
+
+	fclose(f);
+	return ret;
+}
+
+/*
+ * Set up a log for storing io patterns.
+ */
+static int init_iolog_write(struct thread_data *td)
+{
+	struct fio_file *ff;
+	FILE *f;
+	unsigned int i;
+
+	f = fopen(td->o.write_iolog_file, "a");
+	if (!f) {
+		perror("fopen write iolog");
+		return 1;
+	}
+
+	/*
+	 * That's it for writing, setup a log buffer and we're done.
+	  */
+	td->iolog_f = f;
+	td->iolog_buf = malloc(8192);
+	setvbuf(f, td->iolog_buf, _IOFBF, 8192);
+
+	/*
+	 * write our version line
+	 */
+	if (fprintf(f, "%s\n", iolog_ver2) < 0) {
+		perror("iolog init\n");
+		return 1;
+	}
+
+	/*
+	 * add all known files
+	 */
+	for_each_file(td, ff, i)
+		log_file(td, ff, FIO_LOG_ADD_FILE);
+
+	return 0;
+}
+
+int init_iolog(struct thread_data *td)
+{
+	int ret = 0;
+
+	if (td->o.read_iolog_file) {
+		/*
+		 * Check if it's a blktrace file and load that if possible.
+		 * Otherwise assume it's a normal log file and load that.
+		 */
+		if (is_blktrace(td->o.read_iolog_file))
+			ret = load_blktrace(td, td->o.read_iolog_file);
+		else
+			ret = init_iolog_read(td);
+	} else if (td->o.write_iolog_file)
+		ret = init_iolog_write(td);
+
+	return ret;
+}
+
+void setup_log(struct io_log **log)
+{
+	struct io_log *l = malloc(sizeof(*l));
+
+	l->nr_samples = 0;
+	l->max_samples = 1024;
+	l->log = malloc(l->max_samples * sizeof(struct io_sample));
+	*log = l;
+}
+
+void __finish_log(struct io_log *log, const char *name)
+{
+	unsigned int i;
+	FILE *f;
+
+	f = fopen(name, "a");
+	if (!f) {
+		perror("fopen log");
+		return;
+	}
+
+	for (i = 0; i < log->nr_samples; i++) {
+		fprintf(f, "%lu, %lu, %u, %u\n", log->log[i].time,
+						log->log[i].val,
+						log->log[i].ddir,
+						log->log[i].bs);
+	}
+
+	fclose(f);
+	free(log->log);
+	free(log);
+}
+
+void finish_log_named(struct thread_data *td, struct io_log *log,
+		       const char *prefix, const char *postfix)
+{
+	char file_name[256], *p;
+
+	snprintf(file_name, 200, "%s_%s.log", prefix, postfix);
+	p = basename(file_name);
+	__finish_log(log, p);
+}
+
+void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+{
+	finish_log_named(td, log, td->o.name, name);
+}
diff --git a/iolog.h b/iolog.h
index c35ce1e..53bb66c 100644
--- a/iolog.h
+++ b/iolog.h
@@ -1,16 +1,18 @@
 #ifndef FIO_IOLOG_H
 #define FIO_IOLOG_H
 
+#include "lib/ieee754.h"
+
 /*
  * Use for maintaining statistics
  */
 struct io_stat {
-	unsigned long max_val;
-	unsigned long min_val;
-	unsigned long samples;
+	uint64_t max_val;
+	uint64_t min_val;
+	uint64_t samples;
 
-	double mean;
-	double S;
+	fio_fp64_t mean;
+	fio_fp64_t S;
 };
 
 /*
@@ -91,7 +93,7 @@ extern void add_slat_sample(struct thread_data *, enum fio_ddir, unsigned long,
 				unsigned int);
 extern void add_bw_sample(struct thread_data *, enum fio_ddir, unsigned int,
 				struct timeval *);
-extern void show_run_stats(void);
+extern void add_iops_sample(struct thread_data *, enum fio_ddir, struct timeval *);
 extern void init_disk_util(struct thread_data *);
 extern void update_rusage_stat(struct thread_data *);
 extern void update_io_ticks(void);
diff --git a/lib/ieee754.c b/lib/ieee754.c
new file mode 100644
index 0000000..c7742a2
--- /dev/null
+++ b/lib/ieee754.c
@@ -0,0 +1,84 @@
+/*
+ * Shamelessly lifted from Beej's Guide to Network Programming, found here:
+ *
+ * http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#serialization
+ *
+ * Below code was granted to the public domain.
+ */
+#include <inttypes.h>
+#include "ieee754.h"
+
+uint64_t pack754(long double f, unsigned bits, unsigned expbits)
+{
+	long double fnorm;
+	int shift;
+	long long sign, exp, significand;
+	unsigned significandbits = bits - expbits - 1; // -1 for sign bit
+
+	// get this special case out of the way
+	if (f == 0.0)
+		return 0;
+
+	// check sign and begin normalization
+	if (f < 0) {
+		sign = 1;
+		fnorm = -f;
+	} else {
+		sign = 0;
+		fnorm = f;
+	}
+
+	// get the normalized form of f and track the exponent
+	shift = 0;
+	while (fnorm >= 2.0) {
+		fnorm /= 2.0;
+		shift++;
+	}
+	while (fnorm < 1.0) {
+		fnorm *= 2.0;
+		shift--;
+	}
+	fnorm = fnorm - 1.0;
+
+	// calculate the binary form (non-float) of the significand data
+	significand = fnorm * ((1LL << significandbits) + 0.5f);
+
+	// get the biased exponent
+	exp = shift + ((1 << (expbits - 1)) - 1); // shift + bias
+
+	// return the final answer
+	return (sign << (bits - 1)) | (exp << (bits-expbits - 1)) | significand;
+}
+
+long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
+{
+	long double result;
+	long long shift;
+	unsigned bias;
+	unsigned significandbits = bits - expbits - 1; // -1 for sign bit
+
+	if (i == 0)
+		return 0.0;
+
+	// pull the significand
+	result = (i & ((1LL << significandbits) - 1)); // mask
+	result /= (1LL << significandbits); // convert back to float
+	result += 1.0f; // add the one back on
+
+	// deal with the exponent
+	bias = (1 << (expbits - 1)) - 1;
+	shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
+	while (shift > 0) {
+		result *= 2.0;
+		shift--;
+	}
+	while (shift < 0) {
+		result /= 2.0;
+		shift++;
+	}
+
+	// sign it
+	result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;
+
+	return result;
+}
diff --git a/lib/ieee754.h b/lib/ieee754.h
new file mode 100644
index 0000000..5af9518
--- /dev/null
+++ b/lib/ieee754.h
@@ -0,0 +1,20 @@
+#ifndef FIO_IEEE754_H
+#define FIO_IEEE754_H
+
+#include <inttypes.h>
+
+extern uint64_t pack754(long double f, unsigned bits, unsigned expbits);
+extern long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
+
+#define fio_double_to_uint64(val)	pack754((val), 64, 11)
+#define fio_uint64_to_double(val)	unpack754((val), 64, 11)
+
+typedef struct fio_fp64 {
+	union {
+		uint64_t i;
+		double f;
+		uint8_t filler[16];
+	} u;
+} fio_fp64_t;
+
+#endif
diff --git a/log.c b/log.c
index f962864..af974f8 100644
--- a/log.c
+++ b/log.c
@@ -1,541 +1,95 @@
-/*
- * Code related to writing an iolog of what a thread is doing, and to
- * later read that back and replay
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <libgen.h>
-#include <assert.h>
-#include "flist.h"
-#include "fio.h"
-#include "verify.h"
-#include "trim.h"
-
-static const char iolog_ver2[] = "fio version 2 iolog";
-
-void queue_io_piece(struct thread_data *td, struct io_piece *ipo)
-{
-	flist_add_tail(&ipo->list, &td->io_log_list);
-	td->total_io_size += ipo->len;
-}
-
-void log_io_u(struct thread_data *td, struct io_u *io_u)
-{
-	const char *act[] = { "read", "write", "sync", "datasync",
-				"sync_file_range", "wait", "trim" };
-
-	assert(io_u->ddir <= 6);
-
-	if (!td->o.write_iolog_file)
-		return;
-
-	fprintf(td->iolog_f, "%s %s %llu %lu\n", io_u->file->file_name,
-						act[io_u->ddir], io_u->offset,
-						io_u->buflen);
-}
-
-void log_file(struct thread_data *td, struct fio_file *f,
-	      enum file_log_act what)
-{
-	const char *act[] = { "add", "open", "close" };
-
-	assert(what < 3);
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdarg.h>
+#include <syslog.h>
 
-	if (!td->o.write_iolog_file)
-		return;
-
-
-	/*
-	 * this happens on the pre-open/close done before the job starts
-	 */
-	if (!td->iolog_f)
-		return;
-
-	fprintf(td->iolog_f, "%s %s\n", f->file_name, act[what]);
-}
-
-static void iolog_delay(struct thread_data *td, unsigned long delay)
-{
-	unsigned long usec = utime_since_now(&td->last_issue);
-
-	if (delay < usec)
-		return;
-
-	delay -= usec;
-
-	/*
-	 * less than 100 usec delay, just regard it as noise
-	 */
-	if (delay < 100)
-		return;
-
-	usec_sleep(td, delay);
-}
-
-static int ipo_special(struct thread_data *td, struct io_piece *ipo)
-{
-	struct fio_file *f;
-	int ret;
-
-	/*
-	 * Not a special ipo
-	 */
-	if (ipo->ddir != DDIR_INVAL)
-		return 0;
-
-	f = td->files[ipo->fileno];
-
-	switch (ipo->file_action) {
-	case FIO_LOG_OPEN_FILE:
-		ret = td_io_open_file(td, f);
-		if (!ret)
-			break;
-		td_verror(td, ret, "iolog open file");
-		return -1;
-	case FIO_LOG_CLOSE_FILE:
-		td_io_close_file(td, f);
-		break;
-	case FIO_LOG_UNLINK_FILE:
-		unlink(f->file_name);
-		break;
-	default:
-		log_err("fio: bad file action %d\n", ipo->file_action);
-		break;
-	}
-
-	return 1;
-}
-
-int read_iolog_get(struct thread_data *td, struct io_u *io_u)
-{
-	struct io_piece *ipo;
-	unsigned long elapsed;
-	
-	while (!flist_empty(&td->io_log_list)) {
-		int ret;
-
-		ipo = flist_entry(td->io_log_list.next, struct io_piece, list);
-		flist_del(&ipo->list);
-		remove_trim_entry(td, ipo);
-
-		ret = ipo_special(td, ipo);
-		if (ret < 0) {
-			free(ipo);
-			break;
-		} else if (ret > 0) {
-			free(ipo);
-			continue;
-		}
-
-		io_u->ddir = ipo->ddir;
-		if (ipo->ddir != DDIR_WAIT) {
-			io_u->offset = ipo->offset;
-			io_u->buflen = ipo->len;
-			io_u->file = td->files[ipo->fileno];
-			get_file(io_u->file);
-			dprint(FD_IO, "iolog: get %llu/%lu/%s\n", io_u->offset,
-						io_u->buflen, io_u->file->file_name);
-			if (ipo->delay)
-				iolog_delay(td, ipo->delay);
-		} else {
-			elapsed = mtime_since_genesis();
-			if (ipo->delay > elapsed)
-				usec_sleep(td, (ipo->delay - elapsed) * 1000);
-				
-		}
-
-		free(ipo);
-		
-		if (io_u->ddir != DDIR_WAIT)
-			return 0;
-	}
-
-	td->done = 1;
-	return 1;
-}
-
-void prune_io_piece_log(struct thread_data *td)
-{
-	struct io_piece *ipo;
-	struct rb_node *n;
-
-	while ((n = rb_first(&td->io_hist_tree)) != NULL) {
-		ipo = rb_entry(n, struct io_piece, rb_node);
-		rb_erase(n, &td->io_hist_tree);
-		remove_trim_entry(td, ipo);
-		td->io_hist_len--;
-		free(ipo);
-	}
-
-	while (!flist_empty(&td->io_hist_list)) {
-		ipo = flist_entry(td->io_hist_list.next, struct io_piece, list);
-		flist_del(&ipo->list);
-		remove_trim_entry(td, ipo);
-		td->io_hist_len--;
-		free(ipo);
-	}
-}
-
-/*
- * log a successful write, so we can unwind the log for verify
- */
-void log_io_piece(struct thread_data *td, struct io_u *io_u)
-{
-	struct rb_node **p, *parent;
-	struct io_piece *ipo, *__ipo;
-
-	ipo = malloc(sizeof(struct io_piece));
-	init_ipo(ipo);
-	ipo->file = io_u->file;
-	ipo->offset = io_u->offset;
-	ipo->len = io_u->buflen;
-
-	if (io_u_should_trim(td, io_u)) {
-		flist_add_tail(&ipo->trim_list, &td->trim_list);
-		td->trim_entries++;
-	}
-
-	/*
-	 * We don't need to sort the entries, if:
-	 *
-	 *	Sequential writes, or
-	 *	Random writes that lay out the file as it goes along
-	 *
-	 * For both these cases, just reading back data in the order we
-	 * wrote it out is the fastest.
-	 *
-	 * One exception is if we don't have a random map AND we are doing
-	 * verifies, in that case we need to check for duplicate blocks and
-	 * drop the old one, which we rely on the rb insert/lookup for
-	 * handling.
-	 */
-	if ((!td_random(td) || !td->o.overwrite) &&
-	      (file_randommap(td, ipo->file) || td->o.verify == VERIFY_NONE)) {
-		INIT_FLIST_HEAD(&ipo->list);
-		flist_add_tail(&ipo->list, &td->io_hist_list);
-		ipo->flags |= IP_F_ONLIST;
-		td->io_hist_len++;
-		return;
-	}
-
-	RB_CLEAR_NODE(&ipo->rb_node);
-
-	/*
-	 * Sort the entry into the verification list
-	 */
-restart:
-	p = &td->io_hist_tree.rb_node;
-	parent = NULL;
-	while (*p) {
-		parent = *p;
-
-		__ipo = rb_entry(parent, struct io_piece, rb_node);
-		if (ipo->file < __ipo->file)
-			p = &(*p)->rb_left;
-		else if (ipo->file > __ipo->file)
-			p = &(*p)->rb_right;
-		else if (ipo->offset < __ipo->offset)
-			p = &(*p)->rb_left;
-		else if (ipo->offset > __ipo->offset)
-			p = &(*p)->rb_right;
-		else {
-			assert(ipo->len == __ipo->len);
-			td->io_hist_len--;
-			rb_erase(parent, &td->io_hist_tree);
-			remove_trim_entry(td, __ipo);
-			free(__ipo);
-			goto restart;
-		}
-	}
-
-	rb_link_node(&ipo->rb_node, parent, p);
-	rb_insert_color(&ipo->rb_node, &td->io_hist_tree);
-	ipo->flags |= IP_F_ONRB;
-	td->io_hist_len++;
-}
-
-void write_iolog_close(struct thread_data *td)
-{
-	fflush(td->iolog_f);
-	fclose(td->iolog_f);
-	free(td->iolog_buf);
-	td->iolog_f = NULL;
-	td->iolog_buf = NULL;
-}
+#include "fio.h"
 
-/*
- * Read version 2 iolog data. It is enhanced to include per-file logging,
- * syncs, etc.
- */
-static int read_iolog2(struct thread_data *td, FILE *f)
+int log_valist(const char *str, va_list args)
 {
-	unsigned long long offset;
-	unsigned int bytes;
-	int reads, writes, waits, fileno = 0, file_action = 0; /* stupid gcc */
-	char *fname, *act;
-	char *str, *p;
-	enum fio_ddir rw;
-
-	free_release_files(td);
-
-	/*
-	 * Read in the read iolog and store it, reuse the infrastructure
-	 * for doing verifications.
-	 */
-	str = malloc(4096);
-	fname = malloc(256+16);
-	act = malloc(256+16);
-
-	reads = writes = waits = 0;
-	while ((p = fgets(str, 4096, f)) != NULL) {
-		struct io_piece *ipo;
-		int r;
-
-		r = sscanf(p, "%256s %256s %llu %u", fname, act, &offset,
-									&bytes);
-		if (r == 4) {
-			/*
-			 * Check action first
-			 */
-			if (!strcmp(act, "wait"))
-				rw = DDIR_WAIT;
-			else if (!strcmp(act, "read"))
-				rw = DDIR_READ;
-			else if (!strcmp(act, "write"))
-				rw = DDIR_WRITE;
-			else if (!strcmp(act, "sync"))
-				rw = DDIR_SYNC;
-			else if (!strcmp(act, "datasync"))
-				rw = DDIR_DATASYNC;
-			else if (!strcmp(act, "trim"))
-				rw = DDIR_TRIM;
-			else {
-				log_err("fio: bad iolog file action: %s\n",
-									act);
-				continue;
-			}
-		} else if (r == 2) {
-			rw = DDIR_INVAL;
-			if (!strcmp(act, "add")) {
-				td->o.nr_files++;
-				fileno = add_file(td, fname);
-				file_action = FIO_LOG_ADD_FILE;
-				continue;
-			} else if (!strcmp(act, "open")) {
-				fileno = get_fileno(td, fname);
-				file_action = FIO_LOG_OPEN_FILE;
-			} else if (!strcmp(act, "close")) {
-				fileno = get_fileno(td, fname);
-				file_action = FIO_LOG_CLOSE_FILE;
-			} else {
-				log_err("fio: bad iolog file action: %s\n",
-									act);
-				continue;
-			}
-		} else {
-			log_err("bad iolog2: %s", p);
-			continue;
-		}
-
-		if (rw == DDIR_READ)
-			reads++;
-		else if (rw == DDIR_WRITE) {
-			/*
-			 * Don't add a write for ro mode
-			 */
-			if (read_only)
-				continue;
-			writes++;
-		} else if (rw == DDIR_WAIT) {
-			waits++;
-		} else if (rw == DDIR_INVAL) {
-		} else if (!ddir_sync(rw)) {
-			log_err("bad ddir: %d\n", rw);
-			continue;
-		}
-
-		/*
-		 * Make note of file
-		 */
-		ipo = malloc(sizeof(*ipo));
-		init_ipo(ipo);
-		ipo->ddir = rw;
-		if (rw == DDIR_WAIT) {
-			ipo->delay = offset;
-		} else {
-			ipo->offset = offset;
-			ipo->len = bytes;
-			if (bytes > td->o.max_bs[rw])
-				td->o.max_bs[rw] = bytes;
-			ipo->fileno = fileno;
-			ipo->file_action = file_action;
-		}
-			
-		queue_io_piece(td, ipo);
-	}
+	char buffer[1024];
+	size_t len;
 
-	free(str);
-	free(act);
-	free(fname);
+	len = vsnprintf(buffer, sizeof(buffer), str, args);
 
-	if (writes && read_only) {
-		log_err("fio: <%s> skips replay of %d writes due to"
-			" read-only\n", td->o.name, writes);
-		writes = 0;
-	}
-
-	if (!reads && !writes && !waits)
-		return 1;
-	else if (reads && !writes)
-		td->o.td_ddir = TD_DDIR_READ;
-	else if (!reads && writes)
-		td->o.td_ddir = TD_DDIR_WRITE;
+	if (log_syslog)
+		syslog(LOG_INFO, "%s", buffer);
 	else
-		td->o.td_ddir = TD_DDIR_RW;
+		len = fwrite(buffer, len, 1, f_out);
 
-	return 0;
+	return len;
 }
 
-/*
- * open iolog, check version, and call appropriate parser
- */
-static int init_iolog_read(struct thread_data *td)
+int log_local_buf(const char *buf, size_t len)
 {
-	char buffer[256], *p;
-	FILE *f;
-	int ret;
-
-	f = fopen(td->o.read_iolog_file, "r");
-	if (!f) {
-		perror("fopen read iolog");
-		return 1;
-	}
-
-	p = fgets(buffer, sizeof(buffer), f);
-	if (!p) {
-		td_verror(td, errno, "iolog read");
-		log_err("fio: unable to read iolog\n");
-		fclose(f);
-		return 1;
-	}
-
-	/*
-	 * version 2 of the iolog stores a specific string as the
-	 * first line, check for that
-	 */
-	if (!strncmp(iolog_ver2, buffer, strlen(iolog_ver2)))
-		ret = read_iolog2(td, f);
-	else {
-		log_err("fio: iolog version 1 is no longer supported\n");
-		ret = 1;
-	}
+	if (log_syslog)
+		syslog(LOG_INFO, "%s", buf);
+	else
+		len = fwrite(buf, len, 1, f_out);
 
-	fclose(f);
-	return ret;
+	return len;
 }
 
-/*
- * Set up a log for storing io patterns.
- */
-static int init_iolog_write(struct thread_data *td)
+int log_local(const char *format, ...)
 {
-	struct fio_file *ff;
-	FILE *f;
-	unsigned int i;
-
-	f = fopen(td->o.write_iolog_file, "a");
-	if (!f) {
-		perror("fopen write iolog");
-		return 1;
-	}
-
-	/*
-	 * That's it for writing, setup a log buffer and we're done.
-	  */
-	td->iolog_f = f;
-	td->iolog_buf = malloc(8192);
-	setvbuf(f, td->iolog_buf, _IOFBF, 8192);
+	char buffer[1024];
+	va_list args;
+	size_t len;
 
-	/*
-	 * write our version line
-	 */
-	if (fprintf(f, "%s\n", iolog_ver2) < 0) {
-		perror("iolog init\n");
-		return 1;
-	}
+	va_start(args, format);
+	len = vsnprintf(buffer, sizeof(buffer), format, args);
+	va_end(args);
 
-	/*
-	 * add all known files
-	 */
-	for_each_file(td, ff, i)
-		log_file(td, ff, FIO_LOG_ADD_FILE);
+	if (log_syslog)
+		syslog(LOG_INFO, "%s", buffer);
+	else
+		len = fwrite(buffer, len, 1, f_out);
 
-	return 0;
+	return len;
 }
 
-int init_iolog(struct thread_data *td)
+int log_info(const char *format, ...)
 {
-	int ret = 0;
+	char buffer[1024];
+	va_list args;
+	size_t len;
 
-	if (td->o.read_iolog_file) {
-		/*
-		 * Check if it's a blktrace file and load that if possible.
-		 * Otherwise assume it's a normal log file and load that.
-		 */
-		if (is_blktrace(td->o.read_iolog_file))
-			ret = load_blktrace(td, td->o.read_iolog_file);
-		else
-			ret = init_iolog_read(td);
-	} else if (td->o.write_iolog_file)
-		ret = init_iolog_write(td);
+	va_start(args, format);
+	len = vsnprintf(buffer, sizeof(buffer), format, args);
+	va_end(args);
 
-	return ret;
+	if (is_backend)
+		return fio_server_text_output(buffer, len);
+	else if (log_syslog) {
+		syslog(LOG_INFO, "%s", buffer);
+		return len;
+	} else
+		return fwrite(buffer, len, 1, f_out);
 }
 
-void setup_log(struct io_log **log)
+int log_err(const char *format, ...)
 {
-	struct io_log *l = malloc(sizeof(*l));
+	char buffer[1024];
+	va_list args;
+	size_t len;
 
-	l->nr_samples = 0;
-	l->max_samples = 1024;
-	l->log = malloc(l->max_samples * sizeof(struct io_sample));
-	*log = l;
-}
+	va_start(args, format);
+	len = vsnprintf(buffer, sizeof(buffer), format, args);
+	va_end(args);
 
-void __finish_log(struct io_log *log, const char *name)
-{
-	unsigned int i;
-	FILE *f;
+	if (is_backend)
+		return fio_server_text_output(buffer, len);
+	else if (log_syslog) {
+		syslog(LOG_INFO, "%s", buffer);
+		return len;
+	} else {
+		if (f_err != stderr) {
+			int fio_unused ret;
 
-	f = fopen(name, "a");
-	if (!f) {
-		perror("fopen log");
-		return;
-	}
+			ret = fwrite(buffer, len, 1, stderr);
+		}
 
-	for (i = 0; i < log->nr_samples; i++) {
-		fprintf(f, "%lu, %lu, %u, %u\n", log->log[i].time,
-						log->log[i].val,
-						log->log[i].ddir,
-						log->log[i].bs);
+		return fwrite(buffer, len, 1, f_err);
 	}
-
-	fclose(f);
-	free(log->log);
-	free(log);
-}
-
-void finish_log_named(struct thread_data *td, struct io_log *log,
-		       const char *prefix, const char *postfix)
-{
-	char file_name[256], *p;
-
-	snprintf(file_name, 200, "%s_%s.log", prefix, postfix);
-	p = basename(file_name);
-	__finish_log(log, p);
-}
-
-void finish_log(struct thread_data *td, struct io_log *log, const char *name)
-{
-	finish_log_named(td, log, td->o.name, name);
 }
diff --git a/log.h b/log.h
index eea1129..fdf3d7b 100644
--- a/log.h
+++ b/log.h
@@ -2,23 +2,15 @@
 #define FIO_LOG_H
 
 #include <stdio.h>
+#include <stdarg.h>
 
 extern FILE *f_out;
 extern FILE *f_err;
 
-/*
- * If logging output to a file, stderr should go to both stderr and f_err
- */
-#define log_err(args, ...)	do {				\
-	fprintf(f_err, args,  ##__VA_ARGS__);		\
-	if (f_err != stderr)						\
-		fprintf(stderr, args,  ##__VA_ARGS__);	\
-	} while (0)
-
-#define log_info(args, ...)	fprintf(f_out, args, ##__VA_ARGS__)
-#define log_valist(str, args)	vfprintf(f_out, (str), (args))
-
-FILE *get_f_out(void);
-FILE *get_f_err(void);
+extern int log_err(const char *format, ...);
+extern int log_info(const char *format, ...);
+extern int log_local(const char *format, ...);
+extern int log_valist(const char *str, va_list);
+extern int log_local_buf(const char *buf, size_t);
 
 #endif
diff --git a/options.c b/options.c
index 5252477..48bb2a4 100644
--- a/options.c
+++ b/options.c
@@ -595,6 +595,14 @@ static char *get_next_file_name(char **ptr)
 	return start;
 }
 
+static int str_hostname_cb(void *data, const char *input)
+{
+	struct thread_data *td = data;
+
+	td->o.filename = strdup(input);
+	return 0;
+}
+
 static int str_filename_cb(void *data, const char *input)
 {
 	struct thread_data *td = data;
@@ -749,6 +757,17 @@ static int str_write_lat_log_cb(void *data, const char *str)
 	return 0;
 }
 
+static int str_write_iops_log_cb(void *data, const char *str)
+{
+	struct thread_data *td = data;
+
+	if (str)
+		td->o.iops_log_file = strdup(str);
+
+	td->o.write_iops_log = 1;
+	return 0;
+}
+
 static int str_gtod_reduce_cb(void *data, int *il)
 {
 	struct thread_data *td = data;
@@ -758,6 +777,7 @@ static int str_gtod_reduce_cb(void *data, int *il)
 	td->o.disable_clat = !!val;
 	td->o.disable_slat = !!val;
 	td->o.disable_bw = !!val;
+	td->o.clat_percentiles = !val;
 	if (val)
 		td->tv_cache_mask = 63;
 
@@ -829,9 +849,6 @@ static int kb_base_verify(struct fio_option *o, void *data)
 	return 0;
 }
 
-#define __stringify_1(x)	#x
-#define __stringify(x)		__stringify_1(x)
-
 /*
  * Map of job/command line options
  */
@@ -864,6 +881,12 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.help	= "File(s) to use for the workload",
 	},
 	{
+		.name	= "hostname",
+		.type	= FIO_OPT_STR_STORE,
+		.cb	= str_hostname_cb,
+		.help	= "Hostname for net IO engine",
+	},
+	{
 		.name	= "kb_base",
 		.type	= FIO_OPT_INT,
 		.off1	= td_var_offset(kb_base),
@@ -1824,6 +1847,15 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.help	= "Time window over which to calculate bandwidth"
 			  " (msec)",
 		.def	= "500",
+		.parent	= "write_bw_log",
+	},
+	{
+		.name	= "iopsavgtime",
+		.type	= FIO_OPT_INT,
+		.off1	= td_var_offset(iops_avg_time),
+		.help	= "Time window over which to calculate IOPS (msec)",
+		.def	= "500",
+		.parent	= "write_iops_log",
 	},
 	{
 		.name	= "create_serialize",
@@ -1942,11 +1974,18 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.help	= "Write log of latency during run",
 	},
 	{
+		.name	= "write_iops_log",
+		.type	= FIO_OPT_STR,
+		.off1	= td_var_offset(write_iops_log),
+		.cb	= str_write_iops_log_cb,
+		.help	= "Write log of IOPS during run",
+	},
+	{
 		.name	= "hugepage-size",
 		.type	= FIO_OPT_INT,
 		.off1	= td_var_offset(hugepage_size),
 		.help	= "When using hugepages, specify size of each page",
-		.def	= __stringify(FIO_HUGE_PAGE),
+		.def	= __fio_stringify(FIO_HUGE_PAGE),
 	},
 	{
 		.name	= "group_reporting",
@@ -1978,7 +2017,7 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.type	= FIO_OPT_BOOL,
 		.off1	= td_var_offset(clat_percentiles),
 		.help	= "Enable the reporting of completion latency percentiles",
-		.def	= "0",
+		.def	= "1",
 	},
 	{
 		.name	= "percentile_list",
diff --git a/os/os-aix.h b/os/os-aix.h
index 91c8bcd..2f75bf8 100644
--- a/os/os-aix.h
+++ b/os/os-aix.h
@@ -1,6 +1,8 @@
 #ifndef FIO_OS_AIX_H
 #define FIO_OS_AIX_H
 
+#define	FIO_OS	os_aix
+
 #include <errno.h>
 #include <unistd.h>
 #include <sys/devinfo.h>
@@ -25,6 +27,17 @@
 #define OS_MAP_ANON		MAP_ANON
 #define OS_MSG_DONTWAIT		0
 
+#if BYTE_ORDER == BIG_ENDIAN
+#define FIO_BIG_ENDIAN
+#else
+#define FIO_LITTLE_ENDIAN
+#endif
+
+#define FIO_USE_GENERIC_SWAP
+
+#define FIO_OS_HAVE_SOCKLEN_T
+#define fio_socklen_t socklen_t
+
 static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
 	return EINVAL;
diff --git a/os/os-freebsd.h b/os/os-freebsd.h
index 317d403..93205c3 100644
--- a/os/os-freebsd.h
+++ b/os/os-freebsd.h
@@ -1,10 +1,14 @@
 #ifndef FIO_OS_FREEBSD_H
 #define FIO_OS_FREEBSD_H
 
+#define	FIO_OS	os_freebsd
+
 #include <errno.h>
 #include <sys/sysctl.h>
 #include <sys/disk.h>
 #include <sys/thr.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
 
 #include "../file.h"
 
@@ -18,6 +22,16 @@
 
 #define OS_MAP_ANON		MAP_ANON
 
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define FIO_LITTLE_ENDIAN
+#else
+#define FIO_BIG_ENDIAN
+#endif
+
+#define fio_swap16(x)	bswap16(x)
+#define fio_swap32(x)	bswap32(x)
+#define fio_swap64(x)	bswap64(x)
+
 typedef off_t off64_t;
 
 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)
diff --git a/os/os-hpux.h b/os/os-hpux.h
index 4353a01..5943938 100644
--- a/os/os-hpux.h
+++ b/os/os-hpux.h
@@ -1,6 +1,8 @@
 #ifndef FIO_OS_HPUX_H
 #define FIO_OS_HPUX_H
 
+#define	FIO_OS	os_hpux
+
 #include <errno.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
@@ -13,6 +15,7 @@
 #include <sys/pstat.h>
 #include <time.h>
 #include <aio.h>
+#include <arm.h>
 
 #include "../file.h"
 
@@ -43,9 +46,20 @@
 #define MSG_WAITALL	0x40
 #endif
 
+#ifdef LITTLE_ENDIAN
+#define FIO_LITTLE_ENDIAN
+#else
+#define FIO_BIG_ENDIAN
+#endif
+
+#define FIO_USE_GENERIC_SWAP
+
 #define FIO_OS_HAVE_AIOCB_TYPEDEF
 typedef struct aiocb64 os_aiocb_t;
 
+#define FIO_OS_HAVE_SOCKLEN_T
+typedef int fio_socklen_t;
+
 static inline int blockdev_invalidate_cache(struct fio_file *f)
 {
 	return EINVAL;
diff --git a/os/os-linux.h b/os/os-linux.h
index a36552b..9f547ff 100644
--- a/os/os-linux.h
+++ b/os/os-linux.h
@@ -1,6 +1,8 @@
 #ifndef FIO_OS_LINUX_H
 #define FIO_OS_LINUX_H
 
+#define	FIO_OS	os_linux
+
 #include <sys/ioctl.h>
 #include <sys/uio.h>
 #include <sys/syscall.h>
@@ -12,6 +14,7 @@
 #include <linux/unistd.h>
 #include <linux/raw.h>
 #include <linux/major.h>
+#include <endian.h>
 
 #include "indirect.h"
 #include "binject.h"
@@ -89,8 +92,8 @@ typedef struct drand48_data os_random_state_t;
 	sched_getaffinity((pid), (ptr))
 #endif
 
-#define fio_cpu_clear(mask, cpu)	CPU_CLR((cpu), (mask))
-#define fio_cpu_set(mask, cpu)		CPU_SET((cpu), (mask))
+#define fio_cpu_clear(mask, cpu)	(void) CPU_CLR((cpu), (mask))
+#define fio_cpu_set(mask, cpu)		(void) CPU_SET((cpu), (mask))
 
 static inline int fio_cpuset_init(os_cpu_mask_t *mask)
 {
@@ -286,6 +289,18 @@ static inline int fio_lookup_raw(dev_t dev, int *majdev, int *mindev)
 #define FIO_MADV_FREE	MADV_REMOVE
 #endif
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define FIO_LITTLE_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define FIO_BIG_ENDIAN
+#else
+#error "Unknown endianness"
+#endif
+
+#define fio_swap16(x)	__bswap_16(x)
+#define fio_swap32(x)	__bswap_32(x)
+#define fio_swap64(x)	__bswap_64(x)
+
 #define CACHE_LINE_FILE	\
 	"/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size"
 
diff --git a/os/os-mac.h b/os/os-mac.h
index eb55cd7..80c49f4 100644
--- a/os/os-mac.h
+++ b/os/os-mac.h
@@ -1,6 +1,8 @@
 #ifndef FIO_OS_APPLE_H
 #define FIO_OS_APPLE_H
 
+#define	FIO_OS	os_mac
+
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/disk.h>
@@ -9,6 +11,8 @@
 #include <unistd.h>
 #include <signal.h>
 #include <mach/mach_init.h>
+#include <machine/endian.h>
+#include <libkern/OSByteOrder.h>
 
 #include "../file.h"
 
@@ -28,6 +32,18 @@
 
 #define OS_MAP_ANON		MAP_ANON
 
+#if defined(__LITTLE_ENDIAN__)
+#define FIO_LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN__)
+#define FIO_BIG_ENDIAN
+#else
+#error "Undefined byte order"
+#endif
+
+#define fio_swap16(x)	OSSwapInt16(x)
+#define fio_swap32(x)	OSSwapInt32(x)
+#define fio_swap64(x)	OSSwapInt64(x)
+
 /*
  * OSX has a pitifully small shared memory segment by default,
  * so default to a lower number of max jobs supported
diff --git a/os/os-netbsd.h b/os/os-netbsd.h
index e03866d..78ac135 100644
--- a/os/os-netbsd.h
+++ b/os/os-netbsd.h
@@ -1,9 +1,12 @@
 #ifndef FIO_OS_NETBSD_H
 #define FIO_OS_NETBSD_H
 
+#define	FIO_OS	os_netbsd
+
 #include <errno.h>
 #include <sys/param.h>
 #include <sys/thr.h>
+#include <sys/endian.h>
 /* XXX hack to avoid confilcts between rbtree.h and <sys/rb.h> */
 #define	rb_node	_rb_node
 #include <sys/sysctl.h>
@@ -30,6 +33,16 @@
 #define PTHREAD_STACK_MIN 4096
 #endif
 
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define FIO_LITTLE_ENDIAN
+#else
+#define FIO_BIG_ENDIAN
+#endif
+
+#define fio_swap16(x)	bswap16(x)
+#define fio_swap32(x)	bswap32(x)
+#define fio_swap64(x)	bswap64(x)
+
 typedef off_t off64_t;
 
 static inline int blockdev_invalidate_cache(struct fio_file *f)
diff --git a/os/os-solaris.h b/os/os-solaris.h
index c0d3c30..5bf868a 100644
--- a/os/os-solaris.h
+++ b/os/os-solaris.h
@@ -1,6 +1,8 @@
 #ifndef FIO_OS_SOLARIS_H
 #define FIO_OS_SOLARIS_H
 
+#define	FIO_OS	os_solaris
+
 #include <errno.h>
 #include <malloc.h>
 #include <sys/types.h>
@@ -8,6 +10,7 @@
 #include <sys/pset.h>
 #include <sys/mman.h>
 #include <sys/dkio.h>
+#include <sys/byteorder.h>
 
 #include "../file.h"
 
@@ -24,6 +27,16 @@
 #define OS_MAP_ANON		MAP_ANON
 #define OS_RAND_MAX		2147483648UL
 
+#if defined(_BIG_ENDIAN)
+#define FIO_BIG_ENDIAN
+#else
+#define FIO_LITTLE_ENDIAN
+#endif
+
+#define fio_swap16(x)	BSWAP_16(x)
+#define fio_swap32(x)	BSWAP_32(x)
+#define fio_swap64(x)	BSWAP_64(x)
+
 struct solaris_rand_seed {
 	unsigned short r[3];
 };
diff --git a/os/os-windows.h b/os/os-windows.h
index db4127b..8812cfa 100644
--- a/os/os-windows.h
+++ b/os/os-windows.h
@@ -1,10 +1,13 @@
 #ifndef FIO_OS_WINDOWS_H
 #define FIO_OS_WINDOWS_H
 
+#define FIO_OS	os_windows
+
 #include <sys/types.h>
 #include <errno.h>
 #include <windows.h>
 #include <psapi.h>
+#include <stdlib.h>
 
 #include "../smalloc.h"
 #include "../file.h"
@@ -18,6 +21,9 @@
 #define FIO_HAVE_WINDOWSAIO
 #define FIO_HAVE_GETTID
 
+#define FIO_OS_HAVE_SOCKLEN_T
+typedef int fio_socklen_t;
+
 #define FIO_USE_GENERIC_RAND
 
 #define OS_MAP_ANON		MAP_ANON
@@ -26,6 +32,11 @@
 
 #define FIO_PREFERRED_ENGINE	"windowsaio"
 
+#define FIO_LITTLE_ENDIAN
+#define fio_swap16(x)	_byteswap_ushort(x)
+#define fio_swap32(x)	_byteswap_ulong(x)
+#define fio_swap64(x)	_byteswap_uint64(x)
+
 typedef off_t off64_t;
 
 typedef struct {
diff --git a/os/os.h b/os/os.h
index 2eb38e8..1218815 100644
--- a/os/os.h
+++ b/os/os.h
@@ -6,6 +6,19 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+enum {
+	os_linux = 1,
+	os_aix,
+	os_freebsd,
+	os_hpux,
+	os_mac,
+	os_netbsd,
+	os_solaris,
+	os_windows,
+
+	os_nr,
+};
+
 #if defined(__linux__)
 #include "os-linux.h"
 #elif defined(__FreeBSD__)
@@ -115,6 +128,75 @@ typedef unsigned long os_cpu_mask_t;
 #define FIO_MAX_JOBS		2048
 #endif
 
+#ifndef FIO_OS_HAVE_SOCKLEN_T
+typedef socklen_t fio_socklen_t;
+#endif
+
+#ifdef FIO_USE_GENERIC_SWAP
+static inline uint16_t fio_swap16(uint16_t val)
+{
+	return (val << 8) | (val >> 8);
+}
+
+static inline uint32_t fio_swap32(uint32_t val)
+{
+	val = ((val & 0xff00ff00UL) >> 8) | ((val & 0x00ff00ffUL) << 8);
+
+	return (val >> 16) | (val << 16);
+}
+
+static inline uint64_t fio_swap64(uint64_t val)
+{
+	val = ((val & 0xff00ff00ff00ff00ULL) >> 8) |
+	      ((val & 0x00ff00ff00ff00ffULL) << 8);
+	val = ((val & 0xffff0000ffff0000ULL) >> 16) |
+	      ((val & 0x0000ffff0000ffffULL) << 16);
+
+	return (val >> 32) | (val << 32);
+}
+#endif
+
+#ifdef FIO_LITTLE_ENDIAN
+#define __le16_to_cpu(x)		(x)
+#define __le32_to_cpu(x)		(x)
+#define __le64_to_cpu(x)		(x)
+#define __cpu_to_le16(x)		(x)
+#define __cpu_to_le32(x)		(x)
+#define __cpu_to_le64(x)		(x)
+#else
+#define __le16_to_cpu(x)		fio_swap16(x)
+#define __le32_to_cpu(x)		fio_swap32(x)
+#define __le64_to_cpu(x)		fio_swap64(x)
+#define __cpu_to_le16(x)		fio_swap16(x)
+#define __cpu_to_le32(x)		fio_swap32(x)
+#define __cpu_to_le64(x)		fio_swap64(x)
+#endif
+
+#define le16_to_cpu(val) ({			\
+	uint16_t *__val = &(val);		\
+	__le16_to_cpu(*__val);			\
+})
+#define le32_to_cpu(val) ({			\
+	uint32_t *__val = &(val);		\
+	__le32_to_cpu(*__val);			\
+})
+#define le64_to_cpu(val) ({			\
+	uint64_t *__val = &(val);		\
+	__le64_to_cpu(*__val);			\
+})
+#define cpu_to_le16(val) ({			\
+	uint16_t *__val = &(val);		\
+	__cpu_to_le16(*__val);			\
+})
+#define cpu_to_le32(val) ({			\
+	uint32_t *__val = &(val);		\
+	__cpu_to_le32(*__val);			\
+})
+#define cpu_to_le64(val) ({			\
+	uint64_t *__val = &(val);		\
+	__cpu_to_le64(*__val);			\
+})
+
 #ifndef FIO_HAVE_BLKTRACE
 static inline int is_blktrace(const char *fname)
 {
diff --git a/os/windows/install.wxs b/os/windows/install.wxs
index 028c4cc..69a0e98 100755
--- a/os/windows/install.wxs
+++ b/os/windows/install.wxs
@@ -2,8 +2,8 @@
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 
 <?define VersionMajor = 1?>
-<?define VersionMinor = 59?>
-<?define VersionBuild = 0?>
+<?define VersionMinor = 99?>
+<?define VersionBuild = 6?>
 
 	<Product Id="*"
 	  Codepage="1252" Language="1033"
diff --git a/os/windows/version.h b/os/windows/version.h
index 6c8a228..b7d3308 100644
--- a/os/windows/version.h
+++ b/os/windows/version.h
@@ -1,4 +1,6 @@
-#define FIO_VERSION_MAJOR 1
-#define FIO_VERSION_MINOR 59
-#define FIO_VERSION_BUILD 0
-#define FIO_VERSION_STRING "1.59"
+#include "../../fio_version.h"
+
+#define FIO_VERSION_MAJOR FIO_MAJOR
+#define FIO_VERSION_MINOR FIO_MINOR
+#define FIO_VERSION_BUILD FIO_PATCH
+#define FIO_VERSION_STRING "1.99.6"
diff --git a/parse.c b/parse.c
index 239e371..27e7336 100644
--- a/parse.c
+++ b/parse.c
@@ -44,24 +44,25 @@ static void posval_sort(struct fio_option *o, struct value_pair *vpmap)
 	qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp);
 }
 
-static void show_option_range(struct fio_option *o, FILE *out)
+static void show_option_range(struct fio_option *o,
+				int (*logger)(const char *format, ...))
 {
 	if (o->type == FIO_OPT_FLOAT_LIST){
 		if (isnan(o->minfp) && isnan(o->maxfp))
 			return;
 
-		fprintf(out, "%20s: min=%f", "range", o->minfp);
+		logger("%20s: min=%f", "range", o->minfp);
 		if (!isnan(o->maxfp))
-			fprintf(out, ", max=%f", o->maxfp);
-		fprintf(out, "\n");
+			logger(", max=%f", o->maxfp);
+		logger("\n");
 	} else {
 		if (!o->minval && !o->maxval)
 			return;
 
-		fprintf(out, "%20s: min=%d", "range", o->minval);
+		logger("%20s: min=%d", "range", o->minval);
 		if (o->maxval)
-			fprintf(out, ", max=%d", o->maxval);
-		fprintf(out, "\n");
+			logger(", max=%d", o->maxval);
+		logger("\n");
 	}
 }
 
@@ -75,17 +76,17 @@ static void show_option_values(struct fio_option *o)
 		if (!vp->ival)
 			continue;
 
-		printf("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
+		log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
 		if (vp->help)
-			printf(" %s", vp->help);
-		printf("\n");
+			log_info(" %s", vp->help);
+		log_info("\n");
 	}
 
 	if (i)
-		printf("\n");
+		log_info("\n");
 }
 
-static void show_option_help(struct fio_option *o, FILE *out)
+static void show_option_help(struct fio_option *o, int is_err)
 {
 	const char *typehelp[] = {
 		"invalid",
@@ -101,15 +102,21 @@ static void show_option_help(struct fio_option *o, FILE *out)
 		"no argument (opt)",
 		"deprecated",
 	};
+	int (*logger)(const char *format, ...);
+
+	if (is_err)
+		logger = log_err;
+	else
+		logger = log_info;
 
 	if (o->alias)
-		fprintf(out, "%20s: %s\n", "alias", o->alias);
+		logger("%20s: %s\n", "alias", o->alias);
 
-	fprintf(out, "%20s: %s\n", "type", typehelp[o->type]);
-	fprintf(out, "%20s: %s\n", "default", o->def ? o->def : "no default");
+	logger("%20s: %s\n", "type", typehelp[o->type]);
+	logger("%20s: %s\n", "default", o->def ? o->def : "no default");
 	if (o->prof_name)
-		fprintf(out, "%20s: only for profile '%s'\n", "valid", o->prof_name);
-	show_option_range(o, stdout);
+		logger("%20s: only for profile '%s'\n", "valid", o->prof_name);
+	show_option_range(o, logger);
 	show_option_values(o);
 }
 
@@ -357,7 +364,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 							o->type, ptr);
 
 	if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) {
-		fprintf(stderr, "Option %s requires an argument\n", o->name);
+		log_err("Option %s requires an argument\n", o->name);
 		return 1;
 	}
 
@@ -411,12 +418,12 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 			break;
 
 		if (o->maxval && ull > o->maxval) {
-			fprintf(stderr, "max value out of range: %lld"
+			log_err("max value out of range: %lld"
 					" (%d max)\n", ull, o->maxval);
 			return 1;
 		}
 		if (o->minval && ull < o->minval) {
-			fprintf(stderr, "min value out of range: %lld"
+			log_err("min value out of range: %lld"
 					" (%d min)\n", ull, o->minval);
 			return 1;
 		}
@@ -462,22 +469,21 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 			*ilp = ul2;
 		}
 		if (curr >= o->maxlen) {
-			fprintf(stderr, "the list exceeding max length %d\n",
+			log_err("the list exceeding max length %d\n",
 					o->maxlen);
 			return 1;
 		}
 		if(!str_to_float(ptr, &uf)){
-			fprintf(stderr, "not a floating point value: %s\n",
-					ptr);
+			log_err("not a floating point value: %s\n", ptr);
 			return 1;
 		}
 		if (!isnan(o->maxfp) && uf > o->maxfp) {
-			fprintf(stderr, "value out of range: %f"
+			log_err("value out of range: %f"
 				" (range max: %f)\n", uf, o->maxfp);
 			return 1;
 		}
 		if (!isnan(o->minfp) && uf < o->minfp) {
-			fprintf(stderr, "value out of range: %f"
+			log_err("value out of range: %f"
 				" (range min: %f)\n", uf, o->minfp);
 			return 1;
 		}
@@ -603,12 +609,12 @@ match:
 			break;
 
 		if (o->maxval && il > (int) o->maxval) {
-			fprintf(stderr, "max value out of range: %d (%d max)\n",
+			log_err("max value out of range: %d (%d max)\n",
 								il, o->maxval);
 			return 1;
 		}
 		if (o->minval && il < o->minval) {
-			fprintf(stderr, "min value out of range: %d (%d min)\n",
+			log_err("min value out of range: %d (%d min)\n",
 								il, o->minval);
 			return 1;
 		}
@@ -635,10 +641,10 @@ match:
 		break;
 	}
 	case FIO_OPT_DEPRECATED:
-		fprintf(stdout, "Option %s is deprecated\n", o->name);
+		log_info("Option %s is deprecated\n", o->name);
 		break;
 	default:
-		fprintf(stderr, "Bad option type %u\n", o->type);
+		log_err("Bad option type %u\n", o->type);
 		ret = 1;
 	}
 
@@ -648,9 +654,9 @@ match:
 	if (o->verify) {
 		ret = o->verify(o, data);
 		if (ret) {
-			fprintf(stderr,"Correct format for offending option\n");
-			fprintf(stderr, "%20s: %s\n", o->name, o->help);
-			show_option_help(o, stderr);
+			log_err("Correct format for offending option\n");
+			log_err("%20s: %s\n", o->name, o->help);
+			show_option_help(o, 1);
 		}
 	}
 
@@ -776,14 +782,14 @@ int parse_cmd_option(const char *opt, const char *val,
 
 	o = find_option(options, opt);
 	if (!o) {
-		fprintf(stderr, "Bad option <%s>\n", opt);
+		log_err("Bad option <%s>\n", opt);
 		return 1;
 	}
 
 	if (!handle_option(o, val, data))
 		return 0;
 
-	fprintf(stderr, "fio: failed parsing %s=%s\n", opt, val);
+	log_err("fio: failed parsing %s=%s\n", opt, val);
 	return 1;
 }
 
@@ -804,7 +810,7 @@ static char *option_dup_subs(const char *opt)
 	size_t envlen;
 
 	if (strlen(opt) + 1 > OPT_LEN_MAX) {
-		fprintf(stderr, "OPT_LEN_MAX (%d) is too small\n", OPT_LEN_MAX);
+		log_err("OPT_LEN_MAX (%d) is too small\n", OPT_LEN_MAX);
 		return NULL;
 	}
 
@@ -852,7 +858,7 @@ int parse_option(const char *opt, struct fio_option *options, void *data)
 
 	o = get_option(tmp, options, &post);
 	if (!o) {
-		fprintf(stderr, "Bad option <%s>\n", tmp);
+		log_err("Bad option <%s>\n", tmp);
 		free(tmp);
 		return 1;
 	}
@@ -862,7 +868,7 @@ int parse_option(const char *opt, struct fio_option *options, void *data)
 		return 0;
 	}
 
-	fprintf(stderr, "fio: failed parsing %s\n", opt);
+	log_err("fio: failed parsing %s\n", opt);
 	free(tmp);
 	return 1;
 }
@@ -936,7 +942,7 @@ static void __print_option(struct fio_option *o, struct fio_option *org,
 
 	sprintf(p, "%s", o->name);
 
-	printf("%-24s: %s\n", name, o->help);
+	log_info("%-24s: %s\n", name, o->help);
 }
 
 static void print_option(struct fio_option *o)
@@ -1001,7 +1007,7 @@ int show_cmd_help(struct fio_option *options, const char *name)
 		if (show_all || match) {
 			found = 1;
 			if (match)
-				printf("%20s: %s\n", o->name, o->help);
+				log_info("%20s: %s\n", o->name, o->help);
 			if (show_all) {
 				if (!o->parent)
 					print_option(o);
@@ -1012,24 +1018,24 @@ int show_cmd_help(struct fio_option *options, const char *name)
 		if (!match)
 			continue;
 
-		show_option_help(o, stdout);
+		show_option_help(o, 0);
 	}
 
 	if (found)
 		return 0;
 
-	printf("No such command: %s", name);
+	log_err("No such command: %s", name);
 
 	/*
 	 * Only print an appropriately close option, one where the edit
 	 * distance isn't too big. Otherwise we get crazy matches.
 	 */
 	if (closest && best_dist < 3) {
-		printf(" - showing closest match\n");
-		printf("%20s: %s\n", closest->name, closest->help);
-		show_option_help(closest, stdout);
+		log_info(" - showing closest match\n");
+		log_info("%20s: %s\n", closest->name, closest->help);
+		show_option_help(closest, 0);
 	} else
-		printf("\n");
+		log_info("\n");
 
 	return 1;
 }
@@ -1061,20 +1067,17 @@ void option_init(struct fio_option *o)
 		o->maxfp = NAN;
 	}
 	if (o->type == FIO_OPT_STR_SET && o->def) {
-		fprintf(stderr, "Option %s: string set option with"
+		log_err("Option %s: string set option with"
 				" default will always be true\n", o->name);
 	}
-	if (!o->cb && (!o->off1 && !o->roff1)) {
-		fprintf(stderr, "Option %s: neither cb nor offset given\n",
-							o->name);
-	}
+	if (!o->cb && (!o->off1 && !o->roff1))
+		log_err("Option %s: neither cb nor offset given\n", o->name);
 	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
 	    o->type == FIO_OPT_STR_MULTI)
 		return;
 	if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
 		      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
-		fprintf(stderr, "Option %s: both cb and offset given\n",
-							 o->name);
+		log_err("Option %s: both cb and offset given\n", o->name);
 	}
 }
 
diff --git a/server.c b/server.c
new file mode 100644
index 0000000..e7a9057
--- /dev/null
+++ b/server.c
@@ -0,0 +1,1134 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <signal.h>
+
+#include "fio.h"
+#include "server.h"
+#include "crc/crc16.h"
+#include "lib/ieee754.h"
+
+#include "fio_version.h"
+
+int fio_net_port = 8765;
+
+int exit_backend = 0;
+
+static int server_fd = -1;
+static char *fio_server_arg;
+static char *bind_sock;
+static struct sockaddr_in saddr_in;
+
+static const char *fio_server_ops[FIO_NET_CMD_NR] = {
+	"",
+	"QUIT",
+	"EXIT",
+	"JOB",
+	"JOBLINE",
+	"TEXT",
+	"TS",
+	"GS",
+	"SEND_ETA",
+	"ETA",
+	"PROBE",
+	"START",
+	"STOP",
+	"DISK_UTIL",
+};
+
+const char *fio_server_op(unsigned int op)
+{
+	static char buf[32];
+
+	if (op < FIO_NET_CMD_NR)
+		return fio_server_ops[op];
+
+	sprintf(buf, "UNKNOWN/%d", op);
+	return buf;
+}
+
+int fio_send_data(int sk, const void *p, unsigned int len)
+{
+	assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU);
+
+	do {
+		int ret = send(sk, p, len, 0);
+
+		if (ret > 0) {
+			len -= ret;
+			if (!len)
+				break;
+			p += ret;
+			continue;
+		} else if (!ret)
+			break;
+		else if (errno == EAGAIN || errno == EINTR)
+			continue;
+		else
+			break;
+	} while (!exit_backend);
+
+	if (!len)
+		return 0;
+
+	return 1;
+}
+
+int fio_recv_data(int sk, void *p, unsigned int len)
+{
+	do {
+		int ret = recv(sk, p, len, MSG_WAITALL);
+
+		if (ret > 0) {
+			len -= ret;
+			if (!len)
+				break;
+			p += ret;
+			continue;
+		} else if (!ret)
+			break;
+		else if (errno == EAGAIN || errno == EINTR)
+			continue;
+		else
+			break;
+	} while (!exit_backend);
+
+	if (!len)
+		return 0;
+
+	return -1;
+}
+
+static int verify_convert_cmd(struct fio_net_cmd *cmd)
+{
+	uint16_t crc;
+
+	cmd->cmd_crc16 = le16_to_cpu(cmd->cmd_crc16);
+	cmd->pdu_crc16 = le16_to_cpu(cmd->pdu_crc16);
+
+	crc = crc16(cmd, FIO_NET_CMD_CRC_SZ);
+	if (crc != cmd->cmd_crc16) {
+		log_err("fio: server bad crc on command (got %x, wanted %x)\n",
+				cmd->cmd_crc16, crc);
+		return 1;
+	}
+
+	cmd->version	= le16_to_cpu(cmd->version);
+	cmd->opcode	= le16_to_cpu(cmd->opcode);
+	cmd->flags	= le32_to_cpu(cmd->flags);
+	cmd->tag	= le64_to_cpu(cmd->tag);
+	cmd->pdu_len	= le32_to_cpu(cmd->pdu_len);
+
+	switch (cmd->version) {
+	case FIO_SERVER_VER:
+		break;
+	default:
+		log_err("fio: bad server cmd version %d\n", cmd->version);
+		return 1;
+	}
+
+	if (cmd->pdu_len > FIO_SERVER_MAX_PDU) {
+		log_err("fio: command payload too large: %u\n", cmd->pdu_len);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Read (and defragment, if necessary) incoming commands
+ */
+struct fio_net_cmd *fio_net_recv_cmd(int sk)
+{
+	struct fio_net_cmd cmd, *cmdret = NULL;
+	size_t cmd_size = 0, pdu_offset = 0;
+	uint16_t crc;
+	int ret, first = 1;
+	void *pdu = NULL;
+
+	do {
+		ret = fio_recv_data(sk, &cmd, sizeof(cmd));
+		if (ret)
+			break;
+
+		/* We have a command, verify it and swap if need be */
+		ret = verify_convert_cmd(&cmd);
+		if (ret)
+			break;
+
+		if (first) {
+			/* if this is text, add room for \0 at the end */
+			cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
+			assert(!cmdret);
+		} else
+			cmd_size += cmd.pdu_len;
+
+		cmdret = realloc(cmdret, cmd_size);
+
+		if (first)
+			memcpy(cmdret, &cmd, sizeof(cmd));
+		else
+			assert(cmdret->opcode == cmd.opcode);
+
+		if (!cmd.pdu_len)
+			break;
+
+		/* There's payload, get it */
+		pdu = (void *) cmdret->payload + pdu_offset;
+		ret = fio_recv_data(sk, pdu, cmd.pdu_len);
+		if (ret)
+			break;
+
+		/* Verify payload crc */
+		crc = crc16(pdu, cmd.pdu_len);
+		if (crc != cmd.pdu_crc16) {
+			log_err("fio: server bad crc on payload ");
+			log_err("(got %x, wanted %x)\n", cmd.pdu_crc16, crc);
+			ret = 1;
+			break;
+		}
+
+		pdu_offset += cmd.pdu_len;
+		if (!first)
+			cmdret->pdu_len += cmd.pdu_len;
+		first = 0;
+	} while (cmd.flags & FIO_NET_CMD_F_MORE);
+
+	if (ret) {
+		free(cmdret);
+		cmdret = NULL;
+	} else if (cmdret) {
+		/* zero-terminate text input */
+		if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
+		    cmdret->opcode == FIO_NET_CMD_JOB)) {
+			char *buf = (char *) cmdret->payload;
+
+			buf[cmdret->pdu_len ] = '\0';
+		}
+		/* frag flag is internal */
+		cmdret->flags &= ~FIO_NET_CMD_F_MORE;
+	}
+
+	return cmdret;
+}
+
+void fio_net_cmd_crc(struct fio_net_cmd *cmd)
+{
+	uint32_t pdu_len;
+
+	cmd->cmd_crc16 = __cpu_to_le16(crc16(cmd, FIO_NET_CMD_CRC_SZ));
+
+	pdu_len = le32_to_cpu(cmd->pdu_len);
+	if (pdu_len)
+		cmd->pdu_crc16 = __cpu_to_le16(crc16(cmd->payload, pdu_len));
+}
+
+int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size,
+		     uint64_t tag)
+{
+	struct fio_net_cmd *cmd = NULL;
+	size_t this_len, cur_len = 0;
+	int ret;
+
+	do {
+		this_len = size;
+		if (this_len > FIO_SERVER_MAX_PDU)
+			this_len = FIO_SERVER_MAX_PDU;
+
+		if (!cmd || cur_len < sizeof(*cmd) + this_len) {
+			if (cmd)
+				free(cmd);
+
+			cur_len = sizeof(*cmd) + this_len;
+			cmd = malloc(cur_len);
+		}
+
+		fio_init_net_cmd(cmd, opcode, buf, this_len, tag);
+
+		if (this_len < size)
+			cmd->flags = __cpu_to_le32(FIO_NET_CMD_F_MORE);
+
+		fio_net_cmd_crc(cmd);
+
+		ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len);
+		size -= this_len;
+		buf += this_len;
+	} while (!ret && size);
+
+	if (cmd)
+		free(cmd);
+
+	return ret;
+}
+
+static int fio_net_send_simple_stack_cmd(int sk, uint16_t opcode, uint64_t tag)
+{
+	struct fio_net_cmd cmd;
+
+	fio_init_net_cmd(&cmd, opcode, NULL, 0, tag);
+	fio_net_cmd_crc(&cmd);
+
+	return fio_send_data(sk, &cmd, sizeof(cmd));
+}
+
+/*
+ * If 'list' is non-NULL, then allocate and store the sent command for
+ * later verification.
+ */
+int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag,
+			    struct flist_head *list)
+{
+	struct fio_net_int_cmd *cmd;
+	int ret;
+
+	if (!list)
+		return fio_net_send_simple_stack_cmd(sk, opcode, tag);
+
+	cmd = malloc(sizeof(*cmd));
+
+	fio_init_net_cmd(&cmd->cmd, opcode, NULL, 0, (uintptr_t) cmd);
+	fio_net_cmd_crc(&cmd->cmd);
+
+	INIT_FLIST_HEAD(&cmd->list);
+	gettimeofday(&cmd->tv, NULL);
+	cmd->saved_tag = tag;
+
+	ret = fio_send_data(sk, &cmd->cmd, sizeof(cmd->cmd));
+	if (ret) {
+		free(cmd);
+		return ret;
+	}
+
+	flist_add_tail(&cmd->list, list);
+	return 0;
+}
+
+static int fio_server_send_quit_cmd(void)
+{
+	dprint(FD_NET, "server: sending quit\n");
+	return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0, NULL);
+}
+
+static int handle_job_cmd(struct fio_net_cmd *cmd)
+{
+	char *buf = (char *) cmd->payload;
+	int ret;
+
+	if (parse_jobs_ini(buf, 1, 0)) {
+		fio_server_send_quit_cmd();
+		return -1;
+	}
+
+	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
+
+	ret = exec_run();
+	fio_server_send_quit_cmd();
+	reset_fio_state();
+	return ret;
+}
+
+static int handle_jobline_cmd(struct fio_net_cmd *cmd)
+{
+	void *pdu = cmd->payload;
+	struct cmd_single_line_pdu *cslp;
+	struct cmd_line_pdu *clp;
+	unsigned long offset;
+	char **argv;
+	int ret, i;
+
+	clp = pdu;
+	clp->lines = le16_to_cpu(clp->lines);
+	argv = malloc(clp->lines * sizeof(char *));
+	offset = sizeof(*clp);
+
+	dprint(FD_NET, "server: %d command line args\n", clp->lines);
+
+	for (i = 0; i < clp->lines; i++) {
+		cslp = pdu + offset;
+		argv[i] = (char *) cslp->text;
+
+		offset += sizeof(*cslp) + le16_to_cpu(cslp->len);
+		dprint(FD_NET, "server: %d: %s\n", i, argv[i]);
+	}
+
+	if (parse_cmd_line(clp->lines, argv)) {
+		fio_server_send_quit_cmd();
+		free(argv);
+		return -1;
+	}
+
+	free(argv);
+
+	fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_START, 0, NULL);
+
+	ret = exec_run();
+	fio_server_send_quit_cmd();
+	reset_fio_state();
+	return ret;
+}
+
+static int handle_probe_cmd(struct fio_net_cmd *cmd)
+{
+	struct cmd_probe_pdu probe;
+
+	dprint(FD_NET, "server: sending probe reply\n");
+
+	memset(&probe, 0, sizeof(probe));
+	gethostname((char *) probe.hostname, sizeof(probe.hostname));
+#ifdef FIO_BIG_ENDIAN
+	probe.bigendian = 1;
+#endif
+	probe.fio_major = FIO_MAJOR;
+	probe.fio_minor = FIO_MINOR;
+	probe.fio_patch = FIO_PATCH;
+
+	probe.os	= FIO_OS;
+	probe.arch	= FIO_ARCH;
+
+	probe.bpp	= sizeof(void *);
+
+	return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), cmd->tag);
+}
+
+static int handle_send_eta_cmd(struct fio_net_cmd *cmd)
+{
+	struct jobs_eta *je;
+	size_t size;
+	int i;
+
+	if (!thread_number)
+		return 0;
+
+	size = sizeof(*je) + thread_number * sizeof(char) + 1;
+	je = malloc(size);
+	memset(je, 0, size);
+
+	if (!calc_thread_status(je, 1)) {
+		free(je);
+		return 0;
+	}
+
+	dprint(FD_NET, "server sending status\n");
+
+	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->files_open		= cpu_to_le32(je->files_open);
+	je->m_rate		= cpu_to_le32(je->m_rate);
+	je->t_rate		= cpu_to_le32(je->t_rate);
+	je->m_iops		= cpu_to_le32(je->m_iops);
+	je->t_iops		= cpu_to_le32(je->t_iops);
+
+	for (i = 0; i < 2; i++) {
+		je->rate[i]	= cpu_to_le32(je->rate[i]);
+		je->iops[i]	= cpu_to_le32(je->iops[i]);
+	}
+
+	je->elapsed_sec		= cpu_to_le32(je->nr_running);
+	je->eta_sec		= cpu_to_le64(je->eta_sec);
+
+	fio_net_send_cmd(server_fd, FIO_NET_CMD_ETA, je, size, cmd->tag);
+	free(je);
+	return 0;
+}
+
+static int handle_command(struct fio_net_cmd *cmd)
+{
+	int ret;
+
+	dprint(FD_NET, "server: got op [%s], pdu=%u, tag=%lx\n",
+			fio_server_op(cmd->opcode), cmd->pdu_len, cmd->tag);
+
+	switch (cmd->opcode) {
+	case FIO_NET_CMD_QUIT:
+		fio_terminate_threads(TERMINATE_ALL);
+		return -1;
+	case FIO_NET_CMD_EXIT:
+		exit_backend = 1;
+		return -1;
+	case FIO_NET_CMD_JOB:
+		ret = handle_job_cmd(cmd);
+		break;
+	case FIO_NET_CMD_JOBLINE:
+		ret = handle_jobline_cmd(cmd);
+		break;
+	case FIO_NET_CMD_PROBE:
+		ret = handle_probe_cmd(cmd);
+		break;
+	case FIO_NET_CMD_SEND_ETA:
+		ret = handle_send_eta_cmd(cmd);
+		break;
+	default:
+		log_err("fio: unknown opcode: %s\n",fio_server_op(cmd->opcode));
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int handle_connection(int sk, int block)
+{
+	struct fio_net_cmd *cmd = NULL;
+	int ret = 0;
+
+	/* read forever */
+	while (!exit_backend) {
+		struct pollfd pfd = {
+			.fd	= sk,
+			.events	= POLLIN,
+		};
+
+		ret = 0;
+		do {
+			ret = poll(&pfd, 1, 100);
+			if (ret < 0) {
+				if (errno == EINTR)
+					break;
+				log_err("fio: poll: %s\n", strerror(errno));
+				break;
+			} else if (!ret) {
+				if (!block)
+					return 0;
+				continue;
+			}
+
+			if (pfd.revents & POLLIN)
+				break;
+			if (pfd.revents & (POLLERR|POLLHUP)) {
+				ret = 1;
+				break;
+			}
+		} while (!exit_backend);
+
+		if (ret < 0)
+			break;
+
+		cmd = fio_net_recv_cmd(sk);
+		if (!cmd) {
+			ret = -1;
+			break;
+		}
+
+		ret = handle_command(cmd);
+		if (ret)
+			break;
+
+		free(cmd);
+		cmd = NULL;
+	}
+
+	if (cmd)
+		free(cmd);
+
+	return ret;
+}
+
+void fio_server_idle_loop(void)
+{
+	if (server_fd != -1)
+		handle_connection(server_fd, 0);
+}
+
+static int accept_loop(int listen_sk)
+{
+	struct sockaddr_in addr;
+	fio_socklen_t len = sizeof(addr);
+	struct pollfd pfd;
+	int ret, sk, flags, exitval = 0;
+
+	dprint(FD_NET, "server enter accept loop\n");
+
+	flags = fcntl(listen_sk, F_GETFL);
+	flags |= O_NONBLOCK;
+	fcntl(listen_sk, F_SETFL, flags);
+again:
+	pfd.fd = listen_sk;
+	pfd.events = POLLIN;
+	do {
+		ret = poll(&pfd, 1, 100);
+		if (ret < 0) {
+			if (errno == EINTR)
+				break;
+			log_err("fio: poll: %s\n", strerror(errno));
+			goto out;
+		} else if (!ret)
+			continue;
+
+		if (pfd.revents & POLLIN)
+			break;
+	} while (!exit_backend);
+
+	if (exit_backend)
+		goto out;
+
+	sk = accept(listen_sk, (struct sockaddr *) &addr, &len);
+	if (sk < 0) {
+		log_err("fio: accept: %s\n", strerror(errno));
+		return -1;
+	}
+
+	dprint(FD_NET, "server: connect from %s\n", inet_ntoa(addr.sin_addr));
+
+	server_fd = sk;
+
+	exitval = handle_connection(sk, 1);
+
+	server_fd = -1;
+	close(sk);
+
+	if (!exit_backend)
+		goto again;
+
+out:
+	return exitval;
+}
+
+int fio_server_text_output(const char *buf, size_t len)
+{
+	if (server_fd != -1)
+		return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
+
+	return log_local_buf(buf, len);
+}
+
+static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
+{
+	dst->max_val	= cpu_to_le64(src->max_val);
+	dst->min_val	= cpu_to_le64(src->min_val);
+	dst->samples	= cpu_to_le64(src->samples);
+
+	/*
+	 * Encode to IEEE 754 for network transfer
+	 */
+	dst->mean.u.i	= __cpu_to_le64(fio_double_to_uint64(src->mean.u.f));
+	dst->S.u.i	= __cpu_to_le64(fio_double_to_uint64(src->S.u.f));
+}
+
+static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		dst->max_run[i]		= cpu_to_le64(src->max_run[i]);
+		dst->min_run[i]		= cpu_to_le64(src->min_run[i]);
+		dst->max_bw[i]		= cpu_to_le64(src->max_bw[i]);
+		dst->min_bw[i]		= cpu_to_le64(src->min_bw[i]);
+		dst->io_kb[i]		= cpu_to_le64(src->io_kb[i]);
+		dst->agg[i]		= cpu_to_le64(src->agg[i]);
+	}
+
+	dst->kb_base	= cpu_to_le32(src->kb_base);
+	dst->groupid	= cpu_to_le32(src->groupid);
+}
+
+/*
+ * Send a CMD_TS, which packs struct thread_stat and group_run_stats
+ * into a single payload.
+ */
+void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
+{
+	struct cmd_ts_pdu p;
+	int i, j;
+
+	dprint(FD_NET, "server sending end stats\n");
+
+	memset(&p, 0, sizeof(p));
+
+	strcpy(p.ts.name, ts->name);
+	strcpy(p.ts.verror, ts->verror);
+	strcpy(p.ts.description, ts->description);
+
+	p.ts.error	= cpu_to_le32(ts->error);
+	p.ts.groupid	= cpu_to_le32(ts->groupid);
+	p.ts.pid	= cpu_to_le32(ts->pid);
+	p.ts.members	= cpu_to_le32(ts->members);
+
+	for (i = 0; i < 2; i++) {
+		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
+		convert_io_stat(&p.ts.slat_stat[i], &ts->slat_stat[i]);
+		convert_io_stat(&p.ts.lat_stat[i], &ts->lat_stat[i]);
+		convert_io_stat(&p.ts.bw_stat[i], &ts->bw_stat[i]);
+	}
+
+	p.ts.usr_time		= cpu_to_le64(ts->usr_time);
+	p.ts.sys_time		= cpu_to_le64(ts->sys_time);
+	p.ts.ctx		= cpu_to_le64(ts->ctx);
+	p.ts.minf		= cpu_to_le64(ts->minf);
+	p.ts.majf		= cpu_to_le64(ts->majf);
+	p.ts.clat_percentiles	= cpu_to_le64(ts->clat_percentiles);
+
+	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
+		fio_fp64_t *src = &ts->percentile_list[i];
+		fio_fp64_t *dst = &p.ts.percentile_list[i];
+
+		dst->u.i = __cpu_to_le64(fio_double_to_uint64(src->u.f));
+	}
+
+	for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
+		p.ts.io_u_map[i]	= cpu_to_le32(ts->io_u_map[i]);
+		p.ts.io_u_submit[i]	= cpu_to_le32(ts->io_u_submit[i]);
+		p.ts.io_u_complete[i]	= cpu_to_le32(ts->io_u_complete[i]);
+	}
+
+	for (i = 0; i < FIO_IO_U_LAT_U_NR; i++) {
+		p.ts.io_u_lat_u[i]	= cpu_to_le32(ts->io_u_lat_u[i]);
+		p.ts.io_u_lat_m[i]	= cpu_to_le32(ts->io_u_lat_m[i]);
+	}
+
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < FIO_IO_U_PLAT_NR; j++)
+			p.ts.io_u_plat[i][j] = cpu_to_le32(ts->io_u_plat[i][j]);
+
+	for (i = 0; i < 3; i++) {
+		p.ts.total_io_u[i]	= cpu_to_le64(ts->total_io_u[i]);
+		p.ts.short_io_u[i]	= cpu_to_le64(ts->short_io_u[i]);
+	}
+
+	p.ts.total_submit	= cpu_to_le64(ts->total_submit);
+	p.ts.total_complete	= cpu_to_le64(ts->total_complete);
+
+	for (i = 0; i < 2; i++) {
+		p.ts.io_bytes[i]	= cpu_to_le64(ts->io_bytes[i]);
+		p.ts.runtime[i]		= cpu_to_le64(ts->runtime[i]);
+	}
+
+	p.ts.total_run_time	= cpu_to_le64(ts->total_run_time);
+	p.ts.continue_on_error	= cpu_to_le16(ts->continue_on_error);
+	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
+	p.ts.first_error	= cpu_to_le32(ts->first_error);
+	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
+
+	convert_gs(&p.rs, rs);
+
+	fio_net_send_cmd(server_fd, FIO_NET_CMD_TS, &p, sizeof(p), 0);
+}
+
+void fio_server_send_gs(struct group_run_stats *rs)
+{
+	struct group_run_stats gs;
+
+	dprint(FD_NET, "server sending group run stats\n");
+
+	convert_gs(&gs, rs);
+	fio_net_send_cmd(server_fd, FIO_NET_CMD_GS, &gs, sizeof(gs), 0);
+}
+
+static void convert_agg(struct disk_util_agg *dst, struct disk_util_agg *src)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		dst->ios[i]	= cpu_to_le32(src->ios[i]);
+		dst->merges[i]	= cpu_to_le32(src->merges[i]);
+		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
+		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
+	}
+
+	dst->io_ticks		= cpu_to_le32(src->io_ticks);
+	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
+	dst->slavecount		= cpu_to_le32(src->slavecount);
+	dst->max_util.u.i	= __cpu_to_le64(fio_double_to_uint64(src->max_util.u.f));
+}
+
+static void convert_dus(struct disk_util_stat *dst, struct disk_util_stat *src)
+{
+	int i;
+
+	strcpy((char *) dst->name, (char *) src->name);
+
+	for (i = 0; i < 2; i++) {
+		dst->ios[i]	= cpu_to_le32(src->ios[i]);
+		dst->merges[i]	= cpu_to_le32(src->merges[i]);
+		dst->sectors[i]	= cpu_to_le64(src->sectors[i]);
+		dst->ticks[i]	= cpu_to_le32(src->ticks[i]);
+	}
+
+	dst->io_ticks		= cpu_to_le32(src->io_ticks);
+	dst->time_in_queue	= cpu_to_le32(src->time_in_queue);
+	dst->msec		= cpu_to_le64(src->msec);
+}
+
+void fio_server_send_du(void)
+{
+	struct disk_util *du;
+	struct flist_head *entry;
+	struct cmd_du_pdu pdu;
+
+	dprint(FD_NET, "server: sending disk_util %d\n", !flist_empty(&disk_list));
+
+	memset(&pdu, 0, sizeof(pdu));
+
+	flist_for_each(entry, &disk_list) {
+		du = flist_entry(entry, struct disk_util, list);
+
+		convert_dus(&pdu.dus, &du->dus);
+		convert_agg(&pdu.agg, &du->agg);
+
+		fio_net_send_cmd(server_fd, FIO_NET_CMD_DU, &pdu, sizeof(pdu), 0);
+	}
+}
+
+int fio_server_log(const char *format, ...)
+{
+	char buffer[1024];
+	va_list args;
+	size_t len;
+
+	dprint(FD_NET, "server log\n");
+
+	va_start(args, format);
+	len = vsnprintf(buffer, sizeof(buffer), format, args);
+	va_end(args);
+
+	return fio_server_text_output(buffer, len);
+}
+
+static int fio_init_server_ip(void)
+{
+	int sk, opt;
+
+	sk = socket(AF_INET, SOCK_STREAM, 0);
+	if (sk < 0) {
+		log_err("fio: socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	opt = 1;
+	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+		log_err("fio: setsockopt: %s\n", strerror(errno));
+		close(sk);
+		return -1;
+	}
+#ifdef SO_REUSEPORT
+	if (setsockopt(sk, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
+		log_err("fio: setsockopt: %s\n", strerror(errno));
+		close(sk);
+		return -1;
+	}
+#endif
+
+	saddr_in.sin_family = AF_INET;
+
+	if (bind(sk, (struct sockaddr *) &saddr_in, sizeof(saddr_in)) < 0) {
+		log_err("fio: bind: %s\n", strerror(errno));
+		close(sk);
+		return -1;
+	}
+
+	return sk;
+}
+
+static int fio_init_server_sock(void)
+{
+	struct sockaddr_un addr;
+	fio_socklen_t len;
+	mode_t mode;
+	int sk;
+
+	sk = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sk < 0) {
+		log_err("fio: socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	mode = umask(000);
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	strcpy(addr.sun_path, bind_sock);
+	unlink(bind_sock);
+
+	len = sizeof(addr.sun_family) + strlen(bind_sock) + 1;
+
+	if (bind(sk, (struct sockaddr *) &addr, len) < 0) {
+		log_err("fio: bind: %s\n", strerror(errno));
+		close(sk);
+		return -1;
+	}
+
+	umask(mode);
+	return sk;
+}
+
+static int fio_init_server_connection(void)
+{
+	char bind_str[128];
+	int sk;
+
+	dprint(FD_NET, "starting server\n");
+
+	if (!bind_sock)
+		sk = fio_init_server_ip();
+	else
+		sk = fio_init_server_sock();
+
+	if (sk < 0)
+		return sk;
+
+	if (!bind_sock)
+		sprintf(bind_str, "%s:%u", inet_ntoa(saddr_in.sin_addr), fio_net_port);
+	else
+		strcpy(bind_str, bind_sock);
+
+	log_info("fio: server listening on %s\n", bind_str);
+
+	if (listen(sk, 0) < 0) {
+		log_err("fio: listen: %s\n", strerror(errno));
+		return -1;
+	}
+
+	return sk;
+}
+
+int fio_server_parse_string(const char *str, char **ptr, int *is_sock,
+			    int *port, struct in_addr *inp)
+{
+	*ptr = NULL;
+	*is_sock = 0;
+	*port = fio_net_port;
+
+	if (!strncmp(str, "sock:", 5)) {
+		*ptr = strdup(str + 5);
+		*is_sock = 1;
+	} else {
+		const char *host = str;
+		char *portp;
+		int lport = 0;
+
+		/*
+		 * Is it ip:<ip or host>:port
+		 */
+		if (!strncmp(host, "ip:", 3))
+			host += 3;
+		else if (host[0] == ':') {
+			/* String is :port */
+			host++;
+			lport = atoi(host);
+			if (!lport || lport > 65535) {
+				log_err("fio: bad server port %u\n", port);
+				return 1;
+			}
+			/* no hostname given, we are done */
+			*port = lport;
+			return 0;
+		}
+
+		/*
+		 * If no port seen yet, check if there's a last ':' at the end
+		 */
+		if (!lport) {
+			portp = strchr(host, ':');
+			if (portp) {
+				*portp = '\0';
+				portp++;
+				lport = atoi(portp);
+				if (!lport || lport > 65535) {
+					log_err("fio: bad server port %u\n", port);
+					return 1;
+				}
+			}
+		}
+
+		if (lport)
+			*port = lport;
+
+		*ptr = strdup(host);
+
+		if (inet_aton(host, inp) != 1) {
+			struct hostent *hent;
+
+			hent = gethostbyname(host);
+			if (!hent) {
+				free(*ptr);
+				*ptr = NULL;
+				return 1;
+			}
+
+			memcpy(inp, hent->h_addr, 4);
+		}
+	}
+
+	if (*port == 0)
+		*port = fio_net_port;
+
+	return 0;
+}
+
+/*
+ * Server arg should be one of:
+ *
+ * sock:/path/to/socket
+ *   ip:1.2.3.4
+ *      1.2.3.4
+ *
+ * Where sock uses unix domain sockets, and ip binds the server to
+ * a specific interface. If no arguments are given to the server, it
+ * uses IP and binds to 0.0.0.0.
+ *
+ */
+static int fio_handle_server_arg(void)
+{
+	int port = fio_net_port;
+	int is_sock, ret = 0;
+
+	saddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+
+	if (!fio_server_arg)
+		goto out;
+
+	ret = fio_server_parse_string(fio_server_arg, &bind_sock, &is_sock,
+					&port, &saddr_in.sin_addr);
+
+	if (!is_sock && bind_sock) {
+		free(bind_sock);
+		bind_sock = NULL;
+	}
+
+out:
+	fio_net_port = port;
+	saddr_in.sin_port = htons(port);
+	return ret;
+}
+
+static int fio_server(void)
+{
+	int sk, ret;
+
+	dprint(FD_NET, "starting server\n");
+
+	if (fio_handle_server_arg())
+		return -1;
+
+	sk = fio_init_server_connection();
+	if (sk < 0)
+		return -1;
+
+	ret = accept_loop(sk);
+
+	close(sk);
+
+	if (fio_server_arg) {
+		free(fio_server_arg);
+		fio_server_arg = NULL;
+	}
+	if (bind_sock)
+		free(bind_sock);
+
+	return ret;
+}
+
+void fio_server_got_signal(int signal)
+{
+	if (signal == SIGPIPE)
+		server_fd = -1;
+	else {
+		log_info("\nfio: terminating on signal %d\n", signal);
+		exit_backend = 1;
+	}
+}
+
+static int check_existing_pidfile(const char *pidfile)
+{
+	struct stat sb;
+	char buf[16];
+	pid_t pid;
+	FILE *f;
+
+	if (stat(pidfile, &sb))
+		return 0;
+
+	f = fopen(pidfile, "r");
+	if (!f)
+		return 0;
+
+	if (fread(buf, sb.st_size, 1, f) <= 0) {
+		fclose(f);
+		return 1;
+	}
+	fclose(f);
+
+	pid = atoi(buf);
+	if (kill(pid, SIGCONT) < 0)
+		return errno != ESRCH;
+
+	return 1;
+}
+
+static int write_pid(pid_t pid, const char *pidfile)
+{
+	FILE *fpid;
+
+	fpid = fopen(pidfile, "w");
+	if (!fpid) {
+		log_err("fio: failed opening pid file %s\n", pidfile);
+		return 1;
+	}
+
+	fprintf(fpid, "%u\n", (unsigned int) pid);
+	fclose(fpid);
+	return 0;
+}
+
+/*
+ * If pidfile is specified, background us.
+ */
+int fio_start_server(char *pidfile)
+{
+	pid_t pid;
+	int ret;
+
+	if (!pidfile)
+		return fio_server();
+
+	if (check_existing_pidfile(pidfile)) {
+		log_err("fio: pidfile %s exists and server appears alive\n",
+								pidfile);
+		return -1;
+	}
+
+	pid = fork();
+	if (pid < 0) {
+		log_err("fio: failed server fork: %s", strerror(errno));
+		free(pidfile);
+		return -1;
+	} else if (pid) {
+		int ret = write_pid(pid, pidfile);
+
+		exit(ret);
+	}
+
+	setsid();
+	openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
+	log_syslog = 1;
+	close(STDIN_FILENO);
+	close(STDOUT_FILENO);
+	close(STDERR_FILENO);
+	f_out = NULL;
+	f_err = NULL;
+
+	ret = fio_server();
+
+	closelog();
+	unlink(pidfile);
+	free(pidfile);
+	return ret;
+}
+
+void fio_server_set_arg(const char *arg)
+{
+	fio_server_arg = strdup(arg);
+}
diff --git a/server.h b/server.h
new file mode 100644
index 0000000..d709e98
--- /dev/null
+++ b/server.h
@@ -0,0 +1,144 @@
+#ifndef FIO_SERVER_H
+#define FIO_SERVER_H
+
+#include <inttypes.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "stat.h"
+#include "os/os.h"
+#include "diskutil.h"
+
+/*
+ * On-wire encoding is little endian
+ */
+struct fio_net_cmd {
+	uint16_t version;	/* protocol version */
+	uint16_t opcode;	/* command opcode */
+	uint32_t flags;		/* modifier flags */
+	uint64_t tag;		/* passed back on reply */
+	uint32_t pdu_len;	/* length of post-cmd layload */
+	/*
+	 * These must be immediately before the payload, anything before
+	 * these fields are checksummed.
+	 */
+	uint16_t cmd_crc16;	/* cmd checksum */
+	uint16_t pdu_crc16;	/* payload checksum */
+	uint8_t payload[0];	/* payload */
+};
+
+struct fio_net_int_cmd {
+	struct fio_net_cmd cmd;
+	struct flist_head list;
+	struct timeval tv;
+	uint64_t saved_tag;
+};
+
+enum {
+	FIO_SERVER_VER		= 5,
+
+	FIO_SERVER_MAX_PDU	= 1024,
+
+	FIO_NET_CMD_QUIT	= 1,
+	FIO_NET_CMD_EXIT	= 2,
+	FIO_NET_CMD_JOB		= 3,
+	FIO_NET_CMD_JOBLINE	= 4,
+	FIO_NET_CMD_TEXT	= 5,
+	FIO_NET_CMD_TS		= 6,
+	FIO_NET_CMD_GS		= 7,
+	FIO_NET_CMD_SEND_ETA	= 8,
+	FIO_NET_CMD_ETA		= 9,
+	FIO_NET_CMD_PROBE	= 10,
+	FIO_NET_CMD_START	= 11,
+	FIO_NET_CMD_STOP	= 12,
+	FIO_NET_CMD_DU		= 13,
+	FIO_NET_CMD_NR		= 14,
+
+	FIO_NET_CMD_F_MORE	= 1UL << 0,
+
+	/* crc does not include the crc fields */
+	FIO_NET_CMD_CRC_SZ	= sizeof(struct fio_net_cmd) -
+					2 * sizeof(uint16_t),
+
+	FIO_NET_CLIENT_TIMEOUT	= 5000,
+};
+
+struct cmd_ts_pdu {
+	struct thread_stat ts;
+	struct group_run_stats rs;
+};
+
+struct cmd_du_pdu {
+	struct disk_util_stat dus;
+	struct disk_util_agg agg;
+};
+
+struct cmd_probe_pdu {
+	uint8_t hostname[64];
+	uint8_t bigendian;
+	uint8_t fio_major;
+	uint8_t fio_minor;
+	uint8_t fio_patch;
+	uint8_t os;
+	uint8_t arch;
+	uint8_t bpp;
+};
+
+struct cmd_single_line_pdu {
+	uint16_t len;
+	uint8_t text[0];
+};
+
+struct cmd_line_pdu {
+	uint16_t lines;
+	struct cmd_single_line_pdu options[0];
+};
+
+extern int fio_start_server(char *);
+extern int fio_server_text_output(const char *, size_t);
+extern int fio_server_log(const char *format, ...);
+extern int fio_net_send_cmd(int, uint16_t, const void *, off_t, uint64_t);
+extern int fio_net_send_simple_cmd(int, uint16_t, uint64_t, struct flist_head *);
+extern void fio_server_set_arg(const char *);
+extern int fio_server_parse_string(const char *, char **, int *, int *, struct in_addr *);
+extern const char *fio_server_op(unsigned int);
+extern void fio_server_got_signal(int);
+
+struct thread_stat;
+struct group_run_stats;
+extern void fio_server_send_ts(struct thread_stat *, struct group_run_stats *);
+extern void fio_server_send_gs(struct group_run_stats *);
+extern void fio_server_send_du(void);
+extern void fio_server_idle_loop(void);
+
+extern int fio_clients_connect(void);
+extern int fio_clients_send_ini(const char *);
+extern int fio_handle_clients(void);
+extern int fio_client_add(const char *, void **);
+extern void fio_client_add_cmd_option(void *, const char *);
+
+extern int fio_recv_data(int sk, void *p, unsigned int len);
+extern int fio_send_data(int sk, const void *p, unsigned int len);
+extern void fio_net_cmd_crc(struct fio_net_cmd *);
+extern struct fio_net_cmd *fio_net_recv_cmd(int sk);
+
+extern int exit_backend;
+extern int fio_net_port;
+
+static inline void fio_init_net_cmd(struct fio_net_cmd *cmd, uint16_t opcode,
+				    const void *pdu, uint32_t pdu_len,
+				    uint64_t tag)
+{
+	memset(cmd, 0, sizeof(*cmd));
+
+	cmd->version	= __cpu_to_le16(FIO_SERVER_VER);
+	cmd->opcode	= cpu_to_le16(opcode);
+	cmd->tag	= cpu_to_le64(tag);
+
+	if (pdu) {
+		cmd->pdu_len	= cpu_to_le32(pdu_len);
+		memcpy(&cmd->payload, pdu, pdu_len);
+	}
+}
+
+#endif
diff --git a/stat.c b/stat.c
index 3662fd9..d310686 100644
--- a/stat.c
+++ b/stat.c
@@ -9,23 +9,24 @@
 
 #include "fio.h"
 #include "diskutil.h"
+#include "lib/ieee754.h"
 
 void update_rusage_stat(struct thread_data *td)
 {
 	struct thread_stat *ts = &td->ts;
 
-	getrusage(RUSAGE_SELF, &ts->ru_end);
+	getrusage(RUSAGE_SELF, &td->ru_end);
 
-	ts->usr_time += mtime_since(&ts->ru_start.ru_utime,
-					&ts->ru_end.ru_utime);
-	ts->sys_time += mtime_since(&ts->ru_start.ru_stime,
-					&ts->ru_end.ru_stime);
-	ts->ctx += ts->ru_end.ru_nvcsw + ts->ru_end.ru_nivcsw
-			- (ts->ru_start.ru_nvcsw + ts->ru_start.ru_nivcsw);
-	ts->minf += ts->ru_end.ru_minflt - ts->ru_start.ru_minflt;
-	ts->majf += ts->ru_end.ru_majflt - ts->ru_start.ru_majflt;
+	ts->usr_time += mtime_since(&td->ru_start.ru_utime,
+					&td->ru_end.ru_utime);
+	ts->sys_time += mtime_since(&td->ru_start.ru_stime,
+					&td->ru_end.ru_stime);
+	ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
+			- (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
+	ts->minf += td->ru_end.ru_minflt - td->ru_start.ru_minflt;
+	ts->majf += td->ru_end.ru_majflt - td->ru_start.ru_majflt;
 
-	memcpy(&ts->ru_start, &ts->ru_end, sizeof(ts->ru_end));
+	memcpy(&td->ru_start, &td->ru_end, sizeof(td->ru_end));
 }
 
 /*
@@ -101,72 +102,136 @@ static unsigned int plat_idx_to_val(unsigned int idx)
 
 static int double_cmp(const void *a, const void *b)
 {
-	const double fa = *(const double *)a;
-	const double fb = *(const double *)b;
+	const fio_fp64_t fa = *(const fio_fp64_t *) a;
+	const fio_fp64_t fb = *(const fio_fp64_t *) b;
 	int cmp = 0;
 
-	if (fa > fb)
+	if (fa.u.f > fb.u.f)
 		cmp = 1;
-	else if (fa < fb)
+	else if (fa.u.f < fb.u.f)
 		cmp = -1;
 
 	return cmp;
 }
 
-/*
- * Find and display the p-th percentile of clat
- */
-static void show_clat_percentiles(unsigned int* io_u_plat, unsigned long nr,
-				 double* user_list)
+static unsigned int calc_clat_percentiles(unsigned int *io_u_plat,
+					  unsigned long nr, fio_fp64_t *plist,
+					  unsigned int **output,
+					  unsigned int *maxv,
+					  unsigned int *minv)
 {
 	unsigned long sum = 0;
 	unsigned int len, i, j = 0;
-	const double *plist;
-	int is_last = 0;
-	static const double def_list[FIO_IO_U_LIST_MAX_LEN] = {
-			1.0, 5.0, 10.0, 20.0, 30.0,
-			40.0, 50.0, 60.0, 70.0, 80.0,
-			90.0, 95.0, 99.0, 99.5, 99.9};
+	unsigned int oval_len = 0;
+	unsigned int *ovals = NULL;
+	int is_last;
+
+	*minv = -1U;
+	*maxv = 0;
 
-	plist = user_list;
-	if (!plist)
-		plist = def_list;
+	len = 0;
+	while (len < FIO_IO_U_LIST_MAX_LEN && plist[len].u.f != 0.0)
+		len++;
 
-	for (len = 0; len <FIO_IO_U_LIST_MAX_LEN && plist[len] != 0; len++)
-		;
+	if (!len)
+		return 0;
 
 	/*
-	 * Sort the user-specified list. Note that this does not work
-	 * for NaN values
+	 * Sort the percentile list. Note that it may already be sorted if
+	 * we are using the default values, but since it's a short list this
+	 * isn't a worry. Also note that this does not work for NaN values.
 	 */
-	if (user_list && len > 1)
-		qsort((void*)user_list, len, sizeof(user_list[0]), double_cmp);
-
-	log_info("    clat percentiles (usec) :");
+	if (len > 1)
+		qsort((void*)plist, len, sizeof(plist[0]), double_cmp);
 
+	/*
+	 * Calculate bucket values, note down max and min values
+	 */
+	is_last = 0;
 	for (i = 0; i < FIO_IO_U_PLAT_NR && !is_last; i++) {
 		sum += io_u_plat[i];
-		while (sum >= (plist[j] / 100 * nr)) {
-			assert(plist[j] <= 100.0);
+		while (sum >= (plist[j].u.f / 100.0 * nr)) {
+			assert(plist[j].u.f <= 100.0);
 
-			/* for formatting */
-			if (j != 0 && (j % 4) == 0)
-				log_info("                             ");
-
-			/* end of the list */
-			is_last = (j == len - 1);
+			if (j == oval_len) {
+				oval_len += 100;
+				ovals = realloc(ovals, oval_len * sizeof(unsigned int));
+			}
 
-			log_info(" %2.2fth=%u%c", plist[j], plat_idx_to_val(i),
-				 (is_last? '\n' : ','));
+			ovals[j] = plat_idx_to_val(i);
+			if (ovals[j] < *minv)
+				*minv = ovals[j];
+			if (ovals[j] > *maxv)
+				*maxv = ovals[j];
 
+			is_last = (j == len - 1);
 			if (is_last)
 				break;
 
-			if (j % 4 == 3)	/* for formatting */
-				log_info("\n");
 			j++;
 		}
 	}
+
+	*output = ovals;
+	return len;
+}
+
+/*
+ * Find and display the p-th percentile of clat
+ */
+static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long nr,
+				  fio_fp64_t *plist)
+{
+	unsigned int len, j = 0, minv, maxv;
+	unsigned int *ovals;
+	int is_last, scale_down;
+
+	len = calc_clat_percentiles(io_u_plat, nr, plist, &ovals, &maxv, &minv);
+	if (!len)
+		goto out;
+
+	/*
+	 * We default to usecs, but if the value range is such that we
+	 * should scale down to msecs, do that.
+	 */
+	if (minv > 2000 && maxv > 99999) {
+		scale_down = 1;
+		log_info("    clat percentiles (msec):\n     |");
+	} else {
+		scale_down = 0;
+		log_info("    clat percentiles (usec):\n     |");
+	}
+
+	for (j = 0; j < len; j++) {
+		char fbuf[8];
+
+		/* for formatting */
+		if (j != 0 && (j % 4) == 0)
+			log_info("     |");
+
+		/* end of the list */
+		is_last = (j == len - 1);
+
+		if (plist[j].u.f < 10.0)
+			sprintf(fbuf, " %2.2f", plist[j].u.f);
+		else
+			sprintf(fbuf, "%2.2f", plist[j].u.f);
+
+		if (scale_down)
+			ovals[j] = (ovals[j] + 999) / 1000;
+
+		log_info(" %sth=[%5u]%c", fbuf, ovals[j], is_last ? '\n' : ',');
+
+		if (is_last)
+			break;
+
+		if (j % 4 == 3)	/* for formatting */
+			log_info("\n");
+	}
+
+out:
+	if (ovals)
+		free(ovals);
 }
 
 static int calc_lat(struct io_stat *is, unsigned long *min, unsigned long *max,
@@ -181,23 +246,23 @@ static int calc_lat(struct io_stat *is, unsigned long *min, unsigned long *max,
 	*max = is->max_val;
 
 	n = (double) is->samples;
-	*mean = is->mean;
+	*mean = is->mean.u.f;
 
 	if (n > 1.0)
-		*dev = sqrt(is->S / (n - 1.0));
+		*dev = sqrt(is->S.u.f / (n - 1.0));
 	else
 		*dev = 0;
 
 	return 1;
 }
 
-static void show_group_stats(struct group_run_stats *rs, int id)
+void show_group_stats(struct group_run_stats *rs)
 {
 	char *p1, *p2, *p3, *p4;
 	const char *ddir_str[] = { "   READ", "  WRITE" };
 	int i;
 
-	log_info("\nRun status group %d (all jobs):\n", id);
+	log_info("Run status group %d (all jobs):\n", rs->groupid);
 
 	for (i = 0; i <= DDIR_WRITE; i++) {
 		const int i2p = is_power_of_2(rs->kb_base);
@@ -378,7 +443,7 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 		double p_of_agg;
 
 		p_of_agg = mean * 100 / (double) rs->agg[ddir];
-		log_info("    bw (KB/s) : min=%5lu, max=%5lu, per=%3.2f%%,"
+		log_info("     bw (KB/s) : min=%5lu, max=%5lu, per=%3.2f%%,"
 			 " avg=%5.02f, stdev=%5.02f\n", min, max, p_of_agg,
 							mean, dev);
 	}
@@ -433,8 +498,7 @@ static void show_latencies(double *io_u_lat_u, double *io_u_lat_m)
 	log_info("\n");
 }
 
-static void show_thread_status(struct thread_stat *ts,
-			       struct group_run_stats *rs)
+void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs)
 {
 	double usr_cpu, sys_cpu;
 	unsigned long runtime;
@@ -456,7 +520,7 @@ static void show_thread_status(struct thread_stat *ts,
 					ts->error, ts->verror, (int) ts->pid);
 	}
 
-	if (ts->description)
+	if (strlen(ts->description))
 		log_info("  Description  : [%s]\n", ts->description);
 
 	if (ts->io_bytes[DDIR_READ])
@@ -517,16 +581,23 @@ static void show_ddir_status_terse(struct thread_stat *ts,
 				   struct group_run_stats *rs, int ddir)
 {
 	unsigned long min, max;
-	unsigned long long bw;
+	unsigned long long bw, iops;
+	unsigned int *ovals = NULL;
 	double mean, dev;
+	unsigned int len, minv, maxv;
+	int i;
 
 	assert(ddir_rw(ddir));
 
-	bw = 0;
-	if (ts->runtime[ddir])
-		bw = ts->io_bytes[ddir] / ts->runtime[ddir];
+	iops = bw = 0;
+	if (ts->runtime[ddir]) {
+		uint64_t runt = ts->runtime[ddir];
+
+		bw = ts->io_bytes[ddir] / runt;
+		iops = (1000 * (uint64_t) ts->total_io_u[ddir]) / runt;
+	}
 
-	log_info(";%llu;%llu;%llu", ts->io_bytes[ddir] >> 10, bw,
+	log_info(";%llu;%llu;%llu;%llu", ts->io_bytes[ddir] >> 10, bw, iops,
 							ts->runtime[ddir]);
 
 	if (calc_lat(&ts->slat_stat[ddir], &min, &max, &mean, &dev))
@@ -544,6 +615,24 @@ static void show_ddir_status_terse(struct thread_stat *ts,
 	else
 		log_info(";%lu;%lu;%f;%f", 0UL, 0UL, 0.0, 0.0);
 
+	if (ts->clat_percentiles) {
+		len = calc_clat_percentiles(ts->io_u_plat[ddir],
+					ts->clat_stat[ddir].samples,
+					ts->percentile_list, &ovals, &maxv,
+					&minv);
+	} else
+		len = 0;
+
+	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++) {
+		if (i >= len) {
+			log_info(";0%%=0");
+			continue;
+		}
+		log_info(";%2.2f%%=%u", ts->percentile_list[i].u.f, ovals[i]);
+	}
+	if (ovals)
+		free(ovals);
+
 	if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
 		double p_of_agg;
 
@@ -553,7 +642,7 @@ static void show_ddir_status_terse(struct thread_stat *ts,
 		log_info(";%lu;%lu;%f%%;%f;%f", 0UL, 0UL, 0.0, 0.0, 0.0);
 }
 
-#define FIO_TERSE_VERSION	"2"
+#define FIO_TERSE_VERSION	"3"
 
 static void show_thread_status_terse(struct thread_stat *ts,
 				     struct group_run_stats *rs)
@@ -602,16 +691,18 @@ static void show_thread_status_terse(struct thread_stat *ts,
 	/* Millisecond latency */
 	for (i = 0; i < FIO_IO_U_LAT_M_NR; i++)
 		log_info(";%3.2f%%", io_u_lat_m[i]);
+
+	/* disk util stats, if any */
+	show_disk_util(1);
+
 	/* 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("\n");
 
 	/* Additional output if description is set */
-	if (ts->description)
+	if (strlen(ts->description))
 		log_info(";%s", ts->description);
-
-	log_info("\n");
 }
 
 static void sum_stat(struct io_stat *dst, struct io_stat *src, int nr)
@@ -630,23 +721,114 @@ static void sum_stat(struct io_stat *dst, struct io_stat *src, int nr)
 	 *  #Parallel_algorithm>
 	 */
 	if (nr == 1) {
-		mean = src->mean;
-		S = src->S;
+		mean = src->mean.u.f;
+		S = src->S.u.f;
 	} else {
-		double delta = src->mean - dst->mean;
+		double delta = src->mean.u.f - dst->mean.u.f;
 
-		mean = ((src->mean * src->samples) +
-			(dst->mean * dst->samples)) /
+		mean = ((src->mean.u.f * src->samples) +
+			(dst->mean.u.f * dst->samples)) /
 			(dst->samples + src->samples);
 
-		S =  src->S + dst->S + pow(delta, 2.0) *
+		S =  src->S.u.f + dst->S.u.f + pow(delta, 2.0) *
 			(dst->samples * src->samples) /
 			(dst->samples + src->samples);
 	}
 
 	dst->samples += src->samples;
-	dst->mean = mean;
-	dst->S = S;
+	dst->mean.u.f = mean;
+	dst->S.u.f = S;
+}
+
+void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (dst->max_run[i] < src->max_run[i])
+			dst->max_run[i] = src->max_run[i];
+		if (dst->min_run[i] && dst->min_run[i] > src->min_run[i])
+			dst->min_run[i] = src->min_run[i];
+		if (dst->max_bw[i] < src->max_bw[i])
+			dst->max_bw[i] = src->max_bw[i];
+		if (dst->min_bw[i] && dst->min_bw[i] > src->min_bw[i])
+			dst->min_bw[i] = src->min_bw[i];
+
+		dst->io_kb[i] += src->io_kb[i];
+		dst->agg[i] += src->agg[i];
+	}
+
+}
+
+void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr)
+{
+	int l, k;
+
+	for (l = 0; l <= DDIR_WRITE; l++) {
+		sum_stat(&dst->clat_stat[l], &src->clat_stat[l], nr);
+		sum_stat(&dst->slat_stat[l], &src->slat_stat[l], nr);
+		sum_stat(&dst->lat_stat[l], &src->lat_stat[l], nr);
+		sum_stat(&dst->bw_stat[l], &src->bw_stat[l], nr);
+
+		dst->io_bytes[l] += src->io_bytes[l];
+
+		if (dst->runtime[l] < src->runtime[l])
+			dst->runtime[l] = src->runtime[l];
+	}
+
+	dst->usr_time += src->usr_time;
+	dst->sys_time += src->sys_time;
+	dst->ctx += src->ctx;
+	dst->majf += src->majf;
+	dst->minf += src->minf;
+
+	for (k = 0; k < FIO_IO_U_MAP_NR; k++)
+		dst->io_u_map[k] += src->io_u_map[k];
+	for (k = 0; k < FIO_IO_U_MAP_NR; k++)
+		dst->io_u_submit[k] += src->io_u_submit[k];
+	for (k = 0; k < FIO_IO_U_MAP_NR; k++)
+		dst->io_u_complete[k] += src->io_u_complete[k];
+	for (k = 0; k < FIO_IO_U_LAT_U_NR; k++)
+		dst->io_u_lat_u[k] += src->io_u_lat_u[k];
+	for (k = 0; k < FIO_IO_U_LAT_M_NR; k++)
+		dst->io_u_lat_m[k] += src->io_u_lat_m[k];
+
+	for (k = 0; k <= 2; k++) {
+		dst->total_io_u[k] += src->total_io_u[k];
+		dst->short_io_u[k] += src->short_io_u[k];
+	}
+
+	for (k = 0; k <= DDIR_WRITE; k++) {
+		int m;
+		for (m = 0; m < FIO_IO_U_PLAT_NR; m++)
+			dst->io_u_plat[k][m] += src->io_u_plat[k][m];
+	}
+
+	dst->total_run_time += src->total_run_time;
+	dst->total_submit += src->total_submit;
+	dst->total_complete += src->total_complete;
+}
+
+void init_group_run_stat(struct group_run_stats *gs)
+{
+	memset(gs, 0, sizeof(*gs));
+	gs->min_bw[0] = gs->min_run[0] = ~0UL;
+	gs->min_bw[1] = gs->min_run[1] = ~0UL;
+}
+
+void init_thread_stat(struct thread_stat *ts)
+{
+	int j;
+
+	memset(ts, 0, sizeof(*ts));
+
+	for (j = 0; j <= DDIR_WRITE; j++) {
+		ts->lat_stat[j].min_val = -1UL;
+		ts->clat_stat[j].min_val = -1UL;
+		ts->slat_stat[j].min_val = -1UL;
+		ts->bw_stat[j].min_val = -1UL;
+	}
+	ts->groupid = -1;
 }
 
 void show_run_stats(void)
@@ -654,18 +836,13 @@ void show_run_stats(void)
 	struct group_run_stats *runstats, *rs;
 	struct thread_data *td;
 	struct thread_stat *threadstats, *ts;
-	int i, j, k, l, nr_ts, last_ts, idx;
+	int i, j, nr_ts, last_ts, idx;
 	int kb_base_warned = 0;
 
 	runstats = malloc(sizeof(struct group_run_stats) * (groupid + 1));
 
-	for (i = 0; i < groupid + 1; i++) {
-		rs = &runstats[i];
-
-		memset(rs, 0, sizeof(*rs));
-		rs->min_bw[0] = rs->min_run[0] = ~0UL;
-		rs->min_bw[1] = rs->min_run[1] = ~0UL;
-	}
+	for (i = 0; i < groupid + 1; i++)
+		init_group_run_stat(&runstats[i]);
 
 	/*
 	 * find out how many threads stats we need. if group reporting isn't
@@ -687,18 +864,8 @@ void show_run_stats(void)
 
 	threadstats = malloc(nr_ts * sizeof(struct thread_stat));
 
-	for (i = 0; i < nr_ts; i++) {
-		ts = &threadstats[i];
-
-		memset(ts, 0, sizeof(*ts));
-		for (j = 0; j <= DDIR_WRITE; j++) {
-			ts->lat_stat[j].min_val = -1UL;
-			ts->clat_stat[j].min_val = -1UL;
-			ts->slat_stat[j].min_val = -1UL;
-			ts->bw_stat[j].min_val = -1UL;
-		}
-		ts->groupid = -1;
-	}
+	for (i = 0; i < nr_ts; i++)
+		init_thread_stat(&threadstats[i]);
 
 	j = 0;
 	last_ts = -1;
@@ -716,9 +883,9 @@ void show_run_stats(void)
 
 		ts->clat_percentiles = td->o.clat_percentiles;
 		if (td->o.overwrite_plist)
-			ts->percentile_list = td->o.percentile_list;
+			memcpy(ts->percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
 		else
-			ts->percentile_list = NULL;
+			memcpy(ts->percentile_list, def_percentile_list, sizeof(def_percentile_list));
 
 		idx++;
 		ts->members++;
@@ -727,8 +894,13 @@ void show_run_stats(void)
 			/*
 			 * These are per-group shared already
 			 */
-			ts->name = td->o.name;
-			ts->description = td->o.description;
+			strncpy(ts->name, td->o.name, FIO_JOBNAME_SIZE);
+			if (td->o.description)
+				strncpy(ts->description, td->o.description,
+						FIO_JOBNAME_SIZE);
+			else
+				memset(ts->description, 0, FIO_JOBNAME_SIZE);
+
 			ts->groupid = td->groupid;
 
 			/*
@@ -750,58 +922,14 @@ void show_run_stats(void)
 			if (!td->error && td->o.continue_on_error &&
 			    td->first_error) {
 				ts->error = td->first_error;
-				ts->verror = td->verror;
+				strcpy(ts->verror, td->verror);
 			} else  if (td->error) {
 				ts->error = td->error;
-				ts->verror = td->verror;
+				strcpy(ts->verror, td->verror);
 			}
 		}
 
-		for (l = 0; l <= DDIR_WRITE; l++) {
-			sum_stat(&ts->clat_stat[l], &td->ts.clat_stat[l], idx);
-			sum_stat(&ts->slat_stat[l], &td->ts.slat_stat[l], idx);
-			sum_stat(&ts->lat_stat[l], &td->ts.lat_stat[l], idx);
-			sum_stat(&ts->bw_stat[l], &td->ts.bw_stat[l], idx);
-
-			ts->stat_io_bytes[l] += td->ts.stat_io_bytes[l];
-			ts->io_bytes[l] += td->ts.io_bytes[l];
-
-			if (ts->runtime[l] < td->ts.runtime[l])
-				ts->runtime[l] = td->ts.runtime[l];
-		}
-
-		ts->usr_time += td->ts.usr_time;
-		ts->sys_time += td->ts.sys_time;
-		ts->ctx += td->ts.ctx;
-		ts->majf += td->ts.majf;
-		ts->minf += td->ts.minf;
-
-		for (k = 0; k < FIO_IO_U_MAP_NR; k++)
-			ts->io_u_map[k] += td->ts.io_u_map[k];
-		for (k = 0; k < FIO_IO_U_MAP_NR; k++)
-			ts->io_u_submit[k] += td->ts.io_u_submit[k];
-		for (k = 0; k < FIO_IO_U_MAP_NR; k++)
-			ts->io_u_complete[k] += td->ts.io_u_complete[k];
-		for (k = 0; k < FIO_IO_U_LAT_U_NR; k++)
-			ts->io_u_lat_u[k] += td->ts.io_u_lat_u[k];
-		for (k = 0; k < FIO_IO_U_LAT_M_NR; k++)
-			ts->io_u_lat_m[k] += td->ts.io_u_lat_m[k];
-
-
-		for (k = 0; k <= 2; k++) {
-			ts->total_io_u[k] += td->ts.total_io_u[k];
-			ts->short_io_u[k] += td->ts.short_io_u[k];
-		}
-
-		for (k = 0; k <= DDIR_WRITE; k++) {
-			int m;
-			for (m = 0; m < FIO_IO_U_PLAT_NR; m++)
-				ts->io_u_plat[k][m] += td->ts.io_u_plat[k][m];
-		}
-
-		ts->total_run_time += td->ts.total_run_time;
-		ts->total_submit += td->ts.total_submit;
-		ts->total_complete += td->ts.total_complete;
+		sum_thread_stats(ts, &td->ts, idx);
 	}
 
 	for (i = 0; i < nr_ts; i++) {
@@ -858,17 +986,31 @@ void show_run_stats(void)
 		ts = &threadstats[i];
 		rs = &runstats[ts->groupid];
 
-		if (terse_output)
+		if (is_backend)
+			fio_server_send_ts(ts, rs);
+		else if (terse_output)
 			show_thread_status_terse(ts, rs);
 		else
 			show_thread_status(ts, rs);
 	}
 
 	if (!terse_output) {
-		for (i = 0; i < groupid + 1; i++)
-			show_group_stats(&runstats[i], i);
+		for (i = 0; i < groupid + 1; i++) {
+			rs = &runstats[i];
+
+			rs->groupid = i;
+			if (is_backend)
+				fio_server_send_gs(rs);
+			else
+				show_group_stats(rs);
+		}
+
+		if (is_backend)
+			fio_server_send_du();
+		else
+			show_disk_util(0);
 
-		show_disk_util();
+		free_disk_util();
 	}
 
 	free(runstats);
@@ -885,10 +1027,10 @@ static inline void add_stat_sample(struct io_stat *is, unsigned long data)
 	if (data < is->min_val)
 		is->min_val = data;
 
-	delta = val - is->mean;
+	delta = val - is->mean.u.f;
 	if (delta) {
-		is->mean += delta / (is->samples + 1.0);
-		is->S += delta * (val - is->mean);
+		is->mean.u.f += delta / (is->samples + 1.0);
+		is->S.u.f += delta * (val - is->mean.u.f);
 	}
 
 	is->samples++;
@@ -954,8 +1096,8 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	add_stat_sample(&ts->clat_stat[ddir], usec);
 
-	if (ts->clat_log)
-		add_log_sample(td, ts->clat_log, usec, ddir, bs);
+	if (td->clat_log)
+		add_log_sample(td, td->clat_log, usec, ddir, bs);
 
 	if (ts->clat_percentiles)
 		add_clat_percentile_sample(ts, usec, ddir);
@@ -971,8 +1113,8 @@ void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	add_stat_sample(&ts->slat_stat[ddir], usec);
 
-	if (ts->slat_log)
-		add_log_sample(td, ts->slat_log, usec, ddir, bs);
+	if (td->slat_log)
+		add_log_sample(td, td->slat_log, usec, ddir, bs);
 }
 
 void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
@@ -985,8 +1127,8 @@ void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	add_stat_sample(&ts->lat_stat[ddir], usec);
 
-	if (ts->lat_log)
-		add_log_sample(td, ts->lat_log, usec, ddir, bs);
+	if (td->lat_log)
+		add_log_sample(td, td->lat_log, usec, ddir, bs);
 }
 
 void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs,
@@ -998,17 +1140,43 @@ void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs,
 	if (!ddir_rw(ddir))
 		return;
 
-	spent = mtime_since(&ts->stat_sample_time[ddir], t);
+	spent = mtime_since(&td->bw_sample_time, t);
 	if (spent < td->o.bw_avg_time)
 		return;
 
-	rate = (td->this_io_bytes[ddir] - ts->stat_io_bytes[ddir]) *
+	rate = (td->this_io_bytes[ddir] - td->stat_io_bytes[ddir]) *
 			1000 / spent / 1024;
 	add_stat_sample(&ts->bw_stat[ddir], rate);
 
-	if (ts->bw_log)
-		add_log_sample(td, ts->bw_log, rate, ddir, bs);
+	if (td->bw_log)
+		add_log_sample(td, td->bw_log, rate, ddir, bs);
+
+	fio_gettime(&td->bw_sample_time, NULL);
+	td->stat_io_bytes[ddir] = td->this_io_bytes[ddir];
+}
+
+void add_iops_sample(struct thread_data *td, enum fio_ddir ddir,
+		     struct timeval *t)
+{
+	struct thread_stat *ts = &td->ts;
+	unsigned long spent, iops;
+
+	if (!ddir_rw(ddir))
+		return;
+
+	spent = mtime_since(&td->iops_sample_time, t);
+	if (spent < td->o.iops_avg_time)
+		return;
+
+	iops = ((td->this_io_blocks[ddir] - td->stat_io_blocks[ddir]) * 1000) / spent;
+
+	add_stat_sample(&ts->iops_stat[ddir], iops);
+
+	if (td->iops_log) {
+		assert(iops);
+		add_log_sample(td, td->iops_log, iops, ddir, 0);
+	}
 
-	fio_gettime(&ts->stat_sample_time[ddir], NULL);
-	ts->stat_io_bytes[ddir] = td->this_io_bytes[ddir];
+	fio_gettime(&td->iops_sample_time, NULL);
+	td->stat_io_blocks[ddir] = td->this_io_blocks[ddir];
 }
diff --git a/stat.h b/stat.h
new file mode 100644
index 0000000..3115539
--- /dev/null
+++ b/stat.h
@@ -0,0 +1,201 @@
+#ifndef FIO_STAT_H
+#define FIO_STAT_H
+
+struct group_run_stats {
+	uint64_t max_run[2], min_run[2];
+	uint64_t max_bw[2], min_bw[2];
+	uint64_t io_kb[2];
+	uint64_t agg[2];
+	uint32_t kb_base;
+	uint32_t groupid;
+};
+
+/*
+ * How many depth levels to log
+ */
+#define FIO_IO_U_MAP_NR	7
+#define FIO_IO_U_LAT_U_NR 10
+#define FIO_IO_U_LAT_M_NR 12
+
+/*
+ * Aggregate clat samples to report percentile(s) of them.
+ *
+ * EXECUTIVE SUMMARY
+ *
+ * FIO_IO_U_PLAT_BITS determines the maximum statistical error on the
+ * value of resulting percentiles. The error will be approximately
+ * 1/2^(FIO_IO_U_PLAT_BITS+1) of the value.
+ *
+ * FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the maximum
+ * range being tracked for latency samples. The maximum value tracked
+ * accurately will be 2^(GROUP_NR + PLAT_BITS -1) microseconds.
+ *
+ * FIO_IO_U_PLAT_GROUP_NR and FIO_IO_U_PLAT_BITS determine the memory
+ * requirement of storing those aggregate counts. The memory used will
+ * be (FIO_IO_U_PLAT_GROUP_NR * 2^FIO_IO_U_PLAT_BITS) * sizeof(int)
+ * bytes.
+ *
+ * FIO_IO_U_PLAT_NR is the total number of buckets.
+ *
+ * DETAILS
+ *
+ * Suppose the clat varies from 0 to 999 (usec), the straightforward
+ * method is to keep an array of (999 + 1) buckets, in which a counter
+ * keeps the count of samples which fall in the bucket, e.g.,
+ * {[0],[1],...,[999]}. However this consumes a huge amount of space,
+ * and can be avoided if an approximation is acceptable.
+ *
+ * One such method is to let the range of the bucket to be greater
+ * than one. This method has low accuracy when the value is small. For
+ * example, let the buckets be {[0,99],[100,199],...,[900,999]}, and
+ * the represented value of each bucket be the mean of the range. Then
+ * a value 0 has an round-off error of 49.5. To improve on this, we
+ * use buckets with non-uniform ranges, while bounding the error of
+ * each bucket within a ratio of the sample value. A simple example
+ * would be when error_bound = 0.005, buckets are {
+ * {[0],[1],...,[99]}, {[100,101],[102,103],...,[198,199]},..,
+ * {[900,909],[910,919]...}  }. The total range is partitioned into
+ * groups with different ranges, then buckets with uniform ranges. An
+ * upper bound of the error is (range_of_bucket/2)/value_of_bucket
+ *
+ * For better efficiency, we implement this using base two. We group
+ * samples by their Most Significant Bit (MSB), extract the next M bit
+ * of them as an index within the group, and discard the rest of the
+ * bits.
+ *
+ * E.g., assume a sample 'x' whose MSB is bit n (starting from bit 0),
+ * and use M bit for indexing
+ *
+ *        | n |    M bits   | bit (n-M-1) ... bit 0 |
+ *
+ * Because x is at least 2^n, and bit 0 to bit (n-M-1) is at most
+ * (2^(n-M) - 1), discarding bit 0 to (n-M-1) makes the round-off
+ * error
+ *
+ *           2^(n-M)-1    2^(n-M)    1
+ *      e <= --------- <= ------- = ---
+ *             2^n          2^n     2^M
+ *
+ * Furthermore, we use "mean" of the range to represent the bucket,
+ * the error e can be lowered by half to 1 / 2^(M+1). By using M bits
+ * as the index, each group must contains 2^M buckets.
+ *
+ * E.g. Let M (FIO_IO_U_PLAT_BITS) be 6
+ *      Error bound is 1/2^(6+1) = 0.0078125 (< 1%)
+ *
+ *	Group	MSB	#discarded	range of		#buckets
+ *			error_bits	value
+ *	----------------------------------------------------------------
+ *	0*	0~5	0		[0,63]			64
+ *	1*	6	0		[64,127]		64
+ *	2	7	1		[128,255]		64
+ *	3	8	2		[256,511]		64
+ *	4	9	3		[512,1023]		64
+ *	...	...	...		[...,...]		...
+ *	18	23	17		[8838608,+inf]**	64
+ *
+ *  * Special cases: when n < (M-1) or when n == (M-1), in both cases,
+ *    the value cannot be rounded off. Use all bits of the sample as
+ *    index.
+ *
+ *  ** If a sample's MSB is greater than 23, it will be counted as 23.
+ */
+
+#define FIO_IO_U_PLAT_BITS 6
+#define FIO_IO_U_PLAT_VAL (1 << FIO_IO_U_PLAT_BITS)
+#define FIO_IO_U_PLAT_GROUP_NR 19
+#define FIO_IO_U_PLAT_NR (FIO_IO_U_PLAT_GROUP_NR * FIO_IO_U_PLAT_VAL)
+#define FIO_IO_U_LIST_MAX_LEN 20 /* The size of the default and user-specified
+					list of percentiles */
+
+#define MAX_PATTERN_SIZE	512
+#define FIO_JOBNAME_SIZE	128
+#define FIO_VERROR_SIZE		128
+
+struct thread_stat {
+	char name[FIO_JOBNAME_SIZE];
+	char verror[FIO_VERROR_SIZE];
+	uint32_t error;
+	uint32_t groupid;
+	uint32_t pid;
+	char description[FIO_JOBNAME_SIZE];
+	uint32_t members;
+
+	/*
+	 * bandwidth and latency stats
+	 */
+	struct io_stat clat_stat[2];		/* completion latency */
+	struct io_stat slat_stat[2];		/* submission latency */
+	struct io_stat lat_stat[2];		/* total latency */
+	struct io_stat bw_stat[2];		/* bandwidth stats */
+	struct io_stat iops_stat[2];		/* IOPS stats */
+
+	/*
+	 * fio system usage accounting
+	 */
+	uint64_t usr_time;
+	uint64_t sys_time;
+	uint64_t ctx;
+	uint64_t minf, majf;
+
+	/*
+	 * IO depth and latency stats
+	 */
+	uint64_t clat_percentiles;
+	fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
+
+	uint32_t io_u_map[FIO_IO_U_MAP_NR];
+	uint32_t io_u_submit[FIO_IO_U_MAP_NR];
+	uint32_t io_u_complete[FIO_IO_U_MAP_NR];
+	uint32_t io_u_lat_u[FIO_IO_U_LAT_U_NR];
+	uint32_t io_u_lat_m[FIO_IO_U_LAT_M_NR];
+	uint32_t io_u_plat[2][FIO_IO_U_PLAT_NR];
+	uint64_t total_io_u[3];
+	uint64_t short_io_u[3];
+	uint64_t total_submit;
+	uint64_t total_complete;
+
+	uint64_t io_bytes[2];
+	uint64_t runtime[2];
+	uint64_t total_run_time;
+
+	/*
+	 * IO Error related stats
+	 */
+	uint16_t continue_on_error;
+	uint64_t total_err_count;
+	uint32_t first_error;
+
+	uint32_t kb_base;
+};
+
+struct jobs_eta {
+	uint32_t nr_running;
+	uint32_t nr_ramp;
+	uint32_t nr_pending;
+	uint32_t files_open;
+	uint32_t m_rate, t_rate;
+	uint32_t m_iops, t_iops;
+	uint32_t rate[2];
+	uint32_t iops[2];
+	uint64_t elapsed_sec;
+	uint64_t eta_sec;
+
+	/*
+	 * Network 'copy' of run_str[]
+	 */
+	uint32_t nr_threads;
+	uint8_t run_str[0];
+};
+
+extern void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs);
+extern void show_group_stats(struct group_run_stats *rs);
+extern int calc_thread_status(struct jobs_eta *je, int force);
+extern void display_thread_status(struct jobs_eta *je);
+extern void show_run_stats(void);
+extern void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr);
+extern void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src);
+extern void init_thread_stat(struct thread_stat *ts);
+extern void init_group_run_stat(struct group_run_stats *gs);
+
+#endif
diff --git a/t/ieee754.c b/t/ieee754.c
new file mode 100644
index 0000000..afc25f3
--- /dev/null
+++ b/t/ieee754.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include "../ieee754.h"
+
+static double values[] = { -17.23, 17.23, 123.4567, 98765.4321, 0.0 };
+
+int main(int argc, char *argv[])
+{
+	uint64_t i;
+	double f;
+	int j;
+
+	j = 0;
+	do {
+		i = fio_double_to_uint64(values[j]);
+		f = fio_uint64_to_double(i);
+		printf("%f -> %f\n", values[j], f);
+		j++;
+	} while (values[j] != 0.0);
+
+	return 0;
+}
diff --git a/t/log.c b/t/log.c
new file mode 100644
index 0000000..7f1de27
--- /dev/null
+++ b/t/log.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int log_err(const char *format, ...)
+{
+	char buffer[1024];
+	va_list args;
+	size_t len;
+
+	va_start(args, format);
+	len = vsnprintf(buffer, sizeof(buffer), format, args);
+	va_end(args);
+
+	return fwrite(buffer, len, 1, stderr);
+}

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (96 preceding siblings ...)
  2011-08-04 12:08 ` Jens Axboe
@ 2011-08-12  4:00 ` Jens Axboe
  2012-02-01  5:00 ` Jens Axboe
                   ` (2 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-08-12  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit bc5f9ff87cb38ffa3b64ba607e535043eef06d14:

  Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace (2011-08-03 15:06:18 +0200)

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      blktrace 1.0.3

Namhyung Kim (1):
      Add FLUSH/FUA support

 act_mask.c     |    3 ++-
 blkparse.c     |    2 +-
 blkparse_fmt.c |   17 +++++++++++------
 blkrawverify.c |    3 ++-
 blktrace_api.h |    5 +++--
 5 files changed, 19 insertions(+), 11 deletions(-)

---

Diff of recent changes:

diff --git a/act_mask.c b/act_mask.c
index 6d5c193..8f1b8d7 100644
--- a/act_mask.c
+++ b/act_mask.c
@@ -15,7 +15,7 @@ struct mask_map {
 static struct mask_map mask_maps[] = {
 	DECLARE_MASK_MAP(READ),
 	DECLARE_MASK_MAP(WRITE),
-	DECLARE_MASK_MAP(BARRIER),
+	DECLARE_MASK_MAP(FLUSH),
 	DECLARE_MASK_MAP(SYNC),
 	DECLARE_MASK_MAP(QUEUE),
 	DECLARE_MASK_MAP(REQUEUE),
@@ -28,6 +28,7 @@ static struct mask_map mask_maps[] = {
 	DECLARE_MASK_MAP(META),
 	DECLARE_MASK_MAP(DISCARD),
 	DECLARE_MASK_MAP(DRV_DATA),
+	DECLARE_MASK_MAP(FUA),
 };
 
 int find_mask_map(char *string)
diff --git a/blkparse.c b/blkparse.c
index 12c7aae..169d491 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.0.2";
+static char blkparse_version[] = "1.0.3";
 
 struct skip_info {
 	unsigned long start, end;
diff --git a/blkparse_fmt.c b/blkparse_fmt.c
index ed6cd5c..c42e6d7 100644
--- a/blkparse_fmt.c
+++ b/blkparse_fmt.c
@@ -54,12 +54,16 @@ static inline void fill_rwbs(char *rwbs, struct blk_io_trace *t)
 {
 	int w = t->action & BLK_TC_ACT(BLK_TC_WRITE);
 	int a = t->action & BLK_TC_ACT(BLK_TC_AHEAD);
-	int b = t->action & BLK_TC_ACT(BLK_TC_BARRIER);
 	int s = t->action & BLK_TC_ACT(BLK_TC_SYNC);
 	int m = t->action & BLK_TC_ACT(BLK_TC_META);
 	int d = t->action & BLK_TC_ACT(BLK_TC_DISCARD);
+	int f = t->action & BLK_TC_ACT(BLK_TC_FLUSH);
+	int u = t->action & BLK_TC_ACT(BLK_TC_FUA);
 	int i = 0;
 
+	if (f)
+		rwbs[i++] = 'F'; /* flush */
+
 	if (d)
 		rwbs[i++] = 'D';
 	else if (w)
@@ -68,10 +72,11 @@ static inline void fill_rwbs(char *rwbs, struct blk_io_trace *t)
 		rwbs[i++] = 'R';
 	else
 		rwbs[i++] = 'N';
+
+	if (u)
+		rwbs[i++] = 'F'; /* fua */
 	if (a)
 		rwbs[i++] = 'A';
-	if (b)
-		rwbs[i++] = 'B';
 	if (s)
 		rwbs[i++] = 'S';
 	if (m)
@@ -188,7 +193,7 @@ static void print_field(char *act, struct per_cpu_info *pci,
 		break;
 	}
 	case 'd': {
-		char rwbs[6];
+		char rwbs[8];
 
 		fill_rwbs(rwbs, t);
 		fprintf(ofp, strcat(format, "s"), rwbs);
@@ -285,7 +290,7 @@ static void process_default(char *act, struct per_cpu_info *pci,
 			    int pdu_len, unsigned char *pdu_buf)
 {
 	struct blk_io_trace_remap r = { .device_from = 0, };
-	char rwbs[6];
+	char rwbs[8];
 	char *name;
 
 	fill_rwbs(rwbs, t);
@@ -445,7 +450,7 @@ void process_fmt(char *act, struct per_cpu_info *pci, struct blk_io_trace *t,
 			case 'r': fprintf(ofp, "\r"); break;
 			case 't': fprintf(ofp, "\t"); break;
 			default:
-				fprintf(stderr,	
+				fprintf(stderr,
 					"Invalid escape char in format %c\n",
 					p[1]);
 				exit(1);
diff --git a/blkrawverify.c b/blkrawverify.c
index e669179..b6ceb9d 100644
--- a/blkrawverify.c
+++ b/blkrawverify.c
@@ -39,7 +39,7 @@ int data_is_native = -1;
 static struct trace_info traces[] = {
 	TRACE_TO_STRING( BLK_TC_READ ),
 	TRACE_TO_STRING( BLK_TC_WRITE ),
-	TRACE_TO_STRING( BLK_TC_BARRIER ),
+	TRACE_TO_STRING( BLK_TC_FLUSH ),
 	TRACE_TO_STRING( BLK_TC_SYNC ),
 	TRACE_TO_STRING( BLK_TC_QUEUE ),
 	TRACE_TO_STRING( BLK_TC_REQUEUE ),
@@ -50,6 +50,7 @@ static struct trace_info traces[] = {
 	TRACE_TO_STRING( BLK_TC_AHEAD ),
 	TRACE_TO_STRING( BLK_TC_META ),
 	TRACE_TO_STRING( BLK_TC_DISCARD ),
+	TRACE_TO_STRING( BLK_TC_FUA ),
 };
 #define N_TRACES (sizeof(traces) / sizeof(struct trace_info))
 
diff --git a/blktrace_api.h b/blktrace_api.h
index ba9ee60..b222218 100644
--- a/blktrace_api.h
+++ b/blktrace_api.h
@@ -9,7 +9,7 @@
 enum {
 	BLK_TC_READ	= 1 << 0,	/* reads */
 	BLK_TC_WRITE	= 1 << 1,	/* writes */
-	BLK_TC_BARRIER	= 1 << 2,	/* barrier */
+	BLK_TC_FLUSH	= 1 << 2,	/* flush */
 	BLK_TC_SYNC	= 1 << 3,	/* sync */
 	BLK_TC_QUEUE	= 1 << 4,	/* queueing/merging */
 	BLK_TC_REQUEUE	= 1 << 5,	/* requeueing */
@@ -22,8 +22,9 @@ enum {
 	BLK_TC_META	= 1 << 12,	/* metadata */
 	BLK_TC_DISCARD	= 1 << 13,	/* discard requests */
 	BLK_TC_DRV_DATA	= 1 << 14,	/* binary driver data */
+	BLK_TC_FUA	= 1 << 15,	/* fua requests */
 
-	BLK_TC_END	= 1 << 15,	/* only 16-bits, reminder */
+	BLK_TC_END	= 1 << 15,	/* we've run out of bits! */
 };
 
 #define BLK_TC_SHIFT		(16)

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (95 preceding siblings ...)
  2011-08-04 11:50 ` Edward Shishkin
@ 2011-08-04 12:08 ` Jens Axboe
  2011-08-12  4:00 ` Jens Axboe
                   ` (3 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-08-04 12:08 UTC (permalink / raw)
  To: linux-btrace

On 2011-08-04 13:50, Edward Shishkin wrote:
> Hello.
> 
> How about those bits:
> http://marc.info/?l=linux-btrace&m\x130978262022784&w=2
> http://marc.info/?l=linux-btrace&m\x130978263222799&w=2
> 
> any chances it will be applied?

-k isn't meant to kill blktrace, it's meant to fixup broken state if
blktrace is already gone yet the device trace state is still running (or
hosed).

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (94 preceding siblings ...)
  2011-08-04  4:00 ` Jens Axboe
@ 2011-08-04 11:50 ` Edward Shishkin
  2011-08-04 12:08 ` Jens Axboe
                   ` (4 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Edward Shishkin @ 2011-08-04 11:50 UTC (permalink / raw)
  To: linux-btrace

Hello.

How about those bits:
http://marc.info/?l=linux-btrace&m\x130978262022784&w=2
http://marc.info/?l=linux-btrace&m\x130978263222799&w=2

any chances it will be applied?

Thanks in advance,
Edward.


On 08/04/2011 06:00 AM, Jens Axboe wrote:
> The following changes since commit 8e8bb835e375bd8cf0f01debff61f6bf467bb1ed:
>
>    blktrace: Use be32_to_cpu for blk_io_trace->cpu. (2011-05-26 21:11:09 +0200)
>
> are available in the git repository at:
>    git://git.kernel.dk/blktrace.git master
>
> Jeff Moyer (1):
>        blkparse: fix up incorrect pc write completion count
>
> Jens Axboe (1):
>        Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace
>
>   blkparse.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)
>
> ---
>
> Diff of recent changes:
>
> diff --git a/blkparse.c b/blkparse.c
> index 817cb31..12c7aae 100644
> --- a/blkparse.c
> +++ b/blkparse.c
> @@ -1675,7 +1675,7 @@ static void dump_io_stats(struct per_dev_info *pdi, struct io_stats *ios,
>   		fprintf(ofp, " PC Reads Req.:   %s\t\t", size_cnv(x, ios->rrqueue_pc, 0));
>   		fprintf(ofp, " PC Writes Req.:   %s\n", size_cnv(x, ios->wrqueue_pc, 0));
>   		fprintf(ofp, " PC Reads Compl.: %s\t\t", size_cnv(x, ios->creads_pc, 0));
> -		fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites, 0));
> +		fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites_pc, 0));
>   	}
>   	fprintf(ofp, " IO unplugs:      %'8lu%8c\t", ios->io_unplugs, ' ');
>   	fprintf(ofp, " Timer unplugs:    %'8lu\n", ios->timer_unplugs);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrace" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (93 preceding siblings ...)
  2011-05-27  4:00 ` Jens Axboe
@ 2011-08-04  4:00 ` Jens Axboe
  2011-08-04 11:50 ` Edward Shishkin
                   ` (5 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-08-04  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 8e8bb835e375bd8cf0f01debff61f6bf467bb1ed:

  blktrace: Use be32_to_cpu for blk_io_trace->cpu. (2011-05-26 21:11:09 +0200)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Jeff Moyer (1):
      blkparse: fix up incorrect pc write completion count

Jens Axboe (1):
      Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace

 blkparse.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 817cb31..12c7aae 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -1675,7 +1675,7 @@ static void dump_io_stats(struct per_dev_info *pdi, struct io_stats *ios,
 		fprintf(ofp, " PC Reads Req.:   %s\t\t", size_cnv(x, ios->rrqueue_pc, 0));
 		fprintf(ofp, " PC Writes Req.:   %s\n", size_cnv(x, ios->wrqueue_pc, 0));
 		fprintf(ofp, " PC Reads Compl.: %s\t\t", size_cnv(x, ios->creads_pc, 0));
-		fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites, 0));
+		fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites_pc, 0));
 	}
 	fprintf(ofp, " IO unplugs:      %'8lu%8c\t", ios->io_unplugs, ' ');
 	fprintf(ofp, " Timer unplugs:    %'8lu\n", ios->timer_unplugs);

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-06-28  9:36 Konstantin Belousov
@ 2011-06-28 10:37 ` Chris Wilson
  0 siblings, 0 replies; 135+ messages in thread
From: Chris Wilson @ 2011-06-28 10:37 UTC (permalink / raw)
  To: Konstantin Belousov, Intel-gfx

On Tue, 28 Jun 2011 12:36:04 +0300, Konstantin Belousov <kostikbel@gmail.com> wrote:
> I have two questions about recent changes made to the kernel driver:
> 
> 1. Looking at the intel_setup_overlay() after the commit
> ecbec53b1d00ba582f71b210ed96cafc05ebd189, it seems there is potential
> double unlock for the struct_mutex in the (unlikely) case when
> intel_overlay_map_regs() failed.

Dan Carpenter pointed out a further mistake in that we weren't handling
the pin count correctly for 945/965/g33.
 
> 2. In i915_wait_request(), after the commit
> 4697995b98417c6da9ab2708a36f5e2bc926c8ac, shouldn't the calls
> 	i915_driver_irq_preinstall(ring->dev);
> 	i915_driver_irq_postinstall(ring->dev);
> be replaced with
> 	ring->dev->driver->irq_preinstall(ring->dev);
> 	ring->dev->driver->irq_postinstall(ring->dev);
> ?

Yes.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
@ 2011-06-28  9:36 Konstantin Belousov
  2011-06-28 10:37 ` Chris Wilson
  0 siblings, 1 reply; 135+ messages in thread
From: Konstantin Belousov @ 2011-06-28  9:36 UTC (permalink / raw)
  To: Intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 595 bytes --]

I have two questions about recent changes made to the kernel driver:

1. Looking at the intel_setup_overlay() after the commit
ecbec53b1d00ba582f71b210ed96cafc05ebd189, it seems there is potential
double unlock for the struct_mutex in the (unlikely) case when
intel_overlay_map_regs() failed.

2. In i915_wait_request(), after the commit
4697995b98417c6da9ab2708a36f5e2bc926c8ac, shouldn't the calls
	i915_driver_irq_preinstall(ring->dev);
	i915_driver_irq_postinstall(ring->dev);
be replaced with
	ring->dev->driver->irq_preinstall(ring->dev);
	ring->dev->driver->irq_postinstall(ring->dev);
?

[-- Attachment #1.2: Type: application/pgp-signature, Size: 196 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (92 preceding siblings ...)
  2011-03-17  5:00 ` Jens Axboe
@ 2011-05-27  4:00 ` Jens Axboe
  2011-08-04  4:00 ` Jens Axboe
                   ` (6 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-05-27  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit e3d388e310fb9ae8aad89cfc728f8d19c6fb6579:

  blktrace 1.0.2 (2011-03-16 09:06:30 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Tao Ma (2):
      blkparse: Avoid segfault for wrong cpu number.
      blktrace: Use be32_to_cpu for blk_io_trace->cpu.

 blkparse.c |    6 ++++++
 blktrace.h |    2 +-
 2 files changed, 7 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 7ee9f9d..817cb31 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -2354,6 +2354,12 @@ static int ms_prime(struct ms_stream *msp)
 		if (verify_trace(bit))
 			goto err;
 
+		if (bit->cpu != pci->cpu) {
+			fprintf(stderr, "cpu %d trace info has error cpu %d\n",
+				pci->cpu, bit->cpu);
+			continue;
+		}
+
 		if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && bit->action != BLK_TN_MESSAGE) {
 			handle_notify(bit);
 			output_binary(bit, sizeof(*bit) + bit->pdu_len);
diff --git a/blktrace.h b/blktrace.h
index 816ce61..8b3e031 100644
--- a/blktrace.h
+++ b/blktrace.h
@@ -110,7 +110,7 @@ static inline void trace_to_cpu(struct blk_io_trace *t)
 	t->action	= be32_to_cpu(t->action);
 	t->pid		= be32_to_cpu(t->pid);
 	t->device	= be32_to_cpu(t->device);
-	t->cpu		= be16_to_cpu(t->cpu);
+	t->cpu		= be32_to_cpu(t->cpu);
 	t->error	= be16_to_cpu(t->error);
 	t->pdu_len	= be16_to_cpu(t->pdu_len);
 }

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (91 preceding siblings ...)
  2011-02-10  5:00 ` Jens Axboe
@ 2011-03-17  5:00 ` Jens Axboe
  2011-05-27  4:00 ` Jens Axboe
                   ` (7 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-03-17  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 8fe5cc8d646d2fccbf82d0021d3c323ef6738a28:

  gitignore: add blkiomon to .gitignore. (2011-02-09 10:22:39 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      blktrace 1.0.2

Justin TerAvest (1):
      blktrace: Document default values for -b and -n

 blkparse.c |    2 +-
 blktrace.c |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index c911185..7ee9f9d 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "1.0.1";
+static char blkparse_version[] = "1.0.2";
 
 struct skip_info {
 	unsigned long start, end;
diff --git a/blktrace.c b/blktrace.c
index 18c5157..72866e2 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -460,8 +460,8 @@ static char usage_str[] = "\n\n" \
 	"\t-w Stop after defined time, in seconds\n" \
 	"\t-a Only trace specified actions. See documentation\n" \
 	"\t-A Give trace mask as a single value. See documentation\n" \
-	"\t-b Sub buffer size in KiB\n" \
-	"\t-n Number of sub buffers\n" \
+	"\t-b Sub buffer size in KiB (default 512)\n" \
+	"\t-n Number of sub buffers (default 4)\n" \
 	"\t-l Run in network listen mode (blktrace server)\n" \
 	"\t-h Run in network client mode, connecting to the given host\n" \
 	"\t-p Network port to use (default 8462)\n" \

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (90 preceding siblings ...)
  2011-01-15  5:00 ` Jens Axboe
@ 2011-02-10  5:00 ` Jens Axboe
  2011-03-17  5:00 ` Jens Axboe
                   ` (8 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-02-10  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit b7e74b0087fe5d687c6a43a01a2e02d60b618ae0:

  blkiomon: Fix an output error (2011-01-14 09:06:03 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Tao Ma (3):
      blktrace: break mlock in case of is_done.
      blktrace: remove unused idx from devpath.
      gitignore: add blkiomon to .gitignore.

 .gitignore |    3 +++
 blktrace.c |   25 +++++++++++++++++--------
 2 files changed, 20 insertions(+), 8 deletions(-)

---

Diff of recent changes:

diff --git a/.gitignore b/.gitignore
index 9038778..2436e34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,9 @@
 blkparse
 blktrace
 blkrawverify
+blkiomon
+btreplay/btrecord
+btreplay/btreplay
 doc/.depend
 verify_blkparse
 btt/btt
diff --git a/blktrace.c b/blktrace.c
index 4cccb7c..18c5157 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -93,7 +93,7 @@ struct devpath {
 	char *path;			/* path to device special file */
 	char *buts_name;		/* name returned from bt kernel code */
 	struct pdc_stats *stats;
-	int fd, idx, ncpus;
+	int fd, ncpus;
 	unsigned long long drops;
 
 	/*
@@ -721,18 +721,24 @@ static void *my_mmap(void *addr, size_t length, int prot, int flags, int fd,
 	return new;
 }
 
-static int my_mlock(const void *addr, size_t len)
+static int my_mlock(struct tracer *tp,
+		    const void *addr, size_t len)
 {
-	int ret;
+	int ret, retry = 0;
 
 	do {
 		ret = mlock(addr, len);
+		if ((retry >= 10) && tp && tp->is_done)
+			break;
+		retry++;
 	} while (ret < 0 && handle_mem_failure(len));
 
 	return ret;
 }
 
-static int setup_mmap(int fd, unsigned int maxlen, struct mmap_info *mip)
+static int setup_mmap(int fd, unsigned int maxlen,
+		      struct mmap_info *mip,
+		      struct tracer *tp)
 {
 	if (mip->fs_off + maxlen > mip->fs_buf_len) {
 		unsigned long nr = max(16, mip->buf_nr);
@@ -759,7 +765,10 @@ static int setup_mmap(int fd, unsigned int maxlen, struct mmap_info *mip)
 			perror("setup_mmap: mmap");
 			return 1;
 		}
-		my_mlock(mip->fs_buf, mip->fs_buf_len);
+		if (my_mlock(tp, mip->fs_buf, mip->fs_buf_len) < 0) {
+			perror("setup_mlock: mlock");
+			return 1;
+		}
 	}
 
 	return 0;
@@ -1239,7 +1248,7 @@ static int add_devpath(char *path)
 	memset(dpp, 0, sizeof(*dpp));
 	dpp->path = strdup(path);
 	dpp->fd = fd;
-	dpp->idx = ndevs++;
+	ndevs++;
 	list_add_tail(&dpp->head, &devpaths);
 
 	return 0;
@@ -1683,7 +1692,7 @@ static int handle_pfds_file(struct tracer *tp, int nevs, int force_read)
 		if (pfd->revents & POLLIN || force_read) {
 			mip = &iop->mmap_info;
 
-			ret = setup_mmap(iop->ofd, buf_size, mip);
+			ret = setup_mmap(iop->ofd, buf_size, mip, tp);
 			if (ret < 0) {
 				pfd->events = 0;
 				break;
@@ -2381,7 +2390,7 @@ static void net_client_read_data(struct cl_conn *nc, struct devpath *dpp,
 	struct io_info *iop = &dpp->ios[bnh->cpu];
 	struct mmap_info *mip = &iop->mmap_info;
 
-	if (setup_mmap(iop->ofd, bnh->len, &iop->mmap_info)) {
+	if (setup_mmap(iop->ofd, bnh->len, &iop->mmap_info, NULL)) {
 		fprintf(stderr, "ncd(%s:%d): mmap failed\n",
 			nc->ch->hostname, nc->fd);
 		exit(1);

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-01-27 22:06   ` Bruce Cran
@ 2011-01-28  8:28     ` Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-28  8:28 UTC (permalink / raw)
  To: Bruce Cran; +Cc: Steven Pratt, fio

On 2011-01-27 23:06, Bruce Cran wrote:
> On Thu, 27 Jan 2011 15:08:58 -0600
> Steven Pratt <slpratt@austin.ibm.com> wrote:
> 
>> Jens, the nested else ifeq statements in the main Makfile blow up on
>> make versions prior to 3.81.  SLES10 still has 3.80.  Not a big deal
>> for me, but I work with some folks for which this is over their
>> heads.  Any chance we could revert back to a more compatible syntax?
> 
> Confirmed with make 3.75 on FreeBSD. The attached patch should fix it.

Thanks Bruce, I got things reinstated as I like the unified Makefile.
Should have waited a bit on that revert, but hey... At least it's good
now.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-01-27 21:08 ` Steven Pratt
  2011-01-27 21:12   ` Jens Axboe
@ 2011-01-27 22:06   ` Bruce Cran
  2011-01-28  8:28     ` Jens Axboe
  1 sibling, 1 reply; 135+ messages in thread
From: Bruce Cran @ 2011-01-27 22:06 UTC (permalink / raw)
  To: Steven Pratt; +Cc: Jens Axboe, fio

[-- Attachment #1: Type: text/plain, Size: 460 bytes --]

On Thu, 27 Jan 2011 15:08:58 -0600
Steven Pratt <slpratt@austin.ibm.com> wrote:

> Jens, the nested else ifeq statements in the main Makfile blow up on
> make versions prior to 3.81.  SLES10 still has 3.80.  Not a big deal
> for me, but I work with some folks for which this is over their
> heads.  Any chance we could revert back to a more compatible syntax?

Confirmed with make 3.75 on FreeBSD. The attached patch should fix it.

-- 
Bruce Cran

[-- Attachment #2: fio_Makefile.diff.gz --]
[-- Type: application/x-gzip, Size: 481 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-01-27 21:08 ` Steven Pratt
@ 2011-01-27 21:12   ` Jens Axboe
  2011-01-27 22:06   ` Bruce Cran
  1 sibling, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-27 21:12 UTC (permalink / raw)
  To: Steven Pratt; +Cc: fio

On 2011-01-27 22:08, Steven Pratt wrote:
> On 01/24/2011 11:00 PM, Jens Axboe wrote:
>> The following changes since commit b8d42b234f70ce2927e9ef1279aff42d62779cfd:
>>
>>   Fio 1.50-rc4 (2011-01-20 10:17:35 -0700)
>>
>> are available in the git repository at:
>>   git://git.kernel.dk/fio.git master
>>
>> Bruce Cran (1):
>>       Unify makefiles
>>
>> Jens Axboe (3):
>>       Ensure that we exit with non-zero status on IO engine load failure
>>       mmap: catch invalid msync() errors early
>>       Remove flist_sort(), it's no longer used
>>
>>  Makefile         |   53 ++++++++++++++++----
> 
> Jens, the nested else ifeq statements in the main Makfile blow up on
> make versions prior to 3.81.  SLES10 still has 3.80.  Not a big deal
> for me, but I work with some folks for which this is over their heads.
> Any chance we could revert back to a more compatible syntax?

Oops, thanks for letting me know. I'll revert that one for now.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
       [not found] <20110125050003.F378B37A302@kernel.dk>
@ 2011-01-27 21:08 ` Steven Pratt
  2011-01-27 21:12   ` Jens Axboe
  2011-01-27 22:06   ` Bruce Cran
  0 siblings, 2 replies; 135+ messages in thread
From: Steven Pratt @ 2011-01-27 21:08 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio

On 01/24/2011 11:00 PM, Jens Axboe wrote:
> The following changes since commit b8d42b234f70ce2927e9ef1279aff42d62779cfd:
>
>   Fio 1.50-rc4 (2011-01-20 10:17:35 -0700)
>
> are available in the git repository at:
>   git://git.kernel.dk/fio.git master
>
> Bruce Cran (1):
>       Unify makefiles
>
> Jens Axboe (3):
>       Ensure that we exit with non-zero status on IO engine load failure
>       mmap: catch invalid msync() errors early
>       Remove flist_sort(), it's no longer used
>
>  Makefile         |   53 ++++++++++++++++----

Jens, the nested else ifeq statements in the main Makfile blow up on make versions prior to 3.81.  SLES10 still has 3.80.  Not a big deal for me, but I work with some folks for which this is over their heads.  Any chance we could revert back to a more compatible syntax?

Steve

>  Makefile.FreeBSD |   60 -----------------------
>  Makefile.NetBSD  |   59 -----------------------
>  Makefile.Windows |   61 -----------------------
>  Makefile.aix     |   59 -----------------------
>  Makefile.mac     |   60 -----------------------
>  Makefile.solaris |   60 -----------------------
>  README           |   15 ++----
>  engines/mmap.c   |    8 +++
>  flist_sort.h     |    9 ----
>  ioengines.c      |    2 +
>  lib/flist_sort.c |  140 ------------------------------------------------------
>  12 files changed, 56 insertions(+), 530 deletions(-)
>  delete mode 100644 Makefile.FreeBSD
>  delete mode 100644 Makefile.NetBSD
>  delete mode 100644 Makefile.Windows
>  delete mode 100644 Makefile.aix
>  delete mode 100644 Makefile.mac
>  delete mode 100644 Makefile.solaris
>  delete mode 100644 flist_sort.h
>  delete mode 100644 lib/flist_sort.c
>
> ---
>
> Diff of recent changes:
>
> diff --git a/Makefile b/Makefile
> index 19943db..df58489 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -3,20 +3,51 @@ DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
>  CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
>       $(DEBUGFLAGS)
>  OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
> -LIBS = -lpthread -lm -ldl -lrt -laio
> +CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS)
> +LIBS = -lm
>  PROGS        = fio
>  SCRIPTS = fio_generate_plots
> -
> +UNAME  := $(shell uname)
> +
>  SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     diskutil.c fifo.c blktrace.c smalloc.c filehash.c helpers.c \
> -     cgroup.c profile.c debug.c trim.c lib/rand.c lib/flist_sort.c \
> -     lib/num2str.c $(wildcard crc/*.c) engines/cpu.c engines/libaio.c \
> -     engines/mmap.c engines/posixaio.c engines/sg.c engines/splice.c \
> -     engines/sync.c engines/null.c engines/net.c engines/syslet-rw.c \
> -     engines/guasi.c engines/binject.c profiles/tiobench.c
> -
> +             eta.c verify.c memory.c io_u.c parse.c mutex.c options.c \
> +             rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \
> +             lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> +             engines/mmap.c engines/sync.c engines/null.c engines/net.c
> +
> +ifeq ($(UNAME), Linux)
> +  SOURCE += diskutil.c fifo.c blktrace.c helpers.c cgroup.c trim.c \
> +             engines/libaio.c engines/posixaio.c engines/sg.c \
> +             engines/splice.c engines/syslet-rw.c engines/guasi.c \
> +             engines/binject.c profiles/tiobench.c
> +  LIBS += -lpthread -ldl -lrt -laio
> +  CFLAGS += -rdynamic
> +else ifeq ($(UNAME), SunOS)
> +  SOURCE += fifo.c lib/strsep.c helpers.c solaris.c engines/posixaio.c \
> +             engines/solarisaio.c
> +  LIBS        += -lpthread -ldl -laio -lrt -lnsl -lsocket
> +  CPPFLAGS += -D__EXTENSIONS__
> +else ifeq ($(UNAME), FreeBSD)
> +  SOURCE += helpers.c engines/posixaio.c
> +  LIBS        += -lpthread -lrt
> +  CFLAGS += -rdynamic
> +else ifeq ($(UNAME), NetBSD)
> +  SOURCE += helpers.c engines/posixaio.c
> +  LIBS        += -lpthread -lrt
> +  CFLAGS += -rdynamic
> +else ifeq ($(UNAME), AIX)
> +  SOURCE += fifo.c helpers.c lib/getopt_long.c engines/posixaio.c
> +  LIBS        += -lpthread -ldl -lrt
> +  CFLAGS += -rdynamic
> +  CPPFLAGS += -D_LARGE_FILES -D__ppc__
> +else ifeq ($(UNAME), Darwin)
> +  SOURCE += helpers.c engines/posixaio.c
> +  LIBS        += -lpthread -ldl
> +else ifneq (,$(findstring CYGWIN,$(UNAME)))
> +  SOURCE += engines/windowsaio.c
> +  LIBS        += -lpthread -lrt
> +endif
> +
>  OBJS = $(SOURCE:.c=.o)
>
>  ifneq ($(findstring $(MAKEFLAGS),s),s)
> diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD
> deleted file mode 100644
> index 537f770..0000000
> --- a/Makefile.FreeBSD
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
> -     $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
> -LIBS = -lpthread -lm -lrt
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
> -     lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> -     engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
> -     engines/net.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = install
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/Makefile.NetBSD b/Makefile.NetBSD
> deleted file mode 100644
> index cefc34e..0000000
> --- a/Makefile.NetBSD
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
> -LIBS = -lpthread -lm -lrt
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
> -     lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> -     engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
> -     engines/net.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = install
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/Makefile.Windows b/Makefile.Windows
> deleted file mode 100644
> index 3313c04..0000000
> --- a/Makefile.Windows
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
> -     $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -gstabs+ $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS)
> -LIBS = -lpthread -lm -lrt
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     smalloc.c filehash.c profile.c debug.c lib/rand.c \
> -     lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> -     engines/mmap.c engines/sync.c engines/null.c engines/net.c \
> -     engines/net.c engines/windowsaio.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = install
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)windres os/windows/version.rc -O coff -o version.o
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS) version.o
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) version.o core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/Makefile.aix b/Makefile.aix
> deleted file mode 100644
> index 174ffee..0000000
> --- a/Makefile.aix
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
> -     -D_LARGE_FILES -D__ppc__ $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
> -LIBS = -lpthread -lm -ldl -lrt
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     fifo.c smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
> -     lib/getopt_long.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> -     engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
> -     engines/net.c profiles/tiobench.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = installbsd -c
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     mkdir -p -m 755 $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/Makefile.mac b/Makefile.mac
> deleted file mode 100644
> index 6efce20..0000000
> --- a/Makefile.mac
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
> -     $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) -rdynamic
> -LIBS = -lpthread -lm -ldl
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     smalloc.c filehash.c helpers.c profile.c debug.c lib/rand.c \
> -     lib/flist_sort.c lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
> -     engines/mmap.c engines/posixaio.c engines/sync.c engines/null.c \
> -     engines/net.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = install
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/Makefile.solaris b/Makefile.solaris
> deleted file mode 100644
> index 97a3ae5..0000000
> --- a/Makefile.solaris
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -CC   = gcc
> -DEBUGFLAGS = -DFIO_INC_DEBUG
> -CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
> -     -D__EXTENSIONS__ $(DEBUGFLAGS)
> -OPTFLAGS= -O2 -fno-omit-frame-pointer -g $(EXTFLAGS)
> -CFLAGS       = -std=gnu99 -Wall $(OPTFLAGS)
> -LIBS = -lpthread -lm -ldl -laio -lrt -lnsl -lsocket
> -PROGS        = fio
> -SCRIPTS = fio_generate_plots
> -
> -SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
> -     eta.c verify.c memory.c io_u.c parse.c mutex.c options.c rbtree.c \
> -     fifo.c smalloc.c filehash.c lib/strsep.c helpers.c solaris.c \
> -     profile.c debug.c lib/rand.c lib/flist_sort.c lib/num2str.c \
> -     $(wildcard crc/*.c) engines/cpu.c engines/mmap.c engines/posixaio.c \
> -     engines/sync.c engines/null.c engines/net.c engines/solarisaio.c
> -
> -OBJS = $(SOURCE:.c=.o)
> -
> -ifneq ($(findstring $(MAKEFLAGS),s),s)
> -ifndef V
> -     QUIET_CC        = @echo '   ' CC $@;
> -     QUIET_DEP       = @echo '   ' DEP $@;
> -endif
> -endif
> -
> -INSTALL = install
> -prefix = /usr/local
> -bindir = $(prefix)/bin
> -mandir = $(prefix)/man
> -
> -.c.o:
> -     $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
> -
> -fio: $(OBJS)
> -     $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(LIBS) $(OBJS)
> -
> -depend:
> -     $(QUIET_DEP)$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(SOURCE) 1> .depend
> -
> -$(PROGS): depend
> -
> -all: depend $(PROGS) $(SCRIPTS)
> -
> -clean:
> -     -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core
> -
> -cscope:
> -     @cscope -b
> -
> -install: $(PROGS) $(SCRIPTS)
> -     $(INSTALL) -m755 -d $(DESTDIR)$(bindir)
> -     $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
> -     $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
> -     $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
> -
> -ifneq ($(wildcard .depend),)
> -include .depend
> -endif
> diff --git a/README b/README
> index adcced6..cc84fed 100644
> --- a/README
> +++ b/README
> @@ -83,18 +83,11 @@ http://maillist.kernel.dk/fio-devel/
>  Building
>  --------
>
> -Just type 'make' and 'make install'. If on BSD, for now you have to
> -specify the BSD Makefile with -f and use gmake (not make), eg:
> +Just type 'make' and 'make install'.
>
> -$ gmake -f Makefile.FreeBSD && gmake -f Makefile.FreeBSD install
> -
> -Same goes for AIX:
> -
> -$ gmake -f Makefile.aix && gmake -f Makefile.aix install
> -
> -Likewise with OpenSolaris, use the Makefile.solaris to compile there.
> -The OpenSolaris make should work fine. This might change in the
> -future if I opt for an autoconf type setup.
> +Note that GNU make is required. On BSD it's available from devel/gmake;
> +on Solaris it's in the SUNWgmake package. On platforms where GNU make
> +isn't the default, type 'gmake' instead of 'make'.
>
>  If your compile fails with an error like this:
>
> diff --git a/engines/mmap.c b/engines/mmap.c
> index 059bfcf..79238b1 100644
> --- a/engines/mmap.c
> +++ b/engines/mmap.c
> @@ -181,8 +181,16 @@ static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
>
>  static int fio_mmapio_init(struct thread_data *td)
>  {
> +     struct thread_options *o = &td->o;
>       unsigned long shift, mask;
>
> +     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);
> +             return 1;
> +     }
> +
>       mmap_map_size = MMAP_TOTAL_SZ / td->o.nr_files;
>       mask = mmap_map_size;
>       shift = 0;
> diff --git a/flist_sort.h b/flist_sort.h
> deleted file mode 100644
> index 686b7a5..0000000
> --- a/flist_sort.h
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -#ifndef FIO_FLIST_SORT_H
> -#define FIO_FLIST_SORT_H
> -
> -struct flist_head;
> -
> -void flist_sort(void *priv, struct flist_head *head,
> -            int (*cmp)(void *priv, struct flist_head *a,
> -                       struct flist_head *b));
> -#endif
> diff --git a/ioengines.c b/ioengines.c
> index 6b677cb..7f4e104 100644
> --- a/ioengines.c
> +++ b/ioengines.c
> @@ -312,6 +312,8 @@ int td_io_init(struct thread_data *td)
>                       log_err("fio: io engine init failed. Perhaps try"
>                               " reducing io depth?\n");
>               }
> +             if (!td->error)
> +                     td->error = ret;
>       }
>
>       return ret;
> diff --git a/lib/flist_sort.c b/lib/flist_sort.c
> deleted file mode 100644
> index 9a2da84..0000000
> --- a/lib/flist_sort.c
> +++ /dev/null
> @@ -1,140 +0,0 @@
> -#include <string.h>
> -#include <assert.h>
> -
> -#include "../flist.h"
> -#include "../flist_sort.h"
> -
> -#ifndef ARRAY_SIZE
> -#define      ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
> -#endif
> -
> -#define MAX_LIST_LENGTH_BITS 65
> -
> -/*
> - * Returns a list organized in an intermediate format suited
> - * to chaining of merge() calls: null-terminated, no reserved or
> - * sentinel head node, "prev" links not maintained.
> - */
> -static struct flist_head *merge(void *priv,
> -                             int (*cmp)(void *priv, struct flist_head *a,
> -                                     struct flist_head *b),
> -                             struct flist_head *a, struct flist_head *b)
> -{
> -     struct flist_head head, *tail = &head;
> -
> -     while (a && b) {
> -             /* if equal, take 'a' -- important for sort stability */
> -             if ((*cmp)(priv, a, b) <= 0) {
> -                     tail->next = a;
> -                     a = a->next;
> -             } else {
> -                     tail->next = b;
> -                     b = b->next;
> -             }
> -             tail = tail->next;
> -     }
> -     tail->next = a?:b;
> -     return head.next;
> -}
> -
> -/*
> - * Combine final list merge with restoration of standard doubly-linked
> - * list structure.  This approach duplicates code from merge(), but
> - * runs faster than the tidier alternatives of either a separate final
> - * prev-link restoration pass, or maintaining the prev links
> - * throughout.
> - */
> -static void merge_and_restore_back_links(void *priv,
> -                             int (*cmp)(void *priv, struct flist_head *a,
> -                                     struct flist_head *b),
> -                             struct flist_head *head,
> -                             struct flist_head *a, struct flist_head *b)
> -{
> -     struct flist_head *tail = head;
> -
> -     while (a && b) {
> -             /* if equal, take 'a' -- important for sort stability */
> -             if ((*cmp)(priv, a, b) <= 0) {
> -                     tail->next = a;
> -                     a->prev = tail;
> -                     a = a->next;
> -             } else {
> -                     tail->next = b;
> -                     b->prev = tail;
> -                     b = b->next;
> -             }
> -             tail = tail->next;
> -     }
> -     tail->next = a ? : b;
> -
> -     do {
> -             /*
> -              * In worst cases this loop may run many iterations.
> -              * Continue callbacks to the client even though no
> -              * element comparison is needed, so the client's cmp()
> -              * routine can invoke cond_resched() periodically.
> -              */
> -             cmp(priv, tail, tail);
> -
> -             tail->next->prev = tail;
> -             tail = tail->next;
> -     } while (tail->next);
> -
> -     tail->next = head;
> -     head->prev = tail;
> -}
> -
> -/**
> - * flist_sort - sort a list
> - * @priv: private data, opaque to flist_sort(), passed to @cmp
> - * @head: the list to sort
> - * @cmp: the elements comparison function
> - *
> - * This function implements "merge sort", which has O(nlog(n))
> - * complexity.
> - *
> - * The comparison function @cmp must return a negative value if @a
> - * should sort before @b, and a positive value if @a should sort after
> - * @b. If @a and @b are equivalent, and their original relative
> - * ordering is to be preserved, @cmp must return 0.
> - */
> -void flist_sort(void *priv, struct flist_head *head,
> -             int (*cmp)(void *priv, struct flist_head *a,
> -                     struct flist_head *b))
> -{
> -     struct flist_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
> -                                             -- last slot is a sentinel */
> -     int lev;  /* index into part[] */
> -     int max_lev = 0;
> -     struct flist_head *list;
> -
> -     if (flist_empty(head))
> -             return;
> -
> -     memset(part, 0, sizeof(part));
> -
> -     head->prev->next = NULL;
> -     list = head->next;
> -
> -     while (list) {
> -             struct flist_head *cur = list;
> -             list = list->next;
> -             cur->next = NULL;
> -
> -             for (lev = 0; part[lev]; lev++) {
> -                     cur = merge(priv, cmp, part[lev], cur);
> -                     part[lev] = NULL;
> -             }
> -             if (lev > max_lev) {
> -                     assert(lev < ARRAY_SIZE(part) - 1);
> -                     max_lev = lev;
> -             }
> -             part[lev] = cur;
> -     }
> -
> -     for (lev = 0; lev < max_lev; lev++)
> -             if (part[lev])
> -                     list = merge(priv, cmp, part[lev], list);
> -
> -     merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
> -}
> --
> To unsubscribe from this list: send the line "unsubscribe fio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (89 preceding siblings ...)
  2011-01-12  5:00 ` Jens Axboe
@ 2011-01-15  5:00 ` Jens Axboe
  2011-02-10  5:00 ` Jens Axboe
                   ` (9 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-15  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 5480f591a58df0e873ab80ba21e7b81b9a6fa0c5:

  Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace (2011-01-11 08:36:21 +0100)

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Tao Ma (1):
      blkiomon: Fix an output error

 stats.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

---

Diff of recent changes:

diff --git a/stats.h b/stats.h
index fdedf27..5b9a313 100644
--- a/stats.h
+++ b/stats.h
@@ -75,6 +75,9 @@ static inline void minmax_to_be(struct minmax *mm)
 
 static inline double minmax_avg(struct minmax *mm)
 {
+	if (!mm->num)
+		return 0;
+
 	return (mm->sum / (double)mm->num);
 }
 
@@ -82,6 +85,9 @@ static inline double minmax_var(struct minmax *mm)
 {
 	double num = (double)mm->num;
 
+	if (!mm->num)
+		return 0;
+
 	return ((mm->sos - ((mm->sum * mm->sum) / num)) / num);
 }
 

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2011-01-14 11:38 ` Bruce Cran
@ 2011-01-14 11:41   ` Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-14 11:41 UTC (permalink / raw)
  To: Bruce Cran; +Cc: fio

On 2011-01-14 12:38, Bruce Cran wrote:
> On Fri, 14 Jan 2011 06:00:03 +0100 (CET)
> Jens Axboe <jaxboe@fusionio.com> wrote:
> 
>> +	strcpy(fname, basename(ptr));
> 
> libgen.h needs to be included to pick up basename(3).

Indeed, apparently mine picks it up elsewhere. I added the header.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
       [not found] <20110114050004.0ECBF37A2F4@kernel.dk>
@ 2011-01-14 11:38 ` Bruce Cran
  2011-01-14 11:41   ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Bruce Cran @ 2011-01-14 11:38 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio

On Fri, 14 Jan 2011 06:00:03 +0100 (CET)
Jens Axboe <jaxboe@fusionio.com> wrote:

> +	strcpy(fname, basename(ptr));

libgen.h needs to be included to pick up basename(3).

-- 
Bruce Cran


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (88 preceding siblings ...)
  2010-12-20  4:36 ` Duy Le (Dan)
@ 2011-01-12  5:00 ` Jens Axboe
  2011-01-15  5:00 ` Jens Axboe
                   ` (10 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2011-01-12  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit a788dfde86dfaff8f1c277a233f92c1822e06b76:

  Fixed build warning for btreplay (2010-11-29 10:34:30 -0500)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace

Tao Ma (1):
      blkparse: Fix blktrace output pipe broken in the new kernel

 blkparse.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

---

Diff of recent changes:

Too large to post

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (87 preceding siblings ...)
  2010-12-02  5:00 ` Jens Axboe
@ 2010-12-20  4:36 ` Duy Le (Dan)
  2011-01-12  5:00 ` Jens Axboe
                   ` (11 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Duy Le (Dan) @ 2010-12-20  4:36 UTC (permalink / raw)
  To: linux-btrace

Sorry for this newbie question!

I have a disk divided as follows:

=========Disk /dev/sdb: 56.9 GB, 56908316672 bytes
255 heads, 63 sectors/track, 6918 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        1167     9373896   83  Linux
/dev/sdb2            1168        6918    46194907+   5  Extended
/dev/sdb5            1168        2322     9373896   83  Linux
/dev/sdb6            2323        3477     9277506   83  Linux
....
=========
I used blktrace to capture I/Os on sdb5 when I was trying to mount
sdb5. This is a part of the output:

=========...
251,32   0       25     0.000919000  3529  A  RM 18752478 + 8 <- (251,37) 4560
251,32   0       26     0.000919657  3529  Q  RM 18752478 + 8 [mount]
251,32   0       27     0.000920810  3529  G  RM 18752478 + 8 [mount]
251,32   0       28     0.000922188  3529  P   N [mount]
251,32   0       29     0.000923025  3529  I   R 18752478 + 8 [mount]
251,32   0       30     0.000924439  3529  U   N [mount] 1
251,32   0       31     0.000925877  3529  D   R 18752478 + 8 [mount]
251,32   0       32     0.023385527     0  C   R 18752478 + 8 [0]
251,32   0       33     0.023465706  3529  A   R 27664918 + 8 <-
(251,37) 8917000
251,32   0       34     0.023466398  3529  Q   R 27664918 + 8 [mount]
251,32   0       35     0.023467922  3529  G   R 27664918 + 8 [mount]
....
=========
According to blktrace manual, such a number of 18752478 is known as a
"starting block", followed by the size of request. If I understand
correctly, sdb5 is in the range of blocks from 9373897 to
9373896+9373897-1\x18747792. However, blktrace's output shows that a R
request occurs on a block whose index is much larger than the range of
the partition.

How should I understand correctly the value of 18752478? Please help.

Thank you

-- Dan

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (86 preceding siblings ...)
  2010-10-23  4:00 ` Jens Axboe
@ 2010-12-02  5:00 ` Jens Axboe
  2010-12-20  4:36 ` Duy Le (Dan)
                   ` (12 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-12-02  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 5798ffb25496ab8dcb419a2bdc5418802d7f10fc:

  blktrace: btt documentation update (2010-10-22 20:54:11 +0200)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Fixed build warning for btreplay

 btreplay/btreplay.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/btreplay/btreplay.c b/btreplay/btreplay.c
index cba099a..f4f5aa0 100644
--- a/btreplay/btreplay.c
+++ b/btreplay/btreplay.c
@@ -1314,7 +1314,7 @@ static void reset_input_file(struct thr_info *tip)
  */
 static void *replay_sub(void *arg)
 {
-        int i;
+        unsigned int i;
 	char *mdev;
 	char path[MAXPATHLEN];
 	struct io_bunch bunch;

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
@ 2010-11-06  5:00 Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-11-06  5:00 UTC (permalink / raw)
  To: fio

The following changes since commit ca7e0ddb08fece35c95e9056ca877e0806f1e6ef:

  binject: ensure we get aligned memory (2010-10-28 08:52:13 -0600)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Jens Axboe (1):
      Fio 1.44.2

 init.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/init.c b/init.c
index 3f29b91..2e443f6 100644
--- a/init.c
+++ b/init.c
@@ -22,7 +22,7 @@
 
 #include "lib/getopt.h"
 
-static char fio_version_string[] = "fio 1.44.1";
+static char fio_version_string[] = "fio 1.44.2";
 
 #define FIO_RANDSEED		(0xb1899bedUL)
 

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (85 preceding siblings ...)
  2010-10-12 16:52 ` Jens Axboe
@ 2010-10-23  4:00 ` Jens Axboe
  2010-12-02  5:00 ` Jens Axboe
                   ` (13 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-10-23  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ce2151ebdca6f2741dbd903aa3845c56adcba8f4:

  blktrace: disallow -o when using multiple devices (2010-09-16 09:26:22 -0400)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Edward Shishkin (6):
      blktrace: btrecord man pages fixup
      blktrace: blkiomon documentation update
      blktrace: blkparse documentation update
      blktrace: blktrace documentation update
      blktrace: btreplay man pages update
      blktrace: btt documentation update

 blkiomon.c     |    1 +
 blkparse.c     |    2 +
 blktrace.c     |   22 ++++++++++++++++++--
 doc/blkiomon.8 |    9 +++++++-
 doc/blkparse.1 |   20 +++++++++++++++++++
 doc/blktrace.8 |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 doc/btrecord.8 |    2 +-
 doc/btreplay.8 |    7 ++++++
 doc/btt.1      |   21 ++++++++++++++++++++
 9 files changed, 131 insertions(+), 11 deletions(-)

---

Diff of recent changes:

diff --git a/blkiomon.c b/blkiomon.c
index 9fc4d75..a895f65 100644
--- a/blkiomon.c
+++ b/blkiomon.c
@@ -599,6 +599,7 @@ static char usage_str[] = "\n\nblkiomon " \
 	"-I <interval>       | --interval=<interval>\n" \
 	"[ -h <file>         | --human-readable=<file> ]\n" \
 	"[ -b <file>         | --binary=<file> ]\n" \
+	"[ -d <file>         | --dump-lldd=<file> ]\n" \
 	"[ -D <file>         | --debug=<file> ]\n" \
 	"[ -Q <path name>    | --msg-queue=<path name>]\n" \
 	"[ -q <msg queue id> | --msg-queue-id=<msg queue id>]\n" \
diff --git a/blkparse.c b/blkparse.c
index ffad9b6..da34c14 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -2680,6 +2680,8 @@ static char usage_str[] =    "\n\n" \
 	"[ -M                | --no-msgs\n" \
 	"[ -v                | --verbose ]\n" \
 	"[ -V                | --version ]\n\n" \
+	"\t-a Only trace specified actions. See documentation\n" \
+	"\t-A Give trace mask as a single value. See documentation\n" \
 	"\t-b stdin read batching\n" \
 	"\t-d Output file. If specified, binary data is written to file\n" \
 	"\t-D Directory to prepend to input file names\n" \
diff --git a/blktrace.c b/blktrace.c
index 4671a04..4cccb7c 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -435,9 +435,24 @@ static struct option l_opts[] = {
 	}
 };
 
-static char usage_str[] = \
-	"-d <dev> [ -r debugfs path ] [ -o <output> ] [-k ] [ -w time ]\n" \
-	"[ -a action ] [ -A action mask ] [ -I  <devs file> ] [ -v ]\n\n" \
+static char usage_str[] = "\n\n" \
+	"-d <dev>             | --dev=<dev>\n" \
+        "[ -r <debugfs path>  | --relay=<debugfs path> ]\n" \
+        "[ -o <file>          | --output=<file>]\n" \
+        "[ -D <dir>           | --output-dir=<dir>\n" \
+        "[ -w <time>          | --stopwatch=<time>]\n" \
+        "[ -a <action field>  | --act-mask=<action field>]\n" \
+        "[ -A <action mask>   | --set-mask=<action mask>]\n" \
+        "[ -b <size>          | --buffer-size]\n" \
+        "[ -n <number>        | --num-sub-buffers=<number>]\n" \
+        "[ -l                 | --listen]\n" \
+        "[ -h <hostname>      | --host=<hostname>]\n" \
+        "[ -p <port number>   | --port=<port number>]\n" \
+        "[ -s                 | --no-sendfile]\n" \
+        "[ -I <devs file>     | --input-devs=<devs file>]\n" \
+        "[ -v <version>       | --version]\n" \
+        "[ -V <version>       | --version]\n" \
+
 	"\t-d Use specified device. May also be given last after options\n" \
 	"\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
 	"\t-o File(s) to send output to\n" \
@@ -452,6 +467,7 @@ static char usage_str[] = \
 	"\t-p Network port to use (default 8462)\n" \
 	"\t-s Make the network client NOT use sendfile() to transfer data\n" \
 	"\t-I Add devices found in <devs file>\n" \
+	"\t-v Print program version info\n" \
 	"\t-V Print program version info\n\n";
 
 static void clear_events(struct pollfd *pfd)
diff --git a/doc/blkiomon.8 b/doc/blkiomon.8
index aa5ece2..34fbba8 100644
--- a/doc/blkiomon.8
+++ b/doc/blkiomon.8
@@ -7,7 +7,7 @@ blkiomon \- monitor block device I/O based o blktrace data
 
 .SH SYNOPSIS
 .B blkiomon \-I \fIinterval\fR [ \-h \fIfile\fR ] [ \-b \fIfile\fR ]
-[ \-D \fIfile\fR ] [ \-Q \fIpath_name\fR
+[ \-d \fIfile\fR ] [ \-D \fIfile\fR ] [ \-Q \fIpath_name\fR
 \-q \fImsg_queue_id\fR \-m \fImsg_id\fR ] [ \-V ]
 .br
 
@@ -50,6 +50,13 @@ Human-readable output file. Use '\-' for stdout.
 Binary output file. Use '\-' for stdout.
 .RE
 
+\-d \fIfile\fR
+.br
+\-\-dump-lldd=\fIfile\fR
+.RS
+Output file for data emitted by low level device driver.
+.RE
+
 \-D \fIfile\fR
 .br
 \-\-debug=\fIfile\fR
diff --git a/doc/blkparse.1 b/doc/blkparse.1
index 11dab65..9193dbe 100644
--- a/doc/blkparse.1
+++ b/doc/blkparse.1
@@ -58,6 +58,26 @@ option.
 
 
 .SH OPTIONS
+\-A \fIhex-mask\fR
+.br
+\-\-set-mask=\fIhex-mask\fR
+.RS
+Set filter mask to \fIhex-mask\fR, see blktrace (8) for masks
+.RE
+
+\-a \fImask\fR
+.br
+\-\-act-mask=\fImask\fR
+.RS
+Add \fImask\fR to current filter, see blktrace (8) for masks
+.RE
+
+\-D \fIdir\fR
+.br
+\-\-input-directory=\fIdir\fR
+.RS
+Prepend \fIdir\fR to input file names
+.RE
 
 \-b \fIbatch\fR
 .br
diff --git a/doc/blktrace.8 b/doc/blktrace.8
index 50b3a62..b5e69b7 100644
--- a/doc/blktrace.8
+++ b/doc/blktrace.8
@@ -105,23 +105,59 @@ Adds \fIdev\fR as a device to trace
 
 \-I \fIfile\fR
 .br
-\-\-input-devs=\fIfile\fR 
+\-\-input\-devs=\fIfile\fR
 .RS
 Adds the devices found in \fIfile\fR as devices to trace
 .RE
 
 \-n \fInum\-sub\fR 
 .br
-\-\-num\-sub=\fInum-sub\fR    
+\-\-num\-sub\-buffers=\fInum-sub\fR
 .RS
 Specifies number of buffers to use. blktrace defaults to 4 sub buffers.
 .RE
 
-\-o \fIfile\fR 
+\-l
 .br
-\-\-output=\fIfile\fR        
+\-\-listen
 .RS
-Prepend \fIfile\fR to output file name(s)  
+Run in network listen mode (blktrace server)
+.RE
+
+\-h \fIhostname\fR
+.br
+\-\-host=\fIhostname\fR
+.RS
+Run in network client mode, connecting to the given host
+.RE
+
+\-p \fInumber\fR
+.br
+\-\-port=\fInumber\fR
+.RS
+Network port to use (default 8462)
+.RE
+
+\-s
+.br
+\-\-no\-sendfile
+.RS
+Make the network client NOT use sendfile() to transfer data
+.RE
+
+\-o \fIbasename\fR
+.br
+\-\-output=\fIbasename\fR
+.RS
+Specifies base name for input files. Default is device.blktrace.cpu.
+Specifying -o - runs in live mode with blkparse (writing data to standard out).
+.RE
+
+\-D \fIdir\fR
+.br
+\-\-output\-dir=\fIdir\fR
+.RS
+Prepend \fIfile\fR to output file name(s)
 
 This only works when supplying a single device, or when piping the output
 via "-o -" with multiple devices.
@@ -134,9 +170,17 @@ via "-o -" with multiple devices.
 Specifies debugfs mount point  
 .RE
 
+\-v
+.br
+\-\-version
+.RS
+Outputs version
+.RE
+
 \-V               
 .br
-\-\-version                  
+\-\-version
+.RS
 Outputs version  
 .RE
 
@@ -175,6 +219,8 @@ line options.
 \fIwrite\fR: write traces
 .br
 \fInotify\fR: trace messages
+.br
+\fIdrv_data\fR: additional driver specific trace
 .RE
 
 
diff --git a/doc/btrecord.8 b/doc/btrecord.8
index c0655ab..dd92396 100644
--- a/doc/btrecord.8
+++ b/doc/btrecord.8
@@ -107,7 +107,7 @@ Show version number and exit.
 
 \-m <\fInanoseconds\fR>
 .br
-\-\-input\-base=<\fInanoseconds\fR>
+\-\-max\-bunch\-time=<\fInanoseconds\fR>
 .RS
 The \fI\-m\fR option requires a single parameter which specifies an
 amount of time (in nanoseconds) to include in any one bunch of IOs that
diff --git a/doc/btreplay.8 b/doc/btreplay.8
index 1efcd0d..118dc10 100644
--- a/doc/btreplay.8
+++ b/doc/btreplay.8
@@ -168,6 +168,13 @@ When specified on the command line, all pre-bunch stall indicators will be
 ignored. IOs will be replayed without inter-bunch delays.
 .RE
 
+\-x <\fIfactor\fR>
+.br
+\-\-acc\-factor=<\fIfactor\fR>
+.RS
+Specify acceleration factor. Default value is 1 (no acceleration).
+.RE
+
 \-v
 .br
 \-\-verbose
diff --git a/doc/btt.1 b/doc/btt.1
index 60d28ac..28cf912 100644
--- a/doc/btt.1
+++ b/doc/btt.1
@@ -30,6 +30,8 @@ btt \- analyse block i/o traces produces by blktrace
 .br
 [ \-L <\fIfreq\fR>        | \-\-periodic\-latencies=<\fIfreq\fR> ]
 .br
+[ \-m <\fIoutput name\fR> | \-\-seeks\-per\-second=<\fIoutput name\fR> ]
+.br
 [ \-M <\fIdev map\fR>     | \-\-dev\-maps=<\fIdev map\fR>
 .br
 [ \-o <\fIoutput name\fR> | \-\-output\-file=<\fIoutput name\fR> ]
@@ -58,6 +60,8 @@ btt \- analyse block i/o traces produces by blktrace
 .br
 [ \-V               | \-\-version ]
 .br
+[ \-X               | \-\-easy\-parse\-avgs ]
+.br
 [ \-z <\fIoutput name\fR> | \-\-q2d\-latencies=<\fIoutput name\fR> ]
 .br
 [ \-Z               | \-\-do\-active ]
@@ -201,6 +205,15 @@ Q2C and D2C latencies. The frequency specified will regulate how often
 an average latency is output -- a floating point value expressing seconds.
 .RE
 
+.B \-m <\fIoutput name\fR>
+.br
+.B \-\-seeks\-per\-second=<\fIoutput name\fR>
+.RS 4
+Trigger btt to output seeks-per-second information. The first column will
+contain a time value (seconds), and the second column  will indicate the
+number of seeks per second at that point.
+.RE
+
 .B \-M <\fIdev map\fR>
 .br
 .B \-\-dev\-maps=<\fIdev map\fR>
@@ -332,6 +345,14 @@ Shows the version of btt.
 Requests a more verbose output.
 .RE
 
+.B \-X
+.br
+.B \-\-easy\-parse\-avgs
+.RS 4
+Provide data in an easy-to-parse form and write it to a file
+with .avg exentsion
+.RE
+
 .B \-z <\fIoutput name\fR>
 .br
 .B \-\-q2d\-latencies=<\fIoutput name\fR>

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (84 preceding siblings ...)
  2010-10-12 15:38 ` Edward Shishkin
@ 2010-10-12 16:52 ` Jens Axboe
  2010-10-23  4:00 ` Jens Axboe
                   ` (14 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-10-12 16:52 UTC (permalink / raw)
  To: linux-btrace

On 2010-10-12 17:38, Edward Shishkin wrote:
> Hello.
> How about these ones:
> 
> http://marc.info/?l=linux-btrace&m\x128049870115477&w=2
> http://marc.info/?l=linux-btrace&m\x128049870215491&w=2
> http://marc.info/?l=linux-btrace&m\x128049871415498&w=2
> http://marc.info/?l=linux-btrace&m\x128049873015527&w=2
> http://marc.info/?l=linux-btrace&m\x128049874115543&w=2
> http://marc.info/?l=linux-btrace&m\x128049875115566&w=2
> 
> any chances they will be pushed? All of them except the second
> one (blkiomon fixups) are ack-ed by Alan D. Brunelle.

I was expecting Alan to commit them. But I can do it, will push
it later tonight.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (83 preceding siblings ...)
  2010-09-17  4:00 ` Jens Axboe
@ 2010-10-12 15:38 ` Edward Shishkin
  2010-10-12 16:52 ` Jens Axboe
                   ` (15 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Edward Shishkin @ 2010-10-12 15:38 UTC (permalink / raw)
  To: linux-btrace

Hello.
How about these ones:

http://marc.info/?l=linux-btrace&m\x128049870115477&w=2
http://marc.info/?l=linux-btrace&m\x128049870215491&w=2
http://marc.info/?l=linux-btrace&m\x128049871415498&w=2
http://marc.info/?l=linux-btrace&m\x128049873015527&w=2
http://marc.info/?l=linux-btrace&m\x128049874115543&w=2
http://marc.info/?l=linux-btrace&m\x128049875115566&w=2

any chances they will be pushed? All of them except the second
one (blkiomon fixups) are ack-ed by Alan D. Brunelle.

Thanks,
Edward.

Jens Axboe wrote:
> The following changes since commit fb7f86674a516ddff0d60bfab3bd284a4812075f:
>
>   blktrace: disable kill option - take 2 (2010-04-20 15:41:14 +0200)
>
> are available in the git repository at:
>   git://git.kernel.dk/blktrace.git master
>
> Alan D. Brunelle (1):
>       blktrace: disallow -o when using multiple devices
>
>  blktrace.c       |    6 ++++++
>  doc/blktrace.8   |    3 +++
>  doc/blktrace.tex |    5 ++++-
>  3 files changed, 13 insertions(+), 1 deletions(-)
>
> ---
>
> Diff of recent changes:
>
> diff --git a/blktrace.c b/blktrace.c
> index b9f9b68..4671a04 100644
> --- a/blktrace.c
> +++ b/blktrace.c
> @@ -2626,6 +2626,12 @@ int main(int argc, char *argv[])
>  		goto out;
>  	}
>  
> +	if (ndevs > 1 && output_name && strcmp(output_name, "-") != 0) {
> +		fprintf(stderr, "-o not supported with multiple devices\n");
> +		ret = 1;
> +		goto out;
> +	}
> +
>  	signal(SIGINT, handle_sigint);
>  	signal(SIGHUP, handle_sigint);
>  	signal(SIGTERM, handle_sigint);
> diff --git a/doc/blktrace.8 b/doc/blktrace.8
> index ab6a3f3..50b3a62 100644
> --- a/doc/blktrace.8
> +++ b/doc/blktrace.8
> @@ -122,6 +122,9 @@ Specifies number of buffers to use. blktrace defaults to 4 sub buffers.
>  \-\-output=\fIfile\fR        
>  .RS
>  Prepend \fIfile\fR to output file name(s)  
> +
> +This only works when supplying a single device, or when piping the output
> +via "-o -" with multiple devices.
>  .RE
>  
>  \-r \fIrel-path\fR
> diff --git a/doc/blktrace.tex b/doc/blktrace.tex
> index 54fe451..4d8278e 100644
> --- a/doc/blktrace.tex
> +++ b/doc/blktrace.tex
> @@ -389,7 +389,10 @@ Short              & Long                       & Description \\ \hline\hline
>  -d \emph{dev}      & --dev=\emph{dev}           & Adds \emph{dev} as a device to trace \\ \hline
>  -k                 & --kill                     & Kill on-going trace \\ \hline
>  -n \emph{num-sub}  & --num-sub=\emph{num-sub}   & Specifies number of buffers to use \\ \hline
> --o \emph{file}     & --output=\emph{file}       & Prepend \emph{file} to output file name(s) \\ \hline
> +-o \emph{file}     & --output=\emph{file}       & Prepend \emph{file} to output file name(s) \\
> +                   &                            & \textbf{This only works when using a single device} \\
> +                   &                            & \textbf{or when piping the output via \texttt{-o -}} \\
> +                   &                            & \textbf{with multiple devices.} \\ \hline
>  -r \emph{rel-path} & --relay=\emph{rel-path}    & Specifies debugfs mount point \\ \hline
>  -V                 & --version                  & Outputs version \\ \hline
>  -w \emph{seconds}  & --stopwatch=\emph{seconds} & Sets run time to the number of seconds specified \\ \hline
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrace" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>   


-- 
Edward O. Shishkin
Principal Software Engineer
Red Hat Czech


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (82 preceding siblings ...)
  2010-04-21  4:00 ` Jens Axboe
@ 2010-09-17  4:00 ` Jens Axboe
  2010-10-12 15:38 ` Edward Shishkin
                   ` (16 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-09-17  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit fb7f86674a516ddff0d60bfab3bd284a4812075f:

  blktrace: disable kill option - take 2 (2010-04-20 15:41:14 +0200)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      blktrace: disallow -o when using multiple devices

 blktrace.c       |    6 ++++++
 doc/blktrace.8   |    3 +++
 doc/blktrace.tex |    5 ++++-
 3 files changed, 13 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/blktrace.c b/blktrace.c
index b9f9b68..4671a04 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -2626,6 +2626,12 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 
+	if (ndevs > 1 && output_name && strcmp(output_name, "-") != 0) {
+		fprintf(stderr, "-o not supported with multiple devices\n");
+		ret = 1;
+		goto out;
+	}
+
 	signal(SIGINT, handle_sigint);
 	signal(SIGHUP, handle_sigint);
 	signal(SIGTERM, handle_sigint);
diff --git a/doc/blktrace.8 b/doc/blktrace.8
index ab6a3f3..50b3a62 100644
--- a/doc/blktrace.8
+++ b/doc/blktrace.8
@@ -122,6 +122,9 @@ Specifies number of buffers to use. blktrace defaults to 4 sub buffers.
 \-\-output=\fIfile\fR        
 .RS
 Prepend \fIfile\fR to output file name(s)  
+
+This only works when supplying a single device, or when piping the output
+via "-o -" with multiple devices.
 .RE
 
 \-r \fIrel-path\fR
diff --git a/doc/blktrace.tex b/doc/blktrace.tex
index 54fe451..4d8278e 100644
--- a/doc/blktrace.tex
+++ b/doc/blktrace.tex
@@ -389,7 +389,10 @@ Short              & Long                       & Description \\ \hline\hline
 -d \emph{dev}      & --dev=\emph{dev}           & Adds \emph{dev} as a device to trace \\ \hline
 -k                 & --kill                     & Kill on-going trace \\ \hline
 -n \emph{num-sub}  & --num-sub=\emph{num-sub}   & Specifies number of buffers to use \\ \hline
--o \emph{file}     & --output=\emph{file}       & Prepend \emph{file} to output file name(s) \\ \hline
+-o \emph{file}     & --output=\emph{file}       & Prepend \emph{file} to output file name(s) \\
+                   &                            & \textbf{This only works when using a single device} \\
+                   &                            & \textbf{or when piping the output via \texttt{-o -}} \\
+                   &                            & \textbf{with multiple devices.} \\ \hline
 -r \emph{rel-path} & --relay=\emph{rel-path}    & Specifies debugfs mount point \\ \hline
 -V                 & --version                  & Outputs version \\ \hline
 -w \emph{seconds}  & --stopwatch=\emph{seconds} & Sets run time to the number of seconds specified \\ \hline

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (81 preceding siblings ...)
  2010-04-20  4:00 ` Jens Axboe
@ 2010-04-21  4:00 ` Jens Axboe
  2010-09-17  4:00 ` Jens Axboe
                   ` (17 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-04-21  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 014b0ea19762341e217d463308710c3662d50e9c:

  Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace (2010-04-19 19:15:27 +0200)

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Edward Shishkin (5):
      blktrace: avoid device duplication
      blktrace: print correct usage
      blktrace: add back conversion
      blktrace: update blkiomon doc
      blktrace: disable kill option - take 2

 blkparse.c          |    2 +-
 blktrace.c          |   12 ++++++++++--
 btreplay/btreplay.c |   13 +++++++++++--
 btt/args.c          |    3 +--
 doc/blkiomon.8      |    2 ++
 doc/blktrace.8      |   24 ++++--------------------
 6 files changed, 29 insertions(+), 27 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 9bd8023..ffad9b6 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -2702,7 +2702,7 @@ static char usage_str[] =    "\n\n" \
 
 static void usage(char *prog)
 {
-	fprintf(stderr, "Usage: %s %s %s", prog, blkparse_version, usage_str);
+	fprintf(stderr, "Usage: %s %s", prog, usage_str);
 }
 
 int main(int argc, char *argv[])
diff --git a/blktrace.c b/blktrace.c
index b4c919d..b9f9b68 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -442,7 +442,6 @@ static char usage_str[] = \
 	"\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
 	"\t-o File(s) to send output to\n" \
 	"\t-D Directory to prepend to output file names\n" \
-	"\t-k Kill a running trace\n" \
 	"\t-w Stop after defined time, in seconds\n" \
 	"\t-a Only trace specified actions. See documentation\n" \
 	"\t-A Give trace mask as a single value. See documentation\n" \
@@ -493,7 +492,7 @@ static inline void pdc_nev_update(struct devpath *dpp, int cpu, int nevents)
 
 static void show_usage(char *prog)
 {
-	fprintf(stderr, "Usage: %s %s %s", prog, blktrace_version, usage_str);
+	fprintf(stderr, "Usage: %s %s", prog, usage_str);
 }
 
 /*
@@ -1200,8 +1199,17 @@ static int add_devpath(char *path)
 {
 	int fd;
 	struct devpath *dpp;
+	struct list_head *p;
 
 	/*
+	 * Verify device is not duplicated
+	 */
+	__list_for_each(p, &devpaths) {
+	       struct devpath *tmp = list_entry(p, struct devpath, head);
+	       if (!strcmp(tmp->path, path))
+		        return 0;
+	}
+	/*
 	 * Verify device is valid before going too far
 	 */
 	fd = my_open(path, O_RDONLY | O_NONBLOCK);
diff --git a/btreplay/btreplay.c b/btreplay/btreplay.c
index 2d122ca..cba099a 100644
--- a/btreplay/btreplay.c
+++ b/btreplay/btreplay.c
@@ -1314,6 +1314,8 @@ static void reset_input_file(struct thr_info *tip)
  */
 static void *replay_sub(void *arg)
 {
+        int i;
+	char *mdev;
 	char path[MAXPATHLEN];
 	struct io_bunch bunch;
 	struct thr_info *tip = arg;
@@ -1321,8 +1323,15 @@ static void *replay_sub(void *arg)
 
 	pin_to_cpu(tip);
 
-	sprintf(path, "/dev/%s", map_dev(tip->devnm));
-
+	mdev = map_dev(tip->devnm);
+	sprintf(path, "/dev/%s", mdev);
+	/*
+	 * convert underscores to slashes to
+	 * restore device names that have larger paths
+	 */
+	for (i = 0; i < strlen(mdev); i++)
+	        if (path[strlen("/dev/") + i] = '_')
+		        path[strlen("/dev/") + i] = '/';
 #ifdef O_NOATIME
 	oflags = O_NOATIME;
 #else
diff --git a/btt/args.c b/btt/args.c
index 137c2f5..5c5078a 100644
--- a/btt/args.c
+++ b/btt/args.c
@@ -244,8 +244,7 @@ static char usage_str[] = \
 
 static void usage(char *prog)
 {
-	fprintf(stderr, "Usage: %s %s %s", prog, bt_timeline_version,
-		usage_str);
+	fprintf(stderr, "Usage: %s %s", prog, usage_str);
 }
 
 static FILE *setup_ofile(char *fname)
diff --git a/doc/blkiomon.8 b/doc/blkiomon.8
index dbed0df..aa5ece2 100644
--- a/doc/blkiomon.8
+++ b/doc/blkiomon.8
@@ -17,6 +17,8 @@ blkiomon is a block device I/O monitor. It periodically generates per-device
 request size and request latency statistics from blktrace data. It provides
 histograms as well as data that can be used to calculate min, max, average
 and variance. For this purpose, it consumes D and C traces read from stdin.
+Note, that this doesn't work for logical volumes, as high-level drivers
+don't see the completion of the events (C).
 
 There are options for binary output and human-readable output to files and
 stdout. Output to a message queue is supported as well.
diff --git a/doc/blktrace.8 b/doc/blktrace.8
index 58e8f90..ab6a3f3 100644
--- a/doc/blktrace.8
+++ b/doc/blktrace.8
@@ -66,19 +66,10 @@ blktrace may also be run concurrently with blkparse to produce
 .TP 2
 \- 
 The default behaviour for blktrace is to run forever until explicitly
-killed by the user (via a control-C, or kill utility invocation).
-There are two ways to modify this:
-
-.TP 5
-  1. 
-You may utilise the blktrace utility itself to kill
-a running trace -- via the \fB\-k\fR option.
-
-.TP 5
-  2.
-You can specify a run-time duration for blktrace via the
-\fB\-w\fR option -- then blktrace will run for the specified number
-of seconds, and then halt.
+killed by the user (via a control-C, or sending SIGINT signal to the
+process via invocation the kill (1) utility). Also you can specify a
+run-time duration for blktrace via the \fB\-w\fR option -- then
+blktrace will run for the specified number of seconds, and then halt.
 
 
 .SH OPTIONS
@@ -119,13 +110,6 @@ Adds \fIdev\fR as a device to trace
 Adds the devices found in \fIfile\fR as devices to trace
 .RE
 
-\-k 
-.br
-\-\-kill 
-.RS
-Kill on-going trace  
-.RE
-
 \-n \fInum\-sub\fR 
 .br
 \-\-num\-sub=\fInum-sub\fR    

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (80 preceding siblings ...)
  2010-03-23  5:00 ` Jens Axboe
@ 2010-04-20  4:00 ` Jens Axboe
  2010-04-21  4:00 ` Jens Axboe
                   ` (18 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-04-20  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 6abaea7a340536c6afa5944e3fa63831729dfed3:

  Fixed incorrect sizeof instead of strlen in btt/rstats.c (2010-03-22 10:21:12 -0400)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Eric Sandeen (1):
      blkparse: exit with error if no tracefiles found

Jens Axboe (1):
      Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace

 blkparse.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

---

Diff of recent changes:

diff --git a/blkparse.c b/blkparse.c
index 5a49d6b..9bd8023 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -2518,6 +2518,12 @@ static int do_file(void)
 
 		for (cpu = 0; setup_file(pdi, cpu); cpu++)
 			;
+
+		if (!cpu) {
+			fprintf(stderr,"No input files found for %s\n",
+				pdi->name);
+			return 1;
+		}
 	}
 
 	/*

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (79 preceding siblings ...)
  2010-02-23  5:00 ` Jens Axboe
@ 2010-03-23  5:00 ` Jens Axboe
  2010-04-20  4:00 ` Jens Axboe
                   ` (19 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-03-23  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 0d76d14f46195eb4295c35bf15531890378c7684:

  add libpthread to btreplay/Makefile LIBS (2010-02-22 19:56:52 +0100)

are available in the git repository at:
  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Corrected memory leak in btt/p_live.c
      Fixed incorrect sizeof instead of strlen in btt/rstats.c

 btt/p_live.c |    1 +
 btt/rstats.c |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

---

Diff of recent changes:

diff --git a/btt/p_live.c b/btt/p_live.c
index 8bbb893..17f06bb 100644
--- a/btt/p_live.c
+++ b/btt/p_live.c
@@ -86,6 +86,7 @@ static void __p_live_add(struct rb_root *root, __u64 dt, __u64 ct)
 			list_del(&plp->head);
 			rb_erase(&plp->rb_node, root);
 			__p_live_add(root, min(plp->dt, dt), max(plp->ct, ct));
+			free(plp);
 			return;
 		}
 
diff --git a/btt/rstats.c b/btt/rstats.c
index 71f010b..5a336fe 100644
--- a/btt/rstats.c
+++ b/btt/rstats.c
@@ -38,7 +38,7 @@ static LIST_HEAD(rstats);
 
 static int do_open(struct files *fip, char *bn, char *pn)
 {
-	fip->nm = malloc(sizeof(bn) + 16);
+	fip->nm = malloc(strlen(bn) + 16);
 	sprintf(fip->nm, "%s_%s.dat", bn, pn);
 
 	fip->fp = my_fopen(fip->nm, "w");
@@ -55,6 +55,7 @@ static int init_rsip(struct rstat *rsip, struct d_info *dip)
 {
 	char *nm = dip ? dip->dip_name : "sys";
 
+	rsip->base_sec = -1;
 	rsip->ios = rsip->nblks = 0;
 	if (do_open(&rsip->files[0], nm, "iops_fp") ||
 			    do_open(&rsip->files[1], nm, "mbps_fp"))

^ permalink raw reply related	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (78 preceding siblings ...)
  2009-10-10  4:00 ` Jens Axboe
@ 2010-02-23  5:00 ` Jens Axboe
  2010-03-23  5:00 ` Jens Axboe
                   ` (20 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2010-02-23  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 2e37a10ee8b470b805e7c26c703073dbc54ca84e:
  Alan D. Brunelle (1):
        btt: Added in I/O activity per device and system-wide

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Eric Sandeen (1):
      add libpthread to btreplay/Makefile LIBS

 btreplay/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (77 preceding siblings ...)
  2009-10-09  4:00 ` Jens Axboe
@ 2009-10-10  4:00 ` Jens Axboe
  2010-02-23  5:00 ` Jens Axboe
                   ` (21 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-10-10  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit a155ab989ffc8b9cf95a631309e9a825d04bcc68:
  Alan D. Brunelle (1):
        btt: better data file naming

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      btt: Added in I/O activity per device and system-wide

 btt/Makefile         |    2 +-
 btt/args.c           |   12 +-
 btt/bt_timeline.c    |    5 +-
 btt/btt_plot.py      |  102 +-
 btt/devs.c           |    2 +
 btt/doc/Makefile     |    2 +-
 btt/doc/btt.tex      |   73 +-
 btt/doc/live.eps     |65949 ++++++++++++++++++++++++++++++++++++++++++++++++++
 btt/globals.h        |   16 +-
 btt/output.c         |   34 +
 btt/p_live.c         |  202 +
 btt/trace_complete.c |    1 +
 doc/btt.1            |   10 +
 13 files changed, 66380 insertions(+), 30 deletions(-)
 create mode 100644 btt/doc/live.eps
 create mode 100644 btt/p_live.c

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (76 preceding siblings ...)
  2009-09-02  4:00 ` Jens Axboe
@ 2009-10-09  4:00 ` Jens Axboe
  2009-10-10  4:00 ` Jens Axboe
                   ` (22 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-10-09  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 677ef89ccb24fb3e38b13b02b9394318afb78f30:
  Jens Axboe (1):
        Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      btt: better data file naming

 btt/aqd.c         |    6 ++--
 btt/bno_dump.c    |   18 ++++++---------
 btt/devs.c        |   63 +++++++++++++++++++++++-----------------------------
 btt/globals.h     |   15 ++++++------
 btt/latency.c     |   18 ++++++--------
 btt/misc.c        |    5 ++++
 btt/plat.c        |    6 ++--
 btt/rstats.c      |   14 ++++++-----
 btt/seek.c        |    8 ++++--
 btt/unplug_hist.c |   15 ++++++------
 10 files changed, 83 insertions(+), 85 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (75 preceding siblings ...)
  2009-08-15  4:00 ` Jens Axboe
@ 2009-09-02  4:00 ` Jens Axboe
  2009-10-09  4:00 ` Jens Axboe
                   ` (23 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-09-02  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 57c9bbc7f6bd3680910f99ba30d70b54a3076833:
  Alan D. Brunelle (1):
        Added in running stats documentation

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (2):
      blkparse: allow stdout output with -d option (using '-' as the filename)
      Merge branch 'master' of ssh://router.home.kernel.dk/data/git/blktrace

 blkparse.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (74 preceding siblings ...)
  2009-05-13  4:00 ` Jens Axboe
@ 2009-08-15  4:00 ` Jens Axboe
  2009-09-02  4:00 ` Jens Axboe
                   ` (24 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-08-15  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 1e09f6e9012826fca69fa07222b7bc53c3e629ee:
  Jens Axboe (1):
        Version 1.0.1

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Added in running stats for btt
      Added in running stats documentation

 btt/Makefile         |    2 +-
 btt/bt_timeline.c    |    6 +-
 btt/devs.c           |    2 +
 btt/doc/Makefile     |    2 +-
 btt/doc/btt.tex      |   49 ++-
 btt/doc/rstats.eps   | 1267 ++++++++++++++++++++++++++++++++++++++++++++++++++
 btt/globals.h        |   11 +-
 btt/rstats.c         |  136 ++++++
 btt/trace.c          |    2 +
 btt/trace_complete.c |    4 +-
 10 files changed, 1473 insertions(+), 8 deletions(-)
 create mode 100644 btt/doc/rstats.eps
 create mode 100644 btt/rstats.c

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (73 preceding siblings ...)
  2009-04-22  4:00 ` Jens Axboe
@ 2009-05-13  4:00 ` Jens Axboe
  2009-08-15  4:00 ` Jens Axboe
                   ` (25 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-05-13  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit b5f8804a588fffdea10a0cd46a36fc196acea9f2:
  Martin Peschke (1):
        fix off-by-one issues in blkiomon.h

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Converted to using the correct remap entries

Eric Sandeen (5):
      fix max-pkts option inconsistencies
      more manpage fixups
      fix up btrace options & manpage
      blkiomon manpage and usage reference invalid "msg-queue-name" option
      blkrawverify: warn and return error if no traces are found

Jens Axboe (1):
      Version 1.0.1

Martin Peschke (1):
      blkiomon: fix unaligned accesses on ia64

 blkiomon.c          |    4 ++--
 blkiomon.h          |    4 ++--
 blkparse.c          |    2 +-
 blkparse_fmt.c      |   27 ++++++++++++++++-----------
 blkrawverify.c      |    8 +++++++-
 blktrace_api.h      |    4 ++--
 btrace              |    7 ++-----
 btreplay/btrecord.c |    2 +-
 btt/trace_remap.c   |    9 ++++-----
 doc/blkiomon.8      |    4 ++--
 doc/blkparse.1      |    9 +--------
 doc/blkrawverify.1  |    2 +-
 doc/bno_plot.1      |    2 +-
 doc/btrace.8        |   20 ++++++++++++--------
 doc/btrecord.8      |   12 ++++++------
 doc/btreplay.8      |   10 ++++------
 doc/btt.1           |    3 ++-
 17 files changed, 66 insertions(+), 63 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
       [not found] <869776.96350.qm@web63807.mail.re1.yahoo.com>
@ 2009-04-24  4:40 ` Gurudas Pai
  0 siblings, 0 replies; 135+ messages in thread
From: Gurudas Pai @ 2009-04-24  4:40 UTC (permalink / raw)
  To: girish.satihal; +Cc: fio

Do as follow:

DO NOT mount partition on /mnt
run fio.

OR

mount partition on /mnt
use /mnt in fio jobfile. do not use partition.

Thanks,
-guru


Girish Satihal wrote:
> Hi Guru,
> I first mount the paritition with ext3 files system on /mnt and run the 
> fio test on the device.
> When you run mount command you can see the device is mounted on /mnt 
> with ext3 file system. Let me know if you have anything to say on this. 
> Did you ever try such testing earlier?
>  
> Thanks,
>  Girish
> 
> --- On *Wed, 4/22/09, Gurudas Pai /<gurudas.pai@oracle.com>/* wrote:
> 
>     From: Gurudas Pai <gurudas.pai@oracle.com>
>     Subject: Re: Recent changes
>     To: "Girish Satihal" <girish.satihal@yahoo.com>
>     Cc: fio@vger.kernel.org
>     Date: Wednesday, April 22, 2009, 11:23 AM
> 
>     Girish,
> 
>     > The reason for saying ext3, is I run fdisk on /dev/cciss/c1d0 and created
>     a primary partition.
>     > Then I created a ext3 filesystem on this partition by running mkefs and
>     mounted this partition 
>     > on /mnt folder. Then I run fio on this partition.
>     you run it on disk directly(/dev/cciss/c1d0) without mounting it on /mnt.
> 
> 
>     Thanks,
>     -Guru
>     --
>     To unsubscribe from this list: send the line "unsubscribe fio" in
>     the body of a message to majordomo@vger.kernel.org
>     More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-22 16:46                       ` Girish Satihal
@ 2009-04-22 17:40                         ` Jens Axboe
  0 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-04-22 17:40 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Wed, Apr 22 2009, Girish Satihal wrote:
> Hi Jens,
> Running the fio on the partition mounted with filesystem was the
> intention to�compare the functinality of fio with other performance
> benchmarking tool called IOmeter which is used for Windows. We use two
> different performance test tools, one is IOmeter for Windows and fio
> for Linux. 

OK, but that doesn't make a lot of sense. The file system is going to be
very unhappy if you scribble random data to the device while it is
mounted. So either you should keep the device unmounted and run the test
on the raw device (or partition), OR you mount the device and run the
tests on files hosted on that device. With fio, that would either be:

filename=/dev/cciss/c0d0p1

OR

directory=/where/c0d0p1/is/mounted

> Also, recently we got a customer issue who had very bad performance
> numbers for the test they conducted on ext2 filesystem and wanted us
> to try the same. They dont use fio. They have thier�own proprietery
> tool for performance measure. So it was just an investigation for us
> to run fio�on partition with filesystem instead of keep it
> raw.�Since we did not find any problem with�Random Writes but only
> problem with Seqential Writes thought of reporting to you and get the
> solution.

Thanks for reporting, you should always do that. I'm just trying to make
sense of what you want to accomplish.

> I am not bothered about the contents of the device. I was just wanted
> to compare the performance numbers between the Raw partition and the
> filesystem partition.

Typically the only difference will be if the device defaults to a small
block sizes. For buffered IO, one may find that the umounted partition
has 1kb default block size, while once it's mounted, the file system
will set the soft block size to it's own size (typically 4kb). So if
that makes your difference, you should just mount and immediately umount
the partition. That will accomplish the same, and you don't risk
panic'ing the file system due to it becoming corrupt while you run the
test.

> If you want I can look into the erroe messages�logged in�dmesg.

Please do!

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-22  5:46                     ` Jens Axboe
  2009-04-22  5:53                       ` Gurudas Pai
@ 2009-04-22 16:46                       ` Girish Satihal
  2009-04-22 17:40                         ` Jens Axboe
  1 sibling, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-22 16:46 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio

[-- Attachment #1: Type: text/plain, Size: 4236 bytes --]

Hi Jens,
Running the fio on the partition mounted with filesystem was the intention to compare the functinality of fio with other performance benchmarking tool called IOmeter which is used for Windows. We use two different performance test tools, one is IOmeter for Windows and fio for Linux. 
 
Also, recently we got a customer issue who had very bad performance numbers for the test they conducted on ext2 filesystem and wanted us to try the same. They dont use fio. They have thier own proprietery tool for performance measure. So it was just an investigation for us to run fio on partition with filesystem instead of keep it raw. Since we did not find any problem with Random Writes but only problem with Seqential Writes thought of reporting to you and get the solution.
 
I am not bothered about the contents of the device. I was just wanted to compare the performance numbers between the Raw partition and the filesystem partition.
 
If you want I can look into the erroe messages logged in dmesg.
 
 
Thanks,
 Girish 

--- On Wed, 4/22/09, Jens Axboe <jens.axboe@oracle.com> wrote:

From: Jens Axboe <jens.axboe@oracle.com>
Subject: Re: Recent changes
To: "Girish Satihal" <girish.satihal@yahoo.com>
Cc: fio@vger.kernel.org
Date: Wednesday, April 22, 2009, 11:16 AM

On Tue, Apr 21 2009, Girish Satihal wrote:
> Hi Jens,
> The reason for saying ext3, is I run fdisk on /dev/cciss/c1d0 and created
a primary partition.
>  
> Then I created a ext3 filesystem on this partition by running mkefs and
mounted this partition on /mnt folder. Then I run fio on this partition.

You run fio on the partition, or on the mount point? Your fio job file
indicates that you run fio on the full device, not even just the
partition. This has _nothing_ to do with ext3. Irregardless of whether
you run fio on the partition or the device, your file system will be
hosed. Perhaps things go bad because ext3 turns your device read-only on
errors. Did you get any errors logged in dmesg?

> We earlier use to run fio on raw partition. But now we tried running fio
on a partition which has ext3 filesystem.

Why would the content of the device matter?

> When I run fio on raw filesystem I dont get any errors for Sequential
Writes, but when I run fio test on this ext3 filesystem then I am getting the
errors for Sequential Writes what I mentioned u earlier.

Lets back up a bit... What are you trying to test? Running fio on a
device/partition that is mounted with a file system is just a crazy
thing to do. Why would you do that?


>  
> Thanks,
>  Girish 
> 
> --- On Wed, 4/22/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> From: Jens Axboe <jens.axboe@oracle.com>
> Subject: Re: Recent changes
> To: "Girish Satihal" <girish.satihal@yahoo.com>
> Cc: fio@vger.kernel.org
> Date: Wednesday, April 22, 2009, 12:45 AM
> 
> On Tue, Apr 21 2009, Girish Satihal wrote:
> > Hi Jens,
> > I guess I did not understand your question for which I am very sorry.
> 
> Don't apologize for that. But if there's something I write you
> don't
> understand, do just ask for an explanation.
> 
> > As per my understanding I have sent you the job file which was
> > input file to fio for the performance testing.  As only the problem
> > with Seqential Writes, I have cut down the job file to only Write
> > parameters where the issue is being seen. The problem is seen with
all
> > block size and IO depths of Sequential Writes.  Please let me know
> > if this would help you or still you arelooking for anything else.
> 
> So my current question is why you are mentioning ext3? The test case you
> provided is reading and writing directly to the CCISS device, not a file
> inside a file system hosted on that device.
> 
> Also, please try a make clean && make && make install in
your
> fio
> directory. Sometimes things get hosed when updates are pulled, which may
> explain why yours is acting up.
> 
> -- 
> Jens Axboe
> 
> 
> 
> 
>       
-- 
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



      

[-- Attachment #2: Type: text/html, Size: 4952 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-22  5:46                     ` Jens Axboe
@ 2009-04-22  5:53                       ` Gurudas Pai
  2009-04-22 16:46                       ` Girish Satihal
  1 sibling, 0 replies; 135+ messages in thread
From: Gurudas Pai @ 2009-04-22  5:53 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

Girish,

> The reason for saying ext3, is I run fdisk on /dev/cciss/c1d0 and created a primary partition.
> Then I created a ext3 filesystem on this partition by running mkefs and mounted this partition 
 > on /mnt folder. Then I run fio on this partition.
you run it on disk directly(/dev/cciss/c1d0) without mounting it on /mnt.


Thanks,
-Guru

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-21 22:17                   ` Girish Satihal
@ 2009-04-22  5:46                     ` Jens Axboe
  2009-04-22  5:53                       ` Gurudas Pai
  2009-04-22 16:46                       ` Girish Satihal
  0 siblings, 2 replies; 135+ messages in thread
From: Jens Axboe @ 2009-04-22  5:46 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Tue, Apr 21 2009, Girish Satihal wrote:
> Hi Jens,
> The reason for saying ext3, is I run fdisk on /dev/cciss/c1d0 and created a primary partition.
> �
> Then I created a ext3 filesystem on this partition by running mkefs and mounted this partition on /mnt folder. Then I run fio on this partition.

You run fio on the partition, or on the mount point? Your fio job file
indicates that you run fio on the full device, not even just the
partition. This has _nothing_ to do with ext3. Irregardless of whether
you run fio on the partition or the device, your file system will be
hosed. Perhaps things go bad because ext3 turns your device read-only on
errors. Did you get any errors logged in dmesg?

> We earlier use to run fio on raw partition. But now we tried running fio on a partition which has ext3 filesystem.

Why would the content of the device matter?

> When I run fio on raw filesystem I dont get any errors for Sequential Writes, but when I run fio test on this ext3 filesystem then I am getting the errors for Sequential Writes�what I mentioned u earlier.

Lets back up a bit... What are you trying to test? Running fio on a
device/partition that is mounted with a file system is just a crazy
thing to do. Why would you do that?


> �
> Thanks,
> �Girish�
> 
> --- On Wed, 4/22/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> From: Jens Axboe <jens.axboe@oracle.com>
> Subject: Re: Recent changes
> To: "Girish Satihal" <girish.satihal@yahoo.com>
> Cc: fio@vger.kernel.org
> Date: Wednesday, April 22, 2009, 12:45 AM
> 
> On Tue, Apr 21 2009, Girish Satihal wrote:
> > Hi Jens,
> > I guess I did not understand your question for which I am very sorry.
> 
> Don't apologize for that. But if there's something I write you
> don't
> understand, do just ask for an explanation.
> 
> > As per my understanding I have sent you the job file which was
> > input file to fio for the performance testing.  As only the problem
> > with Seqential Writes, I have cut down the job file to only Write
> > parameters where the issue is being seen. The problem is seen with all
> > block size and IO depths of Sequential Writes.  Please let me know
> > if this would help you or still you arelooking for anything else.
> 
> So my current question is why you are mentioning ext3? The test case you
> provided is reading and writing directly to the CCISS device, not a file
> inside a file system hosted on that device.
> 
> Also, please try a make clean && make && make install in your
> fio
> directory. Sometimes things get hosed when updates are pulled, which may
> explain why yours is acting up.
> 
> -- 
> Jens Axboe
> 
> 
> 
> 
>       
-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (72 preceding siblings ...)
  2009-04-18  4:00 ` Jens Axboe
@ 2009-04-22  4:00 ` Jens Axboe
  2009-05-13  4:00 ` Jens Axboe
                   ` (26 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-04-22  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 60886290e2ba6ddae1213f3a13929193180c8c55:
  Jeff Moyer (1):
        handle race to mkdir at startup

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Martin Peschke (2):
      fix include statement in stats.h
      fix off-by-one issues in blkiomon.h

 stats.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-21 19:15                 ` Jens Axboe
@ 2009-04-21 22:17                   ` Girish Satihal
  2009-04-22  5:46                     ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-21 22:17 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio

[-- Attachment #1: Type: text/plain, Size: 1936 bytes --]

Hi Jens,
The reason for saying ext3, is I run fdisk on /dev/cciss/c1d0 and created a primary partition.
 
Then I created a ext3 filesystem on this partition by running mkefs and mounted this partition on /mnt folder. Then I run fio on this partition.
 
We earlier use to run fio on raw partition. But now we tried running fio on a partition which has ext3 filesystem.
 
When I run fio on raw filesystem I dont get any errors for Sequential Writes, but when I run fio test on this ext3 filesystem then I am getting the errors for Sequential Writes what I mentioned u earlier.
 
Thanks,
 Girish 

--- On Wed, 4/22/09, Jens Axboe <jens.axboe@oracle.com> wrote:

From: Jens Axboe <jens.axboe@oracle.com>
Subject: Re: Recent changes
To: "Girish Satihal" <girish.satihal@yahoo.com>
Cc: fio@vger.kernel.org
Date: Wednesday, April 22, 2009, 12:45 AM

On Tue, Apr 21 2009, Girish Satihal wrote:
> Hi Jens,
> I guess I did not understand your question for which I am very sorry.

Don't apologize for that. But if there's something I write you
don't
understand, do just ask for an explanation.

> As per my understanding I have sent you the job file which was
> input file to fio for the performance testing.  As only the problem
> with Seqential Writes, I have cut down the job file to only Write
> parameters where the issue is being seen. The problem is seen with all
> block size and IO depths of Sequential Writes.  Please let me know
> if this would help you or still you arelooking for anything else.

So my current question is why you are mentioning ext3? The test case you
provided is reading and writing directly to the CCISS device, not a file
inside a file system hosted on that device.

Also, please try a make clean && make && make install in your
fio
directory. Sometimes things get hosed when updates are pulled, which may
explain why yours is acting up.

-- 
Jens Axboe




      

[-- Attachment #2: Type: text/html, Size: 2416 bytes --]

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-21 15:46               ` Girish Satihal
@ 2009-04-21 19:15                 ` Jens Axboe
  2009-04-21 22:17                   ` Girish Satihal
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2009-04-21 19:15 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Tue, Apr 21 2009, Girish Satihal wrote:
> Hi Jens,
> I guess I did not understand your question for which I am very sorry.

Don't apologize for that. But if there's something I write you don't
understand, do just ask for an explanation.

> As per my understanding I have sent you the job file which was
> input file to fio for the performance testing.  As only the problem
> with Seqential Writes, I have cut down the job file to only Write
> parameters where the issue is being seen. The problem is seen with all
> block size and IO depths of Sequential Writes.  Please let me know
> if this would help you or still you arelooking for anything else.

So my current question is why you are mentioning ext3? The test case you
provided is reading and writing directly to the CCISS device, not a file
inside a file system hosted on that device.

Also, please try a make clean && make && make install in your fio
directory. Sometimes things get hosed when updates are pulled, which may
explain why yours is acting up.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-21  7:47             ` Jens Axboe
@ 2009-04-21 15:46               ` Girish Satihal
  2009-04-21 19:15                 ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-21 15:46 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio


[-- Attachment #1.1: Type: text/plain, Size: 5090 bytes --]

Hi Jens,
I guess I did not understand your question for which I am very sorry. 
 
As per my understanding I have sent you the job file which was input file to fio 
for the performance testing. 
 
As only the problem with Seqential Writes, I have cut down the job file to only 
Write parameters where the issue is being seen. The problem is seen with all block size and IO depths of Sequential Writes.
 
Please let me know if this would help you or still you are looking for anything else.
 
Thanks,
 Girish


--- On Tue, 4/21/09, Jens Axboe <jens.axboe@oracle.com> wrote:

From: Jens Axboe <jens.axboe@oracle.com>
Subject: Re: Recent changes
To: "Girish Satihal" <girish.satihal@yahoo.com>
Cc: fio@vger.kernel.org
Date: Tuesday, April 21, 2009, 1:17 PM

On Tue, Apr 21 2009, Jens Axboe wrote:
> On Mon, Apr 20 2009, Girish Satihal wrote:
> > Hi Jens,
> > Here is the job file. I am facing problem with Sequential Writes on
> > ext3 file system.
> 
> You are starting to annoy me a bit... Are you reading my emails? What
> did I ask you for? A cut down version that exhibits the problem. You are
> using a piece of free software and expecting help/support with your
> issue, the VERY least you can do is pay a bit of attention and provide
> what is asked (or at least say WHY you didn't provide a cut down
> version, perhaps you couldn't get it working etc).

Your job file works fine for me. I'm not sure why you are talking about
ext3, your job file works on the full device, not a file system.

> 
> 
> 
> >  
> > Thanks,
> >  Girish
> > 
> > --- On Mon, 4/20/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> > 
> > From: Jens Axboe <jens.axboe@oracle.com>
> > Subject: Re: Recent changes
> > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > Cc: fio@vger.kernel.org
> > Date: Monday, April 20, 2009, 11:35 PM
> > 
> > On Mon, Apr 20 2009, Girish Satihal wrote:
> > > 
> > > Hi Jens,
> > > This build is the latest build after version 1.24. This build
was the
> > > outcome of the request for adding blockalign/ba option. Can you
please
> > > help in resolving this issue of sequential writes on ext3 file
system?
> > 
> > I'd love to help you, but you have to help me a bit as well. I
asked you
> > for a job file that reproduces the problem. If you can send me such a
> > job file (preferably cut down to just a single section that exhibits
the
> > problem), then I can probably find the error quickly.
> > 
> > > 
> > > Thanks,
> > > Girish 
> > > 
> > > 
> > > --- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com>
wrote:
> > > 
> > > > From: Jens Axboe <jens.axboe@oracle.com>
> > > > Subject: Re: Recent changes
> > > > To: "Girish Satihal"
<girish.satihal@yahoo.com>
> > > > Cc: fio@vger.kernel.org
> > > > Date: Saturday, April 18, 2009, 11:18 PM
> > > > On Fri, Apr 17 2009, Girish Satihal wrote:
> > > > > Hi Jens,
> > > > > I am seeing a serious problem with fio testing. I
> > > > tried running fio
> > > > > test on ext3 partition with Sequential Reads and
> > > > Writes. I keep
> > > > > getting the I/O write error for Sequential writes. I
> > > > tried with
> > > > > multiple servers with different controllers and I
> > > > still get the same
> > > > > error. With Sequential Reads and Random Reads/Writes
> > > > there is no issue
> > > > > seen. Please find the attached fio results file for
> > > > Sequential
> > > > > Reads/Writes which has the error details pertaining to
> > > > Sequential
> > > > > writes on ext3 file system. Thanks, Girish
> > > > 
> > > > That's pretty strange. Your test job(s) seem pretty
> > > > massive, you don't
> > > > happen to have a cut down version that exhibits the
> > > > problem?
> > > > 
> > > > There also seems to be parts of the error missing from
> > > > io_u_log_error(),
> > > > like the file associated with the error and the io_u
> > > > details (offset=
> > > > and buflen=, for instance).
> > > > 
> > > > What version of fio are you using?
> > > > 
> > > > -- 
> > > > Jens Axboe
> > > > 
> > > > --
> > > > To unsubscribe from this list: send the line
> > > > "unsubscribe fio" in
> > > > the body of a message to majordomo@vger.kernel.org
> > > > More majordomo info at 
> > > > http://vger.kernel.org/majordomo-info.html
> > > 
> > > 
> > >       
> > 
> > -- 
> > Jens Axboe
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe
fio" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> > 
> > 
> >       
> 
> 
> -- 
> Jens Axboe
> 
> --
> To unsubscribe from this list: send the line "unsubscribe fio"
in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



      

[-- Attachment #1.2: Type: text/html, Size: 6570 bytes --]

[-- Attachment #2: StandardSeqnWriteWorkload.fio --]
[-- Type: application/octet-stream, Size: 2539 bytes --]

[global]
; ----------------------------------------------------------
; number of test targets
nrfiles=1
; ----------------------------------------------------------
; this is the test target
filename=/dev/cciss/c1d0
; ----------------------------------------------------------
; algorithm for selecting test targets (if multiple)
file_service_type=roundrobin
; ----------------------------------------------------------
; select the I/O engine
ioengine=libaio
; ioengine=posixaio
; ioengine=solarisaio
; ----------------------------------------------------------
; use non-buffered I/O
direct=1
; ----------------------------------------------------------
time_based

; ----------------------------------------------------------
;
; set up Sequential test parameters
;
; ----------------------------------------------------------
[global]
runtime=30
ramp_time=5

[global]
bs=512
[global]
rw=write
[512B_MaxIO_Write]
stonewall
iodepth=1
[512B_MaxIO_Write]
stonewall
iodepth=2
[512B_MaxIO_Write]
stonewall
iodepth=4
[512B_MaxIO_Write]
stonewall
iodepth=8
[512B_MaxIO_Write]
stonewall
iodepth=16
[512B_MaxIO_Write]
stonewall
iodepth=32
[512B_MaxIO_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=4K
[global]
rw=write
[4KB_Sequential_Write]
stonewall
iodepth=1
[4KB_Sequential_Write]
stonewall
iodepth=2
[4KB_Sequential_Write]
stonewall
iodepth=4
[4KB_Sequential_Write]
stonewall
iodepth=8
[4KB_Sequential_Write]
stonewall
iodepth=16
[4KB_Sequential_Write]
stonewall
iodepth=32
[4KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=64K
[global]
rw=write
[64KB_Sequential_Write]
stonewall
iodepth=1
[64KB_Sequential_Write]
stonewall
iodepth=2
[64KB_Sequential_Write]
stonewall
iodepth=4
[64KB_Sequential_Write]
stonewall
iodepth=8
[64KB_Sequential_Write]
stonewall
iodepth=16
[64KB_Sequential_Write]
stonewall
iodepth=32
[64KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=512K
[global]
rw=write
[512KB_Sequential_Write]
stonewall
iodepth=1
[512KB_Sequential_Write]
stonewall
iodepth=2
[512KB_Sequential_Write]
stonewall
iodepth=4
[512KB_Sequential_Write]
stonewall
iodepth=8
[512KB_Sequential_Write]
stonewall
iodepth=16
[512KB_Sequential_Write]
stonewall
iodepth=32
[512KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-21  5:28           ` Jens Axboe
@ 2009-04-21  7:47             ` Jens Axboe
  2009-04-21 15:46               ` Girish Satihal
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2009-04-21  7:47 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Tue, Apr 21 2009, Jens Axboe wrote:
> On Mon, Apr 20 2009, Girish Satihal wrote:
> > Hi Jens,
> > Here is the job file. I am facing problem with Sequential Writes on
> > ext3 file system.
> 
> You are starting to annoy me a bit... Are you reading my emails? What
> did I ask you for? A cut down version that exhibits the problem. You are
> using a piece of free software and expecting help/support with your
> issue, the VERY least you can do is pay a bit of attention and provide
> what is asked (or at least say WHY you didn't provide a cut down
> version, perhaps you couldn't get it working etc).

Your job file works fine for me. I'm not sure why you are talking about
ext3, your job file works on the full device, not a file system.

> 
> 
> 
> > �
> > Thanks,
> > �Girish
> > 
> > --- On Mon, 4/20/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> > 
> > From: Jens Axboe <jens.axboe@oracle.com>
> > Subject: Re: Recent changes
> > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > Cc: fio@vger.kernel.org
> > Date: Monday, April 20, 2009, 11:35 PM
> > 
> > On Mon, Apr 20 2009, Girish Satihal wrote:
> > > 
> > > Hi Jens,
> > > This build is the latest build after version 1.24. This build was the
> > > outcome of the request for adding blockalign/ba option. Can you please
> > > help in resolving this issue of sequential writes on ext3 file system?
> > 
> > I'd love to help you, but you have to help me a bit as well. I asked you
> > for a job file that reproduces the problem. If you can send me such a
> > job file (preferably cut down to just a single section that exhibits the
> > problem), then I can probably find the error quickly.
> > 
> > > 
> > > Thanks,
> > > Girish 
> > > 
> > > 
> > > --- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> > > 
> > > > From: Jens Axboe <jens.axboe@oracle.com>
> > > > Subject: Re: Recent changes
> > > > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > > > Cc: fio@vger.kernel.org
> > > > Date: Saturday, April 18, 2009, 11:18 PM
> > > > On Fri, Apr 17 2009, Girish Satihal wrote:
> > > > > Hi Jens,
> > > > > I am seeing a serious problem with fio testing. I
> > > > tried running fio
> > > > > test on ext3 partition with Sequential Reads and
> > > > Writes. I keep
> > > > > getting the I/O write error for Sequential writes. I
> > > > tried with
> > > > > multiple servers with different controllers and I
> > > > still get the same
> > > > > error. With Sequential Reads and Random Reads/Writes
> > > > there is no issue
> > > > > seen. Please find the attached fio results file for
> > > > Sequential
> > > > > Reads/Writes which has the error details pertaining to
> > > > Sequential
> > > > > writes on ext3 file system. Thanks, Girish
> > > > 
> > > > That's pretty strange. Your test job(s) seem pretty
> > > > massive, you don't
> > > > happen to have a cut down version that exhibits the
> > > > problem?
> > > > 
> > > > There also seems to be parts of the error missing from
> > > > io_u_log_error(),
> > > > like the file associated with the error and the io_u
> > > > details (offset=
> > > > and buflen=, for instance).
> > > > 
> > > > What version of fio are you using?
> > > > 
> > > > -- 
> > > > Jens Axboe
> > > > 
> > > > --
> > > > To unsubscribe from this list: send the line
> > > > "unsubscribe fio" in
> > > > the body of a message to majordomo@vger.kernel.org
> > > > More majordomo info at 
> > > > http://vger.kernel.org/majordomo-info.html
> > > 
> > > 
> > >       
> > 
> > -- 
> > Jens Axboe
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe fio" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> > 
> > 
> >       
> 
> 
> -- 
> Jens Axboe
> 
> --
> To unsubscribe from this list: send the line "unsubscribe fio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-20 20:54         ` Girish Satihal
@ 2009-04-21  5:28           ` Jens Axboe
  2009-04-21  7:47             ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2009-04-21  5:28 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Mon, Apr 20 2009, Girish Satihal wrote:
> Hi Jens,
> Here is the job file. I am facing problem with Sequential Writes on
> ext3 file system.

You are starting to annoy me a bit... Are you reading my emails? What
did I ask you for? A cut down version that exhibits the problem. You are
using a piece of free software and expecting help/support with your
issue, the VERY least you can do is pay a bit of attention and provide
what is asked (or at least say WHY you didn't provide a cut down
version, perhaps you couldn't get it working etc).



> �
> Thanks,
> �Girish
> 
> --- On Mon, 4/20/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> From: Jens Axboe <jens.axboe@oracle.com>
> Subject: Re: Recent changes
> To: "Girish Satihal" <girish.satihal@yahoo.com>
> Cc: fio@vger.kernel.org
> Date: Monday, April 20, 2009, 11:35 PM
> 
> On Mon, Apr 20 2009, Girish Satihal wrote:
> > 
> > Hi Jens,
> > This build is the latest build after version 1.24. This build was the
> > outcome of the request for adding blockalign/ba option. Can you please
> > help in resolving this issue of sequential writes on ext3 file system?
> 
> I'd love to help you, but you have to help me a bit as well. I asked you
> for a job file that reproduces the problem. If you can send me such a
> job file (preferably cut down to just a single section that exhibits the
> problem), then I can probably find the error quickly.
> 
> > 
> > Thanks,
> > Girish 
> > 
> > 
> > --- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> > 
> > > From: Jens Axboe <jens.axboe@oracle.com>
> > > Subject: Re: Recent changes
> > > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > > Cc: fio@vger.kernel.org
> > > Date: Saturday, April 18, 2009, 11:18 PM
> > > On Fri, Apr 17 2009, Girish Satihal wrote:
> > > > Hi Jens,
> > > > I am seeing a serious problem with fio testing. I
> > > tried running fio
> > > > test on ext3 partition with Sequential Reads and
> > > Writes. I keep
> > > > getting the I/O write error for Sequential writes. I
> > > tried with
> > > > multiple servers with different controllers and I
> > > still get the same
> > > > error. With Sequential Reads and Random Reads/Writes
> > > there is no issue
> > > > seen. Please find the attached fio results file for
> > > Sequential
> > > > Reads/Writes which has the error details pertaining to
> > > Sequential
> > > > writes on ext3 file system. Thanks, Girish
> > > 
> > > That's pretty strange. Your test job(s) seem pretty
> > > massive, you don't
> > > happen to have a cut down version that exhibits the
> > > problem?
> > > 
> > > There also seems to be parts of the error missing from
> > > io_u_log_error(),
> > > like the file associated with the error and the io_u
> > > details (offset=
> > > and buflen=, for instance).
> > > 
> > > What version of fio are you using?
> > > 
> > > -- 
> > > Jens Axboe
> > > 
> > > --
> > > To unsubscribe from this list: send the line
> > > "unsubscribe fio" in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at 
> > > http://vger.kernel.org/majordomo-info.html
> > 
> > 
> >       
> 
> -- 
> Jens Axboe
> 
> --
> To unsubscribe from this list: send the line "unsubscribe fio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 
>       


-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-20 18:05       ` Jens Axboe
@ 2009-04-20 20:54         ` Girish Satihal
  2009-04-21  5:28           ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-20 20:54 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio


[-- Attachment #1.1: Type: text/plain, Size: 2808 bytes --]

Hi Jens,
Here is the job file. I am facing problem with Sequential Writes on ext3 file system.
 
Thanks,
 Girish

--- On Mon, 4/20/09, Jens Axboe <jens.axboe@oracle.com> wrote:

From: Jens Axboe <jens.axboe@oracle.com>
Subject: Re: Recent changes
To: "Girish Satihal" <girish.satihal@yahoo.com>
Cc: fio@vger.kernel.org
Date: Monday, April 20, 2009, 11:35 PM

On Mon, Apr 20 2009, Girish Satihal wrote:
> 
> Hi Jens,
> This build is the latest build after version 1.24. This build was the
> outcome of the request for adding blockalign/ba option. Can you please
> help in resolving this issue of sequential writes on ext3 file system?

I'd love to help you, but you have to help me a bit as well. I asked you
for a job file that reproduces the problem. If you can send me such a
job file (preferably cut down to just a single section that exhibits the
problem), then I can probably find the error quickly.

> 
> Thanks,
> Girish 
> 
> 
> --- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > From: Jens Axboe <jens.axboe@oracle.com>
> > Subject: Re: Recent changes
> > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > Cc: fio@vger.kernel.org
> > Date: Saturday, April 18, 2009, 11:18 PM
> > On Fri, Apr 17 2009, Girish Satihal wrote:
> > > Hi Jens,
> > > I am seeing a serious problem with fio testing. I
> > tried running fio
> > > test on ext3 partition with Sequential Reads and
> > Writes. I keep
> > > getting the I/O write error for Sequential writes. I
> > tried with
> > > multiple servers with different controllers and I
> > still get the same
> > > error. With Sequential Reads and Random Reads/Writes
> > there is no issue
> > > seen. Please find the attached fio results file for
> > Sequential
> > > Reads/Writes which has the error details pertaining to
> > Sequential
> > > writes on ext3 file system. Thanks, Girish
> > 
> > That's pretty strange. Your test job(s) seem pretty
> > massive, you don't
> > happen to have a cut down version that exhibits the
> > problem?
> > 
> > There also seems to be parts of the error missing from
> > io_u_log_error(),
> > like the file associated with the error and the io_u
> > details (offset=
> > and buflen=, for instance).
> > 
> > What version of fio are you using?
> > 
> > -- 
> > Jens Axboe
> > 
> > --
> > To unsubscribe from this list: send the line
> > "unsubscribe fio" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at 
> > http://vger.kernel.org/majordomo-info.html
> 
> 
>       

-- 
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



      

[-- Attachment #1.2: Type: text/html, Size: 3517 bytes --]

[-- Attachment #2: StandardSeqnWorkload.fio --]
[-- Type: application/octet-stream, Size: 4234 bytes --]

[global]
; ----------------------------------------------------------
; number of test targets
nrfiles=1
; ----------------------------------------------------------
; this is the test target
filename=/dev/cciss/c1d0
; ----------------------------------------------------------
; algorithm for selecting test targets (if multiple)
file_service_type=roundrobin
; ----------------------------------------------------------
; select the I/O engine
ioengine=libaio
; ioengine=posixaio
; ioengine=solarisaio
; ----------------------------------------------------------
; use non-buffered I/O
direct=1
; ----------------------------------------------------------
time_based

; ----------------------------------------------------------
;
; set up Sequential test parameters
;
; ----------------------------------------------------------
[global]
runtime=30
ramp_time=5

[global]
bs=512
[global]
rw=read
[512B_MaxIO_Read]
stonewall
iodepth=1
[512B_MaxIO_Read]
stonewall
iodepth=2
[512B_MaxIO_Read]
stonewall
iodepth=4
[512B_MaxIO_Read]
stonewall
iodepth=8
[512B_MaxIO_Read]
stonewall
iodepth=16
[512B_MaxIO_Read]
stonewall
iodepth=32
[512B_MaxIO_Read]
stonewall
iodepth=64
[global]
rw=write
[512B_MaxIO_Write]
stonewall
iodepth=1
[512B_MaxIO_Write]
stonewall
iodepth=2
[512B_MaxIO_Write]
stonewall
iodepth=4
[512B_MaxIO_Write]
stonewall
iodepth=8
[512B_MaxIO_Write]
stonewall
iodepth=16
[512B_MaxIO_Write]
stonewall
iodepth=32
[512B_MaxIO_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=4K
[global]
rw=read
[4KB_Sequential_Read]
stonewall
iodepth=1
[4KB_Sequential_Read]
stonewall
iodepth=2
[4KB_Sequential_Read]
stonewall
iodepth=4
[4KB_Sequential_Read]
stonewall
iodepth=8
[4KB_Sequential_Read]
stonewall
iodepth=16
[4KB_Sequential_Read]
stonewall
iodepth=32
[4KB_Sequential_Read]
stonewall
iodepth=64
[global]
rw=write
[4KB_Sequential_Write]
stonewall
iodepth=1
[4KB_Sequential_Write]
stonewall
iodepth=2
[4KB_Sequential_Write]
stonewall
iodepth=4
[4KB_Sequential_Write]
stonewall
iodepth=8
[4KB_Sequential_Write]
stonewall
iodepth=16
[4KB_Sequential_Write]
stonewall
iodepth=32
[4KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=64K
[global]
rw=read
[64KB_Sequential_Read]
stonewall
iodepth=1
[64KB_Sequential_Read]
stonewall
iodepth=2
[64KB_Sequential_Read]
stonewall
iodepth=4
[64KB_Sequential_Read]
stonewall
iodepth=8
[64KB_Sequential_Read]
stonewall
iodepth=16
[64KB_Sequential_Read]
stonewall
iodepth=32
[64KB_Sequential_Read]
stonewall
iodepth=64
[global]
rw=write
[64KB_Sequential_Write]
stonewall
iodepth=1
[64KB_Sequential_Write]
stonewall
iodepth=2
[64KB_Sequential_Write]
stonewall
iodepth=4
[64KB_Sequential_Write]
stonewall
iodepth=8
[64KB_Sequential_Write]
stonewall
iodepth=16
[64KB_Sequential_Write]
stonewall
iodepth=32
[64KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=512K
[global]
rw=read
[512KB_Sequential_Read]
stonewall
iodepth=1
[512KB_Sequential_Read]
stonewall
iodepth=2
[512KB_Sequential_Read]
stonewall
iodepth=4
[512KB_Sequential_Read]
stonewall
iodepth=8
[512KB_Sequential_Read]
stonewall
iodepth=16
[512KB_Sequential_Read]
stonewall
iodepth=32
[512KB_Sequential_Read]
stonewall
iodepth=64
[global]
rw=write
[512KB_Sequential_Write]
stonewall
iodepth=1
[512KB_Sequential_Write]
stonewall
iodepth=2
[512KB_Sequential_Write]
stonewall
iodepth=4
[512KB_Sequential_Write]
stonewall
iodepth=8
[512KB_Sequential_Write]
stonewall
iodepth=16
[512KB_Sequential_Write]
stonewall
iodepth=32
[512KB_Sequential_Write]
stonewall
iodepth=64
[Idle]
stonewall
rwmixread=100
bs=64k
rate=1
[global]
bs=1M
[global]
rw=read
[1MB_Sequential_Read]
stonewall
iodepth=1
[1MB_Sequential_Read]
stonewall
iodepth=2
[1MB_Sequential_Read]
stonewall
iodepth=4
[1MB_Sequential_Read]
stonewall
iodepth=8
[1MB_Sequential_Read]
stonewall
iodepth=16
[1MB_Sequential_Read]
stonewall
iodepth=32
[1MB_Sequential_Read]
stonewall
iodepth=64

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-20 14:42     ` Girish Satihal
@ 2009-04-20 18:05       ` Jens Axboe
  2009-04-20 20:54         ` Girish Satihal
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2009-04-20 18:05 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Mon, Apr 20 2009, Girish Satihal wrote:
> 
> Hi Jens,
> This build is the latest build after version 1.24. This build was the
> outcome of the request for adding blockalign/ba option. Can you please
> help in resolving this issue of sequential writes on ext3 file system?

I'd love to help you, but you have to help me a bit as well. I asked you
for a job file that reproduces the problem. If you can send me such a
job file (preferably cut down to just a single section that exhibits the
problem), then I can probably find the error quickly.

> 
> Thanks,
> Girish 
> 
> 
> --- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > From: Jens Axboe <jens.axboe@oracle.com>
> > Subject: Re: Recent changes
> > To: "Girish Satihal" <girish.satihal@yahoo.com>
> > Cc: fio@vger.kernel.org
> > Date: Saturday, April 18, 2009, 11:18 PM
> > On Fri, Apr 17 2009, Girish Satihal wrote:
> > > Hi Jens,
> > > I am seeing a serious problem with fio testing. I
> > tried running fio
> > > test on ext3 partition with Sequential Reads and
> > Writes. I keep
> > > getting the I/O write error for Sequential writes. I
> > tried with
> > > multiple servers with different controllers and I
> > still get the same
> > > error. With Sequential Reads and Random Reads/Writes
> > there is no issue
> > > seen. Please find the attached fio results file for
> > Sequential
> > > Reads/Writes which has the error details pertaining to
> > Sequential
> > > writes on ext3 file system. Thanks, Girish
> > 
> > That's pretty strange. Your test job(s) seem pretty
> > massive, you don't
> > happen to have a cut down version that exhibits the
> > problem?
> > 
> > There also seems to be parts of the error missing from
> > io_u_log_error(),
> > like the file associated with the error and the io_u
> > details (offset=
> > and buflen=, for instance).
> > 
> > What version of fio are you using?
> > 
> > -- 
> > Jens Axboe
> > 
> > --
> > To unsubscribe from this list: send the line
> > "unsubscribe fio" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at 
> > http://vger.kernel.org/majordomo-info.html
> 
> 
>       

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-18 17:48   ` Jens Axboe
@ 2009-04-20 14:42     ` Girish Satihal
  2009-04-20 18:05       ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-20 14:42 UTC (permalink / raw)
  To: Jens Axboe; +Cc: fio


Hi Jens,
This build is the latest build after version 1.24. This build was the outcome of the request for adding blockalign/ba option. Can you please help in resolving this issue of sequential writes on ext3 file system?

Thanks,
Girish 


--- On Sat, 4/18/09, Jens Axboe <jens.axboe@oracle.com> wrote:

> From: Jens Axboe <jens.axboe@oracle.com>
> Subject: Re: Recent changes
> To: "Girish Satihal" <girish.satihal@yahoo.com>
> Cc: fio@vger.kernel.org
> Date: Saturday, April 18, 2009, 11:18 PM
> On Fri, Apr 17 2009, Girish Satihal wrote:
> > Hi Jens,
> > I am seeing a serious problem with fio testing. I
> tried running fio
> > test on ext3 partition with Sequential Reads and
> Writes. I keep
> > getting the I/O write error for Sequential writes. I
> tried with
> > multiple servers with different controllers and I
> still get the same
> > error. With Sequential Reads and Random Reads/Writes
> there is no issue
> > seen. Please find the attached fio results file for
> Sequential
> > Reads/Writes which has the error details pertaining to
> Sequential
> > writes on ext3 file system. Thanks, Girish
> 
> That's pretty strange. Your test job(s) seem pretty
> massive, you don't
> happen to have a cut down version that exhibits the
> problem?
> 
> There also seems to be parts of the error missing from
> io_u_log_error(),
> like the file associated with the error and the io_u
> details (offset=
> and buflen=, for instance).
> 
> What version of fio are you using?
> 
> -- 
> Jens Axboe
> 
> --
> To unsubscribe from this list: send the line
> "unsubscribe fio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at 
> http://vger.kernel.org/majordomo-info.html


      


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
  2009-04-17 21:38 ` Girish Satihal
@ 2009-04-18 17:48   ` Jens Axboe
  2009-04-20 14:42     ` Girish Satihal
  0 siblings, 1 reply; 135+ messages in thread
From: Jens Axboe @ 2009-04-18 17:48 UTC (permalink / raw)
  To: Girish Satihal; +Cc: fio

On Fri, Apr 17 2009, Girish Satihal wrote:
> Hi Jens,
> I am seeing a serious problem with fio testing. I tried running fio
> test on ext3 partition with Sequential Reads and Writes. I keep
> getting the I/O write error for Sequential writes. I tried with
> multiple servers with different controllers and I still get the same
> error. With Sequential Reads and Random Reads/Writes there is no issue
> seen. Please find the attached fio results file for Sequential
> Reads/Writes which has the error details pertaining to Sequential
> writes on ext3 file system. Thanks, Girish

That's pretty strange. Your test job(s) seem pretty massive, you don't
happen to have a cut down version that exhibits the problem?

There also seems to be parts of the error missing from io_u_log_error(),
like the file associated with the error and the io_u details (offset=
and buflen=, for instance).

What version of fio are you using?

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (71 preceding siblings ...)
  2009-04-07  4:00 ` Jens Axboe
@ 2009-04-18  4:00 ` Jens Axboe
  2009-04-22  4:00 ` Jens Axboe
                   ` (27 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-04-18  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit bb4a66074cecd59afc37f0053fdf42661503f51c:
  Alan D. Brunelle (1):
        Fixed plug/unplug logic in btt

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jeff Moyer (1):
      handle race to mkdir at startup

 blktrace.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Re: Recent changes
       [not found] <20090409040002.0D18237A271@kernel.dk>
@ 2009-04-17 21:38 ` Girish Satihal
  2009-04-18 17:48   ` Jens Axboe
  0 siblings, 1 reply; 135+ messages in thread
From: Girish Satihal @ 2009-04-17 21:38 UTC (permalink / raw)
  To: fio, Jens Axboe


[-- Attachment #1.1: Type: text/plain, Size: 525 bytes --]

Hi Jens,
I am seeing a serious problem with fio testing. I tried running fio test on ext3 partition with Sequential Reads and Writes. I keep getting the I/O write error for Sequential writes. I tried with multiple servers with different controllers and I still get the same error. With Sequential Reads and Random Reads/Writes there is no issue seen. Please find the attached fio results file for Sequential Reads/Writes which has the error details pertaining to Sequential writes on ext3 file system. Thanks,
Girish


      

[-- Attachment #1.2: Type: text/html, Size: 854 bytes --]

[-- Attachment #2: fioSeqnReadWrite.txt --]
[-- Type: text/plain, Size: 54924 bytes --]

512B_MaxIO_Read: (g=0): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=1
512B_MaxIO_Read: (g=1): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=2
512B_MaxIO_Read: (g=2): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=4
512B_MaxIO_Read: (g=3): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=8
512B_MaxIO_Read: (g=4): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=16
512B_MaxIO_Read: (g=5): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=32
512B_MaxIO_Read: (g=6): rw=read, bs=512-512/512-512, ioengine=libaio, iodepth=64
512B_MaxIO_Write: (g=7): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=1
512B_MaxIO_Write: (g=8): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=2
512B_MaxIO_Write: (g=9): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=4
512B_MaxIO_Write: (g=10): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=8
512B_MaxIO_Write: (g=11): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=16
512B_MaxIO_Write: (g=12): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=32
512B_MaxIO_Write: (g=13): rw=write, bs=512-512/512-512, ioengine=libaio, iodepth=64
Idle: (g=14): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
4KB_Sequential_Read: (g=15): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=1
4KB_Sequential_Read: (g=16): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=2
4KB_Sequential_Read: (g=17): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=4
4KB_Sequential_Read: (g=18): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=8
4KB_Sequential_Read: (g=19): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=16
4KB_Sequential_Read: (g=20): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=32
4KB_Sequential_Read: (g=21): rw=read, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=64
4KB_Sequential_Write: (g=22): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=1
4KB_Sequential_Write: (g=23): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=2
4KB_Sequential_Write: (g=24): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=4
4KB_Sequential_Write: (g=25): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=8
4KB_Sequential_Write: (g=26): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=16
4KB_Sequential_Write: (g=27): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=32
4KB_Sequential_Write: (g=28): rw=write, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=64
Idle: (g=29): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
64KB_Sequential_Read: (g=30): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
64KB_Sequential_Read: (g=31): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=2
64KB_Sequential_Read: (g=32): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=4
64KB_Sequential_Read: (g=33): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=8
64KB_Sequential_Read: (g=34): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=16
64KB_Sequential_Read: (g=35): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=32
64KB_Sequential_Read: (g=36): rw=read, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=64
64KB_Sequential_Write: (g=37): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
64KB_Sequential_Write: (g=38): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=2
64KB_Sequential_Write: (g=39): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=4
64KB_Sequential_Write: (g=40): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=8
64KB_Sequential_Write: (g=41): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=16
64KB_Sequential_Write: (g=42): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=32
64KB_Sequential_Write: (g=43): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=64
Idle: (g=44): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
512KB_Sequential_Read: (g=45): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=1
512KB_Sequential_Read: (g=46): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=2
512KB_Sequential_Read: (g=47): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=4
512KB_Sequential_Read: (g=48): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=8
512KB_Sequential_Read: (g=49): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=16
512KB_Sequential_Read: (g=50): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=32
512KB_Sequential_Read: (g=51): rw=read, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=64
512KB_Sequential_Write: (g=52): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=1
512KB_Sequential_Write: (g=53): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=2
512KB_Sequential_Write: (g=54): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=4
512KB_Sequential_Write: (g=55): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=8
512KB_Sequential_Write: (g=56): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=16
512KB_Sequential_Write: (g=57): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=32
512KB_Sequential_Write: (g=58): rw=write, bs=512K-512K/512K-512K, ioengine=libaio, iodepth=64
Idle: (g=59): rw=write, bs=64K-64K/64K-64K, ioengine=libaio, iodepth=1
1MB_Sequential_Read: (g=60): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=1
1MB_Sequential_Read: (g=61): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=2
1MB_Sequential_Read: (g=62): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=4
1MB_Sequential_Read: (g=63): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=8
1MB_Sequential_Read: (g=64): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=16
1MB_Sequential_Read: (g=65): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=32
1MB_Sequential_Read: (g=66): rw=read, bs=1M-1M/1M-1M, ioengine=libaio, iodepth=64
Starting 67 processes

512B_MaxIO_Read: (groupid=0, jobs=1): err= 0: pid=10239
  read : io=294MiB, bw=10,279KiB/s, iops=20,077, runt= 30001msec
    slat (usec): min=8, max=260, avg= 9.03, stdev= 2.29
    clat (usec): min=2, max=7,842, avg=37.93, stdev=25.59
    bw (KiB/s) : min= 9850, max=10397, per=100.00%, avg=10278.71, stdev=142.01
  cpu          : usr=7.70%, sys=25.72%, ctx=602331, majf=0, minf=11
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=602334/0, short=0/0
     lat (usec): 4=0.01%, 50=97.69%, 100=1.77%, 250=0.46%, 500=0.04%
     lat (usec): 750=0.03%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%
512B_MaxIO_Read: (groupid=1, jobs=1): err= 0: pid=10240
  read : io=416MiB, bw=14,546KiB/s, iops=28,411, runt= 30001msec
    slat (usec): min=7, max=264, avg= 8.62, stdev= 2.38
    clat (usec): min=15, max=1,459, avg=55.57, stdev=16.99
    bw (KiB/s) : min=13876, max=14614, per=100.01%, avg=14546.83, stdev=151.00
  cpu          : usr=9.98%, sys=42.34%, ctx=433157, majf=0, minf=13
  IO depths    : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=852385/0, short=0/0
     lat (usec): 20=0.01%, 50=44.97%, 100=53.27%, 250=1.65%, 500=0.10%
     lat (usec): 750=0.01%, 1000=0.01%
     lat (msec): 2=0.01%
512B_MaxIO_Read: (groupid=2, jobs=1): err= 0: pid=10241
  read : io=537MiB, bw=18,752KiB/s, iops=36,625, runt= 30001msec
    slat (usec): min=7, max=278, avg=12.35, stdev= 7.53
    clat (usec): min=40, max=5,098, avg=92.40, stdev=31.58
    bw (KiB/s) : min=17766, max=18894, per=100.00%, avg=18751.71, stdev=248.35
  cpu          : usr=13.25%, sys=59.93%, ctx=287573, majf=0, minf=13
  IO depths    : 1=0.1%, 2=0.1%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=1098810/0, short=0/0
     lat (usec): 50=0.02%, 100=88.36%, 250=11.46%, 500=0.10%, 750=0.03%
     lat (usec): 1000=0.03%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%
512B_MaxIO_Read: (groupid=3, jobs=1): err= 0: pid=10242
  read : io=543MiB, bw=18,976KiB/s, iops=37,063, runt= 30001msec
    slat (usec): min=7, max=288, avg=12.30, stdev= 7.47
    clat (usec): min=49, max=12,835, avg=199.08, stdev=54.58
    bw (KiB/s) : min=18082, max=19119, per=100.00%, avg=18975.69, stdev=237.93
  cpu          : usr=13.06%, sys=61.39%, ctx=282600, majf=0, minf=12
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=1111948/0, short=0/0
     lat (usec): 50=0.01%, 100=0.02%, 250=90.49%, 500=9.40%, 750=0.02%
     lat (usec): 1000=0.01%
     lat (msec): 2=0.06%, 4=0.01%, 10=0.01%, 20=0.01%
512B_MaxIO_Read: (groupid=4, jobs=1): err= 0: pid=10243
  read : io=543MiB, bw=18,976KiB/s, iops=37,062, runt= 30001msec
    slat (usec): min=7, max=318, avg=12.34, stdev= 7.56
    clat (usec): min=99, max=19,794, avg=414.94, stdev=116.41
    bw (KiB/s) : min=17968, max=19156, per=100.00%, avg=18975.14, stdev=293.15
  cpu          : usr=13.21%, sys=60.92%, ctx=281679, majf=0, minf=14
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=1111915/0, short=0/0
     lat (usec): 100=0.01%, 250=0.06%, 500=92.17%, 750=7.64%, 1000=0.01%
     lat (msec): 2=0.03%, 4=0.07%, 10=0.01%, 20=0.01%
512B_MaxIO_Read: (groupid=5, jobs=1): err= 0: pid=10244
  read : io=543MiB, bw=18,977KiB/s, iops=37,064, runt= 30001msec
    slat (usec): min=7, max=397, avg=12.29, stdev= 7.89
    clat (usec): min=127, max=19,269, avg=846.60, stdev=198.53
    bw (KiB/s) : min=17707, max=19159, per=99.99%, avg=18975.32, stdev=329.36
  cpu          : usr=13.78%, sys=60.71%, ctx=281899, majf=0, minf=16
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued r/w: total=1111976/0, short=0/0
     lat (usec): 250=0.01%, 500=0.10%, 750=0.69%, 1000=98.54%
     lat (msec): 2=0.53%, 4=0.04%, 10=0.09%, 20=0.01%
512B_MaxIO_Read: (groupid=6, jobs=1): err= 0: pid=10245
  read : io=543MiB, bw=18,992KiB/s, iops=37,095, runt= 30001msec
    slat (usec): min=7, max=713, avg=12.20, stdev= 7.85
    clat (usec): min=897, max=20,933, avg=1708.60, stdev=319.15
    bw (KiB/s) : min=17952, max=19176, per=100.00%, avg=18992.56, stdev=324.62
  cpu          : usr=12.95%, sys=63.51%, ctx=256924, majf=0, minf=20
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued r/w: total=1112897/0, short=0/0
     lat (usec): 1000=0.01%
     lat (msec): 2=99.60%, 4=0.22%, 10=0.12%, 20=0.06%, 50=0.01%
512B_MaxIO_Write: (groupid=7, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10246
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


512B_MaxIO_Write: (groupid=8, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10247
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=50.0%, 2=50.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/2, short=0/0


512B_MaxIO_Write: (groupid=9, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10248
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=25.0%, 2=50.0%, 4=25.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/4, short=0/0


512B_MaxIO_Write: (groupid=10, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10249
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=12.5%, 2=25.0%, 4=50.0%, 8=12.5%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/8, short=0/0


512B_MaxIO_Write: (groupid=11, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10250
  cpu          : usr=0.00%, sys=0.00%, ctx=2, majf=0, minf=39
  IO depths    : 1=6.2%, 2=12.5%, 4=25.0%, 8=50.0%, 16=6.2%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/16, short=0/0


512B_MaxIO_Write: (groupid=12, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10251
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=3.1%, 2=6.2%, 4=12.5%, 8=25.0%, 16=50.0%, 32=3.1%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/32, short=0/0


512B_MaxIO_Write: (groupid=13, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10252
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=1.6%, 2=3.1%, 4=6.2%, 8=12.5%, 16=25.0%, 32=50.0%, >=64=1.6%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/64, short=0/0


Idle: (groupid=14, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10253
  cpu          : usr=0.00%, sys=0.00%, ctx=4, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


4KB_Sequential_Read: (groupid=15, jobs=1): err= 0: pid=10254
  read : io=2,041MiB, bw=71,333KiB/s, iops=17,415, runt= 30000msec
    slat (usec): min=8, max=262, avg= 9.04, stdev= 2.21
    clat (usec): min=2, max=7,258, avg=45.52, stdev=36.43
    bw (KiB/s) : min=67158, max=71892, per=100.00%, avg=71330.00, stdev=919.87
  cpu          : usr=6.63%, sys=22.14%, ctx=522448, majf=0, minf=13
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=522463/0, short=0/0
     lat (usec): 4=0.01%, 50=83.40%, 100=10.97%, 250=5.56%, 500=0.05%
     lat (usec): 750=0.01%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%
4KB_Sequential_Read: (groupid=16, jobs=1): err= 0: pid=10255
  read : io=2,694MiB, bw=94,155KiB/s, iops=22,987, runt= 30001msec
    slat (usec): min=7, max=273, avg= 9.69, stdev= 3.65
    clat (usec): min=15, max=8,991, avg=72.16, stdev=45.69
    bw (KiB/s) : min=89309, max=95092, per=100.02%, avg=94170.07, stdev=1141.17
  cpu          : usr=8.51%, sys=35.25%, ctx=388015, majf=0, minf=14
  IO depths    : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=689639/0, short=0/0
     lat (usec): 20=0.01%, 50=1.25%, 100=85.94%, 250=12.67%, 500=0.10%
     lat (usec): 750=0.02%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%
4KB_Sequential_Read: (groupid=17, jobs=1): err= 0: pid=10256
  read : io=3,235MiB, bw=110MiB/s, iops=27,603, runt= 30001msec
    slat (usec): min=7, max=273, avg=12.15, stdev= 6.57
    clat (usec): min=40, max=9,024, avg=129.19, stdev=61.94
    bw (KiB/s) : min=106176, max=113991, per=100.06%, avg=113134.92, stdev=1396.37
  cpu          : usr=9.92%, sys=43.60%, ctx=330705, majf=0, minf=16
  IO depths    : 1=0.1%, 2=0.1%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=828128/0, short=0/0
     lat (usec): 50=0.01%, 100=34.74%, 250=64.91%, 500=0.28%, 750=0.02%
     lat (usec): 1000=0.03%
     lat (msec): 2=0.02%, 4=0.01%, 10=0.01%
4KB_Sequential_Read: (groupid=18, jobs=1): err= 0: pid=10257
  read : io=3,245MiB, bw=111MiB/s, iops=27,690, runt= 30001msec
    slat (usec): min=7, max=293, avg=12.05, stdev= 6.94
    clat (usec): min=64, max=11,538, avg=273.15, stdev=101.30
    bw (KiB/s) : min=100458, max=115048, per=100.06%, avg=113491.71, stdev=3045.06
  cpu          : usr=9.99%, sys=44.00%, ctx=335355, majf=0, minf=20
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=830743/0, short=0/0
     lat (usec): 100=0.01%, 250=35.80%, 500=63.86%, 750=0.22%, 1000=0.02%
     lat (msec): 2=0.05%, 4=0.02%, 10=0.02%, 20=0.01%
4KB_Sequential_Read: (groupid=19, jobs=1): err= 0: pid=10258
  read : io=3,225MiB, bw=110MiB/s, iops=27,520, runt= 30001msec
    slat (usec): min=7, max=333, avg=11.73, stdev= 6.76
    clat (usec): min=39, max=16,859, avg=565.66, stdev=144.59
    bw (KiB/s) : min=95461, max=114851, per=100.04%, avg=112768.17, stdev=3989.65
  cpu          : usr=9.75%, sys=43.47%, ctx=326966, majf=0, minf=28
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=825638/0, short=0/0
     lat (usec): 50=0.01%, 100=0.04%, 250=0.01%, 500=0.68%, 750=97.28%
     lat (usec): 1000=1.63%
     lat (msec): 2=0.24%, 4=0.08%, 10=0.03%, 20=0.01%
4KB_Sequential_Read: (groupid=20, jobs=1): err= 0: pid=10259
  read : io=3,219MiB, bw=110MiB/s, iops=27,467, runt= 30001msec
    slat (usec): min=7, max=362, avg=11.82, stdev= 6.82
    clat (usec): min=40, max=11,055, avg=1149.27, stdev=213.30
    bw (KiB/s) : min=96829, max=114466, per=100.04%, avg=112553.86, stdev=3443.50
  cpu          : usr=9.53%, sys=43.25%, ctx=328117, majf=0, minf=44
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued r/w: total=824064/0, short=0/0
     lat (usec): 50=0.01%, 100=0.01%, 250=0.01%, 500=0.02%, 750=0.06%
     lat (usec): 1000=1.33%
     lat (msec): 2=98.01%, 4=0.46%, 10=0.11%, 20=0.01%
4KB_Sequential_Read: (groupid=21, jobs=1): err= 0: pid=10260
  read : io=3,203MiB, bw=109MiB/s, iops=27,326, runt= 30003msec
    slat (usec): min=7, max=360, avg=11.83, stdev= 6.80
    clat (usec): min=44, max=15,044, avg=2326.10, stdev=363.68
    bw (KiB/s) : min=96354, max=113729, per=100.02%, avg=111955.27, stdev=3448.84
  cpu          : usr=9.46%, sys=43.52%, ctx=318324, majf=0, minf=76
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued r/w: total=819877/0, short=0/0
     lat (usec): 50=0.01%, 100=0.02%, 250=0.01%, 500=0.01%, 750=0.01%
     lat (usec): 1000=0.01%
     lat (msec): 2=1.70%, 4=97.47%, 10=0.75%, 20=0.03%
4KB_Sequential_Write: (groupid=22, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10261
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


4KB_Sequential_Write: (groupid=23, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10262
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=50.0%, 2=50.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/2, short=0/0


4KB_Sequential_Write: (groupid=24, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10263
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=25.0%, 2=50.0%, 4=25.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/4, short=0/0


4KB_Sequential_Write: (groupid=25, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10264
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=12.5%, 2=25.0%, 4=50.0%, 8=12.5%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/8, short=0/0


4KB_Sequential_Write: (groupid=26, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10265
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=6.2%, 2=12.5%, 4=25.0%, 8=50.0%, 16=6.2%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/16, short=0/0


4KB_Sequential_Write: (groupid=27, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10266
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=3.1%, 2=6.2%, 4=12.5%, 8=25.0%, 16=50.0%, 32=3.1%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/32, short=0/0


4KB_Sequential_Write: (groupid=28, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10267
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=1.6%, 2=3.1%, 4=6.2%, 8=12.5%, 16=25.0%, 32=50.0%, >=64=1.6%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/64, short=0/0


Idle: (groupid=29, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10268
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


64KB_Sequential_Read: (groupid=30, jobs=1): err= 0: pid=10269
  read : io=3,867MiB, bw=132MiB/s, iops=2,062, runt= 30001msec
    slat (usec): min=19, max=267, avg=19.82, stdev= 2.43
    clat (usec): min=170, max=7,775, avg=462.19, stdev=67.66
    bw (KiB/s) : min=130416, max=140247, per=100.06%, avg=135223.64, stdev=1249.55
  cpu          : usr=0.86%, sys=5.05%, ctx=61870, majf=0, minf=28
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=61867/0, short=0/0
     lat (usec): 250=1.50%, 500=96.45%, 750=1.97%, 1000=0.07%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%
64KB_Sequential_Read: (groupid=31, jobs=1): err= 0: pid=10270
  read : io=7,024MiB, bw=240MiB/s, iops=3,745, runt= 30001msec
    slat (usec): min=18, max=279, avg=20.13, stdev= 3.83
    clat (usec): min=170, max=444K, avg=509.84, stdev=2124.70
    bw (KiB/s) : min=  851, max=263716, per=100.68%, avg=247160.27, stdev=37824.66
  cpu          : usr=1.41%, sys=9.04%, ctx=88506, majf=0, minf=44
  IO depths    : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=112379/0, short=0/0
     lat (usec): 250=0.01%, 500=77.32%, 750=20.94%, 1000=1.67%
     lat (msec): 2=0.05%, 4=0.01%, 10=0.01%, 20=0.01%, 250=0.01%
     lat (msec): 500=0.01%
64KB_Sequential_Read: (groupid=32, jobs=1): err= 0: pid=10271
  read : io=7,525MiB, bw=257MiB/s, iops=4,012, runt= 30002msec
    slat (usec): min=18, max=291, avg=20.35, stdev= 4.22
    clat (usec): min=162, max=12,394, avg=973.41, stdev=507.76
    bw (KiB/s) : min=257163, max=263847, per=100.04%, avg=263098.66, stdev=896.20
  cpu          : usr=1.51%, sys=9.63%, ctx=97357, majf=0, minf=76
  IO depths    : 1=0.1%, 2=0.1%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=120397/0, short=0/0
     lat (usec): 250=0.01%, 500=28.19%, 750=18.68%, 1000=4.03%
     lat (msec): 2=48.90%, 4=0.19%, 10=0.01%, 20=0.01%
64KB_Sequential_Read: (groupid=33, jobs=1): err= 0: pid=10272
  read : io=7,527MiB, bw=257MiB/s, iops=4,013, runt= 30003msec
    slat (usec): min=18, max=293, avg=20.13, stdev= 4.39
    clat (usec): min=158, max=5,714, avg=1969.89, stdev=1422.31
    bw (KiB/s) : min=260833, max=263454, per=100.04%, avg=263160.90, stdev=380.36
  cpu          : usr=1.46%, sys=9.37%, ctx=93458, majf=0, minf=140
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=120429/0, short=0/0
     lat (usec): 250=0.01%, 500=26.94%, 750=17.04%, 1000=1.80%
     lat (msec): 2=4.34%, 4=49.77%, 10=0.09%
64KB_Sequential_Read: (groupid=34, jobs=1): err= 0: pid=10273
  read : io=7,587MiB, bw=259MiB/s, iops=4,045, runt= 30008msec
    slat (usec): min=18, max=287, avg=20.26, stdev= 3.89
    clat (usec): min=144, max=16,453, avg=3931.35, stdev=3092.75
    bw (KiB/s) : min=261881, max=374341, per=100.06%, avg=265293.56, stdev=14523.76
  cpu          : usr=1.44%, sys=9.50%, ctx=97732, majf=0, minf=268
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=121399/0, short=0/0
     lat (usec): 250=0.04%, 500=22.24%, 750=13.03%, 1000=1.48%
     lat (msec): 2=4.85%, 4=8.61%, 10=49.73%, 20=0.02%
64KB_Sequential_Read: (groupid=35, jobs=1): err= 0: pid=10274
  read : io=7,591MiB, bw=259MiB/s, iops=4,046, runt= 30015msec
    slat (usec): min=18, max=289, avg=20.14, stdev= 3.64
    clat (usec): min=136, max=32,545, avg=7884.74, stdev=5840.24
    bw (KiB/s) : min=    0, max=384172, per=66.67%, avg=176809.00, stdev=126369.08
  cpu          : usr=1.46%, sys=9.43%, ctx=101580, majf=0, minf=524
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued r/w: total=121451/0, short=0/0
     lat (usec): 250=0.02%, 500=13.17%, 750=7.44%, 1000=1.23%
     lat (msec): 2=4.36%, 4=9.46%, 10=22.40%, 20=41.89%, 50=0.03%
64KB_Sequential_Read: (groupid=36, jobs=1): err= 0: pid=10275
  read : io=7,604MiB, bw=259MiB/s, iops=4,051, runt= 30029msec
    slat (usec): min=18, max=319, avg=20.00, stdev= 4.46
    clat (usec): min=155, max=56,162, avg=15771.63, stdev=6261.03
    bw (KiB/s) : min=    0, max=407896, per=49.18%, avg=130570.46, stdev=133920.16
  cpu          : usr=1.64%, sys=9.47%, ctx=109713, majf=0, minf=1036
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=99.9%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued r/w: total=121664/0, short=0/0
     lat (usec): 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.57%, 10=21.54%, 20=49.28%, 50=28.57%
     lat (msec): 100=0.01%
64KB_Sequential_Write: (groupid=37, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10278
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


64KB_Sequential_Write: (groupid=38, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10279
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=50.0%, 2=50.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/2, short=0/0


64KB_Sequential_Write: (groupid=39, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10280
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=40
  IO depths    : 1=25.0%, 2=50.0%, 4=25.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/4, short=0/0


64KB_Sequential_Write: (groupid=40, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10281
  cpu          : usr=0.00%, sys=0.00%, ctx=2, majf=0, minf=39
  IO depths    : 1=12.5%, 2=25.0%, 4=50.0%, 8=12.5%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/8, short=0/0


64KB_Sequential_Write: (groupid=41, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10282
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=6.2%, 2=12.5%, 4=25.0%, 8=50.0%, 16=6.2%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/16, short=0/0


64KB_Sequential_Write: (groupid=42, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10283
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=3.1%, 2=6.2%, 4=12.5%, 8=25.0%, 16=50.0%, 32=3.1%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/32, short=0/0


64KB_Sequential_Write: (groupid=43, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10284
  cpu          : usr=0.00%, sys=200.00%, ctx=2, majf=0, minf=39
  IO depths    : 1=1.6%, 2=3.1%, 4=6.2%, 8=12.5%, 16=25.0%, 32=50.0%, >=64=1.6%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/64, short=0/0


Idle: (groupid=44, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10285
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


512KB_Sequential_Read: (groupid=45, jobs=1): err= 0: pid=10286
  read : io=7,570MiB, bw=258MiB/s, iops=504, runt= 30002msec
    slat (usec): min=105, max=477, avg=107.03, stdev= 9.12
    clat (usec): min=823, max=14,212, avg=1871.73, stdev=364.26
    bw (KiB/s) : min=256901, max=346030, per=100.10%, avg=264824.61, stdev=11162.12
  cpu          : usr=0.21%, sys=5.54%, ctx=15142, majf=0, minf=140
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=15139/0, short=0/0
     lat (usec): 1000=1.45%
     lat (msec): 2=55.88%, 4=42.61%, 10=0.04%, 20=0.02%
512KB_Sequential_Read: (groupid=46, jobs=1): err= 0: pid=10287
  read : io=7,599MiB, bw=259MiB/s, iops=506, runt= 30004msec
    slat (usec): min=105, max=522, avg=108.47, stdev= 7.84
    clat (usec): min=874, max=7,918, avg=3836.69, stdev=368.62
    bw (KiB/s) : min=260574, max=415236, per=100.11%, avg=265856.08, stdev=19788.90
  cpu          : usr=0.20%, sys=5.65%, ctx=15201, majf=0, minf=268
  IO depths    : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=15198/0, short=0/0
     lat (usec): 1000=0.01%
     lat (msec): 2=1.47%, 4=97.03%, 10=1.50%
512KB_Sequential_Read: (groupid=47, jobs=1): err= 0: pid=10288
  read : io=7,605MiB, bw=260MiB/s, iops=506, runt= 30007msec
    slat (usec): min=107, max=522, avg=110.17, stdev=10.07
    clat (usec): min=973, max=15,177, avg=7778.19, stdev=724.03
    bw (KiB/s) : min=259527, max=424673, per=100.11%, avg=266016.07, stdev=21020.07
  cpu          : usr=0.21%, sys=5.76%, ctx=15210, majf=0, minf=524
  IO depths    : 1=0.1%, 2=0.1%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=15209/0, short=0/0
     lat (usec): 1000=0.01%
     lat (msec): 2=0.09%, 4=1.39%, 10=98.45%, 20=0.06%
512KB_Sequential_Read: (groupid=48, jobs=1): err= 0: pid=10289
  read : io=7,609MiB, bw=260MiB/s, iops=507, runt= 30015msec
    slat (usec): min=107, max=529, avg=110.35, stdev=11.99
    clat (msec): min=1, max=27, avg=15.66, stdev= 1.39
    bw (KiB/s) : min=258998, max=431151, per=100.10%, avg=266098.98, stdev=21867.96
  cpu          : usr=0.21%, sys=5.77%, ctx=15220, majf=0, minf=1036
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=15218/0, short=0/0

     lat (msec): 2=0.02%, 4=0.04%, 10=1.47%, 20=98.44%, 50=0.03%
512KB_Sequential_Read: (groupid=49, jobs=1): err= 0: pid=10290
  read : io=7,619MiB, bw=260MiB/s, iops=507, runt= 30032msec
    slat (usec): min=97, max=538, avg=106.09, stdev=16.14
    clat (usec): min=736, max=1,524K, avg=31420.02, stdev=12463.84
    bw (KiB/s) : min=261620, max=441450, per=100.11%, avg=266291.53, stdev=23200.48
  cpu          : usr=0.22%, sys=5.58%, ctx=15216, majf=0, minf=2061
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=99.9%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=15237/0, short=0/0
     lat (usec): 750=0.01%
     lat (msec): 2=0.03%, 4=0.13%, 10=1.30%, 20=0.09%, 50=98.39%
     lat (msec): 100=0.03%, 2000=0.01%
512KB_Sequential_Read: (groupid=50, jobs=1): err= 0: pid=10291
  read : io=7,478MiB, bw=255MiB/s, iops=497, runt= 30064msec
    slat (usec): min=99, max=791, avg=104.88, stdev=22.09
    clat (usec): min=649, max=188K, avg=64193.71, stdev=13521.52
    bw (KiB/s) : min=126877, max=466616, per=100.09%, avg=261039.81, stdev=37852.91
  cpu          : usr=0.21%, sys=5.41%, ctx=14938, majf=0, minf=4108
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=99.8%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued r/w: total=14956/0, short=0/0
     lat (usec): 750=0.02%, 1000=0.01%
     lat (msec): 2=0.03%, 4=0.08%, 10=0.45%, 20=0.90%, 50=0.12%
     lat (msec): 100=97.17%, 250=1.22%
512KB_Sequential_Read: (groupid=51, jobs=1): err= 0: pid=10292
  read : io=7,468MiB, bw=254MiB/s, iops=495, runt= 30126msec
    slat (usec): min=59, max=158K, avg=1698.92, stdev=6183.61
    clat (msec): min=1, max=393, avg=127.31, stdev=23.65
    bw (KiB/s) : min=125664, max=474748, per=100.06%, avg=260087.88, stdev=40168.34
  cpu          : usr=0.18%, sys=5.03%, ctx=3251, majf=0, minf=8203
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.2%, >=64=99.6%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued r/w: total=14936/0, short=0/0

     lat (msec): 2=0.02%, 4=0.02%, 10=0.21%, 20=0.23%, 50=1.00%
     lat (msec): 100=1.31%, 250=96.85%, 500=0.35%
512KB_Sequential_Write: (groupid=52, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10294
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


512KB_Sequential_Write: (groupid=53, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10295
  write: io=512KiB, bw=256MiB/s, iops=1,000, runt=     2msec
    slat (usec): min=12, max=118, avg=65.00, stdev=74.95
    clat (usec): min=1,043, max=1,043, avg=1043.00, stdev= 0.00
  cpu          : usr=0.00%, sys=0.00%, ctx=1, majf=0, minf=40
  IO depths    : 1=50.0%, 2=50.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=33.3%, 4=66.7%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/2, short=0/0

     lat (msec): 2=50.00%
512KB_Sequential_Write: (groupid=54, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10296
  write: io=1,536KiB, bw=512MiB/s, iops=1,333, runt=     3msec
    slat (usec): min=12, max=116, avg=85.50, stdev=49.21
    clat (usec): min=2,547, max=2,765, avg=2655.33, stdev=109.01
  cpu          : usr=0.00%, sys=0.00%, ctx=4, majf=0, minf=40
  IO depths    : 1=25.0%, 2=50.0%, 4=25.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=33.3%, 4=66.7%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/4, short=0/0

     lat (msec): 4=75.00%
512KB_Sequential_Write: (groupid=55, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10297
  write: io=3,584KiB, bw=149MiB/s, iops=333, runt=    24msec
    slat (usec): min=16, max=123, avg=100.12, stdev=34.34
    clat (usec): min=22,430, max=23,107, avg=22766.14, stdev=244.35
  cpu          : usr=0.00%, sys=4.35%, ctx=8, majf=0, minf=40
  IO depths    : 1=12.5%, 2=25.0%, 4=50.0%, 8=12.5%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=33.3%, 4=33.3%, 8=33.3%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/8, short=0/0

     lat (msec): 50=87.50%
512KB_Sequential_Write: (groupid=56, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10298
  cpu          : usr=0.00%, sys=100.00%, ctx=1, majf=0, minf=39
  IO depths    : 1=6.2%, 2=12.5%, 4=25.0%, 8=50.0%, 16=6.2%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/16, short=0/0


512KB_Sequential_Write: (groupid=57, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10299
  cpu          : usr=0.00%, sys=66.67%, ctx=1, majf=0, minf=39
  IO depths    : 1=3.1%, 2=6.2%, 4=12.5%, 8=25.0%, 16=50.0%, 32=3.1%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/32, short=0/0


512KB_Sequential_Write: (groupid=58, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10300
  cpu          : usr=0.00%, sys=14.29%, ctx=3, majf=0, minf=39
  IO depths    : 1=1.6%, 2=3.1%, 4=6.2%, 8=12.5%, 16=25.0%, 32=50.0%, >=64=1.6%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/64, short=0/0


Idle: (groupid=59, jobs=1): err= 5 (file:io_u.c:879, func=io_u error, error=Input/output error): pid=10301
  cpu          : usr=0.00%, sys=0.00%, ctx=0, majf=0, minf=39
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=50.0%, 4=50.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=0/1, short=0/0


1MB_Sequential_Read: (groupid=60, jobs=1): err= 0: pid=10302
  read : io=7,590MiB, bw=259MiB/s, iops=252, runt= 30004msec
    slat (usec): min=206, max=1,027, avg=208.98, stdev=12.66
    clat (usec): min=1,387, max=9,705, avg=3740.99, stdev=356.79
    bw (KiB/s) : min=259010, max=398458, per=100.09%, avg=265490.02, stdev=17619.44
  cpu          : usr=0.10%, sys=5.37%, ctx=7592, majf=0, minf=268
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=7590/0, short=0/0

     lat (msec): 2=1.46%, 4=97.11%, 10=1.42%
1MB_Sequential_Read: (groupid=61, jobs=1): err= 0: pid=10303
  read : io=7,602MiB, bw=259MiB/s, iops=253, runt= 30006msec
    slat (usec): min=205, max=1,049, avg=209.13, stdev=17.17
    clat (usec): min=1,324, max=11,399, avg=7681.35, stdev=691.71
    bw (KiB/s) : min=261099, max=419430, per=100.10%, avg=265916.47, stdev=20333.78
  cpu          : usr=0.11%, sys=5.37%, ctx=7603, majf=0, minf=524
  IO depths    : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=7602/0, short=0/0

     lat (msec): 2=0.07%, 4=1.41%, 10=98.50%, 20=0.03%
1MB_Sequential_Read: (groupid=62, jobs=1): err= 0: pid=10304
  read : io=7,606MiB, bw=259MiB/s, iops=253, runt= 30015msec
    slat (usec): min=205, max=1,046, avg=210.28, stdev=21.76
    clat (msec): min=1, max=23, avg=15.57, stdev= 1.34
    bw (KiB/s) : min=261099, max=423182, per=100.09%, avg=265944.44, stdev=20826.31
  cpu          : usr=0.10%, sys=5.44%, ctx=7608, majf=0, minf=1036
  IO depths    : 1=0.1%, 2=0.1%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=7606/0, short=0/0

     lat (msec): 2=0.01%, 4=0.04%, 10=1.46%, 20=98.47%, 50=0.01%
1MB_Sequential_Read: (groupid=63, jobs=1): err= 0: pid=10305
  read : io=7,617MiB, bw=260MiB/s, iops=253, runt= 30032msec
    slat (usec): min=194, max=1,078, avg=207.05, stdev=29.76
    clat (msec): min=1, max=55, avg=31.32, stdev= 2.91
    bw (KiB/s) : min=260580, max=438304, per=100.10%, avg=266227.58, stdev=22792.71
  cpu          : usr=0.10%, sys=5.36%, ctx=7616, majf=0, minf=2060
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=99.9%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=7617/0, short=0/0

     lat (msec): 2=0.04%, 4=0.14%, 10=1.25%, 20=0.12%, 50=98.42%
     lat (msec): 100=0.03%
1MB_Sequential_Read: (groupid=64, jobs=1): err= 0: pid=10306
  read : io=7,638MiB, bw=260MiB/s, iops=254, runt= 30062msec
    slat (usec): min=192, max=1,112, avg=202.62, stdev=41.97
    clat (msec): min=1, max=119, avg=62.74, stdev= 6.79
    bw (KiB/s) : min=259527, max=466960, per=100.09%, avg=266668.73, stdev=26530.70
  cpu          : usr=0.11%, sys=5.18%, ctx=7621, majf=0, minf=4108
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=99.8%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w: total=7638/0, short=0/0

     lat (msec): 2=0.03%, 4=0.18%, 10=0.45%, 20=0.84%, 50=0.29%
     lat (msec): 100=98.15%, 250=0.07%
1MB_Sequential_Read: (groupid=65, jobs=1): err= 0: pid=10307
  read : io=7,652MiB, bw=260MiB/s, iops=254, runt= 30125msec
    slat (usec): min=111, max=38,547, avg=2527.24, stdev=6275.75
    clat (msec): min=1, max=241, avg=123.36, stdev=17.70
    bw (KiB/s) : min=    0, max=480247, per=66.13%, avg=176143.49, stdev=128614.59
  cpu          : usr=0.08%, sys=4.87%, ctx=4642, majf=0, minf=8204
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.2%, 32=99.6%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued r/w: total=7652/0, short=0/0

     lat (msec): 2=0.04%, 4=0.12%, 10=0.16%, 20=0.13%, 50=1.10%
     lat (msec): 100=2.35%, 250=96.11%
1MB_Sequential_Read: (groupid=66, jobs=1): err= 0: pid=10308
  read : io=7,638MiB, bw=260MiB/s, iops=253, runt= 30089msec
    slat (usec): min=111, max=61,024, avg=3923.41, stdev=8579.21
    clat (msec): min=51, max=335, avg=247.61, stdev=23.33
    bw (KiB/s) : min=192472, max=448512, per=99.57%, avg=265028.88, stdev=26072.12
  cpu          : usr=0.08%, sys=4.09%, ctx=1470, majf=0, minf=16396
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.2%, 32=0.4%, >=64=99.2%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued r/w: total=7638/0, short=0/0

     lat (msec): 100=0.94%, 250=15.29%, 500=83.77%

Run status group 0 (all jobs):
   READ: io=294MiB, aggrb=10,279KiB/s, minb=10,279KiB/s, maxb=10,279KiB/s, mint=30001msec, maxt=30001msec

Run status group 1 (all jobs):
   READ: io=416MiB, aggrb=14,546KiB/s, minb=14,546KiB/s, maxb=14,546KiB/s, mint=30001msec, maxt=30001msec

Run status group 2 (all jobs):
   READ: io=537MiB, aggrb=18,752KiB/s, minb=18,752KiB/s, maxb=18,752KiB/s, mint=30001msec, maxt=30001msec

Run status group 3 (all jobs):
   READ: io=543MiB, aggrb=18,976KiB/s, minb=18,976KiB/s, maxb=18,976KiB/s, mint=30001msec, maxt=30001msec

Run status group 4 (all jobs):
   READ: io=543MiB, aggrb=18,976KiB/s, minb=18,976KiB/s, maxb=18,976KiB/s, mint=30001msec, maxt=30001msec

Run status group 5 (all jobs):
   READ: io=543MiB, aggrb=18,977KiB/s, minb=18,977KiB/s, maxb=18,977KiB/s, mint=30001msec, maxt=30001msec

Run status group 6 (all jobs):
   READ: io=543MiB, aggrb=18,992KiB/s, minb=18,992KiB/s, maxb=18,992KiB/s, mint=30001msec, maxt=30001msec

Run status group 7 (all jobs):

Run status group 8 (all jobs):

Run status group 9 (all jobs):

Run status group 10 (all jobs):

Run status group 11 (all jobs):

Run status group 12 (all jobs):

Run status group 13 (all jobs):

Run status group 14 (all jobs):

Run status group 15 (all jobs):
   READ: io=2,041MiB, aggrb=71,333KiB/s, minb=71,333KiB/s, maxb=71,333KiB/s, mint=30000msec, maxt=30000msec

Run status group 16 (all jobs):
   READ: io=2,694MiB, aggrb=94,155KiB/s, minb=94,155KiB/s, maxb=94,155KiB/s, mint=30001msec, maxt=30001msec

Run status group 17 (all jobs):
   READ: io=3,235MiB, aggrb=110MiB/s, minb=110MiB/s, maxb=110MiB/s, mint=30001msec, maxt=30001msec

Run status group 18 (all jobs):
   READ: io=3,245MiB, aggrb=111MiB/s, minb=111MiB/s, maxb=111MiB/s, mint=30001msec, maxt=30001msec

Run status group 19 (all jobs):
   READ: io=3,225MiB, aggrb=110MiB/s, minb=110MiB/s, maxb=110MiB/s, mint=30001msec, maxt=30001msec

Run status group 20 (all jobs):
   READ: io=3,219MiB, aggrb=110MiB/s, minb=110MiB/s, maxb=110MiB/s, mint=30001msec, maxt=30001msec

Run status group 21 (all jobs):
   READ: io=3,203MiB, aggrb=109MiB/s, minb=109MiB/s, maxb=109MiB/s, mint=30003msec, maxt=30003msec

Run status group 22 (all jobs):

Run status group 23 (all jobs):

Run status group 24 (all jobs):

Run status group 25 (all jobs):

Run status group 26 (all jobs):

Run status group 27 (all jobs):

Run status group 28 (all jobs):

Run status group 29 (all jobs):

Run status group 30 (all jobs):
   READ: io=3,867MiB, aggrb=132MiB/s, minb=132MiB/s, maxb=132MiB/s, mint=30001msec, maxt=30001msec

Run status group 31 (all jobs):
   READ: io=7,024MiB, aggrb=240MiB/s, minb=240MiB/s, maxb=240MiB/s, mint=30001msec, maxt=30001msec

Run status group 32 (all jobs):
   READ: io=7,525MiB, aggrb=257MiB/s, minb=257MiB/s, maxb=257MiB/s, mint=30002msec, maxt=30002msec

Run status group 33 (all jobs):
   READ: io=7,527MiB, aggrb=257MiB/s, minb=257MiB/s, maxb=257MiB/s, mint=30003msec, maxt=30003msec

Run status group 34 (all jobs):
   READ: io=7,587MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30008msec, maxt=30008msec

Run status group 35 (all jobs):
   READ: io=7,591MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30015msec, maxt=30015msec

Run status group 36 (all jobs):
   READ: io=7,604MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30029msec, maxt=30029msec

Run status group 37 (all jobs):

Run status group 38 (all jobs):

Run status group 39 (all jobs):

Run status group 40 (all jobs):

Run status group 41 (all jobs):

Run status group 42 (all jobs):

Run status group 43 (all jobs):

Run status group 44 (all jobs):

Run status group 45 (all jobs):
   READ: io=7,570MiB, aggrb=258MiB/s, minb=258MiB/s, maxb=258MiB/s, mint=30002msec, maxt=30002msec

Run status group 46 (all jobs):
   READ: io=7,599MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30004msec, maxt=30004msec

Run status group 47 (all jobs):
   READ: io=7,605MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30007msec, maxt=30007msec

Run status group 48 (all jobs):
   READ: io=7,609MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30015msec, maxt=30015msec

Run status group 49 (all jobs):
   READ: io=7,619MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30032msec, maxt=30032msec

Run status group 50 (all jobs):
   READ: io=7,478MiB, aggrb=255MiB/s, minb=255MiB/s, maxb=255MiB/s, mint=30064msec, maxt=30064msec

Run status group 51 (all jobs):
   READ: io=7,468MiB, aggrb=254MiB/s, minb=254MiB/s, maxb=254MiB/s, mint=30126msec, maxt=30126msec

Run status group 52 (all jobs):

Run status group 53 (all jobs):
  WRITE: io=512KiB, aggrb=256MiB/s, minb=256MiB/s, maxb=256MiB/s, mint=2msec, maxt=2msec

Run status group 54 (all jobs):
  WRITE: io=1,536KiB, aggrb=512MiB/s, minb=512MiB/s, maxb=512MiB/s, mint=3msec, maxt=3msec

Run status group 55 (all jobs):
  WRITE: io=3,584KiB, aggrb=149MiB/s, minb=149MiB/s, maxb=149MiB/s, mint=24msec, maxt=24msec

Run status group 56 (all jobs):

Run status group 57 (all jobs):

Run status group 58 (all jobs):

Run status group 59 (all jobs):

Run status group 60 (all jobs):
   READ: io=7,590MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30004msec, maxt=30004msec

Run status group 61 (all jobs):
   READ: io=7,602MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30006msec, maxt=30006msec

Run status group 62 (all jobs):
   READ: io=7,606MiB, aggrb=259MiB/s, minb=259MiB/s, maxb=259MiB/s, mint=30015msec, maxt=30015msec

Run status group 63 (all jobs):
   READ: io=7,617MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30032msec, maxt=30032msec

Run status group 64 (all jobs):
   READ: io=7,638MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30062msec, maxt=30062msec

Run status group 65 (all jobs):
   READ: io=7,652MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30125msec, maxt=30125msec

Run status group 66 (all jobs):
   READ: io=7,638MiB, aggrb=260MiB/s, minb=260MiB/s, maxb=260MiB/s, mint=30089msec, maxt=30089msec

Disk stats (read/write):
  cciss!c1d0: ios=13674968/445, merge=21891/0, ticks=32034605/16709, in_queue=32049193, util=96.88%

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (70 preceding siblings ...)
  2009-03-27  5:00 ` Jens Axboe
@ 2009-04-07  4:00 ` Jens Axboe
  2009-04-18  4:00 ` Jens Axboe
                   ` (28 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-04-07  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit d8ba9b683e1a341ab72c40836c05a360875c2e5e:
  Eric Sandeen (1):
        fix trivial typo in manpage

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Working on fixing % time q plugged
      Fixed plug/unplug logic in btt

 btt/devs.c       |   19 ++++++++++++-------
 btt/globals.h    |    4 ++--
 btt/output.c     |   17 +++++++++--------
 btt/trace_plug.c |    3 ++-
 4 files changed, 25 insertions(+), 18 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (69 preceding siblings ...)
  2009-03-26  5:00 ` Jens Axboe
@ 2009-03-27  5:00 ` Jens Axboe
  2009-04-07  4:00 ` Jens Axboe
                   ` (29 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-03-27  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit cfa089d429acfcb5a21be63ded7f943287401fef:
  Carl Henrik Lunde (1):
        Add NOTIFY to activity mask

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Eric Sandeen (1):
      fix trivial typo in manpage

 doc/blktrace.8 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (68 preceding siblings ...)
  2009-03-24  5:00 ` Jens Axboe
@ 2009-03-26  5:00 ` Jens Axboe
  2009-03-27  5:00 ` Jens Axboe
                   ` (30 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-03-26  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit f547a39d32d514eb7bce82b955193b73e9828c85:
  Tom Zanussi (1):
        Blktrace failed to lock reader threads on the cpu used by the corresponding writer. This resulted in stale data being consumed when blktrace accidently read at a position that was being written to at the same time. This issue surfaced as "bad trace magic" warnings emitted by blktrace tools.

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Carl Henrik Lunde (1):
      Add NOTIFY to activity mask

 act_mask.c       |    1 +
 doc/blktrace.8   |    2 ++
 doc/blktrace.tex |    1 +
 3 files changed, 4 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (67 preceding siblings ...)
  2009-03-13  5:00 ` Jens Axboe
@ 2009-03-24  5:00 ` Jens Axboe
  2009-03-26  5:00 ` Jens Axboe
                   ` (31 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-03-24  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 726d2aee9d2b97b32daa08824857c77f9536609f:
  Alan D. Brunelle (1):
        Generate matplotlib plots for btt generated data

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Tom Zanussi (1):
      Blktrace failed to lock reader threads on the cpu used by the corresponding writer. This resulted in stale data being consumed when blktrace accidently read at a position that was being written to at the same time. This issue surfaced as "bad trace magic" warnings emitted by blktrace tools.

 blktrace.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (66 preceding siblings ...)
  2009-02-19  5:00 ` Jens Axboe
@ 2009-03-13  5:00 ` Jens Axboe
  2009-03-24  5:00 ` Jens Axboe
                   ` (32 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-03-13  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit c2039a2eebe7d48d8e1f62e727affa28f0e2b65e:
  Jens Axboe (1):
        Merge branch 'master' of ssh://axboe@router.home.kernel.dk/data/git/blktrace

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Generate matplotlib plots for btt generated data

 btt/btt_plot.py |  394 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 394 insertions(+), 0 deletions(-)
 create mode 100755 btt/btt_plot.py

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (65 preceding siblings ...)
  2009-02-18  5:00 ` Jens Axboe
@ 2009-02-19  5:00 ` Jens Axboe
  2009-03-13  5:00 ` Jens Axboe
                   ` (33 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-19  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 5d65b5e6333cfdd14ab0e944cef8474445e531b3:
  Alan D. Brunelle (1):
        Fixed EAGAIN handling in blktrace.c

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (2):
      Update Jenkins hash to lookup3() variant
      Merge branch 'master' of ssh://axboe@router.home.kernel.dk/data/git/blktrace

 jhash.h |  154 ++++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 84 insertions(+), 70 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (64 preceding siblings ...)
  2009-02-14  5:00 ` Jens Axboe
@ 2009-02-18  5:00 ` Jens Axboe
  2009-02-19  5:00 ` Jens Axboe
                   ` (34 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-18  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ee27874baa43db7d697b5de72938e4ccb71bdabb:
  Alan D. Brunelle (1):
        btt: Added no remap option

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Fixed EAGAIN handling in blktrace.c

Jens Axboe (1):
      O_NOATIME isn't always present

 blktrace.c          |    7 +++++--
 btreplay/btreplay.c |    9 ++++++++-
 2 files changed, 13 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (63 preceding siblings ...)
  2009-02-13  5:00 ` Jens Axboe
@ 2009-02-14  5:00 ` Jens Axboe
  2009-02-18  5:00 ` Jens Axboe
                   ` (35 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-14  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 8f34184f8c7905bb929862d224a7c4969bc9190e:
  Alan D. Brunelle (1):
        btt: Missed fopen conversion to my_fopen

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      btt general cleanup plus valgrind clean
      btt: Added no remap option

 btt/aqd.c         |   13 +----
 btt/args.c        |  111 ++++++++++++++++++++--------------------------
 btt/bno_dump.c    |   36 +++++----------
 btt/bt_timeline.c |   28 ++++--------
 btt/devmap.c      |   60 +++++++++++++++----------
 btt/devs.c        |   50 ++++++++++-----------
 btt/doc/btt.tex   |    7 +++-
 btt/globals.h     |   63 ++++++++++-----------------
 btt/inlines.h     |    7 +--
 btt/iostat.c      |   61 ++++++++++---------------
 btt/latency.c     |   33 +++++--------
 btt/misc.c        |  126 +++++++++++++++++++++++++----------------------------
 btt/mmap.c        |   12 +++--
 btt/output.c      |    4 +-
 btt/plat.c        |   19 ++------
 btt/proc.c        |   31 +++++++------
 btt/q2d.c         |    4 +-
 btt/seek.c        |  109 +++++++++++++++++++++-------------------------
 btt/trace.c       |   15 +++----
 btt/trace_plug.c  |    2 +-
 btt/trace_remap.c |    6 ++-
 btt/unplug_hist.c |   11 ++---
 doc/btt.1         |   10 ++++
 23 files changed, 375 insertions(+), 443 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (62 preceding siblings ...)
  2009-02-12  5:00 ` Jens Axboe
@ 2009-02-13  5:00 ` Jens Axboe
  2009-02-14  5:00 ` Jens Axboe
                   ` (36 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-13  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 3b552a2d1ff8ecccbbb82668f73d1cb134fca1e9:
  Alan D. Brunelle (1):
        Moved starting of tracing after tracers are going

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (4):
      Cleaned up devs that have no data
      Reworked blktrace master/thread interface
      Code review updates
      btt: Missed fopen conversion to my_fopen

 blktrace.c        |  738 ++++++++++++++++++++++++++++-------------------------
 btt/bt_timeline.c |    2 +
 btt/devs.c        |   52 +++--
 btt/globals.h     |    1 +
 btt/unplug_hist.c |    2 +-
 5 files changed, 433 insertions(+), 362 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (61 preceding siblings ...)
  2009-02-10  5:00 ` Jens Axboe
@ 2009-02-12  5:00 ` Jens Axboe
  2009-02-13  5:00 ` Jens Axboe
                   ` (37 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-12  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 3fe0b570b01622e329b9c999ebf867b1f1cb2e20:
  Alan D. Brunelle (1):
        Rewrote blktrace to have a single thread per CPU

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (5):
      Added accept as a system call needing resource increases
      Invoke gethostbyname once, handle errors better
      Synchronized trace gathering
      btt: fixed open in setup_ifile
      Moved starting of tracing after tracers are going

 blktrace.c    |  119 ++++++++++++++++++++++++++++++++++++++++++++++----------
 btt/globals.h |    1 +
 btt/misc.c    |   64 +++++++++++++++++++------------
 btt/mmap.c    |    3 +-
 4 files changed, 139 insertions(+), 48 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (60 preceding siblings ...)
  2009-01-24  5:00 ` Jens Axboe
@ 2009-02-10  5:00 ` Jens Axboe
  2009-02-12  5:00 ` Jens Axboe
                   ` (38 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-02-10  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 99bb5ebc255618e4af913d2e5f1bf268af552bdf:
  Alan D. Brunelle (1):
        Fix btt to handle large numbers of output files

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Rewrote blktrace to have a single thread per CPU

 blktrace.c | 3230 ++++++++++++++++++++++++++++++++++--------------------------
 btt/list.h |   23 +
 2 files changed, 1878 insertions(+), 1375 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (59 preceding siblings ...)
  2009-01-22  5:00 ` Jens Axboe
@ 2009-01-24  5:00 ` Jens Axboe
  2009-02-10  5:00 ` Jens Axboe
                   ` (39 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-01-24  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 61165962f86cb2de0b163f6083bff5649f692e91:
  Martin Peschke (1):
        A couple of min-counters weren't initialised correctly (thrput_r,

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Increased limits to allow for large system runs
      Fix btt to handle large numbers of output files

 blktrace.c     |   65 +++++++++++++++++++++++++++++++++++++++++++++++++------
 btt/aqd.c      |    2 +-
 btt/args.c     |   10 ++++----
 btt/bno_dump.c |    2 +-
 btt/devmap.c   |    2 +-
 btt/devs.c     |    2 +-
 btt/globals.h  |    1 +
 btt/latency.c  |    2 +-
 btt/misc.c     |   46 ++++++++++++++++++++++++++++++++++++++-
 btt/output.c   |    4 +-
 btt/plat.c     |    2 +-
 btt/seek.c     |    4 +-
 12 files changed, 119 insertions(+), 23 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (58 preceding siblings ...)
  2009-01-13  5:00 ` Jens Axboe
@ 2009-01-22  5:00 ` Jens Axboe
  2009-01-24  5:00 ` Jens Axboe
                   ` (40 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-01-22  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 19cfaf3f4d8e53ce43cccd809676f8f2a40f0b34:
  Alan D. Brunelle (1):
        Added no messages option to blkparse.c

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Martin Peschke (2):
      The git commit 11914a53d2ec2974a565311af327b8983d8c820d added __BLK_TA_ABORT
      A couple of min-counters weren't initialised correctly (thrput_r,

 blkiomon.c     |    6 +-----
 blktrace_api.h |    2 ++
 2 files changed, 3 insertions(+), 5 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (57 preceding siblings ...)
  2008-11-13  5:00 ` Jens Axboe
@ 2009-01-13  5:00 ` Jens Axboe
  2009-01-22  5:00 ` Jens Axboe
                   ` (41 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2009-01-13  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ef02006b0131f298595b37afb07562ee50fae5cc:
  Alan D. Brunelle (1):
        gcc 4.3.2 has started to warn about:

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Added no messages option to blkparse.c

 blkparse.c       |   20 +++++++++++++++++---
 doc/blkparse.1   |    9 +++++++++
 doc/blktrace.tex |    1 +
 3 files changed, 27 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (56 preceding siblings ...)
  2008-11-12  5:00 ` Jens Axboe
@ 2008-11-13  5:00 ` Jens Axboe
  2009-01-13  5:00 ` Jens Axboe
                   ` (42 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-11-13  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 0f067275d74a96ca9d574e9912a60bfa81b4df97:
  Alan D. Brunelle (1):
        Merge branch 'add-P'

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      gcc 4.3.2 has started to warn about:

 btt/output.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (55 preceding siblings ...)
  2008-11-11  5:00 ` Jens Axboe
@ 2008-11-12  5:00 ` Jens Axboe
  2008-11-13  5:00 ` Jens Axboe
                   ` (43 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-11-12  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit e47ada103e028a691d296d09d0bc673a3af6a3dc:
  Alan D. Brunelle (1):
        Added in -z to provide running waiting-for-issue latencies

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (6):
      Fixed segfault in aqd.c : need to check for NULL (not requested)
      Fixed 'M' displays on per-io output and added in I/O separator
      Merge branch 'fix-m' into add-P
      Added -P to create a data file w/ Q, D and C per line
      Merge branch 'fix-m'
      Merge branch 'add-P'

 btt/aqd.c            |   22 +++++++++++++---------
 btt/args.c           |   12 +++++++++++-
 btt/bt_timeline.c    |    4 ++--
 btt/devs.c           |   15 +++++++++++++++
 btt/doc/btt.tex      |    9 ++++++++-
 btt/globals.h        |    3 ++-
 btt/trace_complete.c |   24 +++++++++++++++++++++++-
 doc/btt.1            |   11 +++++++++++
 8 files changed, 85 insertions(+), 15 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (54 preceding siblings ...)
  2008-10-31  5:00 ` Jens Axboe
@ 2008-11-11  5:00 ` Jens Axboe
  2008-11-12  5:00 ` Jens Axboe
                   ` (44 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-11-11  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 07b96824e26286321b99c30526d8d67aca16e584:
  Jens Axboe (1):
        Set release version 1.0.0

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (3):
      Moved btrecord/btreplay to version 1.0.0
      Merge branch 'master' of ssh://alanbrunelle@git.kernel.dk/data/git/blktrace
      Added in -z to provide running waiting-for-issue latencies

 btreplay/btrecord.h |    8 ++++----
 btt/args.c          |   12 +++++++++++-
 btt/bt_timeline.c   |    4 ++--
 btt/devs.c          |    3 +++
 btt/doc/btt.tex     |   23 +++++++++++++++--------
 btt/globals.h       |    8 +++++---
 btt/latency.c       |    7 +++++++
 btt/trace_issue.c   |    2 ++
 doc/btt.1           |   15 +++++++++++++--
 9 files changed, 62 insertions(+), 20 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (53 preceding siblings ...)
  2008-10-29  5:00 ` Jens Axboe
@ 2008-10-31  5:00 ` Jens Axboe
  2008-11-11  5:00 ` Jens Axboe
                   ` (45 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-31  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 53cab5f58afd61525674ba7d6de8ac111f173a90:
  Martin Peschke (1):
        blkiomon: add through-put statistics

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (2):
      Update rbtree to version with unified parent + color
      Set release version 1.0.0

 blkparse.c |    2 +-
 blktrace.c |    2 +-
 rbtree.c   |  195 ++++++++++++++++++++++++++++++-----------------------------
 rbtree.h   |   22 ++++++-
 4 files changed, 119 insertions(+), 102 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (52 preceding siblings ...)
  2008-10-21  4:00 ` Jens Axboe
@ 2008-10-29  5:00 ` Jens Axboe
  2008-10-31  5:00 ` Jens Axboe
                   ` (46 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-29  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 3bc3451b471fe4cea365654481258a1a1913018e:
  Martin Peschke (1):
        blkiomon: drv_data traces pass-through

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Martin Peschke (6):
      blkiomon: fix cross-arch data analysis issue
      blkiomon: fix unit in histogram output
      blkiomon: fix trace debug output
      blkiomon: fix some debug messages
      blkiomon: separate statistics for read and write requests
      blkiomon: add through-put statistics

 blkiomon.c |   62 +++++++++++++++++++++++++++++++++++------------------------
 blkiomon.h |   56 ++++++++++++++++++++++++++++++++---------------------
 2 files changed, 71 insertions(+), 47 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (51 preceding siblings ...)
  2008-10-18  4:00 ` Jens Axboe
@ 2008-10-21  4:00 ` Jens Axboe
  2008-10-29  5:00 ` Jens Axboe
                   ` (47 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-21  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit c701176c4befb44efe68e3b5e09ca710b4be357d:
  Martin Peschke (1):
        blkparse: add hint for discarded drv_data traces

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Martin Peschke (1):
      blkiomon: drv_data traces pass-through

 blkiomon.c |   44 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 42 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (50 preceding siblings ...)
  2008-10-17  4:00 ` Jens Axboe
@ 2008-10-18  4:00 ` Jens Axboe
  2008-10-21  4:00 ` Jens Axboe
                   ` (48 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-18  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 2baef5087c57d39ee2fc488cd52348f61f32b1fc:
  Alan D. Brunelle (1):
        Added in -L option - output periodic latency information

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Martin Peschke (1):
      blkparse: add hint for discarded drv_data traces

 blkparse.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (49 preceding siblings ...)
  2008-10-11  4:00 ` Jens Axboe
@ 2008-10-17  4:00 ` Jens Axboe
  2008-10-18  4:00 ` Jens Axboe
                   ` (49 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-17  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit abf63eafd11e42e0f065e56fc4773e6854087d41:
  Alan D. Brunelle (1):
        Removed excessive amounts of seek modes (for random sets of I/Os)

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Added in -Q / --active-queue-depth option
      Added in -L option - output periodic latency information

Jens Axboe (1):
      blktrace: accept -v (lower case) for version info as well

Martin Peschke (1):
      blkiomon: I/O monitor

Stefan Raspl (1):
      Add driver data support

 Makefile             |    5 +-
 act_mask.c           |    1 +
 blkiomon.c           |  708 ++++++++++++++++++++++++++++++++++++++++++++++++++
 blkiomon.h           |  105 ++++++++
 blkparse.c           |    3 +
 blktrace.c           |    9 +-
 blktrace_api.h       |    3 +
 btt/Makefile         |    3 +-
 btt/aqd.c            |   83 ++++++
 btt/args.c           |   22 ++-
 btt/bt_timeline.c    |    4 +-
 btt/devs.c           |    8 +
 btt/doc/btt.tex      |   18 ++-
 btt/globals.h        |   19 ++-
 btt/latency.c        |    2 +
 btt/plat.c           |  102 ++++++++
 btt/trace_complete.c |    1 +
 btt/trace_issue.c    |    1 +
 doc/blkiomon.8       |  116 ++++++++
 doc/btt.1            |   23 ++-
 stats.h              |  155 +++++++++++
 21 files changed, 1381 insertions(+), 10 deletions(-)
 create mode 100644 blkiomon.c
 create mode 100644 blkiomon.h
 create mode 100644 btt/aqd.c
 create mode 100644 btt/plat.c
 create mode 100644 doc/blkiomon.8
 create mode 100644 stats.h

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (48 preceding siblings ...)
  2008-09-27  4:00 ` Jens Axboe
@ 2008-10-11  4:00 ` Jens Axboe
  2008-10-17  4:00 ` Jens Axboe
                   ` (50 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-10-11  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 4133e838c72f5f66e0c5b57af1aa24bf10a23b07:
  Nathan Scott (1):
        spec file tweak

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (3):
      Added in %done for btt
      Merge branch 'master' of ssh://alanbrunelle@git.kernel.dk/data/git/blktrace
      Removed excessive amounts of seek modes (for random sets of I/Os)

 btt/globals.h |    1 +
 btt/mmap.c    |    5 +++++
 btt/output.c  |   18 +++++++++++++-----
 btt/trace.c   |    2 +-
 4 files changed, 20 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (47 preceding siblings ...)
  2008-08-16  4:00 ` Jens Axboe
@ 2008-09-27  4:00 ` Jens Axboe
  2008-10-11  4:00 ` Jens Axboe
                   ` (51 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-09-27  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 64c031619f9d7fbafce96d6e6c29f945b589141b:
  David Woodhouse (1):
        Add documentation of 'D' discard operation

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      Merge branch 'master' of ssh://axboe@router.home.kernel.dk/data/git/blktrace

Nathan Scott (2):
      man page typo
      spec file tweak

 btrace.spec    |    1 +
 doc/blktrace.8 |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (46 preceding siblings ...)
  2008-07-02  4:00 ` Jens Axboe
@ 2008-08-16  4:00 ` Jens Axboe
  2008-09-27  4:00 ` Jens Axboe
                   ` (52 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-08-16  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ea86559e392fc012f9b30eb109d3421d463c8848:
  Jeff Moyer (1):
        spelling and grammar fixes for btreplay.tex

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

David Woodhouse (2):
      blktrace: support discard requests
      Add documentation of 'D' discard operation

 act_mask.c       |    1 +
 blkparse_fmt.c   |    5 ++++-
 blkrawverify.c   |    1 +
 blktrace_api.h   |    1 +
 doc/blkparse.1   |    6 +++---
 doc/blktrace.tex |    4 ++--
 6 files changed, 12 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (45 preceding siblings ...)
  2008-05-28  4:00 ` Jens Axboe
@ 2008-07-02  4:00 ` Jens Axboe
  2008-08-16  4:00 ` Jens Axboe
                   ` (53 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-07-02  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 84a26fcd9adebd1537bf2c4eee69d1ca23ccbc5f:
  Alan D. Brunelle (1):
        Put message notes from kernel into a separate file for easy tracking

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jeff Moyer (1):
      spelling and grammar fixes for btreplay.tex

 btreplay/doc/btreplay.tex |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (44 preceding siblings ...)
  2008-05-22  4:00 ` Jens Axboe
@ 2008-05-28  4:00 ` Jens Axboe
  2008-07-02  4:00 ` Jens Axboe
                   ` (54 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-28  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 5bebfd168c3f3f42acfd4a0263e9f4d1f5faea16:
  Alan D. Brunelle (1):
        Handled no difference in seek times

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (3):
      Added in handling of MESSAGE notes
      Added in new message updates to the documentation.
      Put message notes from kernel into a separate file for easy tracking

 blkparse.c        |   24 +++++++++++++++++++++---
 blkparse_fmt.c    |    6 +++++-
 blktrace_api.h    |    2 ++
 btt/args.c        |   11 ++++++++++-
 btt/bt_timeline.c |    4 +++-
 btt/globals.h     |    3 ++-
 btt/iostat.c      |    2 +-
 btt/misc.c        |   16 ++++++++++++++++
 btt/output.c      |   52 ++++++++++++++++------------------------------------
 btt/trace.c       |   19 +++++++++++++++++++
 doc/blktrace.tex  |   13 ++++++++++++-
 11 files changed, 107 insertions(+), 45 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (43 preceding siblings ...)
  2008-05-19  4:00 ` Jens Axboe
@ 2008-05-22  4:00 ` Jens Axboe
  2008-05-28  4:00 ` Jens Axboe
                   ` (55 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-22  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ebe2d1aa7f334fc526a97f8acf62f1fe7dac9a8a:
  Jens Axboe (1):
        blkparse: cope with missing process notify event

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (2):
      Added in -m option, seeks-per-second
      Handled no difference in seek times

 btt/args.c        |   17 +-
 btt/bt_timeline.c |    5 +-
 btt/doc/btt.tex   |   54 +-
 btt/doc/sps.eps   | 5377 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 btt/globals.h     |    2 +-
 btt/seek.c        |   70 +-
 6 files changed, 5517 insertions(+), 8 deletions(-)
 create mode 100644 btt/doc/sps.eps

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (42 preceding siblings ...)
  2008-05-13  4:00 ` Jens Axboe
@ 2008-05-19  4:00 ` Jens Axboe
  2008-05-22  4:00 ` Jens Axboe
                   ` (56 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-19  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit dd14158dca460522c22afbd7e22343e4012fffe0:
  Alan D. Brunelle (1):
        Fixed percentage calculations for phases of an I/O

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Jens Axboe (1):
      blkparse: cope with missing process notify event

 blkparse.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (41 preceding siblings ...)
  2008-05-10  4:00 ` Jens Axboe
@ 2008-05-13  4:00 ` Jens Axboe
  2008-05-19  4:00 ` Jens Axboe
                   ` (57 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-13  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 354db430eeaced3b8234668e6527910875d54e50:
  Alan D. Brunelle (1):
        Added S2G times + fixed up -X output to include X2X

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Fixed percentage calculations for phases of an I/O

 btt/output.c |   86 +++++++++++++++++----------------------------------------
 1 files changed, 26 insertions(+), 60 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (40 preceding siblings ...)
  2008-05-09  4:00 ` Jens Axboe
@ 2008-05-10  4:00 ` Jens Axboe
  2008-05-13  4:00 ` Jens Axboe
                   ` (58 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-10  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit f028c9584055737f429979e18ab7436583ed41b5:
  Alan D. Brunelle (1):
        Added -X option - generate easily parseable file

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Added S2G times + fixed up -X output to include X2X

 btt/bt_timeline.c    |    2 +-
 btt/doc/btt.tex      |   38 ++++++++++++++++++++++++++++++--------
 btt/globals.h        |    8 ++++++--
 btt/inlines.h        |    5 +++++
 btt/output.c         |   42 +++++++++++++++++++++++++++---------------
 btt/trace.c          |    1 +
 btt/trace_complete.c |    3 +++
 btt/trace_im.c       |   36 +++++++++++++++++++++++++++++++-----
 btt/trace_issue.c    |    4 ++++
 btt/trace_queue.c    |    3 +++
 10 files changed, 111 insertions(+), 31 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (39 preceding siblings ...)
  2008-05-06  4:00 ` Jens Axboe
@ 2008-05-09  4:00 ` Jens Axboe
  2008-05-10  4:00 ` Jens Axboe
                   ` (59 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-09  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 4a7968cc672f39573abc6002f0afbed2a8e8139b:
  Luis Useche (1):
        Add -x accellerator option

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Alan D. Brunelle (1):
      Added -X option - generate easily parseable file

 btt/args.c        |   36 ++++++++++++++++++++++++-----
 btt/bt_timeline.c |    5 ++-
 btt/doc/btt.tex   |   56 +++++++++++++++++++++++++++++++++++++++++++--
 btt/globals.h     |    3 +-
 btt/output.c      |   64 +++++++++++++++++++++++++++++++++++++++++++++++++---
 5 files changed, 148 insertions(+), 16 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (38 preceding siblings ...)
  2008-04-03  7:04 ` Jens Axboe
@ 2008-05-06  4:00 ` Jens Axboe
  2008-05-09  4:00 ` Jens Axboe
                   ` (60 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-05-06  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 801646d63fe28ae2c50ab5bd0e9ea4f75ff64d97:
  Christof Schmitt (1):
        blkparse: Introduce optional accounting of PC requests

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Luis Useche (3):
      eliminate check of empty -F format
      Fix problem with -w option
      Add -x accellerator option

 blkparse.c                |   10 ++++++----
 blkparse_fmt.c            |    4 ----
 btreplay/btreplay.c       |   27 ++++++++++++++++++++++++---
 btreplay/doc/btreplay.tex |   13 ++++++++++++-
 4 files changed, 42 insertions(+), 12 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (37 preceding siblings ...)
  2008-04-03  4:00 ` Jens Axboe
@ 2008-04-03  7:04 ` Jens Axboe
  2008-05-06  4:00 ` Jens Axboe
                   ` (61 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-04-03  7:04 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 967492e81cd045b058fc93dacc15924bebd00b9b:
  Bas Zoetekouw (1):
        Fix section of btrecord and btreplay man pages

are available in the git repository at:

  git://git.kernel.dk/blktrace.git master

Christof Schmitt (2):
      blkparse: Add PC requests to depth trace
      blkparse: Introduce optional accounting of PC requests

 blkparse.c |  138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 blktrace.h |    3 +
 2 files changed, 139 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (36 preceding siblings ...)
  2008-02-23  5:00 ` Jens Axboe
@ 2008-04-03  4:00 ` Jens Axboe
  2008-04-03  7:04 ` Jens Axboe
                   ` (62 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-04-03  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 967492e81cd045b058fc93dacc15924bebd00b9b:
  Bas Zoetekouw (1):
        Fix section of btrecord and btreplay man pages

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Christof Schmitt (2):
      blkparse: Add PC requests to depth trace
      blkparse: Introduce optional accounting of PC requests

 blkparse.c |  138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 blktrace.h |    3 +
 2 files changed, 139 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (35 preceding siblings ...)
  2008-02-14  5:00 ` Jens Axboe
@ 2008-02-23  5:00 ` Jens Axboe
  2008-04-03  4:00 ` Jens Axboe
                   ` (63 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-23  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 8b10aae0cd4137f1cc9848181e4f45a9fa20de24:
  Alan D. Brunelle (1):
        Cleanups: Fixed IOPs in btt left over at end of run

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Bas Zoetekouw (4):
      Added man page for bno_plot and updated btt man page to refer to bno_plot
      Really commit the changes to btt.1
      Don't like btrecord against libaio and librt, as it doesn't use any of their symbols
      Fix section of btrecord and btreplay man pages

 btreplay/Makefile |    2 +-
 doc/bno_plot.1    |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 doc/btrecord.8    |    2 +-
 doc/btreplay.8    |    2 +-
 doc/btt.1         |    8 +++++-
 5 files changed, 74 insertions(+), 4 deletions(-)
 create mode 100644 doc/bno_plot.1

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (34 preceding siblings ...)
  2008-02-13  5:00 ` Jens Axboe
@ 2008-02-14  5:00 ` Jens Axboe
  2008-02-23  5:00 ` Jens Axboe
                   ` (64 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-14  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ef14423994b40499402269896fc1aa5567bcdba9:
  Alan D. Brunelle (1):
        Added info about bno_plot.py and clean ups

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Aaron Carroll (2):
      btt: fix iostat interval default
      btt: fix missing cleanup call

Alan D. Brunelle (1):
      Cleanups: Fixed IOPs in btt left over at end of run

 btt/Makefile         |    3 +-
 btt/args.c           |    1 -
 btt/bno_dump.c       |    2 +-
 btt/bt_timeline.c    |   44 ++-------------------
 btt/devs.c           |   56 +--------------------------
 btt/dip_rb.c         |    7 +--
 btt/globals.h        |   45 ++-------------------
 btt/inlines.h        |  104 +++++++-------------------------------------------
 btt/iostat.c         |    4 +-
 btt/misc.c           |    4 +-
 btt/mmap.c           |    8 +---
 btt/output.c         |    2 -
 btt/proc.c           |   11 ++---
 btt/seek.c           |    8 ++--
 btt/trace.c          |   13 +-----
 btt/trace_complete.c |    8 ++--
 btt/trace_issue.c    |    8 +--
 btt/trace_queue.c    |    2 +-
 btt/unplug_hist.c    |    3 -
 19 files changed, 54 insertions(+), 279 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (33 preceding siblings ...)
  2008-02-09  5:00 ` Jens Axboe
@ 2008-02-13  5:00 ` Jens Axboe
  2008-02-14  5:00 ` Jens Axboe
                   ` (65 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-13  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit feb161907bf39fab6bedacf066fe7de6639cea93:
  Alan D. Brunelle (1):
        Merge branch 'bno_plot.submit'

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Added info about bno_plot.py and clean ups

 btt/bno_plot.py               |    4 +-
 btt/doc/Makefile              |    2 +-
 btt/doc/bno_plot.eps          | 7696 +++++++++++++++++++++++++++++++++++++++++
 btt/doc/btt.tex               |   70 +-
 btt/doc/sample-btt-output.tex |  177 +-
 5 files changed, 7828 insertions(+), 121 deletions(-)
 create mode 100644 btt/doc/bno_plot.eps

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (32 preceding siblings ...)
  2008-02-06  5:00 ` Jens Axboe
@ 2008-02-09  5:00 ` Jens Axboe
  2008-02-13  5:00 ` Jens Axboe
                   ` (66 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-09  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit b70a66427b4674b2a37660a196e5c6db181dd4ec:
  Alan D. Brunelle (1):
        Added new IOs per unplug table

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (2):
      Added bno_plot.py - generate interactive 3D plot of IO blocks and sizes
      Merge branch 'bno_plot.submit'

 Makefile        |    3 +-
 btt/bno_plot.py |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+), 1 deletions(-)
 create mode 100644 btt/bno_plot.py

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (31 preceding siblings ...)
  2008-02-01  5:00 ` Jens Axboe
@ 2008-02-06  5:00 ` Jens Axboe
  2008-02-09  5:00 ` Jens Axboe
                   ` (67 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-06  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 00a47cd169f2cc87b5f63fe93226b7231dee678c:
  Alan D. Brunelle (1):
        UNPLUG does the timing stuff, UNPLUG TIMEOUT only does timeout

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Added new IOs per unplug table

 btt/bt_timeline.c |    2 +-
 btt/devs.c        |   10 +++-
 btt/doc/btt.tex   |  101 ++++++++++++++++++++++++++++++----------------
 btt/globals.h     |    8 ++-
 btt/output.c      |  115 ++++++++++++++++++++++++++++++++++++++---------------
 btt/trace_plug.c  |   10 ++++-
 6 files changed, 170 insertions(+), 76 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (30 preceding siblings ...)
  2008-01-04  5:00 ` Jens Axboe
@ 2008-02-01  5:00 ` Jens Axboe
  2008-02-06  5:00 ` Jens Axboe
                   ` (68 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-02-01  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 461afe819c41fa811f9c6264524cb8edbd2acc63:
  Dave Boutcher (1):
        Fix Q counts during requeue and merges.

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (2):
      Fixed excess bucket information for unplug histograms.
      UNPLUG does the timing stuff, UNPLUG TIMEOUT only does timeout

 btt/devs.c        |   18 ++++++++++++------
 btt/globals.h     |    3 ++-
 btt/output.c      |    2 +-
 btt/trace_plug.c  |   14 +++++---------
 btt/unplug_hist.c |    4 ++--
 5 files changed, 22 insertions(+), 19 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (29 preceding siblings ...)
  2007-12-11  5:00 ` Jens Axboe
@ 2008-01-04  5:00 ` Jens Axboe
  2008-02-01  5:00 ` Jens Axboe
                   ` (69 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2008-01-04  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit ae6d30f4475181d685d1f33faf056755803f189b:
  Alan D. Brunelle (1):
        Separated out g/i/m trace handling.

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Dave Boutcher (1):
      Fix Q counts during requeue and merges.

 btt/trace_im.c      |    3 +++
 btt/trace_requeue.c |    9 +++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (28 preceding siblings ...)
  2007-12-10  5:00 ` Jens Axboe
@ 2007-12-11  5:00 ` Jens Axboe
  2008-01-04  5:00 ` Jens Axboe
                   ` (70 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-12-11  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit a84a97fdf8ce07ccda8dcc4f32f0df2291f2f54f:
  Bas Zoetekouw (1):
        btreplay/btrecord man pages

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Separated out g/i/m trace handling.

 btt/bt_timeline.c    |    2 +-
 btt/doc/btt.tex      |   46 +++++++++--
 btt/globals.h        |   19 +++--
 btt/inlines.h        |   82 ++++++++++++++++----
 btt/iostat.c         |   17 ++---
 btt/output.c         |  209 +++++++++++++++++++++++++++----------------------
 btt/proc.c           |    7 ++-
 btt/trace_complete.c |   22 ++++--
 btt/trace_im.c       |   52 +++++++-----
 btt/trace_issue.c    |    6 +-
 btt/trace_queue.c    |   11 ++-
 11 files changed, 305 insertions(+), 168 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (27 preceding siblings ...)
  2007-12-08  5:00 ` Jens Axboe
@ 2007-12-10  5:00 ` Jens Axboe
  2007-12-11  5:00 ` Jens Axboe
                   ` (71 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-12-10  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 02a94ed057ba88861ed041496646a8be53d0b2e7:
  Alan D. Brunelle (1):
        Merge branch 'master' into add-q2d

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Bas Zoetekouw (1):
      btreplay/btrecord man pages

 doc/btrecord.8 |  210 ++++++++++++++++++++++++++++++++++++++++++++++++++
 doc/btreplay.8 |  235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 445 insertions(+), 0 deletions(-)
 create mode 100644 doc/btrecord.8
 create mode 100644 doc/btreplay.8

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (26 preceding siblings ...)
  2007-12-07  5:00 ` Jens Axboe
@ 2007-12-08  5:00 ` Jens Axboe
  2007-12-10  5:00 ` Jens Axboe
                   ` (72 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-12-08  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 99a55a0392b1634ce81e594f48a1105e8ebc1d58:
  Joshua Root (1):
        Remove strange make dependency

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (2):
      Added in Q2D histograms (requires -A)
      Merge branch 'master' into add-q2d

 btt/Makefile      |    2 +-
 btt/devs.c        |    4 ++
 btt/doc/btt.tex   |   21 +++++++++
 btt/globals.h     |   11 +++++
 btt/output.c      |   48 +++++++++++++++++++++
 btt/q2d.c         |  121 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 btt/trace_issue.c |    4 ++
 7 files changed, 210 insertions(+), 1 deletions(-)
 create mode 100644 btt/q2d.c

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (25 preceding siblings ...)
  2007-11-15  5:00 ` Jens Axboe
@ 2007-12-07  5:00 ` Jens Axboe
  2007-12-08  5:00 ` Jens Axboe
                   ` (73 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-12-07  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 24c7e97eb6a28a3cfcc966aa2d38af6caed01997:
  Jens Axboe (1):
        memset() must be done after NULL check

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Joshua Root (1):
      Remove strange make dependency

 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (24 preceding siblings ...)
  2007-11-14  5:00 ` Jens Axboe
@ 2007-11-15  5:00 ` Jens Axboe
  2007-12-07  5:00 ` Jens Axboe
                   ` (74 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-11-15  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 50f7389936188591eda0f114ab682520e6fe90c9:
  Alan D. Brunelle (1):
        Added active requests at Q information.

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jens Axboe (1):
      memset() must be done after NULL check

 blktrace.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (23 preceding siblings ...)
  2007-11-09  5:00 ` Jens Axboe
@ 2007-11-14  5:00 ` Jens Axboe
  2007-11-15  5:00 ` Jens Axboe
                   ` (75 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-11-14  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 77f256cda4b2f076f5169fdf1bc815f629eea361:
  Alan D. Brunelle (1):
        Fixed REMAP to update Q2A & fixed #Q calculations

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Added active requests at Q information.

 btt/doc/btt.tex   |   32 +++++++++++++++++++++++++++++---
 btt/globals.h     |    1 +
 btt/output.c      |   42 ++++++++++++++++++++++++++++++++++++++++++
 btt/trace_issue.c |    3 +++
 btt/trace_queue.c |    3 +++
 5 files changed, 78 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (22 preceding siblings ...)
  2007-10-30  5:00 ` Jens Axboe
@ 2007-11-09  5:00 ` Jens Axboe
  2007-11-14  5:00 ` Jens Axboe
                   ` (76 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-11-09  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit c0c1840adae820efa96fb0ff797b8bc60a672d63:
  Aneesh Kumar K.V (1):
        blktrace segfault

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Fixed REMAP to update Q2A & fixed #Q calculations

 btt/globals.h     |    2 +-
 btt/output.c      |   18 ++++++++++++++----
 btt/trace_queue.c |    1 +
 btt/trace_remap.c |   34 ++++++++++++++++++++++++----------
 4 files changed, 40 insertions(+), 15 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (21 preceding siblings ...)
  2007-10-11  4:00 ` Jens Axboe
@ 2007-10-30  5:00 ` Jens Axboe
  2007-11-09  5:00 ` Jens Axboe
                   ` (77 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-10-30  5:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 60d658630cfe397a93a97f1b38350b27eacc317e:
  Alan D. Brunelle (1):
        Added O_NOATIME to replay file

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Aneesh Kumar K.V (1):
      blktrace segfault

 blktrace.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (20 preceding siblings ...)
  2007-10-06  4:00 ` Jens Axboe
@ 2007-10-11  4:00 ` Jens Axboe
  2007-10-30  5:00 ` Jens Axboe
                   ` (78 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-10-11  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 0106d9cfa13b912042bace7bbb2d2475dfd35e10:
  Alan D. Brunelle (1):
        Converted fatal to an inline function

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (3):
      Converted fatal from macro to inline
      Merge branch 'master' of git://brick.kernel.dk/data/git/blktrace
      Added O_NOATIME to replay file

Joshua Root (1):
      Fix segfault in replay_sub when verbose is 1

 btreplay/btreplay.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (19 preceding siblings ...)
  2007-10-03  4:00 ` Jens Axboe
@ 2007-10-06  4:00 ` Jens Axboe
  2007-10-11  4:00 ` Jens Axboe
                   ` (79 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-10-06  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit d47a3fec3f4bbcf6b0c6ef757a4eb449dd81d10a:
  Alan D. Brunelle (1):
        Add btrecord/btreplay capability

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Converted fatal to an inline function

 btreplay/btrecord.c |   23 ++++++++++++++++-------
 btreplay/btreplay.c |   23 ++++++++++++++++-------
 2 files changed, 32 insertions(+), 14 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (18 preceding siblings ...)
  2007-10-02  4:00 ` Jens Axboe
@ 2007-10-03  4:00 ` Jens Axboe
  2007-10-06  4:00 ` Jens Axboe
                   ` (80 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-10-03  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 9a8e0e1766abcf7fbc71b7a60cd6d0c85573bd52:
  Bas Zoetekouw (1):
        btt manpages

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (2):
      Added list_splice to btt/list.h
      Add btrecord/btreplay capability

 Makefile                  |   11 +-
 btreplay/Makefile         |   45 ++
 btreplay/btrecord.c       |  780 ++++++++++++++++++++++
 btreplay/btrecord.h       |   95 +++
 btreplay/btreplay.c       | 1590 +++++++++++++++++++++++++++++++++++++++++++++
 btreplay/doc/Makefile     |   18 +
 btreplay/doc/abstract.tex |   34 +
 btreplay/doc/btreplay.tex |  521 +++++++++++++++
 btt/list.h                |   47 ++
 9 files changed, 3140 insertions(+), 1 deletions(-)
 create mode 100644 btreplay/Makefile
 create mode 100644 btreplay/btrecord.c
 create mode 100644 btreplay/btrecord.h
 create mode 100644 btreplay/btreplay.c
 create mode 100644 btreplay/doc/Makefile
 create mode 100644 btreplay/doc/abstract.tex
 create mode 100644 btreplay/doc/btreplay.tex

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (17 preceding siblings ...)
  2007-09-11  4:00 ` Jens Axboe
@ 2007-10-02  4:00 ` Jens Axboe
  2007-10-03  4:00 ` Jens Axboe
                   ` (81 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-10-02  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 4c48f14ea8ae2fae86811ac4dc1d72ad9bb601c2:
  Alan D. Brunelle (1):
        Major revamping (ver 2.0)

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Bas Zoetekouw (2):
      Fix compilation on m68k
      btt manpages

 barrier.h |    2 +-
 doc/btt.1 |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 141 insertions(+), 24 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (16 preceding siblings ...)
  2007-08-29  4:00 ` Jens Axboe
@ 2007-09-11  4:00 ` Jens Axboe
  2007-10-02  4:00 ` Jens Axboe
                   ` (82 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-09-11  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit a5981e2e795319502cc8dda629482928f3b7b204:
  Jens Axboe (1):
        blktrace 0.99.3

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Alan D. Brunelle (1):
      Major revamping (ver 2.0)

 btt/bt_timeline.c             |    7 +-
 btt/devs.c                    |   26 ++-
 btt/doc/btt.tex               |  323 +++++++----------------------------------
 btt/doc/sample-btt-output.tex |  138 ++++++++++++++++++
 btt/globals.h                 |   41 ++---
 btt/inlines.h                 |  187 ++++--------------------
 btt/iostat.c                  |    6 +-
 btt/output.c                  |  111 ++++++++------
 btt/proc.c                    |   72 +++++++---
 btt/seek.c                    |   18 +--
 btt/trace.c                   |   86 ++---------
 btt/trace_complete.c          |  192 ++++++------------------
 btt/trace_im.c                |   95 ++++---------
 btt/trace_issue.c             |   85 ++++--------
 btt/trace_queue.c             |   62 ++------
 btt/trace_remap.c             |   88 +----------
 btt/trace_requeue.c           |   21 +---
 17 files changed, 523 insertions(+), 1035 deletions(-)
 create mode 100644 btt/doc/sample-btt-output.tex

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (15 preceding siblings ...)
  2007-08-28  4:00 ` Jens Axboe
@ 2007-08-29  4:00 ` Jens Axboe
  2007-09-11  4:00 ` Jens Axboe
                   ` (83 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-08-29  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit bb4afebb049c1a1ba6adb4a564413337ca985805:
  Valerie Henson (1):
        blktrace: fix indent typo

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jens Axboe (2):
      blktrace man page: mention buffer size / number of buffers defaults.
      blktrace 0.99.3

 blkparse.c     |    2 +-
 blktrace.c     |    2 +-
 doc/blktrace.8 |    5 +++--
 3 files changed, 5 insertions(+), 4 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (14 preceding siblings ...)
  2007-08-27  4:00 ` Jens Axboe
@ 2007-08-28  4:00 ` Jens Axboe
  2007-08-29  4:00 ` Jens Axboe
                   ` (84 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-08-28  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit e2d964ec9f7f92da9abe0fb2588606dda39306ce:
  Jan Blunck (1):
        Makefile fixes

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Valerie Henson (1):
      blktrace: fix indent typo

 doc/blktrace.8 |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (13 preceding siblings ...)
  2007-08-21  4:00 ` Jens Axboe
@ 2007-08-27  4:00 ` Jens Axboe
  2007-08-28  4:00 ` Jens Axboe
                   ` (85 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-08-27  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit f806a4478092ab8e2383efd05aa88073e55df7e7:
  Jens Axboe (1):
        Disregard generated doc files in .gitignore

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jan Blunck (1):
      Makefile fixes

 Makefile     |   12 ++++++------
 btt/Makefile |   29 ++++++++++++++---------------
 2 files changed, 20 insertions(+), 21 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (12 preceding siblings ...)
  2007-07-31  4:00 ` Jens Axboe
@ 2007-08-21  4:00 ` Jens Axboe
  2007-08-27  4:00 ` Jens Axboe
                   ` (86 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-08-21  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 2885ecaa19a04ab9980896d1a849cdae9238b7d1:
  Vincent Legoll (1):
        Fix Makefile buglets

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jens Axboe (1):
      Disregard generated doc files in .gitignore

 .gitignore |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (11 preceding siblings ...)
  2007-07-25  4:00 ` Jens Axboe
@ 2007-07-31  4:00 ` Jens Axboe
  2007-08-21  4:00 ` Jens Axboe
                   ` (87 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-07-31  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 98eee4e48b9461a04c2461a856c9592d504a6fb1:
  Jens Axboe (1):
        Add man pages

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Vincent Legoll (1):
      Fix Makefile buglets

 Makefile |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (10 preceding siblings ...)
  2007-07-19  4:00 ` Jens Axboe
@ 2007-07-25  4:00 ` Jens Axboe
  2007-07-31  4:00 ` Jens Axboe
                   ` (88 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-07-25  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit e0ede9d3eec5d558abf98d94fa9b6098dc5ee013:
  Jens Axboe (1):
        git:// url location update

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jens Axboe (1):
      Add man pages

 Makefile              |    3 +
 doc/blkparse.1        |  565 +++++++++++++++++++++++++++++++++++++++++++++++++
 doc/blkrawverify.1    |   47 ++++
 doc/blktrace.8        |  255 ++++++++++++++++++++++
 doc/btrace.8          |   84 ++++++++
 doc/btt.1             |  192 +++++++++++++++++
 doc/verify_blkparse.1 |   44 ++++
 7 files changed, 1190 insertions(+), 0 deletions(-)
 create mode 100644 doc/blkparse.1
 create mode 100644 doc/blkrawverify.1
 create mode 100644 doc/blktrace.8
 create mode 100644 doc/btrace.8
 create mode 100644 doc/btt.1
 create mode 100644 doc/verify_blkparse.1

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (9 preceding siblings ...)
  2007-06-14  4:00 ` Jens Axboe
@ 2007-07-19  4:00 ` Jens Axboe
  2007-07-25  4:00 ` Jens Axboe
                   ` (89 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-07-19  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 758019ab551c13f57ba95c3512c73d61322632da:
  Jens Axboe (1):
        Update email address

are available in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git master

Jens Axboe (1):
      git:// url location update

 README |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (8 preceding siblings ...)
  2007-06-01  4:00 ` Jens Axboe
@ 2007-06-14  4:00 ` Jens Axboe
  2007-07-19  4:00 ` Jens Axboe
                   ` (90 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-06-14  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 683ffbab5860bf116b9c07abd7641892d8d0a39f:
  Jens Axboe (1):
        Make the %C format specified explanation more clear

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Jens Axboe (1):
      Update email address

 doc/blktrace.tex |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (7 preceding siblings ...)
  2007-05-31  4:00 ` Jens Axboe
@ 2007-06-01  4:00 ` Jens Axboe
  2007-06-14  4:00 ` Jens Axboe
                   ` (91 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-06-01  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit d57450af7817f35ddaa3241426a6213689a3eec6:
  Jens Axboe (1):
        Small format update for empty requests

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Jens Axboe (1):
      Make the %C format specified explanation more clear

 README |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (6 preceding siblings ...)
  2007-05-22  4:00 ` Jens Axboe
@ 2007-05-31  4:00 ` Jens Axboe
  2007-06-01  4:00 ` Jens Axboe
                   ` (92 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-05-31  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit fb2ec7961d3cfc7fb8f84bcf6ae803ed1c7bd180:
  Jens Axboe (1):
        Account size of merges

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Jens Axboe (1):
      Small format update for empty requests

 blkparse_fmt.c |   52 +++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 37 insertions(+), 15 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (5 preceding siblings ...)
  2007-05-17  4:00 ` Jens Axboe
@ 2007-05-22  4:00 ` Jens Axboe
  2007-05-31  4:00 ` Jens Axboe
                   ` (93 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-05-22  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 00cd304410a4e750ef929823dca3b932baa797b0:
  Jens Axboe (1):
        Fix crash with '-' stdin input

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Jens Axboe (2):
      Fix queued vs dispatch numbers
      Account size of merges

 blkparse.c |   11 ++++++-----
 blktrace.h |    1 +
 2 files changed, 7 insertions(+), 5 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (4 preceding siblings ...)
  2007-05-12  4:00 ` Jens Axboe
@ 2007-05-17  4:00 ` Jens Axboe
  2007-05-22  4:00 ` Jens Axboe
                   ` (94 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-05-17  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 3b79b22702659877d9ced51d77b175f2cbdbf940:
  Alan D. Brunelle (1):
        btrace: Add in -r support for btrace

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Jens Axboe (1):
      Fix crash with '-' stdin input

 blkparse.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (3 preceding siblings ...)
  2007-04-19  4:00 ` Jens Axboe
@ 2007-05-12  4:00 ` Jens Axboe
  2007-05-17  4:00 ` Jens Axboe
                   ` (95 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-05-12  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 5406b9715ffa8deecea13185a281196f878c53c6:
  Alan D. Brunelle (1):
        Fix unplug histogram placement.

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Alan D. Brunelle (1):
      btrace: Add in -r support for btrace

 btrace |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 btrace

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
                   ` (2 preceding siblings ...)
  2007-04-17  4:00 ` Jens Axboe
@ 2007-04-19  4:00 ` Jens Axboe
  2007-05-12  4:00 ` Jens Axboe
                   ` (96 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-04-19  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit fc16a815417c438ed6d980d3a08d2f37122810cc:
  Alan D. Brunelle (1):
        Add in unplug IO count histogram

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Alan D. Brunelle (1):
      Fix unplug histogram placement.

 btt/unplug_hist.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
  2007-04-14  4:00 ` Jens Axboe
  2007-04-15  4:00 ` Jens Axboe
@ 2007-04-17  4:00 ` Jens Axboe
  2007-04-19  4:00 ` Jens Axboe
                   ` (97 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-04-17  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 6904079488cd3063d171021c8954f955f4236849:
  Alan D. Brunelle (1):
        Combine all outstanding patches into one /big patch/

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Alan D. Brunelle (2):
      Cleaned out the btt/README file.
      Add in unplug IO count histogram

 btt/Makefile      |    2 +-
 btt/README        |   75 ++------------------------------------------
 btt/args.c        |   12 ++++++-
 btt/bt_timeline.c |    2 +-
 btt/devs.c        |    2 +
 btt/doc/btt.tex   |   36 +++++++++++++++++++--
 btt/globals.h     |    9 ++++-
 btt/trace_plug.c  |    1 +
 btt/unplug_hist.c |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 149 insertions(+), 80 deletions(-)
 create mode 100644 btt/unplug_hist.c

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
  2007-04-14  4:00 ` Jens Axboe
@ 2007-04-15  4:00 ` Jens Axboe
  2007-04-17  4:00 ` Jens Axboe
                   ` (98 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-04-15  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit c8b0b334cc1028ad8aa5407667233747af96a942:
  Alan D. Brunelle (1):
        A couple of weeks ago Ming Zhang had noted that btt was using tremendous

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Alan D. Brunelle (1):
      Combine all outstanding patches into one /big patch/

 btt/Makefile      |   31 ++++++++--------
 btt/args.c        |   75 +++++++++++++++++++++++++++++----------
 btt/bno_dump.c    |   92 ++++++++++++++++++++++++++++++++++++++++++++++++
 btt/bt_timeline.c |   53 ++++++++++++++++++----------
 btt/devmap.c      |   10 +++++
 btt/devs.c        |   46 ++++++++++++++++++++++++-
 btt/doc/btt.tex   |   48 ++++++++++++++++++++++++-
 btt/globals.h     |   29 +++++++++++----
 btt/inlines.h     |  100 ++++++++++++++++++++++++++++++++++++-----------------
 btt/misc.c        |   35 +++++++++++++++---
 btt/output.c      |   13 +++----
 btt/proc.c        |   32 ++++++++++++++---
 btt/seek.c        |   50 ++++++++++++++++++++++-----
 btt/trace_issue.c |    1 +
 14 files changed, 492 insertions(+), 123 deletions(-)
 create mode 100644 btt/bno_dump.c

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
  2007-04-07  3:56 Jens Axboe
@ 2007-04-14  4:00 ` Jens Axboe
  2007-04-15  4:00 ` Jens Axboe
                   ` (99 subsequent siblings)
  100 siblings, 0 replies; 135+ messages in thread
From: Jens Axboe @ 2007-04-14  4:00 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 425c69552d4fbf7705c74aef4761324ed641cb28:
  Bas Zoetekouw (1):
        Add store barrier defines for a bunch of archs

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Alan D. Brunelle (1):
      A couple of weeks ago Ming Zhang had noted that btt was using tremendous

 btt/Makefile         |   12 +++++--
 btt/bt_timeline.c    |   41 ++++++++++++++++++---
 btt/devs.c           |   11 +++---
 btt/globals.h        |   27 +++++++++-----
 btt/inlines.h        |   94 +++++++++++++++++++++++++++++++++++---------------
 btt/trace.c          |   17 +++++----
 btt/trace_complete.c |   19 +++++-----
 btt/trace_im.c       |   43 ++++++++--------------
 btt/trace_issue.c    |   41 +++++++--------------
 btt/trace_queue.c    |    8 ++--
 btt/trace_remap.c    |   12 +++---
 btt/trace_requeue.c  |   18 +++++-----
 12 files changed, 200 insertions(+), 143 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

* Recent changes
@ 2007-04-07  3:56 Jens Axboe
  2007-04-14  4:00 ` Jens Axboe
                   ` (100 more replies)
  0 siblings, 101 replies; 135+ messages in thread
From: Jens Axboe @ 2007-04-07  3:56 UTC (permalink / raw)
  To: linux-btrace

The following changes since commit 7174703f7b648246e68651d7364daa5baccff9d3:
  Alan D. Brunelle (1):
        Some fixes - added in 4 figures, fixed an error in a section label.

are found in the git repository at:

  git://git.kernel.dk/data/git/blktrace.git

Bas Zoetekouw (1):
      Add store barrier defines for a bunch of archs

 barrier.h |   27 +++++++++++++++++++++------
 1 files changed, 21 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 135+ messages in thread

end of thread, other threads:[~2012-04-14 14:47 UTC | newest]

Thread overview: 135+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20110127050004.1AE9737A304@kernel.dk>
2011-01-27  8:51 ` Recent changes Bruce Cran
2011-01-27  9:08   ` Jens Axboe
     [not found] <20120406040004.1BF99484001@kernel.dk>
2012-04-06  4:29 ` Danny Kukawka
2012-04-06 13:31   ` Jens Axboe
2012-04-06 17:40     ` Danny Kukawka
2012-04-06 17:44       ` Jens Axboe
2012-04-14  6:45         ` Danny Kukawka
2012-04-14 14:47           ` Jens Axboe
2011-10-14  4:00 Jens Axboe
  -- strict thread matches above, loose matches on Subject: below --
2011-06-28  9:36 Konstantin Belousov
2011-06-28 10:37 ` Chris Wilson
     [not found] <20110125050003.F378B37A302@kernel.dk>
2011-01-27 21:08 ` Steven Pratt
2011-01-27 21:12   ` Jens Axboe
2011-01-27 22:06   ` Bruce Cran
2011-01-28  8:28     ` Jens Axboe
     [not found] <20110114050004.0ECBF37A2F4@kernel.dk>
2011-01-14 11:38 ` Bruce Cran
2011-01-14 11:41   ` Jens Axboe
2010-11-06  5:00 Jens Axboe
     [not found] <869776.96350.qm@web63807.mail.re1.yahoo.com>
2009-04-24  4:40 ` Gurudas Pai
     [not found] <20090409040002.0D18237A271@kernel.dk>
2009-04-17 21:38 ` Girish Satihal
2009-04-18 17:48   ` Jens Axboe
2009-04-20 14:42     ` Girish Satihal
2009-04-20 18:05       ` Jens Axboe
2009-04-20 20:54         ` Girish Satihal
2009-04-21  5:28           ` Jens Axboe
2009-04-21  7:47             ` Jens Axboe
2009-04-21 15:46               ` Girish Satihal
2009-04-21 19:15                 ` Jens Axboe
2009-04-21 22:17                   ` Girish Satihal
2009-04-22  5:46                     ` Jens Axboe
2009-04-22  5:53                       ` Gurudas Pai
2009-04-22 16:46                       ` Girish Satihal
2009-04-22 17:40                         ` Jens Axboe
2007-04-07  3:56 Jens Axboe
2007-04-14  4:00 ` Jens Axboe
2007-04-15  4:00 ` Jens Axboe
2007-04-17  4:00 ` Jens Axboe
2007-04-19  4:00 ` Jens Axboe
2007-05-12  4:00 ` Jens Axboe
2007-05-17  4:00 ` Jens Axboe
2007-05-22  4:00 ` Jens Axboe
2007-05-31  4:00 ` Jens Axboe
2007-06-01  4:00 ` Jens Axboe
2007-06-14  4:00 ` Jens Axboe
2007-07-19  4:00 ` Jens Axboe
2007-07-25  4:00 ` Jens Axboe
2007-07-31  4:00 ` Jens Axboe
2007-08-21  4:00 ` Jens Axboe
2007-08-27  4:00 ` Jens Axboe
2007-08-28  4:00 ` Jens Axboe
2007-08-29  4:00 ` Jens Axboe
2007-09-11  4:00 ` Jens Axboe
2007-10-02  4:00 ` Jens Axboe
2007-10-03  4:00 ` Jens Axboe
2007-10-06  4:00 ` Jens Axboe
2007-10-11  4:00 ` Jens Axboe
2007-10-30  5:00 ` Jens Axboe
2007-11-09  5:00 ` Jens Axboe
2007-11-14  5:00 ` Jens Axboe
2007-11-15  5:00 ` Jens Axboe
2007-12-07  5:00 ` Jens Axboe
2007-12-08  5:00 ` Jens Axboe
2007-12-10  5:00 ` Jens Axboe
2007-12-11  5:00 ` Jens Axboe
2008-01-04  5:00 ` Jens Axboe
2008-02-01  5:00 ` Jens Axboe
2008-02-06  5:00 ` Jens Axboe
2008-02-09  5:00 ` Jens Axboe
2008-02-13  5:00 ` Jens Axboe
2008-02-14  5:00 ` Jens Axboe
2008-02-23  5:00 ` Jens Axboe
2008-04-03  4:00 ` Jens Axboe
2008-04-03  7:04 ` Jens Axboe
2008-05-06  4:00 ` Jens Axboe
2008-05-09  4:00 ` Jens Axboe
2008-05-10  4:00 ` Jens Axboe
2008-05-13  4:00 ` Jens Axboe
2008-05-19  4:00 ` Jens Axboe
2008-05-22  4:00 ` Jens Axboe
2008-05-28  4:00 ` Jens Axboe
2008-07-02  4:00 ` Jens Axboe
2008-08-16  4:00 ` Jens Axboe
2008-09-27  4:00 ` Jens Axboe
2008-10-11  4:00 ` Jens Axboe
2008-10-17  4:00 ` Jens Axboe
2008-10-18  4:00 ` Jens Axboe
2008-10-21  4:00 ` Jens Axboe
2008-10-29  5:00 ` Jens Axboe
2008-10-31  5:00 ` Jens Axboe
2008-11-11  5:00 ` Jens Axboe
2008-11-12  5:00 ` Jens Axboe
2008-11-13  5:00 ` Jens Axboe
2009-01-13  5:00 ` Jens Axboe
2009-01-22  5:00 ` Jens Axboe
2009-01-24  5:00 ` Jens Axboe
2009-02-10  5:00 ` Jens Axboe
2009-02-12  5:00 ` Jens Axboe
2009-02-13  5:00 ` Jens Axboe
2009-02-14  5:00 ` Jens Axboe
2009-02-18  5:00 ` Jens Axboe
2009-02-19  5:00 ` Jens Axboe
2009-03-13  5:00 ` Jens Axboe
2009-03-24  5:00 ` Jens Axboe
2009-03-26  5:00 ` Jens Axboe
2009-03-27  5:00 ` Jens Axboe
2009-04-07  4:00 ` Jens Axboe
2009-04-18  4:00 ` Jens Axboe
2009-04-22  4:00 ` Jens Axboe
2009-05-13  4:00 ` Jens Axboe
2009-08-15  4:00 ` Jens Axboe
2009-09-02  4:00 ` Jens Axboe
2009-10-09  4:00 ` Jens Axboe
2009-10-10  4:00 ` Jens Axboe
2010-02-23  5:00 ` Jens Axboe
2010-03-23  5:00 ` Jens Axboe
2010-04-20  4:00 ` Jens Axboe
2010-04-21  4:00 ` Jens Axboe
2010-09-17  4:00 ` Jens Axboe
2010-10-12 15:38 ` Edward Shishkin
2010-10-12 16:52 ` Jens Axboe
2010-10-23  4:00 ` Jens Axboe
2010-12-02  5:00 ` Jens Axboe
2010-12-20  4:36 ` Duy Le (Dan)
2011-01-12  5:00 ` Jens Axboe
2011-01-15  5:00 ` Jens Axboe
2011-02-10  5:00 ` Jens Axboe
2011-03-17  5:00 ` Jens Axboe
2011-05-27  4:00 ` Jens Axboe
2011-08-04  4:00 ` Jens Axboe
2011-08-04 11:50 ` Edward Shishkin
2011-08-04 12:08 ` Jens Axboe
2011-08-12  4:00 ` Jens Axboe
2012-02-01  5:00 ` Jens Axboe
2012-02-02  5:00 ` Jens Axboe
2012-02-28  5:00 ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.