<?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-5275928577461943852</id><updated>2011-09-29T17:23:08.377-04:00</updated><category term='personal'/><category term='food'/><category term='computers'/><title type='text'>Warm Apple Pi</title><subtitle type='html'>A random assortment of Computers, Cooking, and Life.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-6678290657312105701</id><published>2011-09-29T17:01:00.004-04:00</published><updated>2011-09-29T17:23:08.389-04:00</updated><title type='text'>Zài Jiàn Replay</title><content type='html'>&lt;p&gt;I eagerly installed VMware Workstation 8.0 today, hopeful that this update would have better support for &lt;a href="http://warmapplepi.blogspot.com/2009/09/debugging-linux-kernel.html"&gt;replay debugging&lt;/a&gt; that would fix a longstanding bug in their GDB stub's handing of the 'monitor stopat' command.  My enthusiasm lasted until I loaded the program for the first time, and though to myself:&lt;/p&gt;

&lt;blockquote&gt;That's funny.  Where'd the "Record" button go?&lt;/blockquote&gt;

&lt;p&gt;After scouring the VMware support documentation and blogs, I finally discovered where it went.  According to the &lt;a href="http://www.replaydebugging.com/2011/09/goodbye-replay-debugging.html"&gt;blog of E. Lewis&lt;/a&gt;, an engineer at VMware:&lt;/p&gt;

&lt;blockquote&gt;The Workstation management team concluded that not enough people had demonstrated the need or invested the time necessary to configure and use the feature, so they decided to dedicate our engineers to features that would be used by more developers and other customers.&lt;/blockquote&gt;

&lt;p&gt;Yep, it's gone for good.  Amidst a slew of new features added to Workstation 8, a very useful one — the whole reason I use virtual machined in development — was quietly removed.  I'm very sorry to see it go.  It will be interesting to see if VMware will ever reinstate this feature, or if a (small) swarm of angry developers can get together and implement the feature for some open source VM system.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-6678290657312105701?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/6678290657312105701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2011/09/zai-jian-replay.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/6678290657312105701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/6678290657312105701'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2011/09/zai-jian-replay.html' title='Zài Jiàn Replay'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-7832270609046950621</id><published>2010-10-18T11:33:00.003-04:00</published><updated>2010-10-18T12:47:20.569-04:00</updated><title type='text'>System Architecture of the Future</title><content type='html'>&lt;p&gt;
I just read an interesting HotOS paper titled: "&lt;a href="http://anil.recoil.org/papers/2010-hotcloud-lamp.pdf"&gt;Turning Down the LAMP: Software Specialisation for the Cloud&lt;/a&gt;."  The authors explore the idea of condensing the software stack needed for an application.  For instance, your application code is using a language runtime, isolated in a user-space process, talking to a MySQL process, reporting back to an Apache instance, running under the Linux kernel, all executing as a virtual machine in the Xen hypervisor.  The paper introduces the &lt;i&gt;Mirage&lt;/i&gt; system to shrink this down to three layers:  App Code, Mirage Kernel, and Xen.
&lt;/p&gt;&lt;p&gt;
Specifically, they compile an &lt;a href="http://caml.inria.fr/ocaml/"&gt;OCaml&lt;/a&gt; program straight from source code to a virtual machine image that can run under Xen.  The stuff that would be provided by the OS, like concurrency, storage, and isolation, is provided by libraries and the OCaml runtime.  The runtime only includes features needed by the application, so it's lighter and faster than Linux.  Without having to worry about Posix, the application can make better use of system hardware.  It can do some things better:  OCaml programs can be statically verified to be safe, so everything runs in only one address space with minimal memory protection (like &lt;a href="http://research.microsoft.com/en-us/projects/singularity/"&gt;Singularity&lt;/a&gt;).
&lt;/p&gt;&lt;p&gt;
This was just a workshop paper, so their ideas and evaluation aren't flushed out fully.  I look forward to seeing the full version of this paper.
&lt;/p&gt;&lt;p&gt;
This idea of specializing a kernel for the application isn't a new idea.  But when you think about this as a cloud service, the Mirage model starts to look like a different picture: &lt;a href="http://pdos.csail.mit.edu/exo.html"&gt;Exokernels&lt;/a&gt;.  Let's see:
&lt;ul&gt;
&lt;li&gt;One thin layer that multiplexes hardware: Check! (exokernel / Xen)&lt;/li&gt;
&lt;li&gt;OS functionality provided by application: Check! (libos / Mirage kernel)&lt;/li&gt;
&lt;li&gt;Application runs on the kernel best suited for it: Check!&lt;/li&gt;
&lt;/ul&gt;
The tricky parts of an exokernel come from its attemts to share &lt;em&gt;some&lt;/em&gt; state among its applications.  (Can one Linux-like libos provide an effective file system, with permissions, to many applications?  How do two different apps using different libos-s share disk blocks?)  As a cloud service provider, there are no problems!  Just use virtual disks (i.e. a static partitioning of disk space without sharing) and limit VM communication to the networking system (i.e. message passing).
&lt;/p&gt;&lt;p&gt;
So 16 years after exokernels were first proposed, we're back to exploring the same architecture.  Except our exokernel is called Xen.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-7832270609046950621?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/7832270609046950621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2010/10/system-architecture-of-future.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/7832270609046950621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/7832270609046950621'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2010/10/system-architecture-of-future.html' title='System Architecture of the Future'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-2321536623015357549</id><published>2010-01-17T19:07:00.012-05:00</published><updated>2010-01-18T00:22:01.432-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Visualizing CVS</title><content type='html'>&lt;p&gt;In a retrospective mood after finishing development on a long-running project, I started wondering just how much coding had been done.  How much code has been written, over what timescale, and by whom?  Of course, all the answers are sitting there in our CVS repository.  I just need a nice way to visualize it.&lt;/p&gt;

