2026/04/06

Maximizing sshfs throughput in high-speed networks

It takes slightly more than 125 milliseconds to transfer 16MiB of data through a TCP connection over a 1Gib/s link.

The Linux default 128KiB socket receive buffer gets full in ~0.976 milliseconds when receiving from a 1Gib/s link. A receiving process must read the 128KiB socket receive buffer dry at a minimum rate of 1024Hz, in order to be able to receive at the link's 1Gib/s rate at all. Such rate is possible but not sustainable with default distribution kernels and configurations.

CODEL buffer-bloat prevention, aggravated by 128KiB-small default socket buffer sizes (hardly adequate for 1Gib/second links), minimises the network transfer latency at the expense of choking throughput with smaller network adaptor buffers. CODEL is only meaningful when hosts are capable of fully saturating/congesting a network link and it is desirable to minimise latency for the price of lower throughput.

Using sshfs in high-speed local networks demands maximum throughput, rather than low latency — the extreme opposite of CODEL network latency minimisation achieved by making network adaptor buffers tiny.

Tiny buffers minimise Ethernet frame queue sizes and, hence, queuing delays, which throttles senders in connections with flow-control, such as TCP. TCP peers explicitly communicate available receive buffer capacities, so that a TCP sender pauses sending any further TCP segments until the receiver advertises a non-zero receive buffer size.

UDP has no flow-control, so that protocols communicating with UDP datagrams, such as WireGuard, end up hammering the CPU with non-blocking write/send/sendto syscall retries when a tiny network adaptor send buffer gets full and rejects queuing the next Ethernet frame.

ssh compression throughput is limited to ~200MiB/s, when compressing with a CPU core running at 3.5GHz (top cloud CPU cores run at 2.8GHz).

With ssh compression disabled, ssh encryption is the next data transfer bottleneck. No ssh cipher is capable of encrypting/decrypting at or above 1Gib/s rate, apart from aes128-gcm@openssh.com running on CPUs with the AESNI instruction set.

With above facts in mind, maximising throughput for sshfs mounts over 1Gib/s or faster network links requires invoking sshfs with additional option -o compression=no,Ciphers=aes128-gcm@openssh.com to remove ssh data transfer bottlenecks, when AESNI instruction set is available on both peers of an ssh connection.

E.g. before:

sshfs -o reconnect,idmap=user,noatime ...

After:

sshfs -o reconnect,idmap=user,noatime -o compression=no,Ciphers=aes128-gcm@openssh.com ...

Next, maximising the throughput of 1Gib/s or faster network links requires enabling much larger socket buffer sizes, and using much larger socket buffers by default.

Using a much larger sshfs data transfer size per request (than the default 256 FUSE pages, controlled by fs.fuse.max_pages_limit) significantly improves sshfs performance over high-bandwidth network connections too.

These parameters have to be configured with sysctl. E.g.:

# /etc/sysctl.d/98-maximize-net-throughput.conf
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
fs.fuse.max_pages_limit = 32768

Furthermore, enabling Jumbo Ethernet frames reduces the cost/waste of Ethernet frame headers and trailers in large data transfers. Jumbo Ethernet ~9KiB frames improve data transfer speeds by 5-10%, when/if all hosts involved in the particilar route support jumbo Ethernet frame sizes. E.g. both peers in the same network and the switch/router the peers are connected to.

