<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1864509792735323218</id><updated>2012-01-30T13:26:24.765-08:00</updated><category term='apache'/><category term='mobile'/><category term='linux'/><category term='brics'/><category term='sysadmin'/><category term='javascript'/><category term='java'/><category term='web'/><category term='lttng'/><category term='apple'/><category term='noesis'/><category term='geek'/><category term='cloud'/><category term='django'/><category term='tracing'/><category term='augeas'/><category term='puppet'/><category term='firefox'/><category term='flightbox'/><category term='bcfg2'/><category term='windows'/><category term='network'/><category term='testing'/><category term='ubuntu'/><category term='health'/><category term='xsugar'/><title type='text'>Multivax</title><subtitle type='html'>Q : Ho, mutivax, what is the meaning of life?
&lt;br&gt;
A : 42</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-3241785734094134937</id><published>2012-01-24T20:29:00.000-08:00</published><updated>2012-01-24T20:29:02.834-08:00</updated><title type='text'>TCP socket blocking behavior</title><content type='html'>Here are some experiments results of blocking behavior of TCP applications.&amp;nbsp;Blocking is a special state in which a process is waiting for I/O and removed from the scheduler queue. When the data is available, the process is woken up. In the case of distributed applications, the network latency is likely to cause blocking. To understand the behavior of such applications, a small experiment is made with netcat on Linux. System events are recorded with LTTng and network events are recorded with tcpdump. To simulate the network latency, the Linux traffic shaper is used. Here is the script used as the test case.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;tc qdisc add dev lo root netem delay 100ms&lt;br /&gt;netcat -l localhost 8765 &amp;gt; /dev/null &amp;amp;;&lt;br /&gt;echo "lttng" | netcat localhost 8765&lt;br /&gt;tc qdisc del dev lo root&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here, the traffic shapping command sets the latency of packets to 100ms on the loop-back interface. The first netcat process is configured to listen on port 8765. The server exits immediately when a message is received. Next, the netcat client is spawn and a small string is transfered. The last command removes the traffic shapping configuration. The Linux kernel used is 2.6.38 on x86_64.&lt;br /&gt;&lt;br /&gt;Tracing this script reveal three main blockings, as reported by the blocking analysis module of flightbox.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# server process&lt;br /&gt;Blocking report for task /bin/netcat [7495]&lt;br /&gt;Start            Duration (ms)        Syscall Wakeup&lt;br /&gt;8073461215283          300,873     sys_accept SOFTIRQ&lt;/pre&gt;&lt;pre&gt;# client process&lt;br /&gt;Blocking report for task /bin/netcat [7497]&lt;br /&gt;Start            Duration (ms)        Syscall Wakeup&lt;br /&gt;8073461820815          200,155     sys_select SOFTIRQ&lt;br /&gt;8073662056512          200,135       sys_poll SOFTIRQ&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The next figure shows blockings occurring in the system, including messages sent at each steps.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-wHdHhLWdXvY/Tx9-QK5YygI/AAAAAAAAAdE/-slCzVTWlUU/s1600/tcp-delay.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-wHdHhLWdXvY/Tx9-QK5YygI/AAAAAAAAAdE/-slCzVTWlUU/s1600/tcp-delay.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The server process create a new AF_INET socket, binds it and start to listen on the selected port. The accept is then performed for an incoming connection. From the trace, we observe that&amp;nbsp;sys_accept blocks for about 300ms. This delay is very close to three times the network latency and is also almost equal to the process duration. Once the accept returns, the read on the socket doesn't block and the process exits.&lt;br /&gt;&lt;br /&gt;In the case of the client, it creates the socket, then perform a sys_connect to the server. The connect returns immediately the value EINPROGRESS without blocking. The next step performed is a sys_connect, in which the client blocks for about two times the network latency. When the select returns, the actual message is sent to the server without blocking and the socket is closed. Finally, the client waits on sys_poll for about twice the network delay.&lt;br /&gt;&lt;br /&gt;From this observation, the sys_accept performed by the server blocks until the final handshake ACK is received. Hence, unfinished handshake is completely hidden from the application and handled at the OS level. When the read is done, the data is already buffered, such that the read doesn't block in this case. In the case of the client, the connect system call returns in an optimistic fashion. The wait for the socket to be ready is differed to a select system call. This may allow many connect to be performed simultaneously. As for the poll, this may be related to the tear-down procedure of the socket, waiting for the final FIN from the server.&lt;br /&gt;&lt;br /&gt;In the case of the traffic shaper used, the delay between consecutive packets is preserved. For example, the client sends three packets when the sys_select returns in a short burst.&amp;nbsp;Hence, this experiment may not highlight all possible blockings. An alternative to traffic shaper is the iptables NFQUEUE. It allow to forward each packet in userspace for arbitrary processing. More on this in the next blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-3241785734094134937?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/3241785734094134937/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=3241785734094134937' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3241785734094134937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3241785734094134937'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2012/01/tcp-socket-blocking-behavior.html' title='TCP socket blocking behavior'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-wHdHhLWdXvY/Tx9-QK5YygI/AAAAAAAAAdE/-slCzVTWlUU/s72-c/tcp-delay.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-4444026903312177825</id><published>2011-11-16T08:28:00.000-08:00</published><updated>2011-11-16T08:30:36.492-08:00</updated><title type='text'>Tracing MPI application</title><content type='html'>While preparing labs for the Parallel Systems course at Polytechnique, I had the chance to refresh my MPI knowledge. One of the activity consist to compare communication patterns in a MPI application. For this purpose, the MPI library can be linked with special library to record all communication. Jumpshot is the graphical viewer for the trace. I wanted to compared traces obtained from MPE and compare it to a kernel trace.&lt;br /&gt;&lt;br /&gt;First, some technical details on how to instrument MPI program, because it's not so obvious after all and documentation is sparse. I tried MPICH and OpenMPI as MPI implementation. I would recommend MPICH because it seems to provides better error message, which are very valuable to understand failures. In addition, on Fedora, MPE library is built-in in the MPICH package, which is not the case for OpenMPI. On Ubuntu, MPE library must be downloaded and installed by hand [1] because there is no binary package for it. As for the autoconf for the project, I reused m4 macro cs_mpi.m4 from Code Saturne [2] with the following options to configure. By linking to llmpe, the library will ouput suitable file for Jumpshot. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;CC=mpicc LDFLAGS="-L/usr/local/lib" LIBS="-llmpe -lmpe" ./configure&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The experiment consists in a small MPI application that exchange grid boundaries in 1D cartesian decomposition using blocking send and receive. 4 process are launched on the same host. The first figure shows a zoomed view of execution and messages exchanged between process according to time. The second figure shows a statistic view for an interval, in which the time spent in each state is summed. In one look, one can see what is the relative taken for the communication, which is very handy to understand performance.&lt;br /&gt;&lt;br /&gt;The same application has been traced with the LTTng kernel tracer. While the program is computing and exchanging data with neighbors, no system calls are performed to transfer the data. In fact, between process on the same hosts, MPICH uses shared memory for communication, obviously to achieve better performance. This example shows that it may not be possible to recover relationship between processes that communicates through shared memory. One thing to note is that numerous polls on file descriptors are performed, probably for synchronization. Maybe the relationship can be recovered from there. &lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4Q6hfwIRyZQ/TsPjx79SjEI/AAAAAAAAAcc/ZyqTf_NLim0/s1600/Screenshot-TimeLine-jumpshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="255" src="http://3.bp.blogspot.com/-4Q6hfwIRyZQ/TsPjx79SjEI/AAAAAAAAAcc/ZyqTf_NLim0/s320/Screenshot-TimeLine-jumpshot.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Jumshot Timeline view (green: recv, blue: send)&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-yRakFxBYOQ4/TsPj04H1VpI/AAAAAAAAAck/r2WB_wAdXxg/s1600/Screenshot-Histogram-jumpshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="260" src="http://1.bp.blogspot.com/-yRakFxBYOQ4/TsPj04H1VpI/AAAAAAAAAck/r2WB_wAdXxg/s320/Screenshot-Histogram-jumpshot.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Jumshot Histogram view (green: recv, blue: send)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-9STGvgeeMOs/TsPj8ELYCFI/AAAAAAAAAcs/mcs1AhP4k0U/s1600/MPI-kernel.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="74" src="http://4.bp.blogspot.com/-9STGvgeeMOs/TsPj8ELYCFI/AAAAAAAAAcs/mcs1AhP4k0U/s640/MPI-kernel.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;LTTv control flow view (green: userspace)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Would it be possible to trace shared memory accesses  directly? A recent kernel feature allows to trace memory map I/O  (MMIOTRACE). It works by resetting the flag that indicates a page is in  memory, such that a page fault is triggered each time a page is  accessed. The page fault handler is instrumented to record those events.  This technique may be a hint on how to recover shared memory process  relationship. More on this later.&lt;br /&gt;&lt;br /&gt;In conclusion, MPI  instrumentation with MPE helps to understand runtime performance  behaviour of MPI application. The same results can't be obtained with  the current kernel tracing infrastructure found in LTTng. &lt;br /&gt;&lt;br /&gt;[1] &lt;a href="ftp://ftp.mcs.anl.gov/pub/mpi/mpe/mpe2.tar.gz"&gt;ftp://ftp.mcs.anl.gov/pub/mpi/mpe/mpe2.tar.gz&lt;/a&gt;&lt;br /&gt;[2] &lt;a href="http://research.edf.com/research-and-the-scientific-community/software/code-saturne/introduction-code-saturne-80058.html"&gt;http://research.edf.com/research-and-the-scientific-community/software/code-saturne/introduction-code-saturne-80058.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-4444026903312177825?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/4444026903312177825/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=4444026903312177825' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/4444026903312177825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/4444026903312177825'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/11/tracing-mpi-application.html' title='Tracing MPI application'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-4Q6hfwIRyZQ/TsPjx79SjEI/AAAAAAAAAcc/ZyqTf_NLim0/s72-c/Screenshot-TimeLine-jumpshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-1129201530073643297</id><published>2011-07-26T08:59:00.000-07:00</published><updated>2011-07-26T08:59:23.892-07:00</updated><title type='text'>Common Trace Format Bitfields</title><content type='html'>The &lt;a href="http://http://git.efficios.com/?p=ctf.git;a=blob_plain;f=common-trace-format-specification.txt;hb=HEAD"&gt;Common Trace Format&lt;/a&gt; (CTF) will be the default format of the next release of LTTng 2.0. This new trace format is able to write data at the bit level to optimize space usage of each field. Such sub-byte packed bits is called a bitfield. &lt;br /&gt;&lt;br /&gt;Endianness of the bitfield follows the native endianness of the architecture where the trace is obtained. Big endian (BE) and little endian (LE) are supported. But how does the bits are written into the trace? According to the documentation in include/babeltrace/bitfield.h: &lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size:8pt;"&gt;The inside of a bitfield is from high bits to low bits.&lt;br /&gt;&lt;br /&gt;On big endian, bytes are places from most significant to less significant.&lt;br /&gt;Also, consecutive bitfields are placed from higher to lower bits.&lt;br /&gt;&lt;br /&gt;On little endian, bytes are placed from the less significant to the most&lt;br /&gt;significant. Also, consecutive bitfields are placed from lower bits to higher&lt;br /&gt;bits.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To make sure I understood correctly, I created an example based on the current implementation in babeltrace. The structure has three fields. Each field is followed by it's length in bits.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;struct x {&lt;br /&gt;    unsigned int a : 4;&lt;br /&gt;    unsigned int b : 32;&lt;br /&gt;    unsigned int c : 4;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The total size of the structure is 40 bits or 5 bytes. For the example, following values are assigned to the fields to be able to spot them easily:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;x.a = 0x0000000E;&lt;br /&gt;x.b = 0xA1B2C3D4;&lt;br /&gt;x.c = 0x0000000F;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then, writing those values in a byte array in big and little endian gives the results in the table below. The binary and hexadecimal reprensentation of consecutive bytes are displayed.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;pre&gt;Big endian&lt;br /&gt;0b11101010 0xEA&lt;br /&gt;0b00011011 0x1B&lt;br /&gt;0b00101100 0x2C&lt;br /&gt;0b00111101 0x3D&lt;br /&gt;0b01001111 0x4F&lt;br /&gt;0b00000000 0x00&lt;br /&gt;[...]&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;pre&gt;Little endian&lt;br /&gt;0b01001110 0x4E&lt;br /&gt;0b00111101 0x3D&lt;br /&gt;0b00101100 0x2C&lt;br /&gt;0b00011011 0x1B&lt;br /&gt;0b11111010 0xFA&lt;br /&gt;0b00000000 0x00&lt;br /&gt;[...]&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Big endian is simple, because the bitfield is written sequentially. The first byte 0xEA starts with the four bits if the &lt;i&gt;a&lt;/i&gt; field, followed by the first four bits of the &lt;i&gt;b&lt;/i&gt; field. Notice that in consequence all subsequent bytes of the &lt;i&gt;b&lt;/i&gt; field are shifted. The last byte starts with the last four bits of the &lt;i&gt;b&lt;/i&gt; field. The &lt;i&gt;c&lt;/i&gt; field fills the rest of the last byte. All bytes that follow are untouched.&lt;br /&gt;&lt;br /&gt;As to little endian, the first byte ends with the &lt;i&gt;a&lt;/i&gt; field. Then, the &lt;i&gt;b&lt;/i&gt; field is written, but the most significant bit is found on the second half of the last byte. Notice that tbe bytes and written backwards, also shifted by four bits. The third field &lt;i&gt;c&lt;/i&gt; is placed in the upper half of the last byte.&lt;br /&gt;&lt;br /&gt;Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-1129201530073643297?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/1129201530073643297/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=1129201530073643297' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1129201530073643297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1129201530073643297'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/07/common-trace-format-bitfields.html' title='Common Trace Format Bitfields'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-3732197513956842373</id><published>2011-06-16T18:39:00.001-07:00</published><updated>2011-06-16T18:42:51.684-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Summary of Linux Symposium 2011</title><content type='html'>Linux Symposium took place in Ottawa once again in 2011. I went there for a talk about recovering system metrics from kernel trace. There were interesting talks, here is a summary. &lt;br /&gt;&lt;br /&gt;Hitoshi Mitake explained scalability issues for virtualization on multi-core architecture with real-time constraints. He mentioned that when one of the virtual CPU is interrupted, another virtual CPU may tries to enter section protected by a spin lock, which decrease performance under load. Alternative scheduling of virtual CPU is proposed to avoid such situation.&lt;br /&gt;&lt;br /&gt;Sergey Blagodurov talked about scheduling in NUMA multicore architecture. I learned the numactl system calls that can be used at the userspace level to move process and memory between domains. He was developing scheduler algorithms to optimize performance on this architecture. Since the Linux scheduler can migrate a process, but not the related memory pages, then performance is decreased because the inter-domain communication is increased and is much slower. One of his goal was to increase memory locality for pages that were used frequently.&lt;br /&gt;&lt;br /&gt;One talk has been given about Tilera architecture by Jon C Masters, that includes on a single chip up to 100 cores! This piece of hardware is undoubtedly very special, and I would love to get one on my desk! I wonder how does the Linux kernel can scale up to that number of cores.&lt;br /&gt;&lt;br /&gt;Trinity, which is a system call fuzzer has been presented by Dave Jones. It's basically a tool that perform system calls with randomized arguments, but still looking at edge cases. They found and fixed around 20 weired bugs this way. Code coverage report could be useful in future.&lt;br /&gt;&lt;br /&gt;What about redundant data on a disk? There were a talk about block device deduplication by Kuniyasu Suzaki. The principle is that two identical blocks should not be saved twice. Since it operates at the block level, mileage vary between file systems. The presenter showed principally how much space can be recovered according to block size and file system type. I'm still curious what is the performance impact and CPU overhead of performing deduplication online. &lt;br /&gt;&lt;br /&gt;The last talk I wanted to mention is the one given by Alexandre Lissy, about verifications of the Linux kernel. Static checks like Coccinelle are available right now by running make coccicheck in your linux base source tree. While model checking on the entire kernel would be great to get more guarantees about it's well behavior, the feasibility of it with SAT model checker is another story, because of the size and complexity of the Linux source tree, which is quite an undertaking challenge. Maybe an approach like SLAM from Microsoft, that validates interface usage, could be use for Linux drivers too?&lt;br /&gt;&lt;br /&gt;This Linux Symposium was the opportunity to meet a lot of people involved in the kernel community and share ideas. Here are few links related to the conference.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://research.microsoft.com/en-us/projects/slam/"&gt;http://research.microsoft.com/en-us/projects/slam/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://codemonkey.org.uk/projects/trinity/"&gt;http://codemonkey.org.uk/projects/trinity/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://oss.sgi.com/projects/libnuma/"&gt;http://oss.sgi.com/projects/libnuma/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcl.info.waseda.ac.jp/"&gt;http://www.dcl.info.waseda.ac.jp/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.opendedup.org/"&gt;http://www.opendedup.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.tilera.com/"&gt;http://www.tilera.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.linuxsymposium.org/2011/schedule.php"&gt;http://www.linuxsymposium.org/2011/schedule.php&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-3732197513956842373?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/3732197513956842373/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=3732197513956842373' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3732197513956842373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3732197513956842373'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/06/summary-of-linux-symposium-2011.html' title='Summary of Linux Symposium 2011'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6917586523671576838</id><published>2011-05-21T14:58:00.000-07:00</published><updated>2011-05-21T15:00:38.742-07:00</updated><title type='text'>Performance analysis with kernel trace</title><content type='html'>In this blog, I want to show some progress I made toward providing performance analysis tools for developpers and system administrators. The idea is to answer questions like: &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What is the cause of lattency in the system?&lt;/li&gt;&lt;li&gt;How much resource a task require?&lt;/li&gt;&lt;li&gt;What is the relationship between process?&lt;/li&gt;&lt;li&gt;What is the critical path of a task?&lt;/li&gt;&lt;li&gt;Which subsystem is the bottleneck of the system?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To answer such questions, a kernel trace is an excellent source of system performance data. It has low overhead and provide precise timings information about events occuring on the system. But, get an overview of a system behavior by looking at each individual events is a challenge. We need an analysis toolbox. In the rest of this blog, Four tools are presented with which you can experiement yourself. A summary example is presented to show the integration of various analysis made with flightbox, the prototype implementation.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Resource usage recovery&lt;/h2&gt;The basic metric needed to perform various other analysis is resource usage. CPU usage recovery has already been presented from previous post. The same kind of analysis can be done with memory, disk and network usage. &lt;br /&gt;&lt;br /&gt;In the case of CPU usage, kernel scheduling events indicates the process that drives the CPU. The CPU usage of a process is thus the sum of scheduled time. To display on a chart, CPU usage intervals are decomposed in fixed time range.  An average usage is then easy to compute, and the precision can be increased by reducing the duration of time interval. The technique is presented on the following figure. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-QHX8efBvuVY/Tdgy45teTiI/AAAAAAAAAZM/QNNMvjw123Y/s1600/cpu-usage-rastering.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="162" width="320" src="http://4.bp.blogspot.com/-QHX8efBvuVY/Tdgy45teTiI/AAAAAAAAAZM/QNNMvjw123Y/s320/cpu-usage-rastering.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This technique is known as geometric integration. This computation behaves somewhat like a low-pass filter, by smoothing the raw CPU usage, making it easier to understand. The size of the resulting data is proportional to the trace duration times the desired precision times the number of process, no matter the trace size. In consequence, the CPU usage of a large trace can be summarized with a small array of doubles. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Blocking analysis&lt;/h2&gt;A process is blocked when a resource is not available and it can't progress. For example, we a process perform a read on a socket while the data is not yet received, the process block and the sceduler remove the waiting task from the running queue. Blocking can only occur in kernel mode. The main cause of blocking is in system calls. It can also occur during a page fault for which the page is swapped for example. The following picture shows typical example of blocking. Colors are matching legend in LTTV, green is for running in user mode, blue is for running in system call and red is for blocked on IO. Finally, orange represent the interval while the data is ready, but the process is not yet scheduled.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-sorykq4CbE4/TdgzarwVXUI/AAAAAAAAAZU/qumEcRQrGCU/s1600/blocking-sequence.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="80" width="320" src="http://2.bp.blogspot.com/-sorykq4CbE4/TdgzarwVXUI/AAAAAAAAAZU/qumEcRQrGCU/s320/blocking-sequence.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Some blocking are not necesserely bad. Waiting for user input or a server that waits for a request to come is not important. We are mostly interested on blocking on the critical path of an application, meaning blocking that induce processing delay from the user's point of view.&lt;br /&gt;&lt;br /&gt;While a task is blocked, a subtask can perform some work. This subtask can also block, thus blocking among tasks is hierarchical.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Inter-process relationship&lt;/h2&gt;&lt;br /&gt;Under Linux, process can cooperate with various Inter-Process Communication mechanism, namely: &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Socket&lt;/li&gt;&lt;li&gt;Pipe&lt;/li&gt;&lt;li&gt;Fifo&lt;/li&gt;&lt;li&gt;Mutex&lt;/li&gt;&lt;li&gt;Signal&lt;/li&gt;&lt;li&gt;Shared memory&lt;/li&gt;&lt;li&gt;File lock&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Those mechanism make possible to share resource, send message and data between process. Sockets are well instrumented in the Linux kernel. Hence, it's possible to recover the link between process that use socket to communicate. It works at the host level, but provided traces from many hosts, it would be possible to recover links between distributed components. For example, we could recover process relationship for an httpd client, shown at the following figure.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Y-RC66jr4ok/Tdg0i5UrwOI/AAAAAAAAAZc/t66n9CvZD5g/s1600/http-process-relationship.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="320" src="http://1.bp.blogspot.com/-Y-RC66jr4ok/Tdg0i5UrwOI/AAAAAAAAAZc/t66n9CvZD5g/s320/http-process-relationship.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Resource usage accounting&lt;/h2&gt;&lt;br /&gt;The idea behing resource usage accounting is to associate resource usage of a server to the client that does the request. This analysis is able to compute the cost of some request accros distributed process as if it was performed by only one thread. To perform this analysis, ressource usage, inter-process relationship and blocking analysis are required.&lt;br /&gt;&lt;br /&gt;For example, say that an http client perform a request on a web server. The resulting web page is returned to the client. While waiting for the web page, the http client blocks. By associating the CPU usage of the httpd thread that process the request of the client while it's blocked, the resource usage is effectively accounted to the right process. This is shown by the following figure.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-wDy-V2Q99j8/Tdg1F9rWKSI/AAAAAAAAAZk/hCNuHM4CuhY/s1600/resource-accounting.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="91" width="320" src="http://4.bp.blogspot.com/-wDy-V2Q99j8/Tdg1F9rWKSI/AAAAAAAAAZk/hCNuHM4CuhY/s320/resource-accounting.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Example&lt;/h2&gt;&lt;br /&gt;In the following example, we will use a special RPC client and server, srvhog and clihog from workload-kit. The binary srvhog has two commands, sleep and hog. Each operation takes 100ms. Sleep command is implemented with a timer and doesn't consume CPU, while hog command perform computation that last for the duration. A calibration procedure is performed when srvhog starts to ensure that the hog computation duration is close to 100ms. Communication between client and server is done by a simple TCP socket.&lt;br /&gt;&lt;br /&gt;The following picture shows the CPU usage of the traced system, a host that has two cores, for the hog scenario. The overall CPU usage is shown in blue, while the CPU usage of srvhog is red. The calibration phase of srvhog last for about one second followed by a burst of about 100ms. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-7mWJBPm-Gbo/Tdg1MDq2xaI/AAAAAAAAAZs/lWEuCE4quUo/s1600/Screenshot-Flightbox%2B.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="265" width="320" src="http://1.bp.blogspot.com/-7mWJBPm-Gbo/Tdg1MDq2xaI/AAAAAAAAAZs/lWEuCE4quUo/s320/Screenshot-Flightbox%2B.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The second analysis shows blocking of clihog. It waits on system call read for 101ms, that correspond to the computation time of the server before reply is sent. Other blocking are very small and negligeable.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-hBZkNz1mV-Y/Tdg1R6-aQzI/AAAAAAAAAZ0/XfekcX_dCZg/s1600/Screenshot-Flightbox%2B-1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="128" width="320" src="http://4.bp.blogspot.com/-hBZkNz1mV-Y/Tdg1R6-aQzI/AAAAAAAAAZ0/XfekcX_dCZg/s320/Screenshot-Flightbox%2B-1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;By analyzing socket operations of srvhog and clihog, the following graph can be computed. It shows that the client perform a connection to the server. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-G8IWH6JaieM/Tdg1WVOi0kI/AAAAAAAAAZ8/_24InmeJTi4/s1600/rpc-hog-100ms-task-graph.dot.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="160" width="224" src="http://2.bp.blogspot.com/-G8IWH6JaieM/Tdg1WVOi0kI/AAAAAAAAAZ8/_24InmeJTi4/s320/rpc-hog-100ms-task-graph.dot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Finally, by computing resource accounting, the following report is obtained, showing that the CPU usage of srvhog while processing the request should be really accounted to clihog. CPU usage is almost 90ms, which is close to the expected 100ms and waiting time. The exact CPU usage is closer to 100ms and the error can be explained by the lost of precision while computing average CPU usage. To increase precision, smaller CPU usage intervals can be used.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt"&gt;Report for task pid=2668 cmd=/usr/local/bin/clihog&lt;br /&gt;&lt;br /&gt;File descriptor blocking summary&lt;br /&gt;FD                                       N    Sum (ms)&lt;br /&gt;------------------------------------------------------&lt;br /&gt;132.207.224.50:9876                      2     101,225&lt;br /&gt;&lt;br /&gt;CPU accounting&lt;br /&gt;PID                              Self (ms)    Sub (ms)  Total (ms)&lt;br /&gt;------------------------------------------------------------------&lt;br /&gt;2668 clihog                          2,675      89,797      92,471&lt;br /&gt; \_ 2666 srvhog                     89,797       0,000      89,797&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;Kernel analysis goes well beyong kernel developpers. Kernel trace can be very useful to system administrators and application developpers provided simple analysis tools that abstract trace events and produce meaningfull results to users. &lt;br /&gt;&lt;br /&gt;Try it for yourself, see &lt;a href="https://github.com/giraldeau/flightbox"&gt;flightbox&lt;/a&gt; and &lt;a href="https://github.com/giraldeau/workload-kit"&gt;workload-kit&lt;/a&gt; on github. &lt;br /&gt;&lt;br /&gt;More to come, stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6917586523671576838?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6917586523671576838/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6917586523671576838' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6917586523671576838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6917586523671576838'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/05/performance-analysis-with-kernel-trace.html' title='Performance analysis with kernel trace'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-QHX8efBvuVY/Tdgy45teTiI/AAAAAAAAAZM/QNNMvjw123Y/s72-c/cpu-usage-rastering.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-3612152882234453085</id><published>2011-05-10T13:03:00.001-07:00</published><updated>2011-05-24T13:36:40.847-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><title type='text'>Tracing Workshop '11</title><content type='html'>I assisted to the Tracing Workshop held at the École Polytechnique de Montréal on 9-10 may 2011, here are some highlights of the event. Partners presented their challenges followed by current research conducted in the fields from many Canadian universities. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Partners&lt;/h2&gt;Partners mentioned the interest in security, debugging hardware, real-time systems, embedded systems and large scale distributed infrastructure. &lt;br /&gt;&lt;br /&gt;On the security aspects, the goal would be to increase the accuracy of detecting intrusion. It's reported that simple attacks are often working, like sending an email with a link that loads some browser extension or other web site, up to get the user credentials.&lt;br /&gt;&lt;br /&gt;The need to model normal behavior and alert when the system is going outside of it without false positive has been mentioned a lot.&lt;br /&gt;&lt;br /&gt;In the field of large scale infrastructure, there are needs for understanding the system wide behavior of a distributed system at runtime. This is at the heart of finding problems fast on hard to reproduce problems, including kernel, and apps crash and performance slowdowns.&lt;br /&gt;&lt;br /&gt;Monitoring a system modify the system behavior and the measure itself, even in the computer domain. In the embedded and real-time, first there is the challenge to put an upper bound to tracing impact, to make sure to respect timing constraints, even in the case tracing is enabled.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Research&lt;/h2&gt;Sebastian Fischmeister from the University of Waterloo presented research about using a sampling approach to tracing for real-time systems. He presented an approach to add hardware instruction for tracing, that would run it only if the timing requirements would be met.&lt;br /&gt;&lt;br /&gt;Ashvim Goel from the University of Toronto talked about increasing security by recording all system calls to allow off-line analysis. Data is indexed to allow fast queries.&lt;br /&gt;&lt;br /&gt;Greg Frank from Carleton University presented performance model based on traces. Execution paths at the system level can be modeled by a graph. Graph can be annotated with resource consumption.&lt;br /&gt;&lt;br /&gt;Del Mayers from the University of Victoria presented a reverse engineering tool using tracing. By running the program with the desired functionality, then repeating the scenario without using that particular activity, it's possible to do a difference set operation on called methods and isolate with low noise level the classes and methods that implements this particular functionality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-3612152882234453085?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/3612152882234453085/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=3612152882234453085' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3612152882234453085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3612152882234453085'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/05/tracing-workshop-11.html' title='Tracing Workshop &apos;11'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-7139702630822440383</id><published>2011-02-23T07:37:00.000-08:00</published><updated>2011-02-23T08:47:05.103-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Managing Apache config with Augeas</title><content type='html'>Release 0.8.0 of Augeas includes a special lens for managing Apache web server configuration files. First, we will see how the lens maps sections and directives to the tree. Then, we will review some recepies to modify the configuration and show results.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Quick start&lt;/h2&gt;Apache configuration has two main components. The first component is section, which is similar to XML elements. Sections can be nested and contain directives. Directives are composed of a name and positional arguments.&lt;br /&gt;&lt;br /&gt;As you may know, Apache is very modular. A module can define its own directives and Apache will run the module's callback to parse arguments. This is reflected in the way the configuration is handled in Augeas. The lens is mostly generic and allows arbitrary sections and directives, with arbitrary arguments. Apache allow case insensitive sections are directive. The actual version enforce that open and close tags to be the same case. I recommend to standardize the casing of the configuration for simplicity. Now, let's look at a small example, with one section and one directive. &lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;  ServerAdmin foo@example.org&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This configuration produces the following tree.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;{ "VirtualHost"&lt;br /&gt;    { "arg" = "*:80" }&lt;br /&gt;    { "directive" = "ServerAdmin"&lt;br /&gt;      { "arg" = "foo@example.org" }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's say we want to modify the email address of the server admin, we can do a simple set:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; set "/VirtualHost/*[self::directive='ServerAdmin']/arg" "bar@example.com"&lt;br /&gt;&lt;/pre&gt;To select the ServerAdmin directive, we need to search for it as a child of VirtualHost. We then set the first argument of the corresponding directive to a new value. Here is the resulting diff from the original file. If there are more than one VirtualHost entries in the file, then a simple set will fail, a set multiple (setm) is required to change them all at once.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;$ diff -u httpd.conf httpd.conf.augnew &lt;br /&gt;--- httpd.conf 2011-02-22 22:03:34.000000000 -0500&lt;br /&gt;+++ httpd.conf.augnew 2011-02-22 22:04:34.844099001 -0500&lt;br /&gt;@@ -1,3 +1,3 @@&lt;br /&gt; &amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;-  ServerAdmin foo@example.org&lt;br /&gt;+  ServerAdmin bar@example.org&lt;br /&gt; &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Tree structure&lt;/h2&gt;There are 4 special things to know about the tree structure of apache configuration.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Section names are labels of the tree, they appear on the path.&lt;/li&gt;&lt;li&gt;Directives are held in value of a "directive" node.&lt;/li&gt;&lt;li&gt;Arguments of either sections or directives are held in values of "arg" node.&lt;/li&gt;&lt;li&gt;Arguments nodes must be before any other children.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To demonstrate this, let's create a configuration from scratch, and see it build at each step in augtool. First, launch augtool. I suggest to use the -n option to save to a new file. &lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;$ sudo augtool -n&lt;br /&gt;&lt;/pre&gt;The variable $conf holds the path to the target empty file, for example under Ubuntu it would be:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; defvar conf /files/etc/apache2/sites-available/foo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Step 1: create VirtualHost section&lt;/h3&gt;The clear command empty the value of a node and it create it if the node doesn't exists yet.&lt;br /&gt;Command:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; clear $conf/VirtualHost&lt;br /&gt;&lt;/pre&gt;Result:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost&amp;gt;&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Step 2: Set the argument of VirtualHost section.&lt;/h3&gt;Command:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; set $conf/VirtualHost/arg "172.16.0.1:80"&lt;br /&gt;&lt;/pre&gt;Result:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost 172.16.0.1:80&amp;gt;&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Step 3: Create the ServerAdmin directive under VirtualHost.&lt;/h3&gt;Command:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; set $conf/VirtualHost/directive "ServerAdmin"&lt;br /&gt;&lt;/pre&gt;Result:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost 172.16.0.1:80&amp;gt;&lt;br /&gt;ServerAdmin&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Step 4: Set the ServerAdmin first argument to configure the email.&lt;/h3&gt;Command:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; set $conf/VirtualHost/*[self::directive='ServerAdmin']/arg "baz@example.org"&lt;br /&gt;&lt;/pre&gt;Result:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost 172.16.0.1:80&amp;gt;&lt;br /&gt;ServerAdmin baz@example.org&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;The order matters&lt;/h2&gt;What if we perform step 3 before step 2? Here is the result:&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; set $conf/VirtualHost/directive "ServerAdmin"&lt;br /&gt;augtool&amp;gt; set $conf/VirtualHost/arg "172.16.0.1:80"&lt;br /&gt;augtool&amp;gt; print $conf&lt;br /&gt;/files/etc/apache2/sites-available/foo&lt;br /&gt;/files/etc/apache2/sites-available/foo/VirtualHost&lt;br /&gt;/files/etc/apache2/sites-available/foo/VirtualHost/directive = "ServerAdmin"&lt;br /&gt;/files/etc/apache2/sites-available/foo/VirtualHost/arg = "172.16.0.1:80"&lt;br /&gt;augtool&amp;gt; save&lt;br /&gt;Saving failed&lt;br /&gt;augtool&amp;gt; print /augeas/files/etc/apache2/sites-available/foo/error/message = &lt;br /&gt;&lt;br /&gt;Failed to match ({ /arg/ = /[...]/ }({ /arg/ = /[...]/ })*)?(&amp;lt;&amp;lt;rec&amp;gt;&amp;gt;&lt;br /&gt;| { /directive/ = /[...]/ } | { /#comment/ = /[...]/ } | { })*  &lt;br /&gt;&lt;br /&gt;with tree&lt;br /&gt;&lt;br /&gt;{ \"directive\" = \"ServerAdmin\" } { \"arg\" = \"172.16.0.1:80\" }"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I reformated the error message to highlight why it failed. The lens require "arg" nodes to appear before "directive", "#comment" and empty nodes. In this case, the node "directive" is before the "arg" node, and it doesn't match the tree structure. So, how to make sure that we insert nodes before any other? Here is the twist. First, we will remove the arg node and create it at the right place.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; rm $conf/VirtualHost/arg&lt;br /&gt;rm : $conf/VirtualHost/arg 1&lt;br /&gt;augtool&amp;gt; ins arg before  $conf/VirtualHost/*[1]&lt;br /&gt;augtool&amp;gt; set $conf/VirtualHost/arg "baz@example.org"&lt;br /&gt;augtool&amp;gt; save&lt;br /&gt;Saved 1 file(s)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the corresponding result is the one expected. The predicate [1] will always select the first node in a node set and is equivalent to [position()=1]. There is one gotcha, that is if there are no children under VirtualHost, no node will match and the insert will fail. In this case, a simple set is required.&lt;br /&gt;&lt;br /&gt;Also, take care to set a value to "arg" nodes! Otherwise, Augeas use the section name lens to render it. Here is the result of having an "arg" node with a null value.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;&amp;lt;VirtualHost&amp;gt;&lt;br /&gt;&amp;lt;arg&amp;gt;&lt;br /&gt;&amp;lt;/arg&amp;gt;&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Use cases&lt;/h2&gt;&lt;h3&gt;Modify document root&lt;/h3&gt;The first use case I show is to modify document root in the default configuration of Apache under Ubuntu. The default document root is "/var/www", but say we want to change it to "/srv/www". We have to modify the DocumentRoot directive and one Directory section. I'm using the match command to verify that the right node is selected before applying changes. (sorry for long lines...)&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; match $conf2/VirtualHost/*[self::directive="DocumentRoot"]&lt;br /&gt;/files/etc/apache2/sites-available/default/VirtualHost/directive[2] = DocumentRoot&lt;br /&gt;augtool&amp;gt; set $conf2/VirtualHost/*[self::directive="DocumentRoot"]/arg /srv/www&lt;br /&gt;augtool&amp;gt; match $conf2/VirtualHost/Directory/arg[. = "/var/www/"]&lt;br /&gt;/files/etc/apache2/sites-available/default/VirtualHost/Directory[2]/arg = /var/www/&lt;br /&gt;augtool&amp;gt; set $conf2/VirtualHost/Directory/arg[. = "/var/www/"] "/srv/www/"&lt;br /&gt;augtoo&amp;gt; save&lt;br /&gt;Saved 1 file(s)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is the resulting diff. &lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;--- /etc/apache2/sites-available/default 2011-02-22 23:30:48.000000000 -0500&lt;br /&gt;+++ /etc/apache2/sites-available/default.augnew 2011-02-22 23:48:10.000000000 -0500&lt;br /&gt;@@ -1,12 +1,12 @@&lt;br /&gt; &lt;virtualhost *:80=""&gt;&lt;br /&gt;  ServerAdmin webmaster@localhost&lt;br /&gt; &lt;br /&gt;- DocumentRoot /var/www&lt;br /&gt;+ DocumentRoot /srv/www&lt;br /&gt;  &amp;lt;Directory&amp;gt;&lt;br /&gt;   Options FollowSymLinks&lt;br /&gt;   AllowOverride None&lt;br /&gt;  &amp;lt;/Directory&amp;gt;&lt;br /&gt;- &amp;lt;Directory /var/www/&amp;gt;&lt;br /&gt;+ &amp;lt;Directory /srv/www/&amp;gt;&lt;br /&gt;   Options Indexes FollowSymLinks MultiViews&lt;br /&gt;   AllowOverride None&lt;br /&gt;   Order allow,deny&lt;br /&gt;&lt;/virtualhost&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Changing permissions&lt;/h3&gt;&lt;br /&gt;On Ubuntu, Apache is configured to serve documentation on http://localhost/doc/. We will share this documentation with everybody by changing Order and Allow from directive and delete Deny directive of the doc directory. We are using the regexp function to select the node with or without leading slash and with or without quotes. We remove all arguments of "Allow from" to make sure that arguments are sane. &lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;augtool&amp;gt; match $conf2/VirtualHost/Directory[arg =~ regexp(".*/usr/share/doc.*")]/&lt;br /&gt;/files/etc/apache2/sites-available/default/VirtualHost/Directory[4] = (none)&lt;br /&gt;augtool&amp;gt; defvar dir $conf2/VirtualHost/Directory[arg =~ regexp(".*/usr/share/doc.*")]/&lt;br /&gt;augtool&amp;gt; rm $dir/*[self::directive="Allow"]/arg&lt;br /&gt;augtool&amp;gt; set $dir/*[self::directive="Allow"]/arg[1] from&lt;br /&gt;augtool&amp;gt; set $dir/*[self::directive="Allow"]/arg[2] all&lt;br /&gt;augtool&amp;gt; set $dir/*[self::directive="Order"]/arg[1] "allow,deny"&lt;br /&gt;augtool&amp;gt; rm $dir/*[self::directive="Deny"]&lt;br /&gt;rm : $dir/*[self::directive="Deny"] 3&lt;br /&gt;augtool&amp;gt; save&lt;br /&gt;Saved 1 file(s)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this example, the predicate "*[self::directive='Allow']" can be rewritten "directive[ . = 'Allow']", both are equivalent.&lt;br /&gt;&lt;br /&gt;Here is the resulting diff.&lt;br /&gt;&lt;pre style="font-size: 8pt;"&gt;--- /etc/apache2/sites-available/default 2011-02-22 23:30:48.000000000 -0500&lt;br /&gt;+++ /etc/apache2/sites-available/default.augnew 2011-02-23 00:10:14.000000000 -0500&lt;br /&gt;@@ -33,9 +33,8 @@&lt;br /&gt;     &amp;lt;Directory "/usr/share/doc"&amp;gt;&lt;br /&gt;         Options Indexes MultiViews FollowSymLinks&lt;br /&gt;         AllowOverride None&lt;br /&gt;-        Order deny,allow&lt;br /&gt;-        Deny from all&lt;br /&gt;-        Allow from 127.0.0.0/255.0.0.0 ::1/128&lt;br /&gt;+        Order allow,deny&lt;br /&gt;+        Allow from all&lt;br /&gt;     &amp;lt;/directory&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;Augeas is a very powerful and precise tool to modify Apache configuration file. We can do about any changes with a very simple tree structure. As always, don't forget to reload Apache configuration for changes to take effect. &lt;br /&gt;&lt;br /&gt;Thanks to David Lutterkort, who designed the amazing recursive lens that Apache lens uses and feedback for the square lens, and Raphaël Pinson for the feedback and stress test of the lens on more than 2000 Apache configurations and the help for this blog post. &lt;br /&gt;&lt;br /&gt;Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-7139702630822440383?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/7139702630822440383/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=7139702630822440383' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/7139702630822440383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/7139702630822440383'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/02/managing-apache-config-with-augeas.html' title='Managing Apache config with Augeas'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-1498106723940370154</id><published>2011-01-27T11:19:00.000-08:00</published><updated>2011-02-22T21:55:53.832-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Visiting Event Tracing for Windows</title><content type='html'>In previous posts, we discussed Linux kernel tracing with LTTng. On the Microsoft side, Event Tracing for Windows allows to gather a kernel trace and user space trace. It's advertised as low-impact, lock-less, per-cpu buffers tracer, with live mode and circular buffers option. Quite interesting.&lt;br /&gt;Here is a quick introduction to how to gather a simple trace on Windows 7 Professional and the different analysis we can get.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Installation&lt;/h2&gt;Obviously, you will need a Windows 7 Professional host. I installed it in a Linux KVM virtual machine, with 20GB of storage and with two CPUs emulated, with all default options. &lt;br /&gt;First, &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&amp;amp;FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7"&gt;.NET framework 4&lt;/a&gt; has to be installed, required to install tracing tools bundled with &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b"&gt;Windows SDK&lt;/a&gt;. &lt;br /&gt;In summary, you need to install:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;dotNetFx40_Full_x86_x64&lt;/li&gt;&lt;li&gt;winsdk_web&lt;/li&gt;&lt;/ul&gt;It will install required tools for tracing: xperf, xperfview, tracelog and tracerpt.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Get a trace&lt;/h2&gt;To start tracing, open a console in administration mode, as shown in the following screen shot. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TUGoWk04SyI/AAAAAAAAAW0/dbTfoc8JXdw/s1600/cmd-admin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TUGoWk04SyI/AAAAAAAAAW0/dbTfoc8JXdw/s320/cmd-admin.png" width="255" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We create a trace directory for our experiments, and start and stop a simple trace with tracelog, as shown in the following screen shot. While tracing, you can start programs to create some activity on the system. I started IE and did some random browsing.&lt;br /&gt;&lt;br /&gt;The trace file output is set with "-f" option. If a lot of events occurs, some events can be lost. If such a thing occur, increase the buffers size with "-b" option. Other options are there for some extra trace events, refer to help for more information. To give an idea of the disk requirement, I got a trace of about 20MB for a minute of tracing under light load. The trace file can hence become very big. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TUGrV_o2QlI/AAAAAAAAAW4/MpInNSnSFwM/s1600/tracelog-cmd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TUGrV_o2QlI/AAAAAAAAAW4/MpInNSnSFwM/s320/tracelog-cmd.png" width="298" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If the user doesn't have enough privileges for tracing, the following error message will be raised. Make sure the console is launched as administrator. &lt;br /&gt;&lt;code&gt;&lt;br /&gt;C:\trace&amp;gt;tracelog -f kernel.etl -start&lt;br /&gt;Setting log file to: C:\trace\kernel.etl&lt;br /&gt;Could not start logger: NT Kernel Logger&lt;br /&gt;Operation Status:       5L&lt;br /&gt;Access is denied.&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;h2&gt;Analyze the trace&lt;/h2&gt;Launch xperfview to start the Windows Performance Analyzer. Then, load the trace kernel.etl obtained previously. Here is what it looks like.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_R3p5IPVm8ek/TUGuj6xOjhI/AAAAAAAAAXA/FL7-_7JrFAY/s1600/Screenshot-QEMU-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="246" src="http://2.bp.blogspot.com/_R3p5IPVm8ek/TUGuj6xOjhI/AAAAAAAAAXA/FL7-_7JrFAY/s320/Screenshot-QEMU-2.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Disk access graph and CPU usage according to time and process in xperfview.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R3p5IPVm8ek/TUGulVoD9xI/AAAAAAAAAXE/GWXsEqbZIvg/s1600/Screenshot-QEMU-3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="246" src="http://4.bp.blogspot.com/_R3p5IPVm8ek/TUGulVoD9xI/AAAAAAAAAXE/GWXsEqbZIvg/s320/Screenshot-QEMU-3.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Process life graph and page faults by process according to time in xperfview.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_R3p5IPVm8ek/TUGxKCjpXTI/AAAAAAAAAXM/UnzGia8kGUM/s1600/Screenshot-QEMU-disk-offset.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="246" src="http://3.bp.blogspot.com/_R3p5IPVm8ek/TUGxKCjpXTI/AAAAAAAAAXM/UnzGia8kGUM/s320/Screenshot-QEMU-disk-offset.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Offset of disk access to detect system-wide bad seek behavior. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R3p5IPVm8ek/TUGum5tMazI/AAAAAAAAAXI/LqvMjqw4cyk/s1600/Screenshot-QEMU-4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="246" src="http://4.bp.blogspot.com/_R3p5IPVm8ek/TUGum5tMazI/AAAAAAAAAXI/LqvMjqw4cyk/s320/Screenshot-QEMU-4.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Summary of events count obtained from tracerpt&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;What I like about xperf is the ability to isolate resource usage per process. Also, zooming in a trace is intuitive by selecting with the mouse an interval that seems interesting. Trace events are completely abstracted as chart and statistics. There views are appropriate for understanding overall system performance. Also, when executable symbols are loaded, the call trace performance is available, which may be very handy for the software optimization.&amp;nbsp; &lt;br /&gt;The tracerpt utility outputs reports from a trace file, one is the count of all events and the report in HTML gives the statistics for the whole trace by subsystem. Here is an example of &lt;a href="http://pages.usherbrooke.ca/fgiraldeau/ewt/report.html"&gt;report.html generated with tracerpt&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-1498106723940370154?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/1498106723940370154/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=1498106723940370154' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1498106723940370154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1498106723940370154'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/01/visiting-event-tracing-for-windows.html' title='Visiting Event Tracing for Windows'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_R3p5IPVm8ek/TUGoWk04SyI/AAAAAAAAAW0/dbTfoc8JXdw/s72-c/cmd-admin.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6375794619125353553</id><published>2011-01-07T13:10:00.000-08:00</published><updated>2011-02-22T21:55:59.853-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lttng'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><title type='text'>Tracing a linux cluster</title><content type='html'>Gather traces from multiple machines and then showing them all at once is a real challenge, because each computer has it's own independent clock. It means that two events occurring at the same time on two computers have a low probability to have the same time stamp in the trace. &lt;br /&gt;&lt;br /&gt;Linux Trace Toolkit have a synchronization feature to adjust trace time stamps to a reference trace. It works by matching sent and received network packets found in traces. Two parameters are computed: an offset, but also a drift, that is the rate of clock change.&lt;br /&gt;&lt;br /&gt;To experiment it, I did a virtual Ubuntu cluster of 10 nodes installed with LTTng. Virtual machines are sending each other TCP packets with the small utility &lt;i&gt;pingpong&lt;/i&gt; while tracing is enabled. All traces are then sync to the host for analysis. Here are the results:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-size: 6pt;"&gt;$ lttv -m sync_chain_batch --sync --sync-stats -t trace1 -t trace2 [...]&lt;br /&gt;[...]&lt;br /&gt;Resulting synchronization factors:&lt;br /&gt; trace 0 drift= 1 offset= 6.80407e+09 (2.551684) start time= 2433.182802117&lt;br /&gt; trace 1 drift= 1 offset= 4.12691e+09 (1.547687) start time= 2433.254700670&lt;br /&gt; trace 2 drift= 0.999999 offset= 0 (0.000000) start time= 2433.229372444&lt;br /&gt; trace 3 drift= 1 offset= 1.53079e+09 (0.574083) start time= 2433.366687088&lt;br /&gt; trace 4 drift= 1 offset= 2.31812e+10 (8.693471) start time= 2433.217954184&lt;br /&gt; trace 5 drift= 1 offset= 1.48957e+10 (5.586227) start time= 2433.280525047&lt;br /&gt; trace 6 drift= 1 offset= 1.76688e+10 (6.626211) start time= 2433.291125350&lt;br /&gt; trace 7 drift= 1 offset= 2.0463e+10 (7.674116) start time= 2433.325424020&lt;br /&gt; trace 8 drift= 0.999999 offset= 1.2206e+10 (4.577534) start time= 2433.204361289&lt;br /&gt; trace 9 drift= 1 offset= 9.55947e+09 (3.585022) start time= 2433.293578996&lt;br /&gt;[...]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The trace 2 has been selected as the reference trace. We see inside parenthesis the offset between the current trace and the reference trace. We see a delay between each trace that match the delay between virtual machines startup. When loading these traces into lttv with --sync option, all traces events align perfectly, which is not the case without the sync option.&lt;br /&gt;&lt;br /&gt;If you want to know more about trace synchronization, I recommend the paper &lt;a href="http://dmct.dorsal.polymtl.ca/static/publications/poirier-aos.pdf"&gt;Accurate Offline Synchronization of Distributed Traces Using Kernel-Level Events&lt;/a&gt; from Benjamin Poirier. &lt;br /&gt;&lt;br /&gt;One simple note if you want to do this analysis, you need extended network trace events. To enable them, arm ltt with&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ sudo ltt-armall -n&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I found it really interesting, because it allows to see cluster-wide system state.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6375794619125353553?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6375794619125353553/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6375794619125353553' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6375794619125353553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6375794619125353553'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2011/01/tracing-linux-cluster.html' title='Tracing a linux cluster'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2359367990287504569</id><published>2010-12-09T08:51:00.000-08:00</published><updated>2011-02-22T21:56:08.990-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lttng'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><category scheme='http://www.blogger.com/atom/ns#' term='flightbox'/><title type='text'>CPU history from kernel trace</title><content type='html'>Everybody is familiar with CPU history usage, for example with GNOME monitor. We see the average usage in time. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TQECS1PX--I/AAAAAAAAAWY/HyVp8uPy8W4/s1600/Screenshot-7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="95" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TQECS1PX--I/AAAAAAAAAWY/HyVp8uPy8W4/s320/Screenshot-7.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The GNOME monitor poll /proc/stats at regular interval to compute average usage. This file is updated by the kernel. The values comes from sampling that the kernel does for accounting various process. &lt;br /&gt;&lt;br /&gt;How could we compute the CPU usage history from the actual kernel trace? We only have to look at sched_schedule events. The event inform us that in a certain point in time, the kernel switched the task on a given CPU. If the new task has PID zero, we know that's the idle thread from the kernel. By splitting running and idle time in fixed intervals, we can compute CPU average usage. &lt;br /&gt;&lt;br /&gt;I show one small examples done on my computer that is dual core. First, we see the execution of three cpuburn process started with one second of delay. We can see the result in the control flow viewer in LTTV, and the resulting CPU usage view. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R3p5IPVm8ek/TQEFNju8RFI/AAAAAAAAAWc/xGfFRaIPx4E/s1600/Screenshot-8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="113" src="http://4.bp.blogspot.com/_R3p5IPVm8ek/TQEFNju8RFI/AAAAAAAAAWc/xGfFRaIPx4E/s320/Screenshot-8.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TQEFWoBQrXI/AAAAAAAAAWg/_uHyTWHoK2Y/s1600/burn-2x-1sec.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TQEFWoBQrXI/AAAAAAAAAWg/_uHyTWHoK2Y/s320/burn-2x-1sec.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We see a peek at the beginning of the trace. This is likely to be related to the metadata flushing when a trace is started. The two steps after are related to each cpuburn process, and we see that when the third process is started, the CPU usage stays at 100%.&lt;br /&gt;&lt;br /&gt;For testing, I added scripts to generate those traces automatically on your computer. It's written in Java, and you will need some extra packages to run it, see the README file. Get the code on github:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/giraldeau/flightbox"&gt;https://github.com/giraldeau/flightbox&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2359367990287504569?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2359367990287504569/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2359367990287504569' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2359367990287504569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2359367990287504569'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/12/cpu-history-from-kernel-trace.html' title='CPU history from kernel trace'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_R3p5IPVm8ek/TQECS1PX--I/AAAAAAAAAWY/HyVp8uPy8W4/s72-c/Screenshot-7.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6533292629195554411</id><published>2010-11-12T18:50:00.000-08:00</published><updated>2012-01-30T13:26:24.777-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lttng'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='tracing'/><title type='text'>Introduction to Linux Tracing Toolkit</title><content type='html'>The &lt;a href="http://www.lttng.org/"&gt;Linux Tracing Toolkit next generation&lt;/a&gt; (LTTng) is absolutely amazing. In this introduction, we will look at how to interpret the kernel trace of a small program by comparing it to strace. If you want to install components and get a trace on your own machine, you can get packages for the patched kernel and other tools for Ubuntu Maverick in &lt;a href="https://launchpad.net/~lttng/+archive/ppa"&gt;LTTng's PPA on Launchpad&lt;/a&gt;. You will also need build-essential to compile the small C executable, strace and hexdump. &lt;br /&gt;&lt;br /&gt;Here is the small program. It opens a file and write a integer into it. Then, it adds number in a for loop. &lt;br /&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#define INT_MAX 2147483647&lt;br /&gt;int main(volatile int argc, char **argv) {&lt;br /&gt;    int i = 3;&lt;br /&gt;    FILE *fd = fopen("test.out", "w");&lt;br /&gt;    fwrite(&amp;amp;i, sizeof(int), 1, fd);&lt;br /&gt;    fclose(fd);&lt;br /&gt;    volatile long a;&lt;br /&gt;    int x;&lt;br /&gt;    for (x = 0; x&amp;lt;INT_MAX; x++) {&lt;br /&gt;        a++;&lt;br /&gt;    }&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Compile it, test it and run it under strace:  &lt;br /&gt;&lt;pre&gt;$ gcc -o usecase usecase.c&lt;br /&gt;$ ./usecase&lt;br /&gt;$ strace -o usecase.strace ./usecase&lt;/pre&gt;Ok. Now, let's run the program under tracing, but before, we have to enable all trace points in the kernel.  &lt;br /&gt;&lt;pre&gt;$ sudo ltt-armall&lt;/pre&gt;To get a tight window around the command, I'm using the small script trace-cmd.sh (see at the end of the post). The script simply starts tracing, run the program and stop the trace. Invoke it like this (don't forget to set the script executable):  &lt;br /&gt;&lt;pre&gt;./trace-cmd.sh ./usecase&lt;/pre&gt;Now, we are ready to launch lttv-gui, which is the utility to look at the trace. To load a trace, select File-&amp;gt;Add trace, then select the "trace-cmd" directory created in the same directory as the trace-cmd.sh script. Then, scroll down to the "./usecase" process in the control flow viewer, which is in the middle of the window. Each trace events are displayed under the graph. I will present three phase of the process. First, the creation and file access, then computation phase and the process exit. Trace is rotated to make it more readable. Events name and comments are embedded in the graph. &lt;span style="color: red;"&gt;strace&lt;/span&gt; events are in red, while related &lt;span style="color: blue;"&gt;code&lt;/span&gt; is in blue. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-QLHDanH1L1k/TycK00i8FwI/AAAAAAAAAdU/tbyK64odOks/s1600/trace1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-QLHDanH1L1k/TycK00i8FwI/AAAAAAAAAdU/tbyK64odOks/s320/trace1.png" width="244" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GH6-kRlhk0s/TycK6nwMr9I/AAAAAAAAAdc/tMRhEGGmAbU/s1600/trace2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-GH6-kRlhk0s/TycK6nwMr9I/AAAAAAAAAdc/tMRhEGGmAbU/s320/trace2.png" width="211" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-hjCmO_-Fz_E/TycK-bZNswI/AAAAAAAAAdk/FwYaEz7AV5o/s1600/trace3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-hjCmO_-Fz_E/TycK-bZNswI/AAAAAAAAAdk/FwYaEz7AV5o/s320/trace3.png" width="288" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In addition to system calls, we can look at the paging of an application and see process starvation. This information is not shown by strace. Another cool side effect is that, contrary to strace, the running program can't detect it's under tracing, then we can trace viruses that otherwise quit before they can be analyzed. Tracing reports much more information about kernel internals, which helps a lot to understand what's going on. Events timestamps of the kernel trace are in nanoseconds, so the precision is really high, and since trace points are static (simple function calls compiled right into the kernel), performance impact is ridiculously low, below 3% for core trace points! I'm running LTTng in background on my system without noticeable impact, in flight recorder mode. &lt;br /&gt;&lt;br /&gt;I will be working on advanced trace analysis for the next three years or so for my PhD. Since LTTng got all the feature I need for tracing, I will use this tools. My first goal is to create a CPU usage view. Say that something was eating your CPU a minute ago, then with kernel tracing you would be able to go in the "flight recorder" history and see what was running at that time, and understand what was going on. &lt;br /&gt;&lt;br /&gt;You can help me in two ways. First, by submitting your ideas about cool trace analysis we could perform and/or you need. Second, you can write to Linus Torvalds and ask him to merge LTTng in mainline. LTTng is the right stuff we need for tracing and it's a bit a shame that this not merged yet while other operating systems have this since a decade. &lt;br /&gt;&lt;br /&gt;Next post will be about TMF, an eclipse plugin for trace analysis! Stay tuned!&lt;br /&gt;&lt;br /&gt;Script trace-cmd.sh: &lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;if [ -z "$@" ]; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo "missing command argument"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;cmd="$@"&lt;br /&gt;&lt;br /&gt;name="cmd"&lt;br /&gt;dir="$(pwd)/trace-$name"&lt;br /&gt;sudo rm -rf $dir&lt;br /&gt;sudo lttctl -o channel.all.bufnum=8 -C -w $dir $name&lt;br /&gt;echo "executing $cmd..."&lt;br /&gt;$cmd&lt;br /&gt;echo "return code: $?" &lt;br /&gt;sudo lttctl -D $name&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6533292629195554411?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6533292629195554411/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6533292629195554411' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6533292629195554411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6533292629195554411'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/11/introduction-to-linux-tracing-toolkit.html' title='Introduction to Linux Tracing Toolkit'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-QLHDanH1L1k/TycK00i8FwI/AAAAAAAAAdU/tbyK64odOks/s72-c/trace1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-4616870428813511178</id><published>2010-10-22T13:08:00.000-07:00</published><updated>2011-02-22T21:53:16.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geek'/><title type='text'>Scary pumpkin</title><content type='html'>I left my computer for few minutes to carve the scariest pumpking for any programmer, the Big O factorial time pumpkin!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R3p5IPVm8ek/TMHtQMi-jpI/AAAAAAAAAVk/EBMgWNME-aw/s1600/DSC01730-small.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_R3p5IPVm8ek/TMHtQMi-jpI/AAAAAAAAAVk/EBMgWNME-aw/s1600/DSC01730-small.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;Terrifying, isn't?! Hand carved into a local organic grown pumpkin, low power lightening with LEDs, eatable after use, I'm ready for an happy hacking halloween!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-4616870428813511178?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/4616870428813511178/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=4616870428813511178' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/4616870428813511178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/4616870428813511178'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/10/scary-pumpkin.html' title='Scary pumpkin'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_R3p5IPVm8ek/TMHtQMi-jpI/AAAAAAAAAVk/EBMgWNME-aw/s72-c/DSC01730-small.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-5070135402315603138</id><published>2010-10-08T06:48:00.000-07:00</published><updated>2011-02-22T21:50:50.495-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Augedit: regedit for Linux</title><content type='html'>Few months ago, a prototype of GUI for Augeas was posted on the augeas-devel mailing list. I found it awesome, so I wanted to take it further. I think this is the kind of tool that can easy the configuration management on Linux, like regedit does on Windows. It's still require knowledge of what you're doing, but at least, you don't need to worry about the syntax of a particular config file! Here is a screenshot of the latest version.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TK8eMeLKruI/AAAAAAAAAVg/E3ZARjETIEU/s1600/Capture-Augeas+viewer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TK8eMeLKruI/AAAAAAAAAVg/E3ZARjETIEU/s320/Capture-Augeas+viewer.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;On the left pane, there is a GtkTreeView, that shows the tree path and the corresponding value, if any. Then, on the right pane, there is the actual file, where the label and the value are highlighted. At this early stage, the views are read only, but the goal is to make any side editable and make the changes propagate to the other side.&lt;br /&gt;&lt;br /&gt;Some of ideas that this kind of tool should have: basic edit operations (add, modify, move, delete, ...) searching, filtering, bookmarks, auto-completion. &lt;br /&gt;&lt;br /&gt;If you want to try it, you will need the "myhead" branch of augeas, up to date python-augeas branch "aug_info" that adds the API function for highlighting, and the code of Augedit itself.&lt;br /&gt;&lt;br /&gt;http://github.com/giraldeau/augeas&lt;br /&gt;http://github.com/giraldeau/python-augeas&lt;br /&gt;http://github.com/giraldeau/augedit&lt;br /&gt;&lt;br /&gt;Leave your ideas about this tool in comments! ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-5070135402315603138?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/5070135402315603138/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=5070135402315603138' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/5070135402315603138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/5070135402315603138'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/10/augedit-regedit-for-linux.html' title='Augedit: regedit for Linux'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_R3p5IPVm8ek/TK8eMeLKruI/AAAAAAAAAVg/E3ZARjETIEU/s72-c/Capture-Augeas+viewer.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-1309669334747159428</id><published>2010-09-02T22:21:00.000-07:00</published><updated>2011-02-22T21:57:07.502-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Windows Phone 7 adventure</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_R3p5IPVm8ek/TICFjujF4EI/AAAAAAAAAVQ/o5u794lfOA4/s1600/Capture.PNG" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" ox="true" src="http://2.bp.blogspot.com/_R3p5IPVm8ek/TICFjujF4EI/AAAAAAAAAVQ/o5u794lfOA4/s320/Capture.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;I went to &lt;a href="http://www.startupottawa.com/?p=2699"&gt;Ottawa Mobile Conference&lt;/a&gt;, and I won as a presence prize 2 day training on &lt;a href="http://www.microsoft.com/Windowsmobile/en-us/default.mspx"&gt;Windows Phone 7&lt;/a&gt; (WP7) plateform, at the Microsoft office in Ottawa. The training is provided by Colin Melia from &lt;a href="http://devteach.com/"&gt;DevTeach&lt;/a&gt;, which is knows the plateform very well. This was for me the occasion to get an idea of what it will look like. With the iOS, Android and RIM devices, is there a place for WP7? What it stands for? Millions of theses devices are supposed to hit the market before Thanks Giving in the US, made by Samsung, LG and Dell and others, so it has to be good. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;WP7 is the Microsoft implementation of the whole mobile concept from Apple. Mobile Market is equivalent of AppStore, Zune have the same role as iTunes to sync the device and basic apps are about the same, except they are based on Microsoft technology, for example Internet Explorer replace Safari, Bing map and search replaces Google. A light version of Office and SharePoint may be free on the phone for the release. XboxLive will be the basis for all games on the&amp;nbsp;device.&amp;nbsp;Interesting fact, IE doesn't ship with Flash plugin. Seems that Microsoft agree with Apple on this point. &lt;br /&gt;&lt;br /&gt;Concerning the interface, it uses the design pattern &lt;a href="http://www.time-tripper.com/uipatterns/Hub_and_Spoke"&gt;Hub and Spoke&lt;/a&gt;, that force the user to focus on one task at a time. A tile view of apps acts as the Hub. There are three mandatory physical button on the phone itself: back, start and search. Back goes to the previous view, start goes to the tile view and the search go to Bing. There can't multi-process running simultaneously, the same as the iPhone before multitasking. Say that you start an app, then go to the tile view and start another app, the first app instance is lost. &lt;br /&gt;&lt;br /&gt;You can use two different libraries for an app, &lt;a href="http://en.wikipedia.org/wiki/Silverlight"&gt;Silverlight&lt;/a&gt; for straight forward forms or &lt;a href="http://en.wikipedia.org/wiki/Microsoft_XNA"&gt;XNA&lt;/a&gt; for games that requires more heavy video display. We saw mainly how to use Silverlight to design the UI. The application code can be written in C#, using the .NET framework classes. What is realy interesting is the clear separation between the logic and display of the application. It has been thought in such a way that the designer can work on the view independently of the programmer, that fills the view. Some preview data can be supplied to the view at design time, so the designer doesn't need the whole application to work. The UI is completely defined in &lt;a href="http://en.wikipedia.org/wiki/XAML"&gt;XAML&lt;/a&gt; file in a declarative manner. A factory then read the file at runtime and create corresponding objects. .NET library provides a high level of abstraction for XML handling, HTTP and SQL queries, so in very few lines of code, a lot of things occur. &lt;br /&gt;&lt;br /&gt;For those of you who may want to give it a try, here are some notes about installation on a MacBook Pro 1,1. The &lt;a href="http://msdn.microsoft.com/en-us/library/ff626524(v=VS.92).aspx"&gt;requirement and installation instructions&lt;/a&gt; are accurate. You need the VMX extension for virtualization to get good performances. It has to be enabled into EFI boot loader. See the Parallels knowledge base to &lt;a href="http://kb.parallels.com/en/6831"&gt;get instructions&lt;/a&gt;. Microsoft supplies a small utility to check if the extension is available. But, maybe more critical is this MacBook Pro have an ATI X1600 card, and the &lt;a href="http://support.amd.com/us/gpudownload/windows/Legacy/Pages/radeonaiw_vista32.aspx"&gt;latest (and the last) driver from AMD&lt;/a&gt; doesn't support WDDM 1.1, which is required for decent display performance with the phone emulator. Any computer with proper drivers for Windows 7 should do, it just means I will need a new computer to run the emulator appropriately. &lt;br /&gt;&lt;br /&gt;In conclusion, Microsoft is jumping in the arena seriously with WP7. SDK is quite lean yet, and this is a great piece of integrated technology AFAIK. Their first step is obviously to copy recipies of competitors with their own technology. It's right, because innovation comes a lot from inspiration from others. iPhone is still the blue ocean device, and except for the Office app, there is nothing that a WP7 seems to do better, so the price point must be somewhat attractive to change the market forces. The fate of WP7 is now in the hand of customers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-1309669334747159428?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/1309669334747159428/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=1309669334747159428' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1309669334747159428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1309669334747159428'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/09/windows-phone-7-adventure.html' title='Windows Phone 7 adventure'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_R3p5IPVm8ek/TICFjujF4EI/AAAAAAAAAVQ/o5u794lfOA4/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6964588624181438098</id><published>2010-08-31T11:28:00.000-07:00</published><updated>2011-02-22T21:58:55.950-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>No network, no problem!</title><content type='html'>I got a brand new smart phone, and the first thing I noticed is that it worth nothing without network. Wifi hotspot availability is uncertain, everybody has yet beg someone to get some access. 3G data is still expansive. Roaming above all, at &lt;a href="http://www.wireless.att.com/learn/international/roaming/gophone-international-roaming.jsp"&gt;20$ bucks per megabyte&lt;/a&gt;, could ruine somebody looking at few youtube videos. And even 3G network is not always available, for example in subways, and will make your device as useful as a stone. &lt;br /&gt;&lt;br /&gt;We already know the solution: data cache. At least, a device with some type of cache will be useful at some level. I want to bring with me my own files on any of my devices. This way, we do not rely on the cloud for every lookup, and we can sync with low cost network connexion when it becomes available. Mail is an obvious example of asynchronous system that is working well. With IMAP and a good mail client, you can get a cache of all your emails, read them when offline, even compose an email and send them later when network is back. &lt;br /&gt;&lt;br /&gt;Another drastic example of a device that rely only on a cache is the &lt;a href="http://thewikireader.com/"&gt;WikiReader&lt;/a&gt;, that I bought recently. It has a cache of all 3 millions Wikipedia articles on a 8 Gb SSD card. It can be updated with a computer or by subscribing to an update service by old fashion mail. Never forget that a truck loaded with SSD cards has a lot of bandwith! &lt;br /&gt;&lt;br /&gt;Though, keeping in sync multiple disconnected data sets is harder. Yet, many interesting projects, like the distributed replicated database system &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt;, used in &lt;a href="https://one.ubuntu.com/"&gt;Ubuntu One&lt;/a&gt; for online services, borrow my contacts where ever I need them. At the file system level, I'm using &lt;a href="http://www.dropbox.com/"&gt;Dropbox&lt;/a&gt; that replicates my files on all my devices.&amp;nbsp;Beyong replication, it acts as a continuous&amp;nbsp;backup, so I don't worry anymore with hard drive crashed.&amp;nbsp;Also, &lt;a href="http://www.w3.org/TR/offline-webapps/"&gt;HTML5&lt;/a&gt; cache is a great addition, and can be used to lower your precious G3 bandwith, server load and lower latency. Those are example of disconnected aware cloud services, that I think are going to take off. &lt;br /&gt;&lt;br /&gt;This said, sync all data does make sens only if the device belong to the user for a fair amount of time. In the case of shared workstation, for example a school lab, roaming profiles are known to be a disaster, because the data has to be synchronized from scratch multiple time, and it makes the cache useless. We may think of better synchonization, based on the content the user uses frequently, and fetch other things on demand. But the "keep it simple and stupid" way would be to make user reuse the same computer, or at least the same set of computers, and not flush the cache. Keeping users files on a shared computer is always tricky for privacy reasons, but providing encryption based on the user's credentials could be a solution. Another solution would&amp;nbsp;be to let the student own and borrow their&amp;nbsp;computer. With all those &lt;a href="http://www.linuxfordevices.com/c/a/News/Toshiba-Tablet-Folio-100-Samsung-Galaxy-Tab-and-KT-Identity-Tab/"&gt;Linux mobile tablets&lt;/a&gt; that are going to hit the market soon,&amp;nbsp;I think that it will&amp;nbsp;create a&amp;nbsp;great opportunity for providing affordable computers to each and every students. And with 16Gb of flash storage on basic models, there is enough room to cache almost everything!&amp;nbsp;This way, the cache hit will be much higher, and users will be happier. &lt;br /&gt;&lt;br /&gt;In summary, let's take a GPS as an example. Would you prefer a GPS that downloads all it's bitmap maps just-in-time, that rely heavily on network, or a GPS that is using it's embedded geo data. The later will not work without network, the later is not ofter updated, or even not at all. What I would consider the best design is to get a device with both. The mapping data should be embedded and rendered on the device itself, and this sort of cache should be updated each time you get network. Or even if you don't have all the data, you should be able to select areas to cache.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;In conclusion, the cloud is so fantastic that we sometimes forget that without a link to it, we're screwed. I consider that devices that are not designed to work without network is bad design, and those devices will end into the &lt;a href="http://www.computerhistory.org/"&gt;Computer History Museum&lt;/a&gt; soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6964588624181438098?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6964588624181438098/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6964588624181438098' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6964588624181438098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6964588624181438098'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/08/no-network-no-problem.html' title='No network, no problem!'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2430869289180878186</id><published>2010-08-08T12:28:00.000-07:00</published><updated>2011-02-22T21:51:34.750-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><title type='text'>Firefox memory management nightmare</title><content type='html'>Can you believe that you can crash any linux machine with a web page displaying stamp size images, while an iPod can display it without an glitch? Try this dead page with you browser, that displays large images resized and watch your memory usage.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;WARNING: this page requires ~300Mb RAM to display!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://pages.usherbrooke.ca/fgiraldeau/crashff/" targe="_blank"&gt;https://pages.usherbrooke.ca/fgiraldeau/crashff/&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Ok, what's going on? I did a small utility to monitor the memory usage of Firefox, and the memory usage was quite normal. Where did all this memory allocation occur? After few top, it appears that the Xorg process blew up. Here is a graph that show both process on crashff loading.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R3p5IPVm8ek/TF76lLN_x5I/AAAAAAAAAUk/XLXXP30eyVs/s1600/mem-no-optimize.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_R3p5IPVm8ek/TF76lLN_x5I/AAAAAAAAAUk/XLXXP30eyVs/s320/mem-no-optimize.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Memory consumption for crashff page loading according to time&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The test shows the page loading, opening other tabs and coming back to the original page. The full scale image is transfered to the Xserver for rescaling the image. On localhost, it's fast, but when Firefox is started remotely, then all this data has to be transfered on the network! After a while, the image is flushed from Xserver, and display the tab requires doing all this work again. And because the Xserver allocates the memory, if you run out of memory, the Out Of Memory (OOM) killer of the kernel will be triggered, but it's likely to kill the Xorg process and leads to the user's session lost. This is really critical.&lt;br /&gt;&lt;br /&gt;There is one optimization that may help this, and wanted to know the impact. When setting MOZ_DISABLE_IMAGE_OPTIMIZE to 1, it was supposed to change the behavior. Let see the same experiment with this environment value set.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TF79psFeI5I/AAAAAAAAAUs/hF6PIoU209A/s1600/mem-with-optimize.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TF79psFeI5I/AAAAAAAAAUs/hF6PIoU209A/s320/mem-with-optimize.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Memory consumption for crashff page loading, with optimization, according to time&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Ok, so we see that the Xorg process stays at some low level of memory usage, this time firefox blows up. At least, if the user hits the memory limit, then only the Firefox process gets killed, and the user's session will not crash. &lt;br /&gt;&lt;br /&gt;I did also the test with Opera 10.60.6386 and Konqueror 4.4.2, and the result is mostly the same as with Firefox with optimization. Konqueror uses a less memory, and doesn't deallocate the tab, so when displaying it again, it's really fast. Here are the graphs.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_R3p5IPVm8ek/TF8D_1xyQDI/AAAAAAAAAU0/zJw2CHKCBDU/s1600/mem-opera.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_R3p5IPVm8ek/TF8D_1xyQDI/AAAAAAAAAU0/zJw2CHKCBDU/s320/mem-opera.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_R3p5IPVm8ek/TF8ECwcoeGI/AAAAAAAAAU8/FrVYWbj6iVc/s1600/mem-konqueror.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/TF8ECwcoeGI/AAAAAAAAAU8/FrVYWbj6iVc/s320/mem-konqueror.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;So MOZ_DISABLE_IMAGE_OPTIMIZE does the trick, and IMHO, this option should be the default.&lt;br /&gt;&lt;br /&gt;Note: this blog is related to this firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=395260&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2430869289180878186?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2430869289180878186/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2430869289180878186' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2430869289180878186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2430869289180878186'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/08/firefox-memory-management-nightmare.html' title='Firefox memory management nightmare'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_R3p5IPVm8ek/TF76lLN_x5I/AAAAAAAAAUk/XLXXP30eyVs/s72-c/mem-no-optimize.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-3835347956711540106</id><published>2010-07-03T08:01:00.000-07:00</published><updated>2011-02-22T21:52:41.170-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='health'/><title type='text'>Mouse safety</title><content type='html'>For those of you that are working long hours in front of a computer, you may encounter pain in your wrist at some point. This may be caused by repetitive movement, that creates inflammation of tendon.&lt;br /&gt;&lt;br /&gt;The inflammation can be treated with ice, rest and acetaminophen (paracetamol). But the cause, for me, was the abuse of the scroll wheel. Since I'm avoiding to scroll, my hand and wrist pain diminish progressively.&lt;br /&gt;&lt;br /&gt;Hope that this trick helps you. Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-3835347956711540106?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/3835347956711540106/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=3835347956711540106' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3835347956711540106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/3835347956711540106'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/07/mouse-safety.html' title='Mouse safety'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-759447775157414153</id><published>2010-06-09T11:36:00.000-07:00</published><updated>2010-06-09T11:41:57.673-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>APLWACA what?</title><content type='html'>I went to the conference&lt;i&gt; Analysis and Programming Languages for Web Applications and Cloud Applications &lt;/i&gt;(APLWACA) held in Toronto, and I wanted to share one cool stuff I learned: Javascript security. &lt;br /&gt;&lt;br /&gt;The kenote was about the security of untrusted Javascript that browsers may run. This is actually happenning because trusted website can embedded code from other, like analysis code to gather statistics and display ads. Here are two examples of those threath. &lt;br /&gt;&lt;br /&gt;This code will replace every links in a document to somewhere you don't trust.&lt;br /&gt;&lt;pre&gt;els = document.getElementsByTafName("a"); &lt;br /&gt;for (var el in els) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; el[url] = "http://dangerous-site.com/";&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Another bigger threath is that, if you have an active session with a trusted server, then the actual embedded Javascript code can interact with your session like this: &lt;br /&gt;&lt;pre&gt;var x = window.XMLHttpRequest();&lt;br /&gt;x.open("/account");&lt;br /&gt;x.send("some nasty command");&lt;/pre&gt;&lt;br /&gt;To prevent this, all code from untrusted Javascript should be wrapped to prevent calls to XMLHttpRequest. Here is an actual snippet of code that verify simple lookup o[s].&lt;br /&gt;&lt;pre&gt;lookup function(o, s){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s == "XMLHttpRequest"){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return "Not allowed";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return o[s];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Some implementation of this kind of wrapper exists, like Facebook Javascript, Google Caja and Yahoo ADsafe. But, how can we actually prove that these wrappers are safe, and they really don't allow to execute the XMLHttpRequest? For example, our simple lookup, s may be an object, will not be equal to the searched string and will be evaluated. But then, s.toString() function will be evaluated, and can return "XMLHttpRequest"! &lt;br /&gt;&lt;br /&gt;The solution proposed is to statically typecheck Javascript. String that may evaluates to "XMLHttpRequest" are carried, and then all code is checked to look at unsafe calls that may be made. &lt;br /&gt;&lt;br /&gt;Static typecheck has been performed on ADsafe itself. It showed one possible exploit as far. The result is that it could be possible to prove it's secure. &lt;br /&gt;&lt;br /&gt;In the mean time, disabling Javascript may not be a bad idea after all...!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-759447775157414153?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/759447775157414153/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=759447775157414153' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/759447775157414153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/759447775157414153'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/06/aplwaca-what.html' title='APLWACA what?'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-5270790231225612397</id><published>2010-06-01T10:04:00.000-07:00</published><updated>2011-02-22T21:59:21.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Square lens for Augeas</title><content type='html'>Augeas has the ability to handle XML like tag. Here is an example of how to do it with &lt;i&gt;key&lt;/i&gt; and &lt;i&gt;del&lt;/i&gt; lens in a simplified version for a paragraph tag of an HTML document.&lt;br /&gt;&lt;br /&gt;let para = [ Util.del_str("&amp;lt;") . key "p" . Util.del_str("&amp;gt;") .&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; store /[a-zA-Z0-9 \r\n\t]*/ .&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Util.del_str("&amp;lt;/p&amp;gt;") ]&lt;br /&gt;&lt;br /&gt;That's working fine, but there is a gotcha: we have to list all HTML tags as strings, not as a regexp. Let's create a new version of this lens to process arbitrary tag. &lt;br /&gt;&lt;br /&gt;let tag = [ Util.del_str("&amp;lt;") . key /[a-z]+/ . Util.del_str("&amp;gt;") .&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; store /[a-zA-Z0-9 \r\n\t]*/ .&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  Util.del_str("&amp;lt;/") . del /[a-z]+/ "abc" . Util.del_str("&amp;gt;") ]&lt;br /&gt;&lt;br /&gt;Let see what happens with the tree cases get, put and create.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The get will accept arbitrary tags and set the node label accordingly&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt; ---&amp;gt; {"p" = "text"} &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;The put direction, without updating the label, will yield correct result&lt;/li&gt;&lt;ul&gt;&lt;li&gt;{"p" = "text"} ---&amp;gt; &amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;In the create operation, in the case of a new label, this will yield the default value for the close tag, and this will produce a syntax error&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt; ---&amp;gt; {"p" = "text"} ---&amp;gt; {"b" = "text"} ---&amp;gt; &amp;lt;b&amp;gt;text&amp;lt;/abc&amp;gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;Also, this lens accepts a malformed tags, like "&amp;lt;a&amp;gt;text&amp;lt;/p&amp;gt;", and we should throw an error in this case. &lt;br /&gt;&lt;br /&gt;We need that the closed tag be linked to the key. The &lt;i&gt;square&lt;/i&gt; lens is just about that. Let's rewrite the example with the &lt;i&gt;square&lt;/i&gt; lens. The lens takes two arguments. First, a regexp that describe the tag, and behaves as a key. The other is a lens that represent what's inside the tag.&lt;br /&gt;&lt;br /&gt;let content = Util.del("&amp;gt;") . store /[a-zA-Z0-9 \r\n\t]*/ . Util.del_str("&amp;lt;")&lt;br /&gt;let tag = [ Util.del_str("&amp;lt;") . square /[a-z]+/ content . Util.del_str("&amp;gt;") ]&lt;br /&gt;&lt;br /&gt;The first difference is that, now, the open and close tag are related. In the get direction, we can test that the second tag is the same as the first, and then detect syntax errors in the input document. The other difference is about the create operation in the put direction, because now we can copy the key of the node at the end of the content, and then yield correct behavior.&lt;br /&gt;&lt;br /&gt;"&amp;lt;p&amp;gt;text&amp;lt;/p&amp;gt;" ---&amp;gt; {"p" = "text"} ---&amp;gt; {"b" = "text"} ---&amp;gt; "&amp;lt;b&amp;gt;text&amp;lt;/b&amp;gt;"&lt;br /&gt;&lt;br /&gt;The first lens to benefit from it will be httpd.conf lens. Stay tuned, the patch is cooking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-5270790231225612397?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/5270790231225612397/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=5270790231225612397' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/5270790231225612397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/5270790231225612397'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/06/square-lens-for-augeas.html' title='Square lens for Augeas'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6317396614042224778</id><published>2010-05-14T09:31:00.000-07:00</published><updated>2010-05-14T09:33:44.312-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xsugar'/><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Character feedback for XSugar</title><content type='html'>In the previous post, we showed that embedding white chars inside the XML is not a viable solution for strict bidirectionality. Automaticaly pre-process the modified XML to fix it and make sure it conforms to the stylesheet seems not possible based on the stylesheet itself, because the XML tree and AST tree are both orthogonal and not related to each other. &lt;br /&gt;&lt;br /&gt;How does it works in Augeas? Augeas is based on lenses primitives and combinators. The one we are most interested here is the &lt;b&gt;del&lt;/b&gt; lens. In the put direction, the del lens remove the matched content, and stores in a skeleton. In the put direction, the lens restores the original content from the skeleton or provides a default value in case of a new node. The skeleton values are retreived either by sequence or by key. To understand the difference, let's see what happens in case of a subtree move. If skeleton is aligned by sequence, then deleted content by the del lens will be restored in the order in which it appears in the original document. It means that white chars are sticking in place while the content move. In the case of insert, every record following the insert will be modified and get the previous skeleton value, and the last record will get the default value. This behavior doesn't correspond to minimal edit. A better approach is to use the key alignment. Then, skeleton is matched by key, and the correct original chars are selected even in the case of move, insert or delete of records.&lt;br /&gt;&lt;br /&gt;The idea behind this principle of operation is to create a feedback of the original document to insert previous values when possible, while preserving modifications.&lt;br /&gt;&lt;br /&gt;It's possible to do something similar in XSugar, by working on the AST level. In the rest of this blog, I present the principle of operation, a prototype with basic algorithm, obtained results and conclusion about this solution.&lt;br /&gt;&lt;br /&gt;The goal is to to get back original white chars inside the updated document, without embedding them in the XML document. By using the strict version of the stylesheet, where every items are labeled, the resulting AST preserves every parsed chars, and we call strict nodes those that contains chars that would have been lost otherwise. Then, we could use this strict AST to match nodes from the updated XML and the original document, and then copy only strict elements from the original to the updated document.&lt;br /&gt;&lt;br /&gt;The matching algorithm used to test this hypothesis works as follow. For each node of the first tree, search in the second tree a node where each child labels and text matches, except for strict nodes. The algorithm works by traversing the AST in level order, and has a complexity of O(n^2). &lt;br /&gt;&lt;br /&gt;Here is the expected behavior of this simple algorithm.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Round trip without updating content should restore all original values.&lt;/li&gt;&lt;li&gt;Inserted node should get default values.&lt;/li&gt;&lt;li&gt;Updated nodes should get default values, because they will not match any  previous values. They are handled the same way as an insert. &lt;/li&gt;&lt;li&gt;Moved nodes should get their original values.&lt;/li&gt;&lt;li&gt;Deleted nodes should not render any previous associated value. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To test and highlight the behavior, I modified slightly the students.xsg example. Here is the format of records that the stylesheet parses :&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: center;"&gt;( [0-9]+ [z]+ [0-9]+ [a]+ )* &lt;/div&gt;&lt;br /&gt;Hence, two numbers are separated by space, and multiple records are separated by new line, but "z" represents spaces and "a" represents new line. The default number of z's and a's is one, to show the behavior, we use two and more chars to detect when a default value is inserted. &lt;br /&gt;&lt;br /&gt;A parse tree and a match between original document and updated document in which a record has been deleted is shown in the following figure.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_R3p5IPVm8ek/S-1vnfMZUOI/AAAAAAAAAT4/ES_wbHv4gBk/s1600/merge-AST.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://2.bp.blogspot.com/_R3p5IPVm8ek/S-1vnfMZUOI/AAAAAAAAAT4/ES_wbHv4gBk/s400/merge-AST.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here are the results of tests. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test 1 : round trip without modifications&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;input:&amp;nbsp;&amp;nbsp;   1zz1aa11zzz11aaa111zzzz111aaaa&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;default: 1z1a11z11a111z111a&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merged:&amp;nbsp;  1zz1aa11zzz11aaa111zzzz111aaaa&lt;/div&gt;&lt;br /&gt;All characters are recovered, and the resulting document is exactly the same as the input. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test 2: insert&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;input:&amp;nbsp;&amp;nbsp;   1zz1aa11zzz11aaa111zzzz111aaaa&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;default:  1z1a11z11a99z88a111z111a&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merged:&amp;nbsp; 1zz1aa11zzz11aaa99z88aaaa111zzzz111a&lt;/div&gt;&lt;br /&gt;The new record "99 88" gets a default "z", while the last record gets a default "a". &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test 2 : move&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;input: &amp;nbsp;  1zz1aa11zzz11aaa111zzzz111aaaa&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;default: 1z1a111z111a11z11a&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merged:&amp;nbsp;  1zz1aa111zzzz111aaa11zzz11aaaa&lt;/div&gt;&lt;br /&gt;The moved record gets the right number of "z", but "a" chars keeps their order. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test 4 : delete&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;input:&amp;nbsp;&amp;nbsp;   1zz1aa11zzz11aaa111zzzz111aaaa&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;default: 1z1a111z111a&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;merged:&amp;nbsp;  1zz1aa111zzzz111aaa&lt;/div&gt;&lt;br /&gt;The central record is deleted, and the last record gets 3 a's in place of 4. &lt;br /&gt;&lt;br /&gt;From this results, we can see that strict elements z's are retrieved by keys, and a's by sequence. This is caused by the fact that branch nodes that have only one strict leaf nodes are match by their level in the tree. We can't determine if this node should be matched to the parents, or are themselves a parents for other nodes, and in consequence, sequence match is the only remaining possible match. As I understand, other tree matching algorithms can't address this issue. &lt;br /&gt;&lt;br /&gt;The algorithm can be improved to match nodes by leaf node string similarity, using Levenshtein distance. It may be possible to restore chars from updated nodes. But then, the match will depend on the number of changes made to the document, and a node may match another one more similar, may confuse the user by an apparent non-deterministic behavior and may produce non-minimal edit. &lt;br /&gt;&lt;br /&gt;In conclusion, we showed that it's possible to use the original document to merge back otherwise lost chars. But, alignment of original content is mixed between sequence and key. The user can't control which one will apply. It may lead to non-minimal edit of the resulting file. In that respect, lenses primitives and combinators used in Augeas provides a more predictive behavior, by letting explicitly choose between key or sequence alignment by the lens developer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6317396614042224778?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6317396614042224778/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6317396614042224778' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6317396614042224778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6317396614042224778'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/05/character-feedback-for-xsugar.html' title='Character feedback for XSugar'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_R3p5IPVm8ek/S-1vnfMZUOI/AAAAAAAAAT4/ES_wbHv4gBk/s72-c/merge-AST.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-1509410782126427226</id><published>2010-04-09T12:14:00.000-07:00</published><updated>2010-04-09T12:53:49.156-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xsugar'/><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Limitations of XSugar</title><content type='html'>In previous posts, I explained how XSugar could be used to transform configuration files to XML and back. Preserving white characters (space, tab, carriage return, etc.) is possible by creating special elements to hold them. In a simple round-trip, when the XML document is not modified, it works well. But, there are issues when the XML document is modified. For example, be this simple XML with strict nodes, from the &lt;a href="http://www.brics.dk/xsugar/examples.html"&gt;students example of XSugar&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;students xmlns="http://studentsRus.org/"&amp;gt;&lt;br /&gt;  &amp;lt;student sid="19701234"&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;John Doe&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;email&amp;gt;john_doe@notmail.org&amp;lt;/email&amp;gt;&lt;br /&gt;  &amp;lt;/student&amp;gt;&lt;br /&gt;  &amp;lt;space1&amp;gt; &amp;lt;/space1&amp;gt;&lt;br /&gt;  &amp;lt;space2&amp;gt; &amp;lt;/space2&amp;gt;&lt;br /&gt;  &amp;lt;newline&amp;gt;&lt;br /&gt;&amp;lt;/newline&amp;gt;&lt;br /&gt;  &amp;lt;student sid="19785678"&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;Jane Dow&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;email&amp;gt;dow@bmail.org&amp;lt;/email&amp;gt;&lt;br /&gt;  &amp;lt;/student&amp;gt;&lt;br /&gt;  &amp;lt;space1&amp;gt; &amp;lt;/space1&amp;gt;&lt;br /&gt;  &amp;lt;space2&amp;gt; &amp;lt;/space2&amp;gt;&lt;br /&gt;  &amp;lt;newline&amp;gt;&lt;br /&gt;&amp;lt;/newline&amp;gt;&lt;br /&gt;&amp;lt;/students&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are spaces and newline elements that follow the student record. They are used to restitute the exact formating of the original string. We can then modify an existing value, and spaces will be preserved, and this correspond to a minimal edit. &lt;br /&gt;&lt;br /&gt;But, say another record is inserted after the first student, but before &lt;span style="font-style: italic;"&gt;space1&lt;/span&gt; element, then the first record will see it's spacing reset to default values, and the new inserted element will get the spaces from the first record! This doesn't correspond to minimal edit, and is similar to alignment problem found by&lt;a href="http://alliance.seas.upenn.edu/%7Eharmony/"&gt; Foster et. al. in Boomerang&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If a student element is removed, but spaces elements are left, then it will cause a syntax error according to XSugar stylesheet. If an element is moved, it must inserted to right place in the XML, otherwise syntax error may occur.&lt;br /&gt;&lt;br /&gt;It may be possible to fix the XML before transformation to non-XML, by adding, moving or deleting space elements. The idea to use the original document and the modified one to produce the updated output is already what does a lens, and is exactly what Augeas does. And now, with the introduction of the recursive lens, Augeas is about to support context-free languages, and opens the door to handle the Web server Apache configuration, and many other. &lt;br /&gt;&lt;br /&gt;That's all for now, stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-1509410782126427226?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/1509410782126427226/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=1509410782126427226' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1509410782126427226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1509410782126427226'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/04/limitations-of-xsugar.html' title='Limitations of XSugar'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2976535299827675085</id><published>2010-03-11T20:00:00.000-08:00</published><updated>2011-02-22T21:51:49.557-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xsugar'/><title type='text'>Static validation of strict bidirectionality</title><content type='html'>These days, I had some fun to validate XSugar stylesheet for their strict bidirectional property. XSugar can convert non-XML documents to XML documents, and vice-versa. In theory, you get back exactly the same file if it does a round-trip to and from XML. But, there are few tricky things that prevent it to be exactly the same. XSugar verify statically the reversibility of a stylesheet, by verifying that both grammars are bijections. It means that there is no ambiguity, and so there will be always one way to do the conversion. But, not all stylesheet that are valid in this respect will yield correct behavior when performing actual transformation. The problem is linked to the fact that some white spaces may be lost in the transformation. To understand the problem, I will use a concrete example. &lt;br /&gt;&lt;br /&gt;Say you have the following file, and want to convert it to XML. There are a bloc of numbers lines followed by words lines. Elements are separated by space, and there may be spaces before and after each lines. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp;123&amp;nbsp;&amp;nbsp;456&amp;nbsp;&amp;nbsp;789&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;987&amp;nbsp;&amp;nbsp;654&amp;nbsp;&amp;nbsp;321&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;abc&amp;nbsp;&amp;nbsp;def&amp;nbsp;&amp;nbsp;ghi&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ihg&amp;nbsp;&amp;nbsp;fed&amp;nbsp;&amp;nbsp;cba&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We will convert this file to the following XML. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml&amp;nbsp;version=&amp;quot;1.0&amp;quot;&amp;nbsp;encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;a&amp;nbsp;xmlns:b=&amp;quot;http://udes.ca/noesis&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;123&amp;nbsp;456&amp;nbsp;789&lt;br /&gt;987&amp;nbsp;654&amp;nbsp;321&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;z&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;abc&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;def&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;ghi&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/z&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;z&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;ihg&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;fed&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;y&amp;gt;cba&amp;lt;/y&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/z&amp;gt;&lt;br /&gt;&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The stylesheet looks like this... &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;xmlns:b = &amp;quot;http://udes.ca/noesis&amp;quot;&lt;br /&gt;&lt;br /&gt;NUM = [0-9]+ (MAX)   /* numbers */&lt;br /&gt;ALPHA = [a-zA-Z]+ (MAX) /* letters */&lt;br /&gt;NL   = \n|\r|\r\n   /* mandatory new line */&lt;br /&gt;SP = [ \t]+ (MAX)   /* mandatory white space */&lt;br /&gt;OSP = [ \t]* (MAX)   /* optional white space */&lt;br /&gt;&lt;br /&gt;/* top-level rule : define the whole document */&lt;br /&gt;a : [xs x] [ys y] = &amp;lt;a&amp;gt; [xs x] [ys y] &amp;lt;/&amp;gt;&lt;br /&gt;&lt;br /&gt;/* sequence of lines of numbers separated by space, with optional leading and endin white space  */&lt;br /&gt;xs : [OSP] [ns n1] [OSP] [NL] [xs n2] =  [ns n1] [NL] [xs n2]&lt;br /&gt;: =&lt;br /&gt;&lt;br /&gt;/* numbers sequence */&lt;br /&gt;ns : [NUM num] [SP] [ns n] = [NUM num] [SP] [ns n]&lt;br /&gt;: [NUM num] = [NUM num]&lt;br /&gt;&lt;br /&gt;/* sequence of lines of words separated by space, with optional leading and ending white space */&lt;br /&gt;ys :[OSP] [y y1] [OSP] [NL] [ys y2] = &amp;lt;z&amp;gt; [y y1] &amp;lt;/&amp;gt; [ys y2] &lt;br /&gt;: = &lt;br /&gt;&lt;br /&gt;/* sequence of &amp;lt;y&amp;gt; elements that hold actual words */&lt;br /&gt;y : [ALPHA alpha] [SP] [y y1] = &amp;lt;y&amp;gt; [ALPHA alpha] &amp;lt;/&amp;gt; [y y1]&lt;br /&gt;: [ALPHA alpha] = &amp;lt;y&amp;gt; [ALPHA alpha] &amp;lt;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... and it validates well. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ xsugar -b strict-test3.xsg&lt;br /&gt;Transformation is guaranteed to be reversible!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But, when we actually try to convert the XML back to the non-XML format, we get a parse error on char 74. When activating the debug mode of XSugar, we can see the result of XML normalization, which is a preparation step done before parsing. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Normalized input:&lt;br /&gt;&amp;lt;a&amp;gt;123 456 789&lt;br /&gt;987 654 321&amp;lt;z&amp;gt;&amp;lt;y&amp;gt;abc&amp;lt;/&amp;gt;&amp;lt;y&amp;gt;def&amp;lt;/&amp;gt;&amp;lt;y&amp;gt;ghi&amp;lt;/&amp;gt;&amp;lt;/&amp;gt;&amp;lt;z&amp;gt;&amp;lt;y&amp;gt;ihg&amp;lt;/&amp;gt;&amp;lt;y&amp;gt;fed&amp;lt;/&amp;gt;&amp;lt;y&amp;gt;cba&amp;lt;/&amp;gt;&amp;lt;/&amp;gt;&amp;lt;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We see that spaces and carriage return before and after the number text node are lost. This is because the interleaved text with other element is trimmed. Spaces inside the text are preserved by the trim. This doesn't occur when an element contains only text. The parse error occur because the last mandatory new line is dropped. Let's fix the &lt;span style="font-style:italic;"&gt;xs&lt;/span&gt; rule. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/* sequence of lines of numbers separated by space, with optional leading and endin white space  */&lt;br /&gt;xs : [OSP] [ns n1] [OSP] [NL] [xs n2] =  [ns n1] [NL] [xs n2]&lt;br /&gt;: [OSP] [ns n1] [OSP] [NL] = [ns n1]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This makes the last return carriage optional, and parsing succeed. Let's look at the diff between the result and the original file. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ diff -u strict-test.txt strict-test3.txt.back&lt;br /&gt;--- strict-test.txt 2010-03-05 15:33:52.043893254 -0500&lt;br /&gt;+++ strict-test3.txt.back 2010-03-12 00:23:12.482905316 -0500&lt;br /&gt;@@ -1,4 +1,4 @@&lt;br /&gt;-  123  456  789  &lt;br /&gt;-  987  654  321  &lt;br /&gt;-  abc  def  ghi  &lt;br /&gt;-  ihg  fed  cba  &lt;br /&gt;+123 456 789&lt;br /&gt;+987 654 321&lt;br /&gt;+abc def ghi&lt;br /&gt;+ihg fed cba&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The content is there, but the actual diff shows that every lines are modified. This is because some terminals are not labeled. When this is the case, their values are lost, and example string is generated back when there is not corresponding item. It explains why spaces are all reset to their default values, the empty string for the optional white space, one space for the mandatory white space, and the default carriage return. &lt;br /&gt;&lt;br /&gt;Hence, we have to look at two things to make sure stylesheets are strictly bidirectional.&lt;br /&gt;&lt;br /&gt;First, the easy part, all items in the stylesheet must be labeled. This way, we can be sure the XML document will contain all chars from the input, and no information will be lost. We only have to traverse the stylesheet and make sure that every RegexpTerminal are labeled. &lt;br /&gt;&lt;br /&gt;Second, interleaved text nodes must not begin or end with white characters [&amp;nbsp;\t\r\n], otherwise those chars will be lost. This is harder to do. First, we must detect if an element contains text nodes, elements, or both, from the stylesheet. Determining this for StringTerminal, RegexpTerminal and Element objects is straight forward. First two generate text, while the other yield elements. But, this is non-trivial for Nonterminal objects, because of the recursive nature of these items. The problem is a chicken and egg problem, because to determine the actual possible values for a nonterminal, we have to compute this nonterminal and substitute it's actual value in a recursive rule, which produces a loop. One solution to this problem is to compute the regular approximation of the XML stylesheet rules. It yields an automaton for each nonterminal that accepts a superset of the XML content than the stylesheet allow. Here is an example for the rule &lt;span style="font-style:italic;"&gt;y&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_R3p5IPVm8ek/S5nc12fqaJI/AAAAAAAAATw/dax8xXwkWNM/s1600-h/y-3.dot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 149px; height: 216px;" src="http://1.bp.blogspot.com/_R3p5IPVm8ek/S5nc12fqaJI/AAAAAAAAATw/dax8xXwkWNM/s320/y-3.dot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5447628042000820370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We can know which kind of content this nonterminal have by looking at the transitions of the automaton. In the last example, we know for sure that the nonterminal will yield only elements. The last step is to verify that the interleaved text content beginning and end may overlap with white chars. Here again, regular approximation of nonterminal is used, but this time on the grammar itself. The overlap operator, used for horizontal ambiguity detection, is used. If such overlap exists, such as "WHITE &lt;-&gt; TEXT &lt;-&gt; WHITE", information lost may occur. &lt;br /&gt;&lt;br /&gt;With this new information, developers can adjust the stylesheet to label items and enclose text inside elements and prevent information lost. &lt;br /&gt;&lt;br /&gt;In summary, strict bidirectionality is required to prevent lost information in a transformation round-trip. Information lost can be caused by unlabeled items in the stylesheet, or because of trimming of interleaved text nodes. A method to detect areas that may not be strict, based on regular approximation of the stylesheet and the grammar, using the overlap operator, is proposed. Results from different stylesheets will be given soon. Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2976535299827675085?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2976535299827675085/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2976535299827675085' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2976535299827675085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2976535299827675085'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/03/static-validation-of-strict.html' title='Static validation of strict bidirectionality'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_R3p5IPVm8ek/S5nc12fqaJI/AAAAAAAAATw/dax8xXwkWNM/s72-c/y-3.dot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2728001970021978924</id><published>2010-02-06T15:31:00.000-08:00</published><updated>2011-02-22T21:57:11.577-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Why iPad is Evil</title><content type='html'>Apple just launched the iPad last week, and I was a bit shaken by it. It's a piece of art of human interaction design, and it changes the relation we could have with a computer, more ubiquitous than ever. The device itself is amazing at the technical level, and set the bar for competitors. &lt;br /&gt;&lt;br /&gt;But, let's think about the concept in a whole. Apple provides stores for music, books and applications. In fact, this device is a personal buying device, where you can buy only content provided by Apple and it's partner. It's a kind of perfect world, where the consumer is captive like anything ever before, a garden of pure ideology, in each one may bloom, secure, away from the pests, and ... wait a minute! Doesn't it makes you think about 1984? &lt;br /&gt;&lt;br /&gt;http://www.youtube.com/watch?v=OYecfV3ubP8&lt;br /&gt;&lt;br /&gt;What a closed world we would be in if Apple had dominated the market, closed hardware, closed software, and forced to buy content from Apple! &lt;br /&gt;&lt;br /&gt;So, I say no to that iPad, and I will wait for an truly open platform.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2728001970021978924?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2728001970021978924/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2728001970021978924' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2728001970021978924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2728001970021978924'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2010/02/why-ipad-is-evil.html' title='Why iPad is Evil'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-130240571497260801</id><published>2009-12-23T13:26:00.000-08:00</published><updated>2011-02-22T21:57:15.222-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xsugar'/><category scheme='http://www.blogger.com/atom/ns#' term='noesis'/><title type='text'>Strict reversibility in XSugar</title><content type='html'>XSugar is a tool to do bidirectional transformations between two file format. This is particulary useful to provide common API to configuration files under Linux. For example, here is the result of a stylesheet on /etc/hosts file :&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&amp;lt;hosts xmlns="http://usherbrooke.ca/"&amp;gt;&lt;br /&gt;&amp;lt;record&amp;gt;&lt;br /&gt;&amp;lt;ipaddr&amp;gt;127.0.0.1&amp;lt;/ipaddr&amp;gt;&lt;br /&gt;&amp;lt;canonical&amp;gt;localhost&amp;lt;/canonical&amp;gt;&lt;br /&gt;&amp;lt;/record&amp;gt;&lt;br /&gt;&amp;lt;/hosts&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This file can be converted back to it's flat format. But, as you may notice, indentation doesn't appears in the XML file, and will be lost. Spacing is reset to a default value. The round-trip between hosts file and XML format keeps the semantic, but looses formating. Even without modification, if the file is written back, diff will show changes. Once spaces are reset, round-trip will yield identity function i.e. strings will be exactly the same.&lt;br /&gt;&lt;br /&gt;One solution to overcome this problem is to add to the XML all elements that would be lost otherwise. This can be done by labeling terminal elements, and add corresponding nodes to XML part of the stylesheet. For examples, this rule loose optional "a" header :&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;A = [a]*&lt;br /&gt;X = [x]+&lt;br /&gt;n : [A] [X x] "z" = &amp;lt;x&amp;gt; [X x] &amp;lt;/x&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Providing input "aaaaxxz" will give the following XML :&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;x&amp;gt;xx&amp;lt;/x&amp;gt;&lt;/span&gt;&lt;br /&gt;Converting it back to non-XML will yield the string "xxz". Since the empty string matches "[a]*", this is the default string that is returned. &lt;br /&gt;&lt;br /&gt;Now, let's label the terminal "A" : &lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;A = [a]*&lt;br /&gt;X = [x]+&lt;br /&gt;n : [A a] [X x] "z" = &amp;lt;x&amp;gt; [X x] &amp;lt;a&amp;gt; [A a] &amp;lt;a&amp;gt;&amp;lt;/x&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Now, we get the string &lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;x&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xx&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;a&amp;gt;aaaa&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/x&amp;gt;&lt;/span&gt;&lt;br /&gt;and converting it back to non-XML format yield "aaaaxxz", the exact same string as the original input.&lt;br /&gt;&lt;br /&gt;Preserving semantic of the file is simple bidirectional property. In addition, if the stylesheet preserve the concrete representation of an input, I call this strict bidirectionality.&lt;br /&gt;&lt;br /&gt;Strict bidirectionality can be achieved by labeling unlabeled terminal, and add corresponding element to the XML part. I did a small prototype of this algorithm, that augment the resulting stylesheet. Hence, any stylesheet can be made strict bidirectional. &lt;br /&gt;&lt;br /&gt;It rises the question : can we staticaly verify that a stylesheet is strictly bidirectional. Hopefully yes, it's really simple. We have to do the basic check that the stylesheet is bidirectional, and then verify that all regular expression terminal are labeled. This way, we are sure that all the variable concrete string will be represented in the XML. &lt;br /&gt;&lt;br /&gt;Automatic strict bidirectionality for stylesheet and static validation of this property will be useful to provide the behavior a system administrator would expect from a tool that modify configuration files under Linux. Let's go on!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-130240571497260801?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/130240571497260801/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=130240571497260801' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/130240571497260801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/130240571497260801'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/12/strict-reversibility-in-xsugar.html' title='Strict reversibility in XSugar'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6370153274512609504</id><published>2009-12-18T07:45:00.000-08:00</published><updated>2011-02-22T21:57:38.758-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bcfg2'/><category scheme='http://www.blogger.com/atom/ns#' term='puppet'/><category scheme='http://www.blogger.com/atom/ns#' term='sysadmin'/><title type='text'>Bcfg2 V.S. Puppet</title><content type='html'>Bcfg2 and Puppets are two tools for system configuration management, where we want to install configuration files, packages and adjust permissions. It seems simple said like this, but it's near from trivial when the target machines are various operating system and versions.&lt;br /&gt;&lt;br /&gt;Bcfg2 and Puppet, while they share the same goal, are completely different in terms of their concepts, how does the desired state is modeled. The fundamental concept here is more important than the actual implementation.&lt;br /&gt;&lt;br /&gt;Puppet is like a programming language for system administration. It's another meta-language, with it's own syntax, to indicate what files, packages, users and such, should be present on a system. It's concepts are very close to Cfengine. Well, I used Cfengine a lot, even developing a small utility to automating the management of files under Subversion (&lt;a href="http://pulseaudio.revolutionlinux.com/Svnengine"&gt;svnengine&lt;/a&gt;). But, while using this tool, I really came to one simple conclusion : what a mess for so little! I ended up doing everything in scripts, which are copied by cfengine and run in a cron. Big deal.&lt;br /&gt;&lt;br /&gt;Bcfg2 is not the same, because unlike Puppet, you don't program configuration elements, they are declared in XML document. The client, specific to a target, encapsulate actions on that target, their sequencing, error handling, etc. This model enables advanced behavior, because the model can be manipulated programmatically, which is not the case for Puppet. If you want to output a Puppet manifest, you have to output strings, which is a Middle Age practice!&lt;br /&gt;&lt;br /&gt;Bcfg2 implementation itself has some glitches that must be fixed, but the concept behind it represents a building block for semantic system configuration management, which represent the future. Bcfg2 belongs to scientific field, while I think that Puppet has the exposure it has now because of marketing wave.&lt;br /&gt;&lt;br /&gt;But, as the history reminds us, it's not always the best product or software that wins...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6370153274512609504?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6370153274512609504/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6370153274512609504' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6370153274512609504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6370153274512609504'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/12/bcfg2-vs-puppet.html' title='Bcfg2 V.S. Puppet'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-8384097055199479955</id><published>2009-10-17T14:24:00.000-07:00</published><updated>2011-02-22T21:55:20.814-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Pragmatic testing</title><content type='html'>It's certainly a matter of fact that good practice in software development include automated testing. Developing without unit tests is stone age practice. I read few books about testing, and many of them are about writing bureaucracy plans, not code. Reading documentation about unit testing framework doesn't provide much information about how to design tests. Here are few learnings from my experience.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Automated tests should be easy to write and run. If they are hard to run, if they require a special manual setup, then they will be run infrequently. If you need a database or a daemon, it should be setup and launched automatically on localhost by test running scripts. Default config that just work should be provided to avoid configuration mess. Document needed packages from known archives to run tests, that may be different than running or compiling the software.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Take care to apparmor when trying to launch a daemon with unusual locations : it may fail to start because of security restrictions. Disabling it may be necessary in some conditions.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the program operates on file, then create them in a temporary directory, flushed at each run. A program that copy files is testable : execute the operation and verify that files are where they should be.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Running tests should be fast. if testing requires few minutes each time, and you are interested only to the result of one of them, it's not efficient. A simple solution is to provide a way to test only a subset of all tests. &lt;/li&gt;&lt;li&gt;Running tests should usually not require root access, excepted for special purpose. If you bind ports, use a port over 1024 to avoid restrictions. Don't use global settings, use relative path to settings and files. If you get data from system library, you can simulate obtained data by providing objects with the same interface.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Software always operates on data. You will need test data that simulate possible inputs. If your application reads input files, then those files should be held beside test code. &lt;/li&gt;&lt;li&gt;One tests should not depend on previous test to succeed, they should be independent. In other words, the result should not depend on the order in which tests are executed. To make sure that tests are not linked together, always start from a known state. It means reloading initial data for each test, recreating objects and such. This is conveniently done with setup and tear down method usually available from unit testing framework.&lt;/li&gt;&lt;li&gt;Test Driven Development is about creating test and code for some functionality together. This is the basic thing to do to make sure at least it works. Testing can go further for critical code, by trying to break the code, use it in ways that it may not have been thought by programmers. This kind of tests needs a different point of view, and should be done by someone else. &lt;/li&gt;&lt;li&gt;Don't depend on external services. Tests environment should be self-contained, and running tests should be possible without network access. This may not be possible for all situations, for example if the application is interacting with google API, we can do the assumption that the service will be available, and anyway, we can't reproduce the service on localhost. But providing local servers when possible limit dependencies to run tests, and avoid network delays.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I hope that these few advices will help you build better testing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-8384097055199479955?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/8384097055199479955/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=8384097055199479955' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/8384097055199479955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/8384097055199479955'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/10/pragmatic-testing.html' title='Pragmatic testing'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-7628076961995961911</id><published>2009-10-04T20:51:00.000-07:00</published><updated>2009-12-23T13:25:24.710-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><title type='text'>Django, soooo cool</title><content type='html'>A log time ago, I did a small form in PHP to feed data in a database. I did create the HTML form and the database schema, wrote small functions to validate the form, all inside one php page. SQL statements, fields names and everything else was hardcoded, and it was a nightmare to test and maintain. I was feeling like a prehistoric men, who was trying to survive with rudiment tools. Well, it was the old days.&lt;br /&gt;&lt;br /&gt;Now, I had a revelation while using Django! Don't loose your time with other crappy framework and use Django! Django contains all pieces needed for all the gory details of web development, like session management, forms, database and templating. It's so powerfull : you write your model once, Django generate sql statements for the database, generate HTML form to add or modify data, with data validation in bonus, in few lines or code. Documentation is wonderful.&lt;br /&gt;&lt;br /&gt;There are some days like that when I really feel that technology is getting better, and Django is a wise and beautiful piece of work.&lt;br /&gt;&lt;br /&gt;Look at &lt;span style="visibility: visible;" id="main"&gt;&lt;span style="visibility: visible;" id="search"&gt;&lt;cite&gt;www.&lt;b&gt;djangoproject&lt;/b&gt;.com&lt;br /&gt;&lt;/cite&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-7628076961995961911?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/7628076961995961911/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=7628076961995961911' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/7628076961995961911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/7628076961995961911'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/10/django-soooo-cool.html' title='Django, soooo cool'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-6568275326263401016</id><published>2009-09-30T07:05:00.000-07:00</published><updated>2009-09-30T08:58:59.037-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='noesis'/><title type='text'>Java and system administration</title><content type='html'>Java is a wonderful platform for software development, it's mature, stable and feature-full. I had a bias against Java for many reasons in the past, as my coworkers, that lead to dismiss it a few time. Now, since I'm working with Java for Noesis, I had time to revisit this technology. Here are the bias deconstructions.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Java JVM is slow : We don't know for sure at first if the running time of a target application will be slower or faster with C++ or Java, and I don't want to dig into benchmarking. There are so many factors that may lead to a winner and the contrary. We know for sure that there is some overhead while running Java program, but for many applications, the raw output is not a primary concern. In scientific computing field, some code was not optimized and was taking a huge time to run, and optimization was leading to great performance improvement, better than a technology switch. Also, since there are large libraries available for Java, reuse reduces the development time, and it may represent a large portion of total running time. Startup time is annoying, but it occurs only the first time, and can be reduced by read ahead caching. &lt;/li&gt;&lt;li&gt;Java is memory hungry : java applications uses a lot of memory because they do a lot of things.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Java was proprietary : I was excluding Java because it was not open source, and then, any open source Java software had a non-free dependency. Free JVM and libraries was available, but you were on your own by doing this. Since Java JDK is now open, we are free to use it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Java is complicated : there is some learning curve, but that's not so bad. Eclipse is helping a lot to reduce burden because of typechecking. Compiling with "ant" is so much easy compared to autotools madness! And since CDBS has support for ant, it's easy to package a Java program. &lt;/li&gt;&lt;li&gt;Java is huge : Installing JRE headless on a minimal ubuntu requires about 93MB of disk space. I agree that if you run only one application, it's huge. But if we were mainly running java software, this stack would be used for all applications, and also here, the reuse lowers disk requirement. But for Noesis, it's a good question to ask : do system administrator will be willing to install about one hundred MB of stuff for it? 100MB disk space costs about 1 cent today, but with backups and management time, say 5 cents. Well, I guess it would be the best investment we can do with a nickel. Still, I will have to work hard to convince system administrators to install a JRE on their Linux virtual server that takes less than few hundred MB, because it's a large proportion of the server install size.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;What about embedded devices? It could be of practical interest to get Noesis running on a small device. There is the JME, but since it's stripped, I don't really know for sure if it won't break something.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It's a chance that XSugar was in Java, because it's definitely an important technology in the whole picture, and a new arrow to my quiver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-6568275326263401016?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/6568275326263401016/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=6568275326263401016' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6568275326263401016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/6568275326263401016'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/09/java-and-system-administration.html' title='Java and system administration'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2629518971767070446</id><published>2009-09-28T08:26:00.000-07:00</published><updated>2011-02-22T21:57:55.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='brics'/><title type='text'>Brics projects packages</title><content type='html'>New packages from brics projects are now available for Ubuntu. This is a snapshot of dependencies required for bidirectional configuration file parsing. Main packages are :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;automaton : library for finite automata&lt;/li&gt;&lt;li&gt;grammar : library and utility for grammar validation and handling&lt;/li&gt;&lt;li&gt;xsugar : main program for bidirectional transformations&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can find them on launchpad :&lt;br /&gt;&lt;br /&gt;http://launchpad.net/~francis-giraldeau/+archive/noesis&lt;br /&gt;&lt;br /&gt;Take care, names are subject to change. Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2629518971767070446?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2629518971767070446/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2629518971767070446' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2629518971767070446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2629518971767070446'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/09/brics-projects-packages.html' title='Brics projects packages'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-744061196771515141</id><published>2009-09-10T07:06:00.000-07:00</published><updated>2011-02-22T21:54:24.654-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sysadmin'/><title type='text'>Configuration as XML</title><content type='html'>Augeas provides an XPath like interface and API to access and modify configuration files. But, there are few limitations :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Augeas is limited to regular grammar, it can't parse nested structured documents. Il did search to see if it could be possible to use regular approximations for context free grammar, but in this case it's not possible. A regular expression parser uses only a finite automata, and for general context free grammar, we need a stack to keep track of the nested level of the document.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Augeas doesn't provide a complete xml file from a configuration file, and hence, can't use all the XML libraries processing available.&lt;/li&gt;&lt;/ul&gt;We need a parser that will be able to parse a general context-free grammar. It should be easy to write grammars, and LR or LALR parsers are too hard to user, since grammar must be written to avoid ambiguities and some type of recursion. The Earley parser algorithm is able to do that.&lt;br /&gt;&lt;br /&gt;The project XSugar is exactly what I was looking for. First, it implements a tokenless Earley parser, that has relative acceptable performances on config files. XSugar is able to do bidirectional transformation between a concrete file and an XML document and vice versa. There are few issues that must be resolved.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Bidirectional relation doesn't preserve formating of the config file. The reversability propriety is hence approximate, because a round trip will yield the same result, except for spaces and indentation. You have to keep formating manually, and this can be tedious. There is no way to verify that the stylesheet is able to capture all character of the input. Strict unidirectionality is required for config files.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ignorable Elements, like nodes to keep spaces and indentation, has to be present in the XML file, otherwise the unparsing fail. The problem is that clients that will modify the XML will have to add formating nodes. One of the main benefit of using XML was to abstract formating, and this requirement on XML breaks this abstraction. Ignorable Elements must be optional, and when not provided, a default value should be used.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The order of elements matters in the XML. If nodes are not provided in the right order, the unparsing fail. The client has to know in which order to provide Elements, and it would be better if the client has not to worry about it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Those are the main issues I see to make a new day for configuration management come true.&lt;br /&gt;&lt;br /&gt;To test those concepts, I created a new project, called Noesis. It means "insight", and I thought it would be meaningful for the current project. News soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-744061196771515141?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/744061196771515141/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=744061196771515141' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/744061196771515141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/744061196771515141'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/09/configuration-as-xml.html' title='Configuration as XML'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-592169197847411100</id><published>2009-02-22T12:03:00.000-08:00</published><updated>2009-02-22T13:18:12.453-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='augeas'/><title type='text'>Augeas : state of art configuration management</title><content type='html'>If you are like me, you probably find that configuration management under Linux is a real mess. Each software has it's own configuration file syntax and semantic. Since every project has it's own needs and is developed by different teams, a global and standard repository for configuration is unlikely to ever work in the open source model. We saw some initiatives that worked, like LSB and Freedesktop,  but such a shift for configuration file would require a huge coordination  and agreement, and is unlikely to happen, and since configuration values are usually highly coupled in software, it makes it hard to change it.&lt;br /&gt;&lt;br /&gt;There are few ways we can address the situation. You can choose to not manage at all your config files, you can do backups, use revision management software like subversion. You can also parametrize your configuration files with variables and generate them. You can also do some grep'ing and sed'ing on your config files to change values. Everything there tends to be cumbersome and error prone.  But, there is better. If it was possible to have a parser for every config file out there and get in memory representation, change whatever you want and save it back, then you have the st-graal of file configuration management. This way, you can manage configuration at a high semantic level, not manipulate file lines but configuration elements.&lt;br /&gt;&lt;br /&gt;Guess what, Augeas aims is exactly that! The concept is simple. For each file type, you write a lens that describe the format of the file. Then, the lens can be used to parse an instance of that config file and you get a tree in memory. You can access the tree and modify it. When you're done, the lens is used again to write back the file, including any modification you made to the tree. A lens is bidirectional, you don't have to specify how to read and write a file, only one description describe both directions.&lt;br /&gt;&lt;br /&gt;Last year, at the Linux Symposium, I listen to the talk of David Lutterkort about the progress of the project. There is one limitation of Augeas today related to the type of files for which you can write a lens. For example, we can't write lens to process config files that have recursive structures. For example, Apache configuration has this kind of nested structure. Actualy, this is not possible, because the lens semantic doesn't allow to define recursive grammar.&lt;br /&gt;&lt;br /&gt;So, I choosed to do that for my master. When this will be done, it will be possible to manage more file types with Augeas. I will post my findings here, thoughts and ideas on the project. Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-592169197847411100?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/592169197847411100/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=592169197847411100' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/592169197847411100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/592169197847411100'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2009/02/augeas-state-of-art-configuration.html' title='Augeas : state of art configuration management'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2058149006170231323</id><published>2008-04-04T12:12:00.000-07:00</published><updated>2008-04-04T12:30:11.544-07:00</updated><title type='text'>NFS and NBD fight</title><content type='html'>The fight has started last year, when NBD replaced NFS as the default protocol for root device for thin-clients in Ubuntu. But, there was a lack of scientific data about benefits of NBD.&lt;br /&gt;&lt;br /&gt;Few weeks ago, a team from &lt;span class="a"&gt;Birzeit university started to work on the topic. They have compared boot time using NFS and NBD. Results show that a thin-client booting with NBD is 44% faster than with NFS. More testing is underway.&lt;br /&gt;&lt;br /&gt;One big issue with NBD is that it's not as robust as NFS. For example, the client doesn't reconnect if the nbd-server is terminated. The thin-client is left in a unknown state, and must be rebooted. While this is not a big issue in small scale setup, it's not an option when you have central boot server and thousands thin-clients. The team plan to work on the availability issue as well.&lt;br /&gt;&lt;br /&gt;Stay tuned, the final battle is starting.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2058149006170231323?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2058149006170231323/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2058149006170231323' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2058149006170231323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2058149006170231323'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2008/04/nfs-and-nbd-fight.html' title='NFS and NBD fight'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-1023409376782149964</id><published>2008-03-23T21:46:00.000-07:00</published><updated>2008-03-23T22:15:08.991-07:00</updated><title type='text'>Interaction design patterns</title><content type='html'>I do have 26 years old, and I'm still doing homeworks for school. But this time, I admit that the topic is useful.&lt;br /&gt;&lt;br /&gt;I read a book about patterns. You probably know object oriented design patterns. There are patterns everywhere, to save us to reinvent the wheel.&lt;br /&gt;&lt;br /&gt;Patterns I read is about interaction design. It's about usability of electronic devices. The goals are mainly :&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Design the interface as to make it familiar for users&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reduce memory load on users to let them concentrate on their main task&lt;/li&gt;&lt;li&gt;Reduce the time it takes to complete a task, navigate, find something&lt;/li&gt;&lt;li&gt;Make the device fun, easy and efficient to use&lt;/li&gt;&lt;/ul&gt;The book is written by Jenifer Tidwell. It's a really good book, it contains what we need to know to start designing any UI. I did some empiricaly previously, and I would have saved so much time by reading this book first.&lt;br /&gt;&lt;br /&gt;Now, I'm able to evaluate an interface. A bad interface make the user dig into deeply nested dialogs, let the user waiting without a clue that something is going on, etc. There are mistakes all over the place.&lt;br /&gt;&lt;br /&gt;There are also good design out there. And to complete my homework, I will search for UI design patterns in KDE 4. That will be pretty cool to see how much it's usable. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-1023409376782149964?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/1023409376782149964/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=1023409376782149964' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1023409376782149964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/1023409376782149964'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2008/03/interaction-design-patterns.html' title='Interaction design patterns'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1864509792735323218.post-2649253896409877880</id><published>2008-03-22T21:42:00.000-07:00</published><updated>2008-03-22T21:49:16.246-07:00</updated><title type='text'>Hello World</title><content type='html'>Hey, this is my first blog on blogger.&lt;br /&gt;&lt;br /&gt;Alone in universe. That's how I feel these days. I wonder if someone else could understand me. It's like if I was on another planet. So, in next few weeks, I will try to explain that feeling. Anyway, I'm almost sure that nobody will care about this blog, so that will be the proof that the name is perfectly appropriate.&lt;br /&gt;&lt;br /&gt;And, BTW, that will be the occasion to share my toughts, my findings and my soul. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1864509792735323218-2649253896409877880?l=multivax.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://multivax.blogspot.com/feeds/2649253896409877880/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1864509792735323218&amp;postID=2649253896409877880' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2649253896409877880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1864509792735323218/posts/default/2649253896409877880'/><link rel='alternate' type='text/html' href='http://multivax.blogspot.com/2008/03/hello-world.html' title='Hello World'/><author><name>Francis Giraldeau</name><uri>http://www.blogger.com/profile/01004841549682103364</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://4.bp.blogspot.com/_R3p5IPVm8ek/SaGuwBxYiRI/AAAAAAAAANw/5R4s2haib28/S220/moi.jpg'/></author><thr:total>0</thr:total></entry></feed>
