<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    
    <title>Code V.igoro.us</title>
    <link>http://code.v.igoro.us/</link>
    <description>Dustin J. Mitchell</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.6 - http://www.s9y.org/</generator>
    <pubDate>Fri, 18 Nov 2011 18:53:15 GMT</pubDate>

    <image>
        <url>http://code.v.igoro.us/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Code V.igoro.us - Dustin J. Mitchell</title>
        <link>http://code.v.igoro.us/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>IT and Community</title>
    <link>http://code.v.igoro.us/archives/70-IT-and-Community.html</link>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/70-IT-and-Community.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=70</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=70</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Mozilla&#039;s IT team is pivoting to a more community-focused approach.  Our director of IT, mrz, has been &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/06/my-job-after-5-558-years/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/06/my-job-after-5-558-years/&quot;&gt;writing&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/12/step-1-community-it/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/12/step-1-community-it/&quot;&gt;extensively&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/blog.mozilla.com/mrz/2011/10/28/step-1-01-mozilla-it-mozcamp/&#039;]);&quot;  href=&quot;http://blog.mozilla.com/mrz/2011/10/28/step-1-01-mozilla-it-mozcamp/&quot;&gt;about&lt;/a&gt; &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/htmlpad.org/community-IT-slides/#&#039;]);&quot;  href=&quot;http://htmlpad.org/community-IT-slides/#&quot;&gt;it&lt;/a&gt; over the last few weeks.&lt;/p&gt;

&lt;p&gt;As you can imagine, the difficult part of this is to balance security with accessibility.  We&#039;d like to be open, but we can&#039;t give the keys to the kingdom out to anyone who promises to help.  The approach we&#039;re taking is to treat volunteers as we would part-time employees - post positions, interview, and then supervise to gain trust.  This is a fairly common model, actually, for any organization with volunteers and a need for security.  Youth programs, for example, generally do an interview and background check with new volunteers, and those volunteers will be paired with senior volunteers or staff for a while.&lt;/p&gt;

&lt;p&gt;However, it&#039;s a bit cumbersome, both for Mozilla and for potential volunteers.  We must design entire positions - ongoing tasks or roles that a volunteer can work on for an extended period of time - and then select a limited number of volunteers to fill those roles.  For potential volunteers, an application and interview can mean a long time (weeks?) before they get to do anything hands-on.  It also carries the risk that we&#039;d have to turn a qualified volunteer away due to lack of suitable positions.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;So what to do?&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;We need a more fluid way of interacting with potential contributors.  Since our bug database is public, we can begin by simply tagging a few bugs that are appropriate for newcomers -- things that don&#039;t require sensitive access and are well-encapsulated so they can be completed without extensive knowledge of Mozilla&#039;s infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/bit.ly/tTsnix&#039;]);&quot;  href=&quot;http://bit.ly/tTsnix&quot;&gt;Here&#039;s the list.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It&#039;s a bit short right now.  There are a few things that may help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can get better about identifying appropriate tasks and projects and making bugs out of them.
&lt;li&gt;We can identify a means of giving limited or sandboxed access to a new volunteer.
&lt;li&gt;Consumers of Mozilla&#039;s IT resources can begin tagging bugs, where Mozilla can provide the resources and volunteers can do the heavy lifting - got any ideas?
&lt;/ul&gt; 
 
    </content:encoded>

    <pubDate>Wed, 16 Nov 2011 23:05:24 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/70-guid.html</guid>
    
</item>
<item>
    <title>Subscribe to a google group with a different address?</title>
    <link>http://code.v.igoro.us/archives/67-Subscribe-to-a-google-group-with-a-different-address.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/67-Subscribe-to-a-google-group-with-a-different-address.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=67</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=67</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Google Groups is one place where, IMHO, Google pushes its hegemony too far, making it difficult to use.  I wanted to subscribe to puppet-users with my Mozilla address, but since I have a Google account, Groups assumes I want to subscribe with that address.  No!&lt;/p&gt;

&lt;p&gt;I found the fix with a bit of Googling (some irony there).  It involves editing a URL:&lt;/p&gt;

&lt;blockquote&gt;http://groups.google.com/group/puppet-users/boxsubscribe?email=email@domain.com&lt;/blockquote&gt;

&lt;p&gt;where you&#039;d substitute the name of the group you want for &lt;i&gt;puppet-users&lt;/i&gt; and add your email at the end. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 02 Sep 2011 15:04:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/67-guid.html</guid>
    
</item>
<item>
    <title>Nagios NSCA from Python</title>
    <link>http://code.v.igoro.us/archives/69-Nagios-NSCA-from-Python.html</link>
            <category>Code</category>
            <category>mozilla</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/69-Nagios-NSCA-from-Python.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=69</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=69</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve been working on improving the monitoring of the build slaves at Mozilla.  As part of this project, I needed to be able to submit passive check results to the Nagios servers via &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/community.nagios.org/2009/06/11/nagios-setting-up-the-nsca-addon-for-passive-checks/&#039;]);&quot;  href=&quot;http://community.nagios.org/2009/06/11/nagios-setting-up-the-nsca-addon-for-passive-checks/&quot;&gt;NSCA&lt;/a&gt; during system startup.  I&#039;m doing this from a Python script that needs to run on a wide array of systems using whatever random Python is available.  We run some oddball stuff, so the common denominator is Python 2.4.&lt;/p&gt;

&lt;p&gt;It turns out that there&#039;s no Python NSCA library, although there is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/search.cpan.org/dist/Net-Nsca/lib/Net/Nsca.pm&#039;]);&quot;  href=&quot;http://search.cpan.org/dist/Net-Nsca/lib/Net/Nsca.pm&quot;&gt;Net::Nsca&lt;/a&gt; in Perl.  So, I wrote one, and put it on github: &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/djmitche/pynsca&#039;]);&quot;  href=&quot;https://github.com/djmitche/pynsca&quot;&gt;https://github.com/djmitche/pynsca&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the moment, this only knows XOR, and only does service checks.  That&#039;s all I need, but hopefully it can be easily expanded to cover other purposes.  The one thing I want to avoid is adding mandatory requirements -- this should work, at least in plain-text and XOR modes, on a plain-vanilla Python installation.&lt;/p&gt;

&lt;p&gt;By the way, the startup script I&#039;m working on is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/hg.mozilla.org/build/puppet-manifests/file/tip/modules/buildslave/files/runslave.py&#039;]);&quot;  href=&quot;http://hg.mozilla.org/build/puppet-manifests/file/tip/modules/buildslave/files/runslave.py&quot;&gt;runslave.py&lt;/a&gt;, which includes a modified copy of &lt;i&gt;pynsca&lt;/i&gt; and does a number of other housekeeping jobs as well.  More on that in a subsequent post. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 20 May 2011 16:55:11 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/69-guid.html</guid>
    
</item>
<item>
    <title>Amanda's Transfer Mechanisms</title>
    <link>http://code.v.igoro.us/archives/68-Amandas-Transfer-Mechanisms.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/68-Amandas-Transfer-Mechanisms.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=68</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;There&#039;s been a bit of confusion on the mailing list and IRC about how Amanda assembles transfers out of transfer elements, and how transfer mechanisms influence that.  &lt;/p&gt;