&lt;p&gt;After hacking around for a bit, here's a pretty graph I came up with: (click for larger size)&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_blU8z9Yk5Gw/S1On9HxpLjI/AAAAAAAAAAM/F-jTabtE4k0/s1600-h/Linux+commits.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 95px;" src="http://3.bp.blogspot.com/_blU8z9Yk5Gw/S1On9HxpLjI/AAAAAAAAAAM/F-jTabtE4k0/s400/Linux+commits.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5427866644412706354" /&gt;&lt;/a&gt;

&lt;p&gt;&lt;i&gt;To explain:&lt;/i&gt; Each circle in this graph represents a single CVS commit to our custom Linux kernel.  A commit is positioned along the X-axis according to the date it was committed.  Each tick represents one month, so you're seeing a bit over a year's worth of development out of the repository's entire lifetime.  The size of each circle shows how big the commit was:  the unified diff for each commit was run through &lt;tt&gt;diffstat&lt;/tt&gt; to determine its lines added (&lt;i&gt;A&lt;/i&gt;) and lines removed (&lt;i&gt;D&lt;/i&gt;).  The area of each circle is proportional to &lt;i&gt;A+D&lt;/i&gt;.  The color of the circle shows who performed the commit.  Positioning along the Y-axis is random, just to spread out the circles a bit.&lt;/p&gt;

&lt;p&gt;This project was driven mostly by paper deadlines.  I have drawn lines to highlight two important dates.  Our first deadline was when the project's paper was first submitted to a conference (line #1).  This marked an enormous push by everyone to get the system fully working.  Work beyond that was at a subdued pace, though not completely absent.  Though we had a paper draft submitted, we knew what its problems were, so we kept trying to improve the system.&lt;/p&gt;