Jumbo Ethernet frames are enabled by explicitly setting connection/link MTU to the maximum MTU supported by particular network adaptors (adaptor's maxmtu in ip -d link show output), instead of default "auto" (1500-byte) MTU in network connection settings.

Wireless adaptors also support Jumbo Frames, contrary to all claims elsewhere. A laptop I type this text on, for example, supports 9216-byte jumbo frames for wired Ethernet and 2304-byte jumbo frames over WiFi.

2026/02/06

Timing multiple commands with time

time vs /bin/time

Bash implements time command:
$ type time
time is a shell keyword

$ time date
Thu  5 Feb 23:05:56 GMT 2026

real	0m0.001s
user	0m0.000s
sys	0m0.001s
Which is different from /bin/time:
$ type /bin/time 
/bin/time is /bin/time

$ /bin/time date
Thu  5 Feb 23:06:00 GMT 2026
0.00user 0.00system 0:00.00elapsed 90%CPU (0avgtext+0avgdata 2016maxresident)k
0inputs+0outputs (0major+91minor)pagefaults 0swaps

In 2026, the above /bin/time default output looks like corrupted gibberish, rather than something formatted nicely for humans to read. Its reported metrics "inputs", "outputs", "avgtext", "avgdata", "swaps" are little more than meaningless and worthless noise in 2026.

Yet, the full report of /bin/time is unmatched by its cheap-and-quick shell keyword knock-offs:

$ /bin/time -v date
Thu  5 Feb 23:06:26 GMT 2026
	Command being timed: "date"
	User time (seconds): 0.00
	System time (seconds): 0.00
	Percent of CPU this job got: 86%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 2016
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 0
	Minor (reclaiming a frame) page faults: 91
	Voluntary context switches: 1
	Involuntary context switches: 0
	Swaps: 0
	File system inputs: 0
	File system outputs: 0
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0

/bin/time -v report is most verbose. With those "Average" metrics with 0 values being in there only to avoid breaking some still existing obsolete software.

/bin/time -p does match the bare output of shell keyword time to prevent POSIX aficionados typing all that extra-verbose POSIX-compliant /bin/sh codes invoking time -p from rioting.

From engineering perspective, it is most desirable to see some of the key metrics /bin/time -v reports above, which shell keyword time does not report. But without having to type anything more beyond the already aggravating enough /bin/time. And that's where environment variable TIME enters ~/.bashrc (which should be always sourced by ~/.bash_profile):

# put this line into /etc/environment or your ~/.bashrc
$ export TIME='Elapsed time %E, user %Us, system %Ss, CPU %P, RSS %MkB, exit-status %x.\n'

With environment variable TIME set as above:

$ /bin/time date
Thu  5 Feb 23:06:33 GMT 2026
Elapsed time 0:00.00, user 0.00s, system 0.00s, CPU 89%, RSS 2016kB, exit-status 0.

Making /bin/time report in one line the wall/user/system times, which shell keyword time reports in multiple lines, most wastefully. As well as CPU and RAM usage, and the exit status.

In other words, setting environment variable TIME makes /bin/time output immediately more useful, insightful and helpful.

Timing multiple commands

Timing one command is easy:
$ /bin/time date
Thu  5 Feb 23:06:27 GMT 2026
Elapsed time 0:00.00, user 0.00s, system 0.00s, CPU 83%, RSS 2016kB, exit-status 0.

Timing multiple commands is harder because /bin/time must start before the first command and terminate after the last. Just prefixing any command line with /bin/time only times a command before the next bash control operator -- a token that performs a control function, ... one of the following symbols: || & && ; ;; ;& ;;& ( ) | |&

For shell pipelines, bash has to create the pipeline consumer process first (the process on the right of pipeline binary operator), and terminate it last. Wrapping multiple commands into a compound list { cmds ; } (wrapping with extra `{`, `;`, `}` tokens), and piping the compound list into that pipeline consumer process | /bin/time cat ends up measuring time from just before the compound list started executing till just after it terminated.

pipefail option must be explicitly enabled to fail on errors earliest instead of ignoring errors silently.

Timing multiple commands:

$ { uname -a && echo && cat /proc/cmdline && echo && make --version ; } | /bin/time cat
Linux supernova2 6.8.0-94-generic #96-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan  9 20:36:55 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux

BOOT_IMAGE=... root=UUID=... ro transparent_hugepage=always mitigations=off iommu=pt amdgpu.aspm=0

GNU Make 4.4.1
...
Elapsed time 0:00.00, user 0.00s, system 0.00s, CPU 0%, RSS 1920kB, exit-status 0.

2010/05/23

Visualize perforce change log with gource

Having seen amazing videos of gource I wanted to vizualize the changelog of the codebase I work on. The only trouble was that gource does not understand perforce change log format directly. Fortunately, gource can read text files where each line is a change to one file in the format "timestamp|author|filename|action|colour".

Perforce logs produced by `p4 describe -s` command have the following format:
Change 106 by max@max_perforce on 2008/10/20 16:17:31
mt makefiles

Affected files ...

... //depot/infra/main/src/infra/Makefile#3 edit
... //depot/infra/main/src/infra/Makefile.mt#3 delete

Which should be converted for gource to:
1224515851|max|M|//depot/infra/main/src/infra/Makefile|
1224515851|max|D|//depot/infra/main/src/infra/Makefile.mt|
It is a two-stage process to convert perforce logs to gource logs. The first stage is to extract perforce logs into a file, because it takes a while and you may like to make several passes over it. It can be done with a couple of lines of bash:
$ p4_head=$(p4 changes -m 1 | { read -a words && echo ${words[1]}; })
$ { for((i = 0; ++i <= p4_head;)); do p4 describe -s $i; done } > p4.log
The second stage is to filter and convert perforce changelog into gsource log. Here is how to convert changes only in //depot/infra/main with the python script I wrote:
$ ./p4-gource.py -p //depot/infra/main -o main.gource p4.log
Now gource can be used to vizualize the changelog:
$ gource --highlight-all-users main.gource

2010/03/23

0 vs NULL in C++

Just thought I'd drop a line.

Consider this snippet:
1 #include <stddef.h> // NULL macro
2 void foo(int);
3 void foo(void*);
4 int main()
5 {
6     foo(0);
7     foo(NULL);
8 }
Compiling it gives an error on line 7:
[max@truth test]$ g++ -Wall -o test test.cc
test.cc: In function ‘int main()’:
test.cc:7: error: call of overloaded ‘foo(NULL)’ is ambiguous
test.cc:2: note: candidates are: void foo(int)
test.cc:3: note:                 void foo(void*)
Why is the error? Is NULL different from 0 in C++? Let's check it out:
[max@truth test]$ g++ -E -dD -Wall test.cc | grep NULL
#undef NULL
#define NULL __null
#undef __need_NULL
So, NULL is defined as a gcc keyword __null. The difference between __null and integer constant 0 is that 0 converts to int more easily than to a pointer, hence foo(0) calls foo(int). Whereas __null is not an integer constant and converts to int and a pointer equally easy, so that the compiler can not figure the best overload of foo() from a set of viable functions foo(int) and void(void*).

Using NULL can be helpful in C++ with function overloading, when 0 can silently convert to int where conversion to a pointer is expected.

2009/12/03

Profiling function calls with Systemtap on Fedora 12

Linux now has Systemtap, a system-wide tool to observe and investigate the inner workings of software stacks. Being similar to DTrace, Systemtap can dynamically instrument the Linux kernel and applications.

Having read an excellent introduction Linux introspection and SystemTap, I tried using it to dynamically instrument an application to profile function call times on Fedora 12. Dynamic instrumentation requires debuginfo to be available for the application being instrumented.

The application that was dynamically instrumented is /bin/ls. It was invoked as `ls -Rl ~/src > /dev/null`.

Here is the output of the profile script:

[max@truth ~]$ uname -a
Linux truth 2.6.31.5-127.fc12.x86_64 #1 SMP Sat Nov 7 21:11:14 EST 2009 x86_64 x86_64 x86_64 GNU/Linux

[max@truth ~]$ stap -V
SystemTap translator/driver (version 1.0/0.143 non-git sources)
Copyright (C) 2005-2009 Red Hat, Inc. and others
This is free software; see the source for copying conditions.

[max@truth ~]$ sudo stap --vp 01 ~/src/systemtap-scripts/profile.stp /bin/ls
Pass 2: analyzed script: 421 probe(s), 4 function(s), 3 embed(s), 3 global(s) in 20usr/0sys/19real ms.
Collecting data for /bin/ls
process 10505 started
process 10505 terminated
978009 calls 11411514046nsec gnu_mbswidth
978009 calls 5095937872nsec mbsnwidth
553455 calls 6516854084nsec xstrcoll_name
553455 calls 2973420055nsec xstrcoll
432234 calls 2443338583nsec human_readable
279432 calls 5578451810nsec format_user_or_group_width
279431 calls 1454525884nsec getuser
279431 calls 1476571224nsec umaxtostr
279431 calls 1462740182nsec getgroup
279430 calls 5592908987nsec format_user_or_group
205189 calls 1096534601nsec xmalloc
165892 calls 2214172043nsec xmemdup
165890 calls 3276158518nsec xstrdup
152831 calls 3470895161nsec quote_name
152831 calls 2164873563nsec quotearg_buffer
152831 calls 857089762nsec quotearg_buffer_restyled
139744 calls 4347714683nsec print_name_with_quoting
139716 calls 25976606795nsec gobble_file
139716 calls 4942869834nsec format_user_width
139716 calls 2251024688nsec file_has_acl
139715 calls 727046826nsec strmode
139715 calls 3132965701nsec align_nstrftime
139715 calls 27707055961nsec print_long_format
139715 calls 1972675668nsec nstrftime
139715 calls 4871097460nsec format_group
139715 calls 4933490513nsec format_user
139715 calls 1627706138nsec filemodestring
139715 calls 818129922nsec strftime_case_
131267 calls 10444585148nsec mpsort_with_tmp
26174 calls 144849501nsec free_pending_ent
26174 calls 500319229nsec hash_find_entry
26174 calls 939925939nsec queue_directory
26174 calls 139966373nsec dev_ino_hash
26172 calls 140919473nsec last_component
16519 calls 87194194nsec dev_ino_compare
13088 calls 9420945286nsec sort_files
13088 calls 1642026249nsec extract_dirs_from_files
13088 calls 9303928062nsec mpsort
13088 calls 82016194nsec clear_files
13087 calls 67338468933nsec print_dir
13087 calls 411821913nsec hash_delete
13087 calls 308501198nsec hash_insert
13087 calls 68924698nsec dev_ino_free
13086 calls 287384316nsec mfile_name_concat
13086 calls 68382189nsec base_len
13086 calls 396034744nsec file_name_concat
13056 calls 28224393588nsec print_current_files
29 calls 323169nsec areadlink_with_size
4 calls 156509nsec xrealloc
2 calls 27356nsec close_stream
2 calls 50274nsec clone_quoting_options
1 calls 41537nsec close_stdout
1 calls 12722nsec xstrtoul
1 calls 6598nsec set_char_quoting
1 calls 12513nsec set_program_name
1 calls 7107nsec check_tuning
1 calls 7215nsec hard_locale
1 calls 7616nsec hash_free
1 calls 9458nsec hash_get_n_entries
1 calls 32489nsec hash_initialize
1 calls 6820nsec get_quoting_style
1 calls 7110nsec gettime
1 calls 9946nsec argmatch
1 calls 6972nsec compute_bucket_size
1 calls 10856nsec human_options
1 calls 20279nsec __xargmatch_internal
It shows the number of calls and the total time spent in a function. The total time function is inclusive, that is, it includes the time a function spent calling other functions.

Here is the script:

[max@truth ~]$ cat ~/src/systemtap-scripts/profile.stp
global gpid = -1
global times, entry

probe begin {
printf("Collecting data for %s\n", @1)
}

probe process(@1).begin {
gpid = pid()
printf("process %u started\n", gpid)
}

probe process(@1).end {
if(gpid != pid())
next

printf("process %u terminated\n", gpid)

foreach(fn in times-)
printf("%6u calls %12unsec %s\n", @count(times[fn]), @sum(times[fn]), fn)
exit()
}

probe process(@1).function("*").call {
now = gettimeofday_ns()
entry[probefunc()] = now
}

probe process(@1).function("*").return {
now = gettimeofday_ns()
time = now - entry[probefunc()]
times[probefunc()] <<< time
}

It looks quite simple.

Systemtap appears to be quite a useful tool, will try to use it more.

2009/11/20

Android and iPhone ping times

Did a quick experiment just for fun.

Compared ping times in a local 802.11g wireless network from a wired desktop (running Fedora 12 (Linux kerner 2.6.31) with Intel E8400 and Marvell 88E8056 Gigabit Ethernet adapter) connected through 100Mbit/s ethernet to a router to the following wireless devices:

  • iPhone 1st Gen, version 2.2 (5G77) (a freedom-friendly build).

  • Android Dep Phone 1 (HTC Dream), firmware 1.6 (Linux kernel 2.6.29).

  • An Intel Centrino notebook running Fedora 11 (Linux kernel 2.6.27) with Pentuim M 1.86GHz running at 798MHz and Intel PRO/Wireless 2200BG Network adapter wireless network adapter.

  • THOMSON ST585 Speedtouch wireless router and ADSL modem, software release 6.2.29.2.

The command I ran was `sudo ping -f -c 1000 <host>`. This command sends 1000 ICMP echo requests to the host with no delay beetween requests (-f stands for flood). ICMP requests are normally handled by the kernel without a roundtrip to a user-land process (might not be true for Symbian OS, which is a joke anyway):

The results follow sorted by the total ping time in the worst-to-best order:

--- iphone ping statistics ---
1000 packets transmitted, 948 received, 5% packet loss, time 3453ms
rtt min/avg/max/mdev = 2.106/2.813/81.745/3.936 ms, pipe 6, ipg/ewma 3.457/2.497 ms

--- android ping statistics ---
1000 packets transmitted, 1000 received, 0% packet loss, time 2480ms
rtt min/avg/max/mdev = 2.117/2.433/16.472/0.779 ms, ipg/ewma 2.483/2.395 ms

--- centrino-notebook ping statistics ---
1000 packets transmitted, 1000 received, 0% packet loss, time 1351ms
rtt min/avg/max/mdev = 1.138/1.335/9.912/0.581 ms, ipg/ewma 1.352/1.208 ms

--- wireless-router ping statistics ---
1000 packets transmitted, 1000 received, 0% packet loss, time 664ms
rtt min/avg/max/mdev = 0.572/0.633/4.329/0.128 ms, ipg/ewma 0.664/0.640 ms

What is interesting about iPhone is that its ping packet loss was normally around ~11% in this test, the 5% above was the least packet loss rate I observed. Another interesting point is that when iPhone screen is off it does not respond to ping at all. It does respond when the screen is on but still locked.

The results are probably of little use, just killed some time for fun formatting this blog in emacs html mode.

2009/11/14

Using Linux ps utility to display the command line of a process

Sometimes it is useful to see the full command line of a process when using Linux ps utility. Linux ps utility obeys COLUMNS environment variable or --columns command line option to limit the line size of the output. The default values are normally too small and cause ps to truncate the command line:
[max@truth ~]$ ps -u $USER -fH
UID PID PPID C STIME TTY TIME CMD
max 7421 7385 0 17:04 ? 00:00:00 gnome-session
max 7527 7421 0 17:04 ? 00:00:02 metacity
max 7539 7421 0 17:04 ? 00:00:00 gnome-panel
max 7540 7421 0 17:04 ? 00:00:00 nautilus
max 7541 7421 0 17:04 ? 00:00:00 /usr/libexec/gdu-notification-
max 7543 7421 0 17:04 ? 00:00:00 /usr/bin/seapplet
max 7544 7421 0 17:04 ? 00:00:00 gnome-power-manager
max 7545 7421 0 17:04 ? 00:00:00 gpk-update-icon
max 7550 7421 0 17:04 ? 00:00:00 bluetooth-applet
max 7551 7421 0 17:04 ? 00:00:00 gnome-volume-control-applet
max 7552 7421 0 17:04 ? 00:00:00 nm-applet --sm-disable
max 7559 7421 0 17:04 ? 00:00:00 kerneloops-applet
max 7561 7421 0 17:04 ? 00:00:00 python /usr/share/system-confi
max 8127 1 0 17:25 ? 00:00:01 gcalctool
max 7942 1 0 17:12 ? 00:00:00 /bin/sh /usr/lib64/firefox-3.5.4
max 7954 7942 2 17:12 ? 00:01:34 /usr/lib64/firefox-3.5.4/firef
max 7774 1 0 17:06 ? 00:00:09 emacs
max 7821 7774 0 17:06 pts/0 00:00:00 /bin/bash --noediting -i
max 8600 7821 0 18:15 pts/0 00:00:00 ps -u max -fH
max 7740 1 0 17:05 ? 00:00:00 gnome-screensaver
max 7730 1 2 17:05 ? 00:01:30 rhythmbox
max 7728 1 0 17:05 ? 00:00:00 /usr/libexec/gvfsd-burn --spawne
max 7719 1 0 17:05 ? 00:00:00 /usr/libexec/notification-area-a
max 7717 1 0 17:05 ? 00:00:02 /usr/libexec/clock-applet --oaf-
max 7715 1 0 17:05 ? 00:00:08 /usr/libexec/multiload-applet-2
max 7711 1 0 17:05 ? 00:00:00 /usr/libexec/cpufreq-applet --oa
max 7708 1 0 17:05 ? 00:00:00 /usr/libexec/wnck-applet --oaf-a
max 7698 1 0 17:04 ? 00:00:00 /usr/libexec/gvfs-gphoto2-volume
max 7693 1 0 17:04 ? 00:00:00 /usr/libexec/gvfs-gdu-volume-mon
max 7691 1 0 17:04 ? 00:00:00 /usr/libexec/bonobo-activation-s
max 7687 1 0 17:04 ? 00:00:00 /usr/libexec/gvfsd-trash --spawn
max 7685 1 0 17:04 ? 00:00:00 /usr/libexec/gconf-im-settings-d
max 7572 1 0 17:04 ? 00:00:00 /usr/libexec/im-settings-daemon
max 7569 1 0 17:04 ? 00:00:00 /usr/libexec/notification-daemon
max 7535 1 0 17:04 ? 00:00:00 /usr/libexec//gvfs-fuse-daemon /
max 7529 1 0 17:04 ? 00:00:00 /usr/libexec/gvfsd
max 7519 1 0 17:04 ? 00:00:00 /usr/libexec/gnome-settings-daem
max 7516 1 0 17:04 ? 00:00:00 /usr/libexec/gconfd-2
max 7433 1 0 17:04 ? 00:00:00 dbus-launch --sh-syntax --exit-w
max 7432 1 0 17:04 ? 00:00:00 /bin/dbus-daemon --fork --print-
max 7405 1 0 17:04 ? 00:00:00 /usr/bin/gnome-keyring-daemon --
max 7320 1 1 17:04 ? 00:01:07 /usr/bin/pulseaudio --start --lo
max 7323 7320 0 17:04 ? 00:00:00 /usr/libexec/pulse/gconf-helpe
The maximum command line length of a process can be read from ARG_MAX sysconf variable
[max@truth ~]$ getconf ARG_MAX
2621440
On my system it is 2.5Mb. The first idea that comes to mind to make ps show the full command line is to pass ARG_MAX (+ some constant for other ps output fields) as the line limit to ps.
[max@truth ~]$ ps -u $USER -fH --columns=`getconf ARG_MAX`
Fix bigness error.
UID PID PPID C STIME TTY TIME CMD
Fix bigness error.
max 7421 7385 0 17:04 ? 00:00:00 gnome-session
Fix bigness error.
max 7527 7421 0 17:04 ? 00:00:02 metacity
Fix bigness error.
...
However, ps does not seem to like the columns value. A quick binary search for the maximum of --columns value reveals:
[max@truth ~]$ ps -u $USER -fH --columns=131073
Fix bigness error.
UID PID PPID C STIME TTY TIME CMD
Fix bigness error.
max 7421 7385 0 17:04 ? 00:00:00 gnome-session
Fix bigness error.
max 7527 7421 0 17:04 ? 00:00:02 metacity
Fix bigness error.
...

[max@truth ~]$ ps -u $USER -fH --columns=131072
UID PID PPID C STIME TTY TIME CMD
max 7421 7385 0 17:04 ? 00:00:00 gnome-session
max 7527 7421 0 17:04 ? 00:00:02 metacity
max 7539 7421 0 17:04 ? 00:00:00 gnome-panel
max 7540 7421 0 17:04 ? 00:00:00 nautilus
max 7541 7421 0 17:04 ? 00:00:00 /usr/libexec/gdu-notification-daemon
max 7543 7421 0 17:04 ? 00:00:00 /usr/bin/seapplet
max 7544 7421 0 17:04 ? 00:00:00 gnome-power-manager
max 7545 7421 0 17:04 ? 00:00:00 gpk-update-icon
max 7550 7421 0 17:04 ? 00:00:00 bluetooth-applet
max 7551 7421 0 17:04 ? 00:00:00 gnome-volume-control-applet
max 7552 7421 0 17:04 ? 00:00:00 nm-applet --sm-disable
max 7559 7421 0 17:04 ? 00:00:00 kerneloops-applet
max 7561 7421 0 17:04 ? 00:00:00 python /usr/share/system-config-printer/applet.py
max 8127 1 0 17:25 ? 00:00:01 gcalctool
max 7942 1 0 17:12 ? 00:00:00 /bin/sh /usr/lib64/firefox-3.5.4/run-mozilla.sh /usr/lib64/firefox-3.5.4/firefox
max 7954 7942 2 17:12 ? 00:01:36 /usr/lib64/firefox-3.5.4/firefox
max 7774 1 0 17:06 ? 00:00:10 emacs
max 7821 7774 0 17:06 pts/0 00:00:00 /bin/bash --noediting -i
max 8629 7821 0 18:21 pts/0 00:00:00 ps -u max -fH --columns=131072
max 7740 1 0 17:05 ? 00:00:00 gnome-screensaver
max 7730 1 2 17:05 ? 00:01:37 rhythmbox
max 7728 1 0 17:05 ? 00:00:00 /usr/libexec/gvfsd-burn --spawner :1.7 /org/gtk/gvfs/exec_spaw/1
max 7719 1 0 17:05 ? 00:00:00 /usr/libexec/notification-area-applet --oaf-activate-iid=OAFIID:GNOME_NotificationAreaApplet_Factory --oaf-ior-fd=27
max 7717 1 0 17:05 ? 00:00:02 /usr/libexec/clock-applet --oaf-activate-iid=OAFIID:GNOME_ClockApplet_Factory --oaf-ior-fd=30
max 7715 1 0 17:05 ? 00:00:09 /usr/libexec/multiload-applet-2 --oaf-activate-iid=OAFIID:GNOME_MultiLoadApplet_Factory --oaf-ior-fd=21
max 7711 1 0 17:05 ? 00:00:00 /usr/libexec/cpufreq-applet --oaf-activate-iid=OAFIID:GNOME_CPUFreqApplet_Factory --oaf-ior-fd=24
max 7708 1 0 17:05 ? 00:00:00 /usr/libexec/wnck-applet --oaf-activate-iid=OAFIID:GNOME_Wncklet_Factory --oaf-ior-fd=18
max 7698 1 0 17:04 ? 00:00:00 /usr/libexec/gvfs-gphoto2-volume-monitor
max 7693 1 0 17:04 ? 00:00:00 /usr/libexec/gvfs-gdu-volume-monitor
max 7691 1 0 17:04 ? 00:00:00 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=19
max 7687 1 0 17:04 ? 00:00:00 /usr/libexec/gvfsd-trash --spawner :1.7 /org/gtk/gvfs/exec_spaw/0
max 7685 1 0 17:04 ? 00:00:00 /usr/libexec/gconf-im-settings-daemon
max 7572 1 0 17:04 ? 00:00:00 /usr/libexec/im-settings-daemon
max 7569 1 0 17:04 ? 00:00:00 /usr/libexec/notification-daemon
max 7535 1 0 17:04 ? 00:00:00 /usr/libexec//gvfs-fuse-daemon /home/max/.gvfs
max 7529 1 0 17:04 ? 00:00:00 /usr/libexec/gvfsd
max 7519 1 0 17:04 ? 00:00:00 /usr/libexec/gnome-settings-daemon
max 7516 1 0 17:04 ? 00:00:00 /usr/libexec/gconfd-2
max 7433 1 0 17:04 ? 00:00:00 dbus-launch --sh-syntax --exit-with-session
max 7432 1 0 17:04 ? 00:00:00 /bin/dbus-daemon --fork --print-pid 9 --print-address 11 --session
max 7405 1 0 17:04 ? 00:00:00 /usr/bin/gnome-keyring-daemon --daemonize --login
max 7320 1 1 17:04 ? 00:01:13 /usr/bin/pulseaudio --start --log-target=syslog
max 7323 7320 0 17:04 ? 00:00:00 /usr/libexec/pulse/gconf-helper
It looks like there is a hardcoded maximum of the line length in Linux Fedora 11 ps utility equal to 128Kb (0x20000 in hex). It would be nice to remove that limit.

p.s.: The lines of this post get truncated when viewed as a web-page using Firefox or Chromium. To view untruncated use an RSS reader, such as Google Reader.

p.p.s.: And yes, I should have updated my Firefox to 3.5.5 which is available on Fedora 11 updates repository now.