&lt;p&gt;In the final form of a transfer, any two adjacent elements must have
the &lt;em&gt;same&lt;/em&gt; mechanism.  For example is, an upstream element speaking
XFER_MECH_PUSH_BUFFER cannot talk to a downstream element using
XFER_MECH_READ_FD (nor, more confusingly, XFER_MECH_PULL_BUFFER).  So each mechanism is an
isolated definition of &quot;here&#039;s how upstream and downstream should
talk&quot;.  They come in pairs because generally anything upstream can do
to downstream (e.g., upstream can write to downstream&#039;s fd) can occur
in reverse (e.g., downstream can read from upstream&#039;s fd).&lt;/p&gt;

&lt;p&gt;What makes this confusing is that if you specify a set of elements which can&#039;t talk directly to one another, then xfer.c will add &quot;glue&quot; elements &lt;em&gt;between&lt;/em&gt; the specified elements.  To make that concrete, imagine you specify a transfer as&lt;/p&gt;

&lt;pre&gt;source-holding --&gt; filter-xor --&gt; dest-fd&lt;/pre&gt;

(if you like practical examples, then imagine filter-xor is a buffer-based decompression filter, and you&#039;re pulling data from holding disk, decompressing, and sending to a pipe -- something amfetchdump would do).  Here are the mechanisms supported by each element:

&lt;pre&gt;
source-holding:
 XFER_MECH_PULL_BUFFER
&lt;/pre&gt;

&lt;pre&gt;
filter-xor
 XFER_MECH_PULL_BUFFER (input) and
 XFER_MECH_PULL_BUFFER (output)
or
 XFER_MECH_PUSH_BUFFER (input) and
 XFER_MECH_PUSH_BUFFER (output)
&lt;/pre&gt;

&lt;pre&gt;
dest-fd
 XFER_MECH_WRITEFD (input)
&lt;/pre&gt;

&lt;p&gt;In putting these together, source-holding and filter-xor can use the same mechanism (PULL_BUFFER).  This leaves filter-xor using PULL_BUFFER for output, but dest-fd does not support this.  So xfer.c adds a glue element that can speak PULL_BUFFER on input and WRITEFD on output.  This element basically loops in a thread, calling upstream-&gt;pull_buffer and write(downstream-&gt;input_fd, buffer).  So the final xfer looks like&lt;/p&gt;

&lt;pre&gt;
 source-holding --(PULL_BUFFER)--&gt; filter-xor --(PULL_BUFFER)--&gt; glue --(WRITEFD)--&gt; dest-fd
&lt;/pre&gt;

&lt;p&gt;Hopefully that helps to explain how the glue works.&lt;/p&gt;

&lt;p&gt;Note that one of the cool things about this arrangement is that in most cases the complexity is in the glue, not the elements.  In fact, in this case the glue provides the only thread that&#039;s required to run this transfer, so the other three element implementations don&#039;t need to manage threads at all. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 22 Jan 2011 14:47:13 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/68-guid.html</guid>
    
</item>
<item>
    <title>virtualenv for Perl</title>
    <link>http://code.v.igoro.us/archives/66-virtualenv-for-Perl.html</link>
            <category>Code</category>
    
    <comments>http://code.v.igoro.us/archives/66-virtualenv-for-Perl.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=66</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=66</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I absolutely love &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/pypi.python.org/pypi/virtualenv&#039;]);&quot;  href=&quot;http://pypi.python.org/pypi/virtualenv&quot;&gt;virtualenv&lt;/a&gt; for Python development.  It allows me to develop &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/buildbot.net&#039;]);&quot;  href=&quot;http://buildbot.net&quot;&gt;Buildbot&lt;/a&gt; against several versions of Python and several versions of its dependencies, without modifying my system&#039;s Python installation at all!&lt;/p&gt;

&lt;p&gt;Now, I need to do the same thing in Perl.  So I thought I&#039;d compare the two side-by-side.&lt;/p&gt;

&lt;p&gt;&lt;h2&gt;virtualenv&lt;/h2&gt;&lt;/p&gt;

&lt;pre&gt;
# install virtualenv locally
wget http://bitbucket.org/ianb/virtualenv/raw/tip/virtualenv.py
# set up a sandbox
python virtualenv.py sandbox
# activate it
source sandbox/bin/activate
# start installing stuff
easy_install buildbot
&lt;/pre&gt;

&lt;h2&gt;local::lib&lt;/h2&gt;

&lt;p&gt;There is no local::lib gentoo ebuild!  I&#039;m sure there&#039;s a good reason, but that&#039;s odd all the same!&lt;/p&gt;

&lt;pre&gt;
# install local::lib locally
wget http://search.cpan.org/CPAN/authors/id/G/GE/GETTY/local-lib-1.006007.tar.gz
tar -zxf local-lib-1.006007.tar.gz
cd local-lib-1.006007
perl Makefile.PL --bootstrap # (accept lots of defaults)
make test &amp;&amp;amp; make install
# activate it (permanently)
echo &#039;eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)&#039; &gt;&gt;~/.bashrc
eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)
# start installing stuff
perl -MCPAN -e install Config::General # (I have to accept the same defaults again??)
&lt;/pre&gt;

&lt;p&gt;I think virtualenv is the clear winner here!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Thu, 11 Nov 2010 10:48:43 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/66-guid.html</guid>
    
</item>
<item>
    <title>Firefox 4.0b7 - a few tweaks</title>
    <link>http://code.v.igoro.us/archives/65-Firefox-4.0b7-a-few-tweaks.html</link>
            <category>mozilla</category>
    
    <comments>http://code.v.igoro.us/archives/65-Firefox-4.0b7-a-few-tweaks.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=65</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=65</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;The new beta of Firefox 4.0 was released today.  I&#039;m not quite willing to run Minefield (nightlies), so I&#039;ve been eagerly awaiting this beta to fix some nagging but not show-stopper bugs in 4.0b6.  One of those involved bad interactions of App Tabs with Panorama.  Now the app tabs nicely decorate the side of each tab set in the panorama view.&lt;/p&gt;

&lt;p&gt;Another nice thing is that the Option-Space key combination, which opened panorama in 4.0b6, no longer does so.  That&#039;s OK - I found that to be too easy to press anyway.  It&#039;s now bound to Command-E (right there at the top of the &quot;View&quot; menu).&lt;/p&gt;

&lt;p&gt;Panorama has also been re-bound to swipe-up and swipe-down, which makes me less happy.  In most apps on the Mac, those swipes are equivalent to the &quot;Home&quot; and &quot;End&quot; keystrokes -- they scroll to the top or bottom of the current page.  So with a little help from my new co-workers, I discovered the settings to fix that.&lt;/p&gt;

&lt;p&gt;The full list of gesture bindings is &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/t.tal.by/post/95428783/changing-firefox-gestures&#039;]);&quot;  href=&quot;http://t.tal.by/post/95428783/changing-firefox-gestures&quot;&gt;written up here&lt;/a&gt;, but the two I needed to change are &lt;tt&gt;browser.gesture.swipe.up&lt;/tt&gt; and &lt;tt&gt;.down&lt;/tt&gt;.  The scrolling commands to bind to them are &lt;tt&gt;cmd_scrollTop&lt;/tt&gt; and &lt;tt&gt;cmd_scrollBottom&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;4.0 has a number of other great UI enhancements, too.  I&#039;m excited to see 4.0 finally released!&lt;/p&gt;

&lt;p&gt;[edit: fixed formatting] &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Wed, 10 Nov 2010 15:44:46 -0600</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/65-guid.html</guid>
    
</item>
<item>
    <title>irssi settings for status-in-nick</title>
    <link>http://code.v.igoro.us/archives/63-irssi-settings-for-status-in-nick.html</link>
            <category>mozilla</category>
    
    <comments>http://code.v.igoro.us/archives/63-irssi-settings-for-status-in-nick.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=63</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=63</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I am getting started in releng at Mozilla, and IRC provides a central meeting-place for the group.  As such, indicating your status to this group is an important, so others can know whether you&#039;re nearby to answer a question or take care of a problem.  This is generally done by adding suffixes to the IRC nickname, e.g., &quot;dustin|afk&quot; or &quot;dustin|lunch&quot;.&lt;/p&gt;

&lt;p&gt;Before I go further, I know that this is frown on, and even results in autoignores, in some corners of IRC.  If that&#039;s the case for you, read no further. &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/irssi.org/&#039;]);&quot;  href=&quot;http://irssi.org/&quot;&gt;Irssi&lt;/a&gt;&#039;s documentation is utterly incomplete.  So the only way to figure out how to configure something or write a script is to find and adapt examples.  So hopefully this entry will feed back into that pool.&lt;/p&gt;

&lt;p&gt;What I want is an easy way to bind some keystrokes to commands like &lt;tt&gt;/NICK dustin|afk&lt;/tt&gt;.  However, I want to be very careful &lt;i&gt;not&lt;/i&gt; to set this nick on other chatnets, particularly since I&#039;m generally known as djmitche there, not dustin.  So I began by writing a script that can double-check this:&lt;/p&gt;

&lt;pre&gt;
use strict;

use vars qw ($VERSION %IRSSI);

$VERSION = &#039;v1.0&#039;;
%IRSSI = (
          name        =&gt; &#039;moznick&#039;,
          authors     =&gt; &#039;dustin&#039;,
          contact     =&gt; &#039;dustin@mozilla.com&#039;,
          url         =&gt; &#039;http://code.v.igoro.us/&#039;,
          license     =&gt; &#039;GPLv2&#039;,
          description =&gt; &#039;Sets my nick status for Mozilla co-workers&#039;,
         );

use Irssi;

my $last_nick = &#039;&#039;;

sub is_mozilla {
    my ($server) = @_;
    if (!$server || $server-&gt;{&#039;chatnet&#039;} eq &#039;mozilla&#039;) {
        return 1;
    }

    Irssi::print(&quot;This isn&#039;t a mozilla channel!&quot;);
    return 0;
}

sub cmd_moznick {
    my ($data, $server, $channel) = @_;

    if (is_mozilla($server)) {
        my $new_nick = $data? &quot;dustin|$data&quot; : &quot;dustin&quot;;
        return if ($new_nick eq $last_nick);

        $server-&gt;command(&quot;NICK $new_nick&quot;);
        Irssi::print(&quot;nick set to $new_nick&quot;);
        $last_nick = $new_nick;
    }
}

Irssi::command_bind(&quot;moznick&quot;, &quot;cmd_moznick&quot;);
&lt;/pre&gt;

&lt;p&gt;This just adds a &lt;tt&gt;/MOZNICK&lt;/tt&gt; command that will set my nick, but only on a Mozilla chatnet.  Then I added an alias and some bindings.  I don&#039;t like irssi&#039;s configuration-writing stuff, as it&#039;s several times blown away my configuration.  Instead, I edit the config file directly.  So I have:&lt;/p&gt;

&lt;pre&gt;
aliases = { 
    moznick_moz = &quot;window goto #build; moznick $*&quot;;
};

keyboard = ( 
    { key = &quot;meta-space&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build&quot;; },
    { key = &quot;meta-z&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build brb&quot;; },
    { key = &quot;meta-x&quot;; id = &quot;multi&quot;; data = &quot;command moznick_build away; command away&quot;; }
);
&lt;/pre&gt;

&lt;p&gt;The advantage of the &lt;tt&gt;window goto&lt;/tt&gt; in the alias is that it will switch to a channel on the mozilla chatnet.  I&#039;d love to have a way to just switch to that chatnet without changing windows, but this isn&#039;t bad.&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 22 Oct 2010 12:06:04 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/63-guid.html</guid>
    
</item>
<item>
    <title>IPv6 and Amanda</title>
    <link>http://code.v.igoro.us/archives/61-IPv6-and-Amanda.html</link>
            <category>amanda</category>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/61-IPv6-and-Amanda.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=61</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=61</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Amanda joined the IPv6 revolution in November 2006 - all of the BSD-style authentication mechanisms can support IPv6 endpoints.  However, it&#039;s generally agreed that this was a mistake, and in this post I will talk about why that&#039;s the case. First, a bit of background on how Amanda&#039;s networking code works, and what had to change to support IPv6.  Amanda supports security mechanisms called BSD (the oldest), BSDUDP, and BSDTCP.  These all authenticate (if you can call it that) using the same sorts of checks that rsh uses.  The incoming connection is accepted if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is from a &quot;reserved&quot; port (less than 1024);&lt;/ii&gt;
&lt;li&gt;the address of the initiator has complementary forward and reverse DNS records in place; and&lt;/li&gt;
&lt;li&gt;the initiator&#039;s hostname is in &lt;tt&gt;.amandahosts&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During a backup operation, the Amanda server contacts each client host.  When using the BSD authentications, this triggers &lt;tt&gt;amandad&lt;/tt&gt;, which checks the above restrictions before beginning communication with the server.  This initial connection is packet-based, and can be carried out over UDP (for BSD and BSDUDP) or TCP (BSDTCP).  When a dump begins, several &quot;streams&quot; are opened to transmit the data, index, and metadata.  For BSD and BSDUDP, each stream is implemented as a distinct TCP connection, where the client sends a port number to the server and the server connects to that port.  BSDTCP multiplexes all streams over a single TCP connection using a basic type/length packet encapsulation.&lt;/p&gt;

&lt;p&gt;The first challenge in adding IPv6 support was to deal properly with IPv6 addresses when querying the DNS.  That meant switching to getaddrinfo and getnameinfo, as suggested by &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.kame.net/newsletter/19980604/&#039;]);&quot;  href=&quot;http://www.kame.net/newsletter/19980604/&quot;&gt;Jun-ichiro itojun Itoh&lt;/a&gt;. These functions bring their own compatibility problems, but Amanda uses &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.gnu.org/software/gnulib/&#039;]);&quot;  href=&quot;http://www.gnu.org/software/gnulib/&quot;&gt;gnulib&lt;/a&gt;, which provides compatibile implementations on systems where they are not available, minimizing the difficulty.&lt;/p&gt;

&lt;p&gt;We had a lot of trouble from systems such as RHEL3 possessing IPv6 support in the compiler environment but not in the kernel.  On such systems, code using constants like AF_INET6 or AI_V4MAPPED would compile without problems, but fail at runtime.  We added a WORKING_IPV6 preprocessor conditional, without which all references to IPv6-related symbols were removed.  At configure time, Amanda tries to create an IPv6 socket, and sets this conditional to true if it succeeds.  The &lt;tt&gt;--without-ipv6&lt;/tt&gt; configure option forcibly disables IPv6 support.&lt;/p&gt;

&lt;p&gt;The sockaddr structures and API for IPv6 are fairly difficult to use, particularly if it&#039;s not known in advance what sort of address they will contain.  We added a set of macros and utility functions in &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.c&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.c&quot;&gt;sockaddr-util.c&lt;/a&gt; and &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.h&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/blob/master/common-src/sockaddr-util.h&quot;&gt;sockaddr-util.h&lt;/a&gt;.  Using these macros throughout Amanda removed a significant amount of code that was conditionalized on both compile-time support and runtime address family, and centralized that logic in one easily-maintained place.&lt;/p&gt;

&lt;p&gt;On our build systems, we had to deal with different levels of support in the compile environment and the kernel.  This is fine: most Amanda users install binary packages that are produced on roughly the same OS distribution and version as was used for the build, so the kernel support is generally the same.  However, a third variable has tripped up lots of Amanda users: system configuration.  In particular, several newer Linux distributions have shipped with &lt;tt&gt;localhost&lt;/tt&gt; resolving to ::1 vi &lt;tt&gt;/etc/hosts&lt;/tt&gt;, but without enough interface configuration to actually utilize a socket bound to that address.  Amanda uses localhost sockets for inter-process communication, so this misconfiguration causes backup operations to fail.  The solution is to either finish configuring IPv6 on the host, remove the reference to ::1 in &lt;tt&gt;/etc/hosts&lt;/tt&gt;, or build Amanda with &lt;tt&gt;--without-ipv6&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;I have not yet heard of an Amanda installation where IPv6 communication is in use.  But I have heard from countless IPv4 users whose Amanda installations have failed due to bad IPv6 support.  At the moment, then, I feel that adding IPv6 support to Amanda has been a net negative for the project.  Although there is doubtless room for improvement, I will not entertain patches for better IPv6 support, for fear they will introduce new bugs for our exclusively IPv4 userbase.&lt;/p&gt;

&lt;p&gt;Of course, all of this may change as dual-stack networks grow more prevalent and are replaced by pure IPv6 networks!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Fri, 16 Jul 2010 22:04:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/61-guid.html</guid>
    
</item>
<item>
    <title>SSH With Snow Leopard</title>
    <link>http://code.v.igoro.us/archives/60-SSH-With-Snow-Leopard.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/60-SSH-With-Snow-Leopard.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=60</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=60</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I just upgraded my Macbook to Snow Leopard, and the upgrade has changed the way SSH authentication works.  I have set up a system I like quite a bit, now, and thought I would share. My usage pattern is that I do most of my work via &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.gnu.org/software/screen/&#039;]);&quot;  href=&quot;http://www.gnu.org/software/screen/&quot;&gt;GNU screen&lt;/a&gt; running on my login server, &lt;tt&gt;euclid&lt;/tt&gt;.  So I want a simple procedure that will connect me to that screen session, with a proper SSH agent set up.&lt;/p&gt;

&lt;p&gt;Snow Leopard automatically starts an &lt;tt&gt;ssh-agent&lt;/tt&gt; process at login.  This is great, but does not interoperate with &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/sshkeychain.sourceforge.net/&#039;]);&quot;  href=&quot;http://sshkeychain.sourceforge.net/&quot;&gt;SSHKeychain&lt;/a&gt;.  Dropping SSHKeychain is OK with me - I don&#039;t use SSH tunnels, so it really only acted as a GUI for passphrase entry.  It also ate CPU occasionally, which of course causes the macbook to become more painfully hot than usual.&lt;/p&gt;

&lt;p&gt;So I have three problems to solve: 1. automatically add my key to ssh-agent; 2. automatically expire the key at appropriate times (at my paranoia level, that&#039;s at system sleep); and 3. make multiple agent instances usable from the same shell session on the server.&lt;/p&gt;

&lt;h1&gt;Adding the Key at Connection Time&lt;/h1&gt;

&lt;p&gt;Adding the key is relatively straightforward.  I wrote a short script that Terminal runs when I hit ⌘-N or ⌘-T:&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash

# does ssh-agent not have a key?
if ! ssh-add -l; then
    ssh-add ~/.ssh/dustin || exit 1
fi

exec ssh -x -t euclid.r.igoro.us bin/startscreen
&lt;/pre&gt;

&lt;p&gt;This will prompt me for the passphrase when there is not already a key active, but proceed directly to the ssh invocation if the key situation is OK.  The &lt;tt&gt;-x&lt;/tt&gt; option to &lt;tt&gt;ssh&lt;/tt&gt; is there to turn off X11 forwarding; without this option, SSH will helpfully start the X11 app.  I think this is a great feature, but I don&#039;t use X11 apps very often, so I&#039;ve disabled it.&lt;/p&gt;

&lt;h1&gt;Expiring the Key Automatically&lt;/h1&gt;

&lt;p&gt;Mac OS has a nicely designed system in place to allow applications to get notified when the system is changing power states.  However, I wasn&#039;t interested in writing a full OS X app for this particular project.  Enter &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.bernhard-baehr.de/&#039;]);&quot;  href=&quot;http://www.bernhard-baehr.de/&quot;&gt;sleepwatcher&lt;/a&gt;.  This is a beautifully simple program that just executes scripts on particular power events.  I set this up to run via launchd, as directed in the README, and to run &lt;tt&gt;~/.ssh/sleep&lt;/tt&gt; on sleep.  That script contains:&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash

# first, don&#039;t inherit a socket (sleepwatcher doesn&#039;t get the user&#039;s env)
SSH_AUTH_SOCK=

# find some sockets
echo &quot;.ssh/sleep:&quot; `id`
for sock in /tmp/launch-*/Listeners; do
    if [ -w $sock ]; then
        echo &quot;Trying to remove .ssh/dustin from socket $sock&quot;
        SSH_AUTH_SOCK=$sock /opt/local/bin/ssh-add -d ~/.ssh/dustin
    else
        echo &quot;Skipping unwritable socket $sock&quot;
    fi  
done
&lt;/pre&gt;

&lt;p&gt;The for loop is required because a script run from sleepwatcher doesn&#039;t inherit the &lt;tt&gt;SSH_AUTH_SOCK&lt;/tt&gt; variable that points to the running SSH agent.  The loop simply searches for a writable SSH socket of the pattern used by the system&#039;s agent.&lt;/p&gt;

&lt;h1&gt;SSH Agent and Screen&lt;/h1&gt;

&lt;p&gt;If you naïvely set up an SSH agent, connect to a remote system, and start screen there, things will work great - until you disconnect from the screen session.  When you connect to the remote system, SSH forwards the agent connection for you, and sets &lt;tt&gt;SSH_AUTH_SOCK&lt;/tt&gt; on the remote system to point to this forwarded socket.  Screen passes this variable along blindly, so it appears in all of the shells opened in screen windows, and things work as you&#039;d expect.  When that SSH connection is removed, and a new one established, the forwarded agent appears at a new socket.  But those shells running in screen windows are still pointing to the old name, and will no longer be able to connect.&lt;/p&gt;

&lt;p&gt;The fix is to create a socket with a well-known name that will not change from connection to connection.  The following script takes care of it.  WARNING: this script is vulnerable to /tmp race conditions.  I am the only user on my servers, so this doesn&#039;t bother me, but fixing it should be relatively straightforward.&lt;/p&gt;

&lt;pre&gt;
#! /bin/bash
# hard-link the SSH socket to one with a fixed name on the local
# machine, and set SSH_AUTH_SOCK to point to that fixed name.  Later
# invocations of this script will change the link, but the name will
# remain valid, allowing existing shells to continue to function.
setup_fixed_socket() {
  local old_socket=&quot;$SSH_AUTH_SOCK&quot;
  local socket_dir=&quot;/tmp/$(uname -n)-$(id -u)&quot;
  local socket_file=$socket_dir/agent

  # set up the directory and permissions
  [ -e $socket_dir ] || mkdir -p $socket_dir
  chmod 700 $socket_dir

  # remove an existing link
  [ -e $socket_file ] &amp;&amp;amp; rm $socket_file

  # hard-link in the new one
  ln $old_socket $socket_file

  # return the new socket
  echo $socket_file
}

# this variable will be exported to every shell opened by this
# invocation of screen -- even subsequent connections to it.  This
# variable may live for days or weeks.
export SSH_AUTH_SOCK=$(setup_fixed_socket)

# finally, fire up screen.  Try reattaching to a running
# session; otherwise start up a new one
screen -R -DD ${@} || screen
&lt;/pre&gt;
 
    </content:encoded>

    <pubDate>Sat, 10 Jul 2010 14:27:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/60-guid.html</guid>
    
</item>
<item>
    <title>What's New in Amanda: The End of Fragmentation</title>
    <link>http://code.v.igoro.us/archives/59-Whats-New-in-Amanda-The-End-of-Fragmentation.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/59-Whats-New-in-Amanda-The-End-of-Fragmentation.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=59</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=59</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;Most of my posts in this series have been about features that are available in a released version of Amanda.  This time, I want to share a project I&#039;m working on right now - one that will be available in Amanda-3.2.  I&#039;m reworking the way Amanda writes its data to tape (or any other kind of storage) to make it more efficient, more reliable, and simpler to configure.&lt;/p&gt;

&lt;p&gt;Historically, Amanda&#039;s conservative approach to finicky tape hardware has meant that it wasted some space at the end of each tape.  With the changes I&#039;m working on, Amanda will no longer waste this space, and can also avoid some needless copying of data in most cases, with a minimum of additional risk. &lt;h1&gt;Amanda&#039;s Storage Format&lt;/h1&gt;&lt;/p&gt;

&lt;p&gt;Before examining the new functionality, let&#039;s look at Amanda&#039;s storage format.  Amanda treats all storage devices like tapes&lt;sup&gt;1&lt;/sup&gt; - a set of sequentially numbered data files of arbitrary size, each composed of a sequence of fixed-size blocks.  Each file begins with a one-block header that identifies the dump and gives information about its contents.  The header is followed by blocks of raw data.&lt;/p&gt;

&lt;p&gt;Amanda supports writing a dump across multiple tapes - spanning.&lt;sup&gt;2&lt;/sup&gt;  The technique is this: a dump is split into a sequence of parts, and each part is written a a single file on a volume.  During recovery, Amanda reads the parts in sequence, and concatenates their data to reproduce the original dumpfile.  Usually all parts are the same size, and this size is generally 1-5% of the tape capacity.&lt;/p&gt;

&lt;h1&gt;Better Safe than Sorry - At a Cost&lt;/h1&gt;

&lt;p&gt;Amanda was originally designed around tape drives - in fact, if you look at the history of Linux kernel support for tape drives, it is closely intertwined with Amanda development.  Tape drives are finicky beasts, and in many cases cannot distinguish the end of the tape (called EOM) from any other fatal error.  Worse, tape drives employ large caches to ensure they can write continuously, and when an error occurs all of the data in that cache is lost, and there is no way for Amanda to determine how much actually made it onto the tape.  Beginning a new on-tape file (writing a filemark) flushes the cache and signals any errors immediately.&lt;/p&gt;

&lt;p&gt;Since time immemorial, then, Amanda has treated any error from the tape drive as EOM, and assumed that all data written since the last filemark is potentially corrupt.  That means that the part in progress when the error occurred is logged as PARTIAL, and Amanda will start at the beginning of that part on the next tape.&lt;/p&gt;

&lt;p&gt;The PARTIAL part is recorded in the catalog, but will not be used for recovery, so it is effectively wasted space.  A little arithmetic will tell you that, on average, each tape will waste half of the part size.  This is at least excusable with real tape drives; with vtapes (disk), this wasted space is completely unnecessary.  Worse, vtapes are most flexible when they are kept small and dumps are spanned over many vtapes per night; but the wasted space increases linearly with the number of vtapes used.&lt;/p&gt;

&lt;p&gt;In order to rewind a part and write it again on a new tape, Amanda also needs to keep its data somewhere, called the part cache.  When the dump is on the holding disk, the holding disk acts as a part cache.  Otherwise, Amanda can cache parts in memory or on disk.  Caching in memory is faster, but requires a lot of RAM for a reasonable part size.  Caching on disk allows larger parts, but is considerably slower.&lt;/p&gt;

&lt;h1&gt;Logical EOM&lt;/h1&gt;

&lt;p&gt;More recent tape drives (those made in the last decade or so) have a feature called &quot;early warning&quot;.  With this feature enabled, the drive alerts the host system when it is &quot;near&quot; EOM, and flushes the cache to tape.  Exactly what &quot;near&quot; means is not specified in the SCSI standard, but in general there&#039;s room to flush the cache and write a filemark, at least.  This is sometimes called a logical EOM - LEOM.&lt;/p&gt;

&lt;p&gt;Amanda can take advantage of this functionality to cleanly finish a part before running headlong into a physical EOM.  This eliminates the wasted space for a PARTIAL part, and also eliminates the need to cache parts, since rewinding is not required.  In one small change (well, OK, it&#039;s &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&quot;&gt;about 4,300 lines&lt;/a&gt;), Amanda gets faster and uses storage space more efficiently.  What&#039;s not to love?&lt;/p&gt;

&lt;p&gt;Better yet, all of the non-tape devices (vtapes, S3 devices, DVD-ROMs, etc.) can easily emulate LEOM, so backups to these devices will automatically benefit from this improvement.&lt;/p&gt;

&lt;h1&gt;In the Code&lt;/h1&gt;

&lt;p&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda/compare/1bc521c5ce1be2d144fefc8ce37917c55ab690e8...6a087798ea0c9945093226150da37d5af49d1810&quot;&gt;Three important patches&lt;/a&gt; toward this functionality were just committed.  What remains is to set up real LEOM support for the VFS device (vtapes) and for the tape device.&lt;/p&gt;

&lt;p&gt;The VFS device can, of course, trivially emulate LEOM when it is enforcing the MAX_VOLUME_USAGE property - the vtape length.  However, predicting when a filesystem will run out of space is much more difficult.  We are still discussing options, and I would love to hear suggestions here or on the mailing list.&lt;/p&gt;

&lt;p&gt;As for the tape device, it will assume that LEOM is not supported unless the user configures it explicitly (with the &quot;LEOM&quot; device property) or we can determine support for LEOM from the operating system at runtime.  Unfortunately, this is one of those areas so technical that only a half-dozen people know how it works, so it may take me some time to track down this information for non-Linux operating systems.  Again, advice and assistance is welcome!&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
&lt;li&gt;&lt;sup&gt;1&lt;/sup&gt;This is an ages-old design decision, but one that artificially constrains Amanda&#039;s flexibility, especially with vtapes.
&lt;li&gt;&lt;sup&gt;2&lt;/sup&gt;In fact, Amanda has supported spanning for something like 7 years now.  Yet I occasionally see users in #amanda complaining about this serious limitation and wondering when we&#039;re going to do anything about it.  Will 2003 be soon enough?
&lt;/ul&gt;
 
    </content:encoded>

    <pubDate>Thu, 08 Jul 2010 18:07:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/59-guid.html</guid>
    
</item>
<item>
    <title>What's New in Amanda: Hackability</title>
    <link>http://code.v.igoro.us/archives/45-Whats-New-in-Amanda-Hackability.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/45-Whats-New-in-Amanda-Hackability.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=45</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=45</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;It&#039;s been a while since I&#039;ve posted about recent development in &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/amanda.org&#039;]);&quot;  href=&quot;http://amanda.org&quot;&gt;Amanda&lt;/a&gt;, but it&#039;s not for lack of interesting topics!&lt;/p&gt;

&lt;p&gt;Today I want to talk a little bit about Amanda&#039;s development.  Historically, Amanda has always had a small, core group of developers who do the lion&#039;s share of the development work.  There are probably lots of reasons for this, not least of which is that a backup application isn&#039;t the sexiest project on which to spend your spare time.  But I think there&#039;s a deeper reason, and it has to do with hackability.
 Amanda was originally written in C, which means any changes require the full set of developer tools.  For example, just to fix a typo in an error message, you would need to find the source, configure and compile it, find and fix the error message, and recompile to test.  Fixing something more substantial in the highly interdependent Amanda codebase also requires a deep understanding of many parts of Amanda - from the obscure configuration interface to the oddly interlinked disklist structure.  This level of programming skill is not common among Amanda&#039;s user base (systems administrators), and I can count the people who understand the disklist structure on one hand.&lt;/p&gt;

&lt;p&gt;The result has been a paltry flow of patches from anyone but the core hackers.  Furthermore, no entry path has been available by which newcomers could work their way up to being core developers.  While I don&#039;t want to disparage the work of any of the great programmers who have written Amanda over the years, it&#039;s a shame that there have been so few at any time, and I worry about what would happen if the number were to reach zero.  So what to do?&lt;/p&gt;

&lt;h1&gt;$hackability++&lt;/h1&gt;

&lt;p&gt;We&#039;ve done a few things to try to make Amanda more hackable.  Probably the biggest change is to rewrite parts of Amanda in Perl.  I&#039;m asked &quot;why&quot; quite often, and while we had a lot of reasons, two relate directly to hackability.  First, more sysadmins know Perl than C, because Perl is quite often used to build the &quot;glue&quot; that links systems together.  Interestingly, based on many conversations, it seems that Python may also have been a good choice, as I &lt;a href=&quot;http://code.v.igoro.us/archives/12-Perl-vs.-Python.html&quot;&gt;suspected when I first proposed the rewrite&lt;/a&gt;.  But it&#039;s too late now!&lt;/p&gt;

&lt;p&gt;Second, and more importantly, Perl code can be hacked in place.  If &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/man/amvault.8.html&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/man/amvault.8.html&quot;&gt;amvault&lt;/a&gt; isn&#039;t acting the way you want it to, just open up &lt;tt&gt;/usr/sbin/amvault&lt;/tt&gt; and tweak away.  No need to download the source, no need to compile, no segmentation faults, just hacking.  When you&#039;re done, run a quick &lt;tt&gt;diff&lt;/tt&gt; and send the results to amanda-hackers.&lt;/p&gt;

&lt;p&gt;Even users who do not know Perl can take advantage of this &lt;i&gt;in-situ&lt;/i&gt; hackability.  Within Amanda&#039;s C code, if I want a user to try a patch, that user must figure out how to download Amanda&#039;s source, apply the patch, configure, compile, and install.  None of those steps are trivial.  With Perl code, I can often provide a patch that is simple enough to be applied directly to the installed executables by hand, or with a simple application of &lt;tt&gt;patch&lt;/tt&gt;.  Everyone stays focused on the bug under investigation, and the user&#039;s backups are up and running that much more quickly.&lt;/p&gt;

&lt;h1&gt;New APIs&lt;/h1&gt;

&lt;p&gt;As I mentioned before, historically Amanda&#039;s code has been highly interdependent.  Details of the implementation of the holding disk were spread over most of the files in the server implementation.  The dumplevel -987 has a special meaning that is documented nowhere, but referenced in several source files.  All of this makes new development difficult, because it&#039;s impossible to &quot;slice off&quot; and study a portion of Amanda in isolation.&lt;/p&gt;

&lt;p&gt;The solution here is to create abstract interfaces, where new functionality can be &quot;plugged in&quot; and Amanda can use it without changes.  The Amanda developers have abused the term &quot;API&quot; for these interfaces, and we now have quite a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Application_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Application_API&quot;&gt;Application API&lt;/a&gt; - an abstraction of backup clients, e.g., &lt;a href=&quot;http://code.v.igoro.us/archives/50-Whats-New-in-Amanda-Postgres-Backups.html&quot;&gt;ampgsql&lt;/a&gt; for Postgres;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Device_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Device_API&quot;&gt;Device API&lt;/a&gt; - an abstraction of backend storage devices, such as tape, disk, cloud, or DVD-RW;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Changer_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Changer_API&quot;&gt;Changer API&lt;/a&gt; - an abstraction of tape changers and other mechanisms for selecting from a set of volumes; and
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/wiki.zmanda.com/index.php/Script_API&#039;]);&quot;  href=&quot;http://wiki.zmanda.com/index.php/Script_API&quot;&gt;Script API&lt;/a&gt; - a means of invoking scripts before or after certain events during a backup.
&lt;/ul&gt;

&lt;p&gt;This strategy has already paid off: we have seen several new scripts and applications contributed, and the DVD-RW device arrived out of the blue as a contribution from someone who found it useful.&lt;/p&gt;

&lt;h1&gt;Other Changes&lt;/h1&gt;

&lt;p&gt;In the interest of greater accessibility to new hackers, we have also put Amanda on &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/github.com/zmanda/amanda&#039;]);&quot;  href=&quot;http://github.com/zmanda/amanda&quot;&gt;github&lt;/a&gt; and created a set of good &quot;beginner&quot; projects.  Zmanda has even offered to &lt;a href=&quot;http://code.v.igoro.us/archives/53-Want-to-work-on-Amanda.html&quot;&gt;pay people to hack on Amanda&lt;/a&gt;, as a way of easing the cost of entry.  I also try to point out interesting projects on the Amanda mailing list, particularly projects that Jean-Louis and I probably will not find time to work on.&lt;/p&gt;

&lt;p&gt;The idea here is to encourage new hackers to pick up a well-scoped project to become familiar with Amanda.  The hackers can then move on to more sophisticated projects that meet their particular backup needs or address a particular interest.&lt;/p&gt;

&lt;h1&gt;Will You Join Me?&lt;/h1&gt;

&lt;p&gt;So Amanda is ready for you.  When can you start?&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Thu, 01 Jul 2010 22:29:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/45-guid.html</guid>
    
</item>
<item>
    <title>IPv6 Configuration</title>
    <link>http://code.v.igoro.us/archives/57-IPv6-Configuration.html</link>
            <category>Sysadmin</category>
    
    <comments>http://code.v.igoro.us/archives/57-IPv6-Configuration.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=57</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=57</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;&lt;div style=&quot;float:right&quot;&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/ipv6.he.net/certification/scoresheet.php?pass_name=djmitche&#039;]);&quot;  href=&quot;http://ipv6.he.net/certification/scoresheet.php?pass_name=djmitche&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://ipv6.he.net/certification/create_badge.php?pass_name=djmitche&amp;amp;badge=3&quot; width=229 height=137 border=0 alt=&quot;IPv6 Certification Badge for djmitche&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div&gt;I&#039;ve been meaning to get IPv6 set up on my local network for some time.  My only practical reason is that &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/amanda.org&#039;]);&quot;  href=&quot;http://amanda.org&quot;&gt;Amanda&lt;/a&gt; supports IPv6 and I should test that support.  It was also a good chance to re-immerse myself in network configuration, and Hurricane Electric has a neat &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/ipv6.he.net/certification&#039;]);&quot;  href=&quot;http://ipv6.he.net/certification&quot;&gt;certification process&lt;/a&gt; to add some motivation. I began by getting local IPv6 connectivity set up over the HE tunnel, using my Gentoo systems.  This was fairly straightforward, as the Gentoo net scripts natively support IPv6.  The firewall system I use (&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.shorewall.net/&#039;]);&quot;  href=&quot;http://www.shorewall.net/&quot;&gt;Shorewall&lt;/a&gt;) does not support IPv6 directly.  Instead, there&#039;s a parallel &lt;tt&gt;shorewall6&lt;/tt&gt; package to install.  Aside from the annoyance of setting up two separate firewalls, this did not cause appreciable difficulties.  With all of this in place, I was at the &quot;Explorer&quot; level.&lt;/p&gt;

&lt;p&gt;The next task was to set up a working IPv6 desktop.  My home network uses 802.1q VLAN tagging to layer both an external, publicly routable IPv4 network (99.89.149.16/29 on VLAN 20) and an internal, NAT&#039;d IPv4 network (172.16.1/24 on VLAN 10).  I wanted to make VLAN 10 a dual-stack network, rather than invent a new VLAN for my IPv6 network.  Initially, I didn&#039;t realize that HE uses, in my case, 2001:470:1f10:826::0/64 just for the tunnel (yes, two addresses out of 2&lt;sup&gt;64&lt;/sup&gt; used -- maybe we&#039;ll need IPv8 sooner than we think!).  I assumed that the /64 I was allocated was to be used for all of my nodes, and tried to subnet it locally, using 2001:470:1f10:826::0/112 for the tunnel and 2001:470:1f10::1/112 for the internal network.  This worked with manual configuration, but &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.litech.org/radvd/&#039;]);&quot;  href=&quot;http://www.litech.org/radvd/&quot;&gt;radvd&lt;/a&gt; seemed to always want to advertise a /64.  A little reading about the RA protocol showed this to be correct: RA provides the high 64 bits (the network portion), and the clients provide the low 64 bits using EUI-64.  I was stymied until I looked at the tunnel details again and noticed that the &quot;Routed IPv6 Prefixes&quot; section listed a different prefix (2001:470:1f11:826/64).&lt;/p&gt;

&lt;p&gt;With this in place, the subnet and firewall setup was a breeze.  Using a manual configuration on my MacBook, I was able to communicate via IPv6.  However, the stateless autoconfiguration didn&#039;t work.  I briefly tried DHCPv6, but Macs do not support it.  The RA client correctly combines the network and EUI-64 components to create a full address, and it correctly copies the link-local address of the router, but it does not set up a default route using that router, making the whole thing fairly useless.  A trip to #ipv6 confirmed that Macs are, indeed, broken this way, so I stopped worrying about it.&lt;/p&gt;

&lt;p&gt;The remainder of the certification process involved getting Apache, Postfix, and Bind speaking IPv6, none of which was very difficult.  I did discover that BIND&#039;s $ORIGIN didn&#039;t work correctly.  A zonefile with&lt;/p&gt;

&lt;pre&gt;
$ORIGIN 6.2.8.0.1.1.f.1.0.7.4.0.1.0.0.2.ip6.arpa.
8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR knuth.r.igoro.us.
&lt;/pre&gt;

&lt;p&gt;didn&#039;t work, but spelling out the entire reversed address did.  I&#039;m sure this was due to a typo, but several checks didn&#039;t reveal anything.&lt;/p&gt;

&lt;p&gt;However, I&#039;m now stuck at the Guru level until GoDaddy starts supporting IPv6 glue for the &lt;tt&gt;.us&lt;/tt&gt; TLD.  I feel cheated, somehow!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sun, 27 Jun 2010 16:27:12 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/57-guid.html</guid>
    
</item>
<item>
    <title>LCD Display and TMP102 sensor</title>
    <link>http://code.v.igoro.us/archives/55-LCD-Display-and-TMP102-sensor.html</link>
            <category>Arduino</category>
    
    <comments>http://code.v.igoro.us/archives/55-LCD-Display-and-TMP102-sensor.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=55</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=55</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;It is &lt;i&gt;incredibly&lt;/i&gt; easy to throw things together with an Arduino.  It&#039;s common to see criticism of the device when it&#039;s used in in projects that don&#039;t require even a fraction of its power, and that might be justified.  As a flexible platform for test-driving complex modules, though, the Arduino hits the mark perfectly on flexibility and usability.&lt;/p&gt;

&lt;p&gt;I don&#039;t have a particular project in mind for my Arduino, but since I don&#039;t have a multimeter or an oscilloscope, I want to use it as a test harness for various basic components as I experiment with them.  To this end, I bought a cute &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.sparkfun.com/commerce/product_info.php?products_id=9054&#039;]);&quot;  href=&quot;http://www.sparkfun.com/commerce/product_info.php?products_id=9054&quot;&gt;16x2 character amber LCD display&lt;/a&gt;.  With thoughts of building a fermentation-temperature monitor and learning about the I&lt;sup&gt;2&lt;/sup&gt;C bus, I also bought a relatively cheap &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.sparkfun.com/commerce/product_info.php?products_id=9418&#039;]);&quot;  href=&quot;http://www.sparkfun.com/commerce/product_info.php?products_id=9418&quot;&gt;TMP102 and breakout board&lt;/a&gt;.  With a little bit of reading, I was able to stitch them together quickly and easily.
 &lt;h2&gt;LCD Display&lt;/h2&gt;&lt;/p&gt;

&lt;p&gt;The display I purchased is command-driven via a 4-bit parallel port.  It&#039;s a ST7066, compatible with HD44780.  There are two datasheets available -- one for the &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.sparkfun.com/datasheets/LCD/st7066.pdf&#039;]);&quot;  href=&quot;http://www.sparkfun.com/datasheets/LCD/st7066.pdf&quot;&gt;ST7066&lt;/a&gt;, and one for the &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.sparkfun.com/datasheets/LCD/ADM1602K-NSA-FBS-3.3v.pdf&#039;]);&quot;  href=&quot;http://www.sparkfun.com/datasheets/LCD/ADM1602K-NSA-FBS-3.3v.pdf&quot;&gt;assembled board&lt;/a&gt;.  The latter adequately described the pinout through unattributed copying from the former, but was otherwise useless.  &quot;Qiu&quot;, &quot;Chen&quot;, and &quot;Ye&quot;, all three of whom helpfully signed the cover page, should be ashamed.  Anyway, here&#039;s a brief description of the pins and some more details I culled from the ST7066 datasheet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;V&lt;sub&gt;ss&lt;/sub&gt; (ground) and V&lt;sub&gt;dd&lt;/sub&gt; (positive supply): these are rated up to 7V, so running from the Arduino&#039;s 5V supply is great.&lt;/li&gt;
&lt;li&gt;V&lt;sub&gt;0&lt;/sub&gt; sets the LCD contrast.  Short on jumpers, I initially assumed I could leave this unconnected to get &quot;reasonable&quot; contrast.  Not so!  I tried setting up a few voltage dividers to get the right contrast, without any luck.  Plan to add a 10k pot between ground and the positive supply, and tie the wiper to this pin.&lt;/li&gt;
&lt;li&gt;RS (register select) selects whether an operation is to configuration registers (0) or RAM (1)&lt;/li&gt;
&lt;li&gt;R/W (read/write) selects whether an operation reads or writes to the device&lt;/li&gt;
&lt;li&gt;DB0-DB7 is the data bus&lt;/li&gt;
&lt;li&gt;E (enable), strobed to move a byte across the data bus&lt;/li&gt;
&lt;li&gt;LED+/LED- supply power to the LED backlight, and can be wired directly to the 5V supply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Arduino has a lot of digital pins, but all the same it&#039;s handy to save a few pins.  The display supports reading character and font data, but that&#039;s not much use: the Arduino can remember whatever it needs to.  So we won&#039;t need the R/W pin, and can tie it to ground (read) instead.&lt;/p&gt;

&lt;p&gt;The display can operate in two data lengths (controlled by the DL configuration bit).  In the default mode, only 4 bits (DB4-DB7) on the parallel bus are used.  The display starts in 8-bit mode, but fortunately the DL bit comes in at pin DB4, so it&#039;s relatively easy to reset the data length with only 4 pins connected.  Note that there&#039;s an odd sequencing required here, where you need to set 8-bit mode three times &lt;i&gt;before&lt;/i&gt; setting 4-bit mode.  Don&#039;t worry, though: the Arduino &lt;i&gt;LiquidCrystal&lt;/i&gt; library takes care of that for you.&lt;/p&gt;

&lt;p&gt;So aside from pins tied to V+ or GND, we only need 6 digital I/O pins.  It&#039;s best to avoid the pins that have other functions on the Arduino: 0 and 1 are RS-232 I/O, and 13 is the onboard LED.  I used pins 2-5 for the data bus, pin 12 for E, and pin 13 for RS, since that was at the top of the LiquidCrystal example.  V&lt;sub&gt;ss&lt;/sub&gt;, LED-, and R/W go to GND; V&lt;sub&gt;dd&lt;/sub&gt; and LED+ go to the 5V supply; and V&lt;sub&gt;0&lt;/sub&gt; is wired as described above.&lt;/p&gt;

&lt;p&gt;From there on out, it&#039;s a straightforward application of the &lt;i&gt;LiquidCrystal&lt;/i&gt; library:&lt;/p&gt;

&lt;pre&gt;
#include &amp;lt;LiquidCrystal.h&amp;gt;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

void setup() {    
    lcd.begin(16, 2); 
}

void loop() {
    lcd.setCursor(0, 0);
    lcd.print(&quot;Hello, World&quot;);
}
&lt;/pre&gt;

&lt;p&gt;Note that the display itself is capable of a number of interesting things not supported by the library.  It has an 80-byte character memory, and can scroll that through the display without rewriting the entire screen every time.  It can also accept 8 custom 5x11 glyphs, making rudimentary animation possible.&lt;/p&gt;

&lt;h2&gt;TMP102&lt;/h2&gt;

&lt;p&gt;The TMP102 is ridiculously tiny - smaller than the SMD resistors that Sparkfun has placed around it on the breakout board.  It senses temperature internally, which means it&#039;s basically monitoring the temperature of its leads.&lt;/p&gt;

&lt;p&gt;The device speaks I&lt;sup&gt;2&lt;/sup&gt;C (also known as the two-wire interface or SMBus), which makes it pretty easy to connect to the Arduino.  The MCU speaks I&lt;sup&gt;2&lt;/sup&gt;C via hardware, so the corresponding Arduino library doesn&#039;t even need to bit-bang the data.  On the Duemilanove, it uses analog-in pin 4 for SDA and analog-in pin 5 for SCL.  You&#039;ll also need to hook up V+ to the &lt;b&gt;3.3V pin&lt;/b&gt; on the Arduino (the device is only specified for 3.6V) and GND to the TMP102&#039;s GND.  Finally, the TMP102&#039;s ADD0 pin can cleverly select one of four addresses for the device by tying it to one of these four pins.  I tied it to GND, giving address 0b1001000.  ALARM is an output pin, so you can leave it unconnected.&lt;/p&gt;

&lt;p&gt;The TMP102 is a very nice low-power device that&#039;s designed to handle several common tasks without any interaction from the MCU - it can trigger an interrupt when the temperature strays from a configured boundaries, poll temperature on a relatively slow schedule, or even poll on command.  I didn&#039;t use any of that, relying on the device to simply sample the temperature on its own schedule.&lt;/p&gt;

&lt;p&gt;The TMP102 has four registers, but we&#039;ll only use one -- temperature (0b01).  Like many devices, this one multiplexes addresses and data over the same bus.  To read a register, you first select the register by writing it to the device, then read the 16-bit value, again with the MSB first.  Once a register is selected, it can be read multiple times.&lt;/p&gt;

&lt;p&gt;The device&#039;s temperature register contains a two&#039;s-complement 12-bit value, left-aligned, where 0x7FF is 128&amp;deg;C; equivalently, a change of one unit in the 12-bit value is equivalent to 0.0625&amp;deg;C.&lt;/p&gt;

&lt;h2&gt;Putting it Together&lt;/h2&gt;

&lt;p&gt;The obvious combination of these tools is to display the ambient temperature on the LCD screen.  Here&#039;s the program to do so:&lt;/p&gt;

&lt;pre&gt;
#include &amp;lt;Wire.h&amp;gt;
#include &amp;lt;LiquidCrystal.h&amp;gt;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

#define TEMP_REG 0b00000000
int tmp102 = 0b1001000;  // with ADD0 tied to ground

void setPR(int reg) {
  Wire.beginTransmission(tmp102);
  Wire.send(reg);
  Wire.endTransmission();
}

int getReg() {
  unsigned char lo, hi;

  Wire.requestFrom(tmp102, 2);
  hi = Wire.receive();
  lo = Wire.receive();
  return (hi &lt;&lt; 8) + lo;
}

void setup()   {    
  lcd.begin(16, 2);
  Wire.begin();
  setPR(TEMP_REG);
}

void show_temp() {
  int temp_reg = getReg();
  lcd.setCursor(0, 0);
  show_bin(temp_reg);

  temp_reg &gt;&gt;= 4;

  float temp_C = temp_reg * 0.0625;
  float temp_F = (temp_C * 9 / 5) + 32;

  lcd.setCursor(0, 0);
  lcd.print(temp_C);
  lcd.print(&quot;\xdf&quot;&quot;C  &quot;);
  lcd.setCursor(0, 1);
  lcd.print(temp_F);
  lcd.print(&quot;\xdf&quot;&quot;F  &quot;);
}

void loop() {
  show_temp();
}
&lt;/pre&gt;

&lt;p&gt;The &lt;tt&gt;setup&lt;/tt&gt; function sets up the LCD, then uses &lt;tt&gt;setPR&lt;/tt&gt; to point the TMP102 at the temperature register.  Subsequent reads will then return the 12-bit encoded temperature.  The &lt;tt&gt;loop&lt;/tt&gt; function reads the temperature register, decodes it, and displays the result in both Celsius and Fahrenheit.&lt;/p&gt;

&lt;p&gt;Note that this is horrendously inefficient: the TMP102 only measures temperature every 26ms or so, during which &lt;tt&gt;loop&lt;/tt&gt; will probably run a half-dozen times, feeding the same time strings to the LCD each run.  It would be much better to put the TMP102 in one-shot mode, and measure the temperature at a much lower frequency - say once a second - with a correspondingly low update frequency for the display.  I&#039;ll leave that as an exercise for the reader.&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 17 Apr 2010 21:22:01 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/55-guid.html</guid>
    
</item>
<item>
    <title>Modern Multiprocessing</title>
    <link>http://code.v.igoro.us/archives/29-Modern-Multiprocessing.html</link>
            <category>multiprocessing</category>
    
    <comments>http://code.v.igoro.us/archives/29-Modern-Multiprocessing.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=29</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=29</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve been thinking a lot lately about the way we accomplish multiprocessing.  We&#039;ve seen a significant change in the operation of Moore&#039;s law for CPU speeds: today&#039;s CPUs are about the same speed as those of a few years ago, but they have more cores, and more virtual processors on those cores.  This is great for heavily-loaded servers, which have plenty of distinct tasks to place on those cores and VCPUs, but not so useful for users working with single-threaded applications.&lt;/p&gt;

&lt;p&gt;Why are most applications still single-threaded?  There are lots of good reasons. Threaded code is harder to write, and not just because it requires careful analysis and use of synchronization primitives: many common tasks are difficult to meaningfully parallelize without careful control over inter-thread communication, and in a portable application you don&#039;t have that kind of control.  Threaded code generally performs badly on single-CPU systems, which are still common.  Some popular languages still make threading difficult, at least in a portable fashion.  And threads are still relatively heavyweight entities in most operating systems: you don&#039;t spawn ten threads to mergesort a 100-item array.&lt;/p&gt;

&lt;p&gt;Some of these problems will go away with a little more time, but some will get worse.  &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/en.wikipedia.org/wiki/Non-Uniform_Memory_Access&#039;]);&quot;  href=&quot;http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access&quot;&gt;NUMA&lt;/a&gt; architectures can make sharing data between threads slow.  Hyperthreading and its interaction with processor caches adds yet another level of unpredictability.&lt;/p&gt;

&lt;p&gt;We know how to build massively parallel systems that run massively parallel algorithms.  What is still unknown is how to build portable, simple software that can run efficiently across a vareity of architectures.  This is a problem of practice, not theory, and there&#039;s lots of interesting work going on in this area.&lt;/p&gt;

&lt;p&gt;Of course, there are languages designed explicitly to support communication, such as &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.vitanuova.com/inferno/papers/limbo.html&#039;]);&quot;  href=&quot;http://www.vitanuova.com/inferno/papers/limbo.html&quot;&gt;Limbo&lt;/a&gt; or &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.erlang.org/index.html&#039;]);&quot;  href=&quot;http://www.erlang.org/index.html&quot;&gt;Erlang&lt;/a&gt;, &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/www.haskell.org/&#039;]);&quot;  href=&quot;http://www.haskell.org/&quot;&gt;Haskell&lt;/a&gt;, and &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/clojure.org/&#039;]);&quot;  href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;.  For the most part, these languages are structured as communicating sequential processes, which is to say that they represent multiprocessing as a set of sequential threads that pass information to one another.  Problems of thread safety are subsumed by the languages, but mapping the parallelism to available resources is generally left to the programmer or administrator.&lt;/p&gt;

&lt;p&gt;One interesting project is Apple&#039;s &lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/developer.apple.com/mac/articles/cocoa/introblocksgcd.html&#039;]);&quot;  href=&quot;http://developer.apple.com/mac/articles/cocoa/introblocksgcd.html&quot;&gt;Grand Central Dispatch&lt;/a&gt;.  It defines a simple but highly expressive closure syntax (a block) and a mechanism to dynamically schedule execution of such closures (queues).  Critically, the GCD library takes care of scaling the parallelism of the queue processing appropriately to the underlying hardware.  On a single-threaded CPU, this amounts to cooperative multitasking, but on parallel hardware the operating system can dynamically allocate virtual CPUs to applications needing more parallelism.&lt;/p&gt;

&lt;p&gt;This topic seems to come up often in my various pursuits, so I will return to it again. &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Mon, 12 Apr 2010 15:24:00 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/29-guid.html</guid>
    
</item>
<item>
    <title>Want to work on Amanda?</title>
    <link>http://code.v.igoro.us/archives/53-Want-to-work-on-Amanda.html</link>
            <category>amanda</category>
    
    <comments>http://code.v.igoro.us/archives/53-Want-to-work-on-Amanda.html#comments</comments>
    <wfw:comment>http://code.v.igoro.us/wfwcomment.php?cid=53</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://code.v.igoro.us/rss.php?version=2.0&amp;type=comments&amp;cid=53</wfw:commentRss>
    

    <author>nospam@example.com (Dustin J. Mitchell)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve not made any secret of the fact that I want more people hacking on Amanda.  This is both for selfish reasons -- many hands make light work -- and for altruistic reasons -- a broader community of developers can provide better governance for the project and long-term continuity.  With a few noticable exceptions, I haven&#039;t had a lot of satisfaction.&lt;/p&gt;

&lt;p&gt;I think part of the reason is that Amanda has a steep learning curve, even within the new Perl code.  The time to climb that curve is a big investment, and folks with only a small itch to scratch can&#039;t afford it.&lt;/p&gt;

&lt;p&gt;In an effort to sweeten the pot, we (Zmanda) are offering to pay for flexible work on Amanda.  Part-time or full-time, on your own schedule.  Your choice of projects.  Support and gratitude from the other hackers.  And the option to become a full Zmanda employee if that&#039;s your bent.&lt;/p&gt;

&lt;p&gt;Here are some possible projects, to pique your interest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MySQL application (to round out the set with &lt;tt&gt;&lt;a href=&quot;http://code.v.igoro.us/archives/50-Whats-New-in-Amanda-Postgres-Backups.html&quot;&gt;ampgsql&lt;/a&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a onclick=&quot;_gaq.push([&#039;_trackPageview&#039;, &#039;/extlink/cyrusimap.web.cmu.edu/&#039;]);&quot;  href=&quot;http://cyrusimap.web.cmu.edu/&quot;&gt;Cyrus Imapd&lt;/a&gt; application (gnutar doesn&#039;t deal well with the application&#039;s tiny files and hard links)&lt;/li&gt;
&lt;li&gt;OpenSSL for network transport, using certificates and keys for authentication&lt;/li&gt;
&lt;li&gt;Database-backed backup catalog&lt;/li&gt;
&lt;li&gt;Amvault upgrade&lt;/li&gt;
&lt;li&gt;Handle Logical EOM (LEOM) on all devices that support it, drastically reducing the number of parts Amanda writes&lt;/li&gt;
&lt;li&gt;Support for more cloud backends than just S3&lt;/li&gt;
&lt;li&gt;Parallel writes to multiple devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&#039;re interested, contact me (&lt;tt&gt;dustin@zmanda.com&lt;/tt&gt;) and we&#039;ll work something out! &lt;/p&gt;
 
    </content:encoded>

    <pubDate>Mon, 12 Apr 2010 14:04:34 -0500</pubDate>
    <guid isPermaLink="false">http://code.v.igoro.us/archives/53-guid.html</guid>
    
</item>

</channel>
</rss>