&lt;p&gt;Our paper thankfully got accepted, so the next deadline was the camera-ready version of our paper (line #2) that addressed our reviewers' comments and included up-to-date results.  It was a mad dash  there at the end, but we were able to add enough system support to get some additional benchmarks working in time for our deadline.&lt;/p&gt;

&lt;p&gt;A bit about the graph generation:  I used &lt;tt&gt;cvsps&lt;/tt&gt; as my interface to the CVS repository.  This tool collects and correlates information about the commits to each file and presents that information as a series of patch sets.  Strictly, each point on the graph shows a patch set.  Cvsps provided commit date and author, and it would also extract the patch for each change set to be fed to &lt;tt&gt;diffstat&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The intermediate output of this process was saved to text files and then tweaked.  Patch extraction was a rather length process, probably because I wasn't doing this on the CVS server itself.  Also for some reason, one of the patch sets contained a new version of the file rather than a 4-line patch.  Something was obviously wrong when I got a circle 100x larger than the rest.  That's really the only thing that needed hand-modification.&lt;/p&gt;

&lt;p&gt;That information was then loaded through a Python script that used &lt;tt&gt;matplotlib&lt;/tt&gt; to generate the graph itself.  I'd never really used that graphing tool before, but I was sick of working with &lt;tt&gt;gnuplot&lt;/tt&gt; and &lt;tt&gt;jgraph&lt;/tt&gt;.  While I don't quite have a full grasp of the platform, I was able to put together enough to make the plot above.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-2321536623015357549?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/2321536623015357549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2010/01/visualizing-cvs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/2321536623015357549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/2321536623015357549'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2010/01/visualizing-cvs.html' title='Visualizing CVS'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_blU8z9Yk5Gw/S1On9HxpLjI/AAAAAAAAAAM/F-jTabtE4k0/s72-c/Linux+commits.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-3109000720113164900</id><published>2009-12-02T18:00:00.005-05:00</published><updated>2009-12-02T18:47:17.347-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Debugging Kernel Modules with GDB 7</title><content type='html'>&lt;p&gt;When you're debugging your Linux kernel, every try to browse into a module?  That only works well if you can read assembly easily.  GDB has debug info for the linked-in part of the kernel, but being separately-compiled entities, modules are a big unknown.  There is a command in GDB to fix this: &lt;i&gt;add-symbol-file&lt;/i&gt;, which informs GDB of the symbols in the given file.  You just have to tell GDB where that file lives in the process's address space.

&lt;p&gt;Figuring that out isn't necessarily straightforward.  VMware's solution (from their tech note &lt;i&gt;&lt;a href="http://www.vmware.com/pdf/ws7_replay_linux_technote.pdf"&gt;Replay Debugging on Linux&lt;/a&gt;&lt;/i&gt;) isn't very satisfactory.  To paraphrase, you need to go into the guest, examine files in &lt;i&gt;/sys/modules/&amp;lt;foo&amp;gt;/sections&lt;/i&gt; to extract the module's segment offsets, and then build an appropriate GDB command line from that.  That's fine, unless your load addresses change every now and then (preventing you from hard-coding this into your GDB init script).  And of course the guest system isn't exactly accessible when a debugger is attached.

&lt;p&gt;I thought I'd get around this issue by having GDB look at the running kernel to figure out where it should locate the module.  Linux keeps a linked list of all loaded modules in a list named &lt;i&gt;modules&lt;/i&gt;.  So GDB just needs to traverse this list until it finds the named module, then extract the info and build its own command line.  Sounds easy, right?

&lt;p&gt;I fought with GDB's scripting language to implement this, and it won.  The killer: I couldn't figure out how to do a string compare in it.  Anyway, I shelved this idea and waited.  Since then, GDB 7 has been released with support for Python scripting, and I couldn't help but take another look at this problem.

&lt;p&gt;The script below adds the new GDB command &lt;b&gt;add-kernel-module&lt;/b&gt;.  It takes one argument, the file name of the kernel module to load.  The code does about what I mentioned above: it walks kernel data structures, extracts relevant info, and builds a GDB command line from it.  It's not very pretty code, but it works.

&lt;p&gt;Be sure to name this "vmlinux-gdb.py" so that it can be automatically loaded when you debug your kernel.

&lt;pre class="file"&gt;import os.path

long_type = gdb.lookup_type('unsigned long')

# These functions are counterparts to the Linux kernel macros
def offset(gdb_type, member):
    '''Return the offset of a member within a structure.'''
    ptr = gdb.Value(0).cast(gdb_type.pointer())
    return ptr[member].address.cast(long_type)

def list_entry(list_head_ptr, gdb_type, off):
    '''Return the base element that holds a list_head struct.'''
    base = list_head_ptr.cast(long_type) - off
    return base.cast(gdb_type.pointer())

def listhead_iter(list_head, typename, member):
    '''Iterate over elements of a list_head.  The first argument should
be a *reference* to the main list_head.'''
    type = gdb.lookup_type(typename)
    off = offset(type, member)
    pos = list_head['next']
    while pos != list_head.address:
        yield list_entry(pos, type, off)
        pos = pos['next']

class AddKernModCmd(gdb.Command):
    '''Load symbols for a currently-running kernel module.'''

    def __init__(self):
        super(AddKernModCmd, self).__init__('add-kernel-module',
                                            gdb.COMMAND_FILES,
                                            gdb.COMPLETE_FILENAME)

    def invoke(self, filename, from_tty):
        if filename == '':
            print 'USAGE: add-kernel-module FILE.ko'
            return
        if not os.path.isfile(filename):
            if os.path.isfile(filename + '.ko'):
                filename += '.ko'
            else:
                print 'Could not find module file %s' % filename
                return
        base = os.path.splitext(os.path.basename(filename))[0]
        try:
            frame = gdb.selected_frame()
            modules = frame.read_var("modules")
        except:
            print 'A running kernel must be attached in order to get section information'
            return
        for mod in listhead_iter(modules, 'struct module', 'list'):
            if mod['name'].string() == base:
                # Found it!  Now, get the section attributes
                sect = mod['sect_attrs']
                num_sect = int(str(sect['nsections']))
                attrs = [ sect['attrs'][i] for i in range(num_sect) ]
                adict = dict([ (a['name'].string(), str(a['address']))
                               for a in attrs ])
                cmd = 'add-symbol-file %s %s' %(filename,adict['.text'])
                for sec in ('.bss', '.data', '.init.text'):
                    if sec in adict:
                        cmd += ' -s %s %s' % (sec, adict[sec])
                gdb.execute(cmd)
                return
        print 'Module %s not found' % base

AddKernModCmd()
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-3109000720113164900?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/3109000720113164900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/12/handling-kernel-modules-with-gdb-7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/3109000720113164900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/3109000720113164900'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/12/handling-kernel-modules-with-gdb-7.html' title='Debugging Kernel Modules with GDB 7'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-6822782840507517164</id><published>2009-12-01T11:21:00.004-05:00</published><updated>2009-12-01T11:41:34.809-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>"Fixing" my PowerBook's Lid</title><content type='html'>&lt;p&gt;I love my little PowerBook G4, but it's starting to show its age.  In particular, the case itself has taken some wear over the years.  Dings in the aluminum don't matter that much, but one piece of damage has seriously affected its usability.

&lt;p&gt;Macs have always worked well with power management.  You close the lid and it goes to sleep.  When you open the lid again, everything just pops up.  It's power management without thinking.  Macs were doing this before Windows thought to copy them and before Linux knew how to resume.  (Suspend is easy; it's brining things back that's tricky.)

&lt;p&gt;Anyway, this handy feature worked fine, up until my Mac wouldn't stay shut.  There is a little spring-loaded magnetic hook that would pop down from the top of the case when the lid was close to the base, and that would hold the laptop shut.  That hook broke off earlier this year.  So the case will naturally rest right on the edge of the open/shut sensor.  If I travel with it in my backpack, it goes in and out of sleep every time I shift my weight.  It's strange picking up my bag and then hearing the beep that tells me I have new mail.  You can imagine what this does to my battery life.

&lt;p&gt;I finally figured out how to "fix" my PowerBook without disassembling the case.  There's a simple command line that will prevent the laptop from waking up when the case is opened:

&lt;pre&gt;sudo pmset -a lidwake 0&lt;/pre&gt;

&lt;p&gt;After running this, my laptop won't wake unless I hit the power button on the keyboard.  The &lt;i&gt;pmset&lt;/i&gt; command is a utility for changing power settings.  It performs the same changes that the Energy Saver preference pane does, plus a few.  The "lidwake" setting doesn't show up in Energy Saver, but you can still set it directly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-6822782840507517164?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/6822782840507517164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/12/fixing-my-powerbooks-lid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/6822782840507517164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/6822782840507517164'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/12/fixing-my-powerbooks-lid.html' title='&quot;Fixing&quot; my PowerBook&apos;s Lid'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-7906538948575614024</id><published>2009-10-22T13:27:00.007-04:00</published><updated>2009-11-15T23:39:38.438-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>UMich LDAP for Thunderbird</title><content type='html'>&lt;p&gt;At the University of Michigan, setting up Thunderbird to query the university's LDAP directory has always been a mystery.  The basic directory server settings for Thunderbird are easy enough to get right:&lt;/p&gt;

&lt;pre&gt;Hostname: ldap.itd.umich.edu
Base DN: dc=umich,dc=edu&lt;/pre&gt;

&lt;p&gt;But for some reason, Thunderbird would still refuse to work. I've started looking a bit more closely at OpenLDAP lately, and now I finally figured out how to get it partially working.  First, some background...&lt;/p&gt;

&lt;p&gt;To find someone in an LDAP directory, a client constructs a query that tells the directory what entry to look for.  For those not steeped in LDAP, a query looks something like "(cn=Benjamin*)" to search for records showing a &lt;b&gt;c&lt;/b&gt;ommon &lt;b&gt;n&lt;/b&gt;ame that starts with 'Benjamin'.  Other attributes you could search for are given name, surname, or mail address, to name a few.&lt;/p&gt;

&lt;p&gt;The default query for Thunderbird, when you type someone's name into the Address Book search box, looks something like: "(|(mail=*benjamin*)(cn=*benjamin*)(givenName=*benjamin*)(sn=*benjamin*))". Anything that has "benjamin" as a substring in any of those four attributes will match.  That's a pretty wide net to cast.&lt;/p&gt;

&lt;p&gt;And our administrators don't allow it.  Querying on the "mail" attribute when there is a "*" in the parameter, or on "givenName" for any parameter will result in an "Administrative limit exceeded" error.   So when you &lt;span style="font-style: italic;"&gt;OR&lt;/span&gt; all those together, of course the server rejects it.&lt;/p&gt;

&lt;p&gt;The solution is to have Thunderbird change how it constructs its queries. I haven't found out how to do this for the search box, but it is possible to get address auto-completion working.  According to an &lt;a href="http://www.mail-archive.com/mozilla-directory@mozilla.org/msg00817.html"&gt;ancient email&lt;/a&gt;, you can do this by adding the following line to Thunderbird's "prefs.js" file:&lt;/p&gt;

&lt;pre&gt;user_pref("ldap_2.servers.UMich.autoComplete.filterTemplate",
          "(|(cn=*%v*)(mail=%v)(uid=%v))");&lt;/pre&gt;

&lt;p&gt;Then enable auto-complete via LDAP in the Preferences | Composition | Addressing dialog.  You should change "UMich" to reflect whatever Thunderbird has internally named your LDAP server profile (look through prefs.js to figure that out).  This directs Thunderbird to search for substrings of common names and exact matches for your mail address or uniqname.  The latter two parts are of limited use, but the first seems to return good results.  You still hit an admin limit if your search is too generic though (i.e. "ben").&lt;/p&gt;

&lt;p&gt;I bet there's a similar hidden preference setting to adjust the main search box, but I doubt I'll find it unless I start reading through more XPCOM code than I care to do.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-7906538948575614024?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/7906538948575614024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/10/umich-ldap-for-thunderbird.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/7906538948575614024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/7906538948575614024'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/10/umich-ldap-for-thunderbird.html' title='UMich LDAP for Thunderbird'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-2758979256295024048</id><published>2009-10-04T16:45:00.002-04:00</published><updated>2009-11-15T23:35:30.816-05:00</updated><title type='text'>Nothing is New</title><content type='html'>&lt;blockquote&gt;I have read of a gentleman who owned a so fine house in London, and when he went for months of summer to Switzerland and lock up his house, some burglar come and broke window at back and got in. Then he went and made open the shutters in front and walk out and in through the door, before the very eyes of the police. Then he have an auction in that house, and advertise it, and put up big notice. And when the day come he sell off by a great auctioneer all the goods of that other man who own them. Then he go to a builder, and he sell him that house, making an agreement that he pull it down and take all away within a certain time. And your police and other authority help him all they can. And when that owner come back from his holiday in Switzerland he find only an empty hole where his house had been.&lt;/blockquote&gt;

&lt;p&gt;I found this passage in Bram Stoker's Dracula, published in 1897.  It reminded me of a scam I first heard of being used on Craigslist.  Someone looking to rent a room in another town finds a nice place online, sends in a deposit, and then shows up to find that the owner of the house knows nothing about a room for rent.  The poster, who is not the owner of the house, gets away with whatever deposit was paid.  It looks like pretending to own some property and selling it off is not by any measure a new fraud!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-2758979256295024048?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/2758979256295024048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/10/nothing-is-new.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/2758979256295024048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/2758979256295024048'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/10/nothing-is-new.html' title='Nothing is New'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-411769462933909883</id><published>2009-09-22T18:17:00.004-04:00</published><updated>2009-11-15T23:35:07.278-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Algebra Economics</title><content type='html'>&lt;p&gt;Consider a TI-83+ calculator.  Made in 1999, a minor update to a 1996 product.  6 MHz processor.  While I don't have a good source for historical price data, one web site claims that a 1999 price for this hardware is about $90.  I figure that's about right; I remember buying a different model graphing calculator for something near that.&lt;/p&gt;

&lt;p&gt;In the last decade, processors have gone from 300 MHz Pentiums with a feature size of 800 nm to 3 GHz 8-threaded Core i7s having 45nm features.  A typical amount of RAM for a desktop system has gone from 128 MB of PC100 to 2 GB of DDR3-1066.  And with all of this progress, the price of desktops has slowly been going down.  Something like this ran through my head as I saw that the TI-83+ in my hand cost $110 today.&lt;/p&gt;

&lt;p&gt;There is one feature of the TI-83+ that suddenly became relevant to me:  you can bring this model into ACT, SAT, and AP exams.  This is one of the fixed list of calculators certified appropriate for use on these all-important measures of a high-school student's worth.  High school math programs typically mandate which calculator all its students purchase, and I have a suspicion that a significant percentage of all US schools require that exact model.&lt;/p&gt;

&lt;p&gt;Since students are not free to select a calculator based on open competition for features and usability, why would the price ever drop?  I should have remembered my own high school classes, particularly economics.  Price reflects what people are willing to pay for a good, not how much it costs to make it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-411769462933909883?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/411769462933909883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/09/algebra-economics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/411769462933909883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/411769462933909883'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/09/algebra-economics.html' title='Algebra Economics'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-5103600437756396140</id><published>2009-09-21T16:28:00.045-04:00</published><updated>2009-11-15T23:24:12.837-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Debugging the Linux Kernel</title><content type='html'>&lt;div&gt;&lt;p&gt;If you've ever tried to debug your own Linux kernel, you have my deepest sympathy.  It isn't fun, nor is it easy. Thankfully, there is a great tool that can help with this:  VMware Workstation lets you record and replay a virtual machine and all interaction with it while a debugger is attached to it.   Simply install your custom Linux kernel inside a virtual machine and debug it from your desktop.&lt;/p&gt;&lt;p&gt;The blog &lt;a href="http://stackframe.blogspot.com/"&gt;Debugging the Virtual World&lt;/a&gt; is a great source for information on how to set up your system for kernel debugging.  Unfortunately, this guide is based on the older 6.0 version of Workstation, and updates to 6.5 have made parts of the document unnecessary.  There is other material out there to help you use VMware to debug &lt;em&gt;applications&lt;/em&gt; from your &lt;em&gt;Windows&lt;/em&gt; development environment.  Linux support is a bit lacking.&lt;/p&gt;&lt;p&gt;So for those who use and love Linux, I hope to make this debugging process a bit easier.  Plus, I have a few additional ways I'd like to present to ease the debugging process.&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/em&gt; Recently VMware Workstation 7.0 was released.  Once I manage to get a license for it, I'll present an updated how-to.&lt;/p&gt;&lt;/div&gt;
&lt;h4&gt;Basic Setup&lt;/h4&gt;&lt;div&gt;&lt;p&gt;First, you will need a copy of VMware Workstation 6.5.  I haven't tried other versions, but I'd be doubtful.  You will also need to be proficient with GDB for debugging.  I use Emacs or DDD to drive, but that's just my preference.  &lt;a href="http://www.dest-unreach.org/socat/"&gt;Socat&lt;/a&gt; is a tool I use to access unix named sockets, which VMware uses for serial output.&lt;/p&gt;&lt;p&gt;You will need to extract the Linux source tree on the host machine, since you will be debugging there.  Let's say you stash it in a directory &lt;span style="font-style: italic;"&gt;$LINUX&lt;/span&gt;.  I use rsync to copy this tree inside the VM where it is built and installed.  After this happens, I need to copy some files back out, and I put them in a directory &lt;span style="font-style: italic;"&gt;$VMSHARE&lt;/span&gt;, but more on this later.&lt;/p&gt;&lt;/div&gt;
&lt;h4&gt;VMware&lt;/h4&gt;&lt;div&gt;&lt;p&gt;Workstation 6.5 is already configured to record and replay.  The other setup required is to enable the built-in GDB debug stub.  This lets an external GDB process control Workstation like a remote process.  To enable this, add the following to the virtual machine's &lt;i&gt;.vmx&lt;/i&gt; definition file:&lt;/p&gt;&lt;pre&gt;debugStub.listen.guest32 = "TRUE"&lt;/pre&gt;That's for 32-bit guests.  If you run 64-bit, try:&lt;pre&gt;debugStub.listen.guest64 = "TRUE"&lt;/pre&gt;I also like to configure my system to dump kernel output to a serial port, so that if the kernel panics the full report is saved.   To do this, make sure the VM has a serial port, and configure it to output from &lt;span style="font-style: italic;"&gt;server&lt;/span&gt; to &lt;span style="font-style: italic;"&gt;an application&lt;/span&gt;.  This really means "to a named socket," which I dump to the console with:&lt;p&gt;&lt;/p&gt;&lt;pre&gt;socat unix-connect:/path/to/serial stdio&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Configuring Linux in the VM&lt;/h4&gt;&lt;div&gt;&lt;p&gt;I'll assume you're doing this because you have a hacked kernel you built yourself and you wish to debug.  Make sure when configuring you select:&lt;/p&gt;&lt;pre&gt;General setup ---&gt;
  Configure standard kernel features (for small system) ---&gt;
    [*] Load all symbols for debugging/ksymoops
    [*]   Include all symbols in kallsyms
    [*]   Do an extra kallsyms pass
Kernel hacking ---&gt;
  [*] Compile the kernel with debug info&lt;/pre&gt;&lt;p&gt;You probably want to add other kernel hacking options, but that's up to your need.  Once the kernel is built, copy the uncompressed &lt;i&gt;vmlinux&lt;/i&gt; binary into your host's &lt;span style="font-style: italic;"&gt;$VMSHARE&lt;/span&gt; directory.  I do this all with a simple build script in my VM that looks something like this:&lt;/p&gt;&lt;pre class="file"&gt;
#!/bin/sh
cd $HOME/linux-2.6.26 &amp;&amp;
rsync -auvC -e ssh --include core  host:$LINUX $HOME  &amp;&amp;
make &amp;&amp;
sudo make install &amp;&amp;
scp vmlinux host:$VMSHARE &amp;&amp;
echo "Done!"
&lt;/pre&gt;&lt;p&gt;To configure Linux to send its output to the serial port, add some lines to your kernel command line in &lt;i&gt;/boot/grub/menu.lst&lt;/i&gt;, so that it looks something like this:&lt;/p&gt;&lt;pre&gt;title Debug Kernel
  kernel /vmlinuz ... console=ttyS0,115200n8 console=tty0
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Using GDB&lt;/h4&gt;&lt;div&gt;&lt;p&gt;Once you have this system set up, you still have to work with GDB: not the easiest thing to do.  I've put together a script that defines some extra commands that make GDB more usable for me.  This script lives in my source tree on the host as &lt;span style="font-style: italic;"&gt;$LINUX/.gdbinit&lt;/span&gt; so it gets loaded whenever I launch GDB.&lt;/p&gt;&lt;p&gt;The following code is heavily tied to the 32-bit x86 architecture.  If you're working on a different architecture, let these examples inspire you to do something similar.&lt;/p&gt;&lt;p&gt;I assume you know how to use GDB already; if not, there are bound to be some useful guides out there on the net somewhere.  I'm mostly going to go over my own script and the new commands it defines.&lt;/p&gt;&lt;h5&gt;Basic commands&lt;/h5&gt;&lt;p&gt;First, to start debugging after loading GDB, you need to tell it to connect to VMware.  You do this with the &lt;b&gt;connect&lt;/b&gt; command when the virtual machine is running.  This also prints out the kernel build number and date, so you can make sure you're debugging the correct build.  To release control of the debugger, use the &lt;b&gt;detach&lt;/b&gt; command.&lt;/p&gt;&lt;p&gt;Eventually, you'll want to examine the kernel's &lt;i&gt;current&lt;/i&gt; variable.  Unfortunately for x86 architectures, &lt;i&gt;current&lt;/i&gt; is a macro written in assembly, so GDB can't access it.  You can however use the convenience variable &lt;b&gt;$current&lt;/b&gt;, which is refreshed every time the debugger stops.&lt;/p&gt;&lt;p&gt;While debugging, you can use the &lt;b&gt;loc&lt;/b&gt; command to have GDB print out information on the current process, and if you are debugging a recording, the timestamp of your current location.  This also gets printed out when you stop after a &lt;i&gt;continue&lt;/i&gt; command.  The information printed is the current process's PID and some relevant flags.  You change exactly which flags you want to look at by adjusting the &lt;i&gt;__tsk_flags&lt;/i&gt; command as necessary.  Just follow the example to add other flags:  &lt;i&gt;TIF_*&lt;/i&gt; flags are in &lt;i&gt;thread_info_32.h&lt;/i&gt;, and &lt;span style="font-style: italic;"&gt;PF_*&lt;/span&gt; flags are in &lt;span style="font-style: italic;"&gt;sched.h&lt;/span&gt;).  When working correctly, it gives you a status line that looks something like this:&lt;/p&gt;&lt;pre&gt;Current pid=(2734) flags=(TIF_NEED_RESCHED ) VM position=632864&lt;/pre&gt;&lt;p&gt;When you are replaying, the &lt;b&gt;monitor &lt;i&gt;x&lt;/i&gt;&lt;/b&gt; commands can be useful.  First, &lt;i&gt;monitor offset&lt;/i&gt; displays your location within a replay (also shown by &lt;i&gt;loc&lt;/i&gt;).  Knowing that location, you can quickly jump back to the same point on a subsequent replay by using &lt;i&gt;monitor stopat&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;And now, the full &lt;i&gt;$LINUX/.gdbinit&lt;/i&gt; script.  Make sure that you copy and paste this correctly.  All lines that look like they end in "\" really have a trailing space that must be preserved, and GDB is very picky about this!&lt;/p&gt;&lt;pre class="file"&gt;
file $VMSHARE/vmlinux

# Recompute $current at every stop.  Valid only inside kernel.
define set-current
  set $current=*((struct task_struct**)((unsigned long)$esp&amp;0xfffff000))
end
define hook-stop
  set-current
end

# Reconnect to the VM after issuing "detach."
define connect
  target remote localhost:8832
  echo Kernel version =
  output/s init_uts_ns.name.version[0]@36
  echo \n
end

# Print extra information about the current process and replay location
define loc
  if $esp &gt;= 0xc0000000
    # Extra information if in kernel
    echo Current \ 
    echo pid=(
    output $current-&gt;pid
    echo ) \ 
    echo flags=(
    __tsk_flags $current
    echo ) \ 
  end
  echo VM position=
  monitor position
end
define hookpost-continue
  loc
end

# helper
define __test_tsk_thread_flag
  if (*((unsigned long)($arg0)-&gt;stack + 0x8) &amp; (1U &lt;&lt; ($arg1))) != 0
    echo $arg2\ \ 
  end
end
# helper
define __test_tsk_flag
  if (($arg0)-&gt;flags &amp; ($arg1)) != 0
    echo $arg2\ \ 
  end
end

# Print out the task flags I'm interested in
define __tsk_flags
  __test_tsk_thread_flag ($arg0) 2 TIF_NEED_RESCHED
  __test_tsk_flag ($arg0) 0x00000004 PF_EXITING
end

# Print flags for the given task_struct
define tsk_flags
  echo flags=(
  __tsk_flags $arg0
  echo )\n
end
&lt;/pre&gt;&lt;p&gt;Hopefully, this collection of GDB functions helps ease the pain of debugging, if only a little bit.&lt;/p&gt;&lt;/div&gt;
&lt;h4&gt;Further Reading&lt;/h4&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://stackframe.blogspot.com/"&gt;Debugging the virtual world&lt;/a&gt;: blog where I got my info&lt;/li&gt;&lt;li&gt;&lt;a href="http://communities.vmware.com/community/vmtn/general/guestdebugmonitor"&gt;VMware Replay discussion board&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.replaydebugging.com/2008/08/vmware-workstation-65-reverse-and.html"&gt;VMware Workstation 6.5: Reverse and Replay Debugging is Here!&lt;/a&gt;: good explanation for why you might like replay debugging&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-5103600437756396140?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/5103600437756396140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/09/debugging-linux-kernel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/5103600437756396140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/5103600437756396140'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/09/debugging-linux-kernel.html' title='Debugging the Linux Kernel'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-9007843602688153368</id><published>2009-08-18T14:27:00.005-04:00</published><updated>2009-11-15T23:33:50.200-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Courgette</title><content type='html'>&lt;p&gt;Google has recently publicized a new method for compressing Chrome patches, which they call "&lt;a href="http://dev.chromium.org/developers/design-documents/software-updates-courgette"&gt;Courgette&lt;/a&gt;".  They argue that the generic &lt;a href="http://www.daemonology.net/bsdiff/"&gt;bsdiff&lt;/a&gt; tool isn't efficient enough for them, and they can save a lot of bandwidth by reducing patch size.  That makes it more practical for them to patch more often, automatically.&lt;/p&gt;

&lt;p&gt;They offer one example of the effect of this new method for compression.  For a 9.9MB full update, the bsdiff patch is 6.8% of that size (688KB), and a Courgette update is 0.76% (77KB).  This number is certainly impressive, but it is only one example.  I'd like to know if it is reasonable to expect this level of compression on all updates.  Existing work in this area does consider updates to many different packages, across many types of updates, and the particular update does make a difference.&lt;/p&gt;

&lt;p&gt;Though they compare against bsdiff, their technique sounds a lot like Exediff.  The Exediff algorithm goes something like this.  First, try to match instructions in the original executable against instructions in the updated version.  All unmatched instructions are "primary differences," and these changes must be encoded in the patch file.  Then, based on these changes, predict how the matched instructions should have changed.  When the change is predictable, it doesn't need to be encoded in the update.  Otherwise, the change is a "secondary difference" and must be include in the update.  Exediff uses knowledge of the instruction set to predict how matched instructions will change, if at all.  Despite this, the author of bsdiff showed that across many different types of patches, Exediff and bsdiff have similar performance.&lt;/p&gt;

&lt;p&gt;So, both Exediff and Courgette appear to do the same thing.  How then does Courgette do so much better at compressing?  It looks like the "adjust" step is where the magic happens.  Courgette changes the updated binary so that it has fewer differences, letting the patch be smaller.  That updated binary is then reconstructed by the client, &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; the&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;original update.&lt;/p&gt;

&lt;p&gt;This leads to some interesting questions, the first concerning repeated patching.  For instance, if I have a base version A which I patch to version B, how should I generate the patch to version C?  Do I generate the binary for C so that the patch B -&gt; C is minimized, or should the patch A -&gt; C be minimized?  What happens for patch M, or Z, or AAA?&lt;/p&gt;

&lt;p&gt;Deciding which patch to optimize would seem to depend on which upgrade path is more popular.  With the goal of decreasing total bandwidth usage, you could use server logs (or other usage data) to predict an initial distribution of versions currently in use.  Based on historical data, you could then predict which users are going to update their software before the next patch is released.  The aggregate of this data gives you a distribution of patch downloads.  Pick the most popular one, and optimize that.  Possibly, the others will be similarly small.  Or, given such a distribution, can that information be used in the adjustment process to generate a binary that minimizes changes over a set of patches, rather than one in particular?&lt;/p&gt;

&lt;p&gt;My guess is that Courgette optimizes each patch against only the latest version, assuming that most everyone will be running it.  With auto-updating software, a user would have to fail to open the program for an extended amount of time, longer than it takes to push out two patches.  This may not be likely.&lt;/p&gt;

&lt;p&gt;I also wonder what side effects the binary modifications might have on the updated binary.  By reordering or moving code, could it get slower?&lt;/p&gt;

&lt;p&gt;These are interesting points that I hope Google engineers may address if they ever decide to publish a paper describing Courgette in greater depth.  I hope they do.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-9007843602688153368?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/9007843602688153368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/08/courgette.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/9007843602688153368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/9007843602688153368'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/08/courgette.html' title='Courgette'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-1706583810721177405</id><published>2009-06-18T15:35:00.005-04:00</published><updated>2009-11-15T23:32:51.329-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>SSH Master</title><content type='html'>&lt;p&gt;I just discovered (via &lt;a href="http://www.torchbox.com/blog/ssh_tips_2.html"&gt;blog&lt;/a&gt;) an amazing setting for OpenSSH:  the MasterController.  You can now designate an SSH invocation to run a "master" session.  Then if I run SSH again connecting to the same computer, a new connection will be opened over that master session, without making a new TCP connection, establishing a new session key, or reauthenticating.  This greatly speeds up connection speeds, making things like distcc a lot more practical.&lt;/p&gt;

&lt;p&gt;I've know this was possible from using the commercial SSH for Windows on school computers, I just had no clue how to get it working from the Unix world until now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-1706583810721177405?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/1706583810721177405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/ssh-master.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/1706583810721177405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/1706583810721177405'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/ssh-master.html' title='SSH Master'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-3983476064063975125</id><published>2009-06-17T14:54:00.008-04:00</published><updated>2009-11-15T23:32:07.618-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Chrome parallelism</title><content type='html'>&lt;p&gt;If you haven't used Google's new &lt;a href="http://www.google.com/chrome"&gt;Chrome&lt;/a&gt; browser, it's definitely worth looking at.  The team at Google has written a browser that tries to address some of the shortcomings of other modern browsers.  Each part of a web page, the renderer, the JavaScript engine, plugins, etc. all operate in their own processes.  This lets each component be isolated from one another in separate address spaces.  So when Flash crashes, or Acrobat gets exploited, other tabs keep on going.  (I believe the latest Internet Explorer also does something similar to this.)  Having separate processes also helps reduce memory fragmentation.&lt;/p&gt;

&lt;p&gt;Compare this with the dominant method for writing parallel programs:  shared memory with locks and condition variables.  That system is fast, but plagued with problems.  Shared memory doesn't enforce exclusive access:  the programmer is responsible for getting the right locks.  When she doesn't, data races happen.  If she gets the ordering of some locks wrong, deadlocks could happen.  If locks are too fine-grained, she might introduce atomicity violations.  And if one thread fails, what can you do if it's holding locks and has left shared state inconsistent?&lt;/p&gt;

&lt;p&gt;A simpler life exists:  do not share memory, and use explicit communication between concurrent processes.  Instantly, locking goes away.  No deadlocks, no data races.  Failure handling becomes simpler, since no state can be corrupted.&lt;/p&gt;

&lt;p&gt;This kind of model is used in the &lt;a href="http://erlang.org/"&gt;Erlang&lt;/a&gt; language, and microkernels have featured these benefits for years.  Erlang was developed to be exceptionally fault-tolerant, and still drives critial hardware systems (in addition to Facebook's IM application).  These systems haven't been used extensively in part because shared memory is fast.  (And perhaps because of Erlang's syntax.)  As a result, we researchers try to replay data races quickly and design fault-tolerant wrappers for Linux kernel modules.&lt;/p&gt;

&lt;p&gt;I'm glad to see a significant desktop application decide that fault-tolerance and isolation is more important than raw speed.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-3983476064063975125?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/3983476064063975125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/chrome-parallelism.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/3983476064063975125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/3983476064063975125'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/chrome-parallelism.html' title='Chrome parallelism'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-1174282563318594129</id><published>2009-06-16T18:30:00.005-04:00</published><updated>2009-11-15T23:31:16.223-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>Restaurant deals and BBQ</title><content type='html'>&lt;p&gt;This week in Ann Arbor, restaurants all along main street will be wooing townies to sample their meals by offering fixed-price menus.  Waltz in and be treated to a selection of the restaurant's finest three-course meal for only $25.  It's all part of &lt;a href="http://mainstreetannarbor.org/2009/04/restaurant-week-june-14-19-2009/"&gt;Ann Arbor Restaurant Week&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My wife and I were looking through the menus online when we began to ask ourselves, "Just how much are we saving by eating out for this special event?"  After searching through a couple of menus, it turns out to be wrong for us.  Restaurants aren't offering special menu items, so we just priced the same meal.  Some places offered choices, so we chose the most expensive items to compare.&lt;/p&gt;

&lt;p&gt;We found that most places only save us a couple of dollars off the equivalent meal.  In one case, the fixed price dinner (with no options) would cost $1 more than normal.  But it's worse than that.  When we go out, we would order less food than 2 fixed meals:  we typically split appetizers and deserts.  Taking that into account, there wasn't a single restaurant we looked at that presented us a true savings.&lt;/p&gt;

&lt;p&gt;So what is the use of Restaurant Week?  It's all just advertising, pure and simple.&lt;/p&gt;

&lt;p&gt;Usually, I hate letting myself be influenced by advertising, but this time, the advertisers were successful.  Not in the way they intended though.&lt;/p&gt;

&lt;p&gt;We had been trying to pick out our favorite place for BBQ baby-back ribs in Ann Arbor, and we thought this would be a good time to experiment.  We headed home with a half-rack of ribs from our two top-runners:  &lt;a href="http://www.grizzlypeak.net/"&gt;Grizzly Peak&lt;/a&gt; and &lt;a href="http://www.bluetractor.net/"&gt;The Blue Tractor&lt;/a&gt;.  They're owned by the same parent company, but they do serve different food.  We'd been going back an forth on this issue for a while now, so we finally made the direct comparison.&lt;/p&gt;

&lt;p&gt;The winner:  Blue Tractor sauce on Grizzly Peak meat.  Grizzly Peak's meat was more tender and better quality, but the sauce was really too sweet.  Blue Tractor had a nice spicy sauce, but its meat was a little tough.  Since meat quality could vary by the night and by chef, we can't definitively say which place serves better ribs, but our bet's on Blue Tractor.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-1174282563318594129?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/1174282563318594129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/restaurant-deals-and-bbq.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/1174282563318594129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/1174282563318594129'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/06/restaurant-deals-and-bbq.html' title='Restaurant deals and BBQ'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-9076420659433969062</id><published>2009-05-30T16:00:00.002-04:00</published><updated>2009-11-15T23:29:20.779-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Dead Camera</title><content type='html'>&lt;p&gt;Today, I picked up my camera from Best Buy.  During my honeymoon a couple months ago, it took a dip into a melted snow cone, and it hasn't turned on since.  I bought an extended warranty with the camera, so I figured I would see what Best Buy could do.&lt;/p&gt;

&lt;p&gt;After dropping off the camera, it took Best Buy (through their Geek Squad service) two weeks to ship the camera to a central repair location before once looked at it.  I imagine it took a competent person about 10 minutes to look at it before deciding that "corrosive damage" wasn't covered by my warranty and the cost to repair it exceeded its value.  Three weeks later, I get my camera back.&lt;/p&gt;

&lt;p&gt;All right, it was questionable whether accidental damage was ever meant to be covered.  But still, what is the point of the extended warranty?&lt;/p&gt;

&lt;p&gt;As for Geek Squad, seriously, taking &lt;i&gt;weeks&lt;/i&gt; just to tell me that my damage is not covered is unacceptable.  If it wasn't covered, it would have been nice to tell me that when I tried to get it repaired.  It may be that centralized repair is the only way Best Buy can function, but I would hardly call this "functioning."  There is a better way:  ignore the Geek Squad and stay local.&lt;/p&gt;

&lt;p&gt;Now, I get to see just how difficult it is to disassemble my camera and clean it myself!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-9076420659433969062?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/9076420659433969062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/05/dead-camera.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/9076420659433969062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/9076420659433969062'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/05/dead-camera.html' title='Dead Camera'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5275928577461943852.post-5998366673534370666</id><published>2009-05-29T13:32:00.003-04:00</published><updated>2009-11-15T23:27:22.673-05:00</updated><title type='text'>Hello World</title><content type='html'>&lt;p&gt;Hi all, and welcome to my blog.&lt;/p&gt;

&lt;p&gt;This site isn't about much in particular, just whatever I feel like sharing at the time.  I'm a graduate student in computer science living in Michigan, so you're likely to see a very geeky theme throughout all these posts.   That's me!&lt;/p&gt;

&lt;p&gt;The title comes from three parts of my life, though not of equal importance.  I love π.  It's official:  I even have a t-shirt proclaiming it.  I like apples, both the kind you make cider out of (yay autumn in Michigan) and the kind you program.  I'm also a big foodie, finding solace in making a nice bowl of chili.  This blog is kind of a big mixture for all the interesting things going in my life.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5275928577461943852-5998366673534370666?l=warmapplepi.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warmapplepi.blogspot.com/feeds/5998366673534370666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warmapplepi.blogspot.com/2009/05/hello-world.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/5998366673534370666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5275928577461943852/posts/default/5998366673534370666'/><link rel='alternate' type='text/html' href='http://warmapplepi.blogspot.com/2009/05/hello-world.html' title='Hello World'/><author><name>Benjamin</name><uri>http://www.blogger.com/profile/07649856258183506778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
