<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>zomo tech</title>
	<atom:link href="http://www.zomo.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zomo.co.uk</link>
	<description>Is it done yet?</description>
	<pubDate>Tue, 30 Sep 2008 07:06:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>MySQL replication health</title>
		<link>http://www.zomo.co.uk/2008/09/mysql-replication-health/</link>
		<comments>http://www.zomo.co.uk/2008/09/mysql-replication-health/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 07:05:48 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=116</guid>
		<description><![CDATA[It&#8217;s possible for MySQL&#8217;s statement-based replication to get out of sync. I&#8217;ve yet to see a real example myself, perhaps because the DB abstraction layers I encounter not creating the &#8220;dangerous&#8221; queries that can make this happen. Still, other than monitoring replication health with SHOW SLAVE STATUS and friends I&#8217;ve sometimes been concerned about whether [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s possible for MySQL&#8217;s statement-based replication to get out of sync. I&#8217;ve yet to see a real example myself, perhaps because the DB abstraction layers I encounter not creating the <a href="http://www.xaprb.com/blog/2007/11/08/how-mysql-replication-got-out-of-sync/">&#8220;dangerous&#8221; queries</a> that can make this happen. Still, other than monitoring replication health with <code>SHOW SLAVE STATUS</code> and friends I&#8217;ve sometimes been concerned about whether my MySQL slaves are faithful copies of the master. Finding that out during a failover moment is the wrong time.</p>
<p>The author of the piece linked above has scratched this itch with <a href="http://code.google.com/p/maatkit/">Maatkit</a>, a suite of replication-focused MySQL tools which include some for checksumming tables.</p>
<p>This can run with standalone instances but most appealing is the way it runs across a replication chain: the statements to perform the table checksums are themselves introduced into the replication and store their results in a table alongside the master&#8217;s checksums. You can then compare and contrast on each slave: neat. All straightforward to roll into Nagios or other monitoring.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/09/mysql-replication-health/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Firewalls</title>
		<link>http://www.zomo.co.uk/2008/09/firewalls/</link>
		<comments>http://www.zomo.co.uk/2008/09/firewalls/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 06:25:01 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[vague]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=111</guid>
		<description><![CDATA[Ace quote from Bruce Schneier&#8217;s book Secrets and Lies:
The first firewalls were on trains.  Coal-powered trains had a large furnace in the engine room, along with a pile of coal.  The engineer  would shovel coal into the engine.  This process created coal dust, which was highly flammable.  Occasionally the coal [...]]]></description>
			<content:encoded><![CDATA[<p>Ace quote from <a href="http://www.schneier.com/">Bruce Schneier&#8217;s</a> book <a href="http://www.schneier.com/book-sandl.html">Secrets and Lies</a>:</p>
<blockquote><p>The first firewalls were on trains.  Coal-powered trains had a large furnace in the engine room, along with a pile of coal.  The engineer  would shovel coal into the engine.  This process created coal dust, which was highly flammable.  Occasionally the coal dust would catch fire, causing an engine fire that sometimes spread into the passenger cars.  Since dead passengers reduced revenue, train engines were built with iron walls right behind the engine compartment.  This stopped fires from spreading into the passenger cars, but didn&#8217;t protect the engineer between the coal pile and the furnace.  (<strong>There&#8217;s a lesson for sysadmins in this somewhere</strong>.)</p></blockquote>
<p>(My emphasis)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/09/firewalls/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using Single Sign-On To Integrate Ning With An External Site</title>
		<link>http://www.zomo.co.uk/2008/08/using-single-sign-on-to-integrate-ning-with-an-external-site/</link>
		<comments>http://www.zomo.co.uk/2008/08/using-single-sign-on-to-integrate-ning-with-an-external-site/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 18:14:10 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[sw]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=77</guid>
		<description><![CDATA[Overview
Ning provide off the peg hosted social networks. The service is free unless you pay to not have their context-driven ads on your pages. Within a few minutes of sign-up you&#8217;re away.
Particulary cool is that they will let you at the source of your network. You can&#8217;t then wander off and run it elsewhere, it [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Overview</strong><br />
<a href="http://www.ning.com/">Ning</a> provide off the peg hosted social networks. The service is free unless you pay to not have their context-driven ads on your pages. Within a few minutes of sign-up you&#8217;re away.</p>
<p>Particulary cool is that they will let you at the source of your network. You can&#8217;t then wander off and run it elsewhere, it sits atop of their core web framework that you can&#8217;t see. With the source (which is encouragingly well written PHP) you can do perform all manner of modifications to bend the template network to your will.</p>
<p>Ning provide their own authentication system, and there&#8217;s no API to hook in someone else&#8217;s which is a hassle if you&#8217;re trying to build a social network alongside another site: maintaining a login for each site is going to annoy the users and be a nightmare to manage. Nil points.</p>
<p>One solution is to build a <a href="http://en.wikipedia.org/wiki/Single_sign-on">single sign-on</a> system around what Ning already provide, which is robust, tested and better presented than anything we could achieve! I&#8217;d sketched out such a system for a proposal years ago but never had the opportunity to build it. A current project provided the perfect excuse to try this out.</p>
<p><strong>Layout</strong><br />
<a href="http://www.zomo.co.uk/wp-content/uploads/2008/08/ning-sso.png"><img src="http://www.zomo.co.uk/wp-content/uploads/2008/08/ning-sso.png" alt="" title="ning-sso" width="300" height="197" class="aligncenter size-medium wp-image-96" /></a><br />
<strong>Operation</strong><br />
The numbers here match those in the diagram.</p>
<ol>
<li>User visits <em>www.example.com</em> (which for us happens to be a <a href="http://www.rubyonrails.org/">Rails</a>) site.</li>
<li>The PageController notices the browser supplied no cookie and must therefore log on to Ning before proceeding. The site returns a redirect to Ning&#8217;s authentication page.</li>
<li>The browser follows this redirect to Ning.</li>
<li>Ning authenticates the user. The login code is modified from the original Ning behaviour. Here, it issues a redirect to <em>sso.example.com</em> with some parameters, including the user&#8217;s Ning ID and a salted hash to prevent spoofing. In this redirect Ning sets a range of cookies, including one that identifies the user to Ning.</li>
<li>The browser follows this redirect to the SSO server (which happens to be a <a href="http://merbivore.com/">Merb</a> site - I wanted to try it out!)</li>
<li>The SSO app checks the provided hash against its own idea of what it should be. Assuming they match it considers the Ning ID to be valid. Finally, the SSO app issues another redirect along with cookies for just <em>.example.com</em>. This cookie identifies the user to the external site</li>
<li>In passing, the SSO app keeps track of users it has seen, and if this is a new user it will make an API request to Ning to fetch that user&#8217;s profile data and create a matching user on the <em>www.example.com</em> site.</li>
<li>The browser follows this last redirect back to Ning. It could be back to <em>www.example.com</em> or Ning  depending on the situation.</li>
<li>Ning knows who the user is by merit of its cookies.</li>
<li>As does our external site.</li>
</ol>
<p><strong>Notes</strong></p>
<ul>
<li>Having the SSO app different from the <em>www.example.com</em> site is perhaps a bit baroque. It works because the SSO app issues a cookie for <em>.example.com</em> which the browser will offer to both <em>sso.example.com</em> and <em>www.example.com</em>. In favour of this approach is that the SSO app is simple, and thus less likely to fail during development iterations than the nascent <em>www.example.com</em> site. A failure in the SSO app is bad, becaise it locks people out of Ning too. That Rails and Merb can share session data (and a database) is cool.</li>
<li>The SSO app&#8217;s fetching of Ning profile data allows us to maintain a local version of a user&#8217;s profile to avoid the need to fetch it from Ning every time we need. There&#8217;s a nuance of Ning API authentication that meant I had to write a custom widget (Ning site component) to handle that.</li>
</ul>
<p><strong>Specifics</strong><br />
I was about to paste bits of modified Ning code, but I&#8217;ll need to check if I can under the various blurbs you agree too when signing up! Anyhow, the information above should help answer some of the requests for details from the Ning developers forum.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/08/using-single-sign-on-to-integrate-ning-with-an-external-site/feed/</wfw:commentRss>
		</item>
		<item>
		<title>High Availability Rails Cluster</title>
		<link>http://www.zomo.co.uk/2008/08/high-availability-rails-cluster/</link>
		<comments>http://www.zomo.co.uk/2008/08/high-availability-rails-cluster/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 18:33:30 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[sw]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=38</guid>
		<description><![CDATA[I&#8217;ve been asked about this a few times, so I figured I&#8217;d post here. This is a brief description of a highly available Rails cluster I&#8217;ve built. Some preliminaries:

There&#8217;s no invention here, I believe this setup is very common.
High availability isn&#8217;t the same thing as load balanced. There is nothing here to intelligently shared load [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been asked about this a few times, so I figured I&#8217;d post here. This is a brief description of a highly available Rails cluster I&#8217;ve built. Some preliminaries:</p>
<ul>
<li>There&#8217;s no invention here, I believe this setup is very common.</li>
<li>High availability isn&#8217;t the same thing as load balanced. There is nothing here to intelligently shared load across the frontend servers, and one backend server is essentially idle all the time.</li>
<li>This cluster is built with a bunch of open-source software on non-fancy kit. As such it doesn&#8217;t have the enormous capacity of clusters built upon commercial shared-storage products, SAN kit, layer 7 web switches etc. Its ambition is to run a few busy Rails sites well whilst coping with hardware failure gracefully.</li>
</ul>
<p><strong>Layout</strong><br />
<img src="http://tech.zomo.co.uk/wp-content/uploads/2008/08/high-availability.png" alt="" title="high-availability" width="253" height="300" class="aligncenter size-medium wp-image-37" /></p>
<p><strong>Operation</strong></p>
<ul>
<li>Web traffic is spread across the managed frontend interfaces by multiple A records in the DNS.</li>
<li><a href="http://www.backhand.org/wackamole/">Wackamole</a> uses a <a href="http://www.spread.org/">Spread messaging network</a> to ensure these multiple A record IPs are always present across the frontend. It achieves this by managing the hosts&#8217; interfaces when it detects hosts joining or leaving the cluster.</li>
<li>A pair of <a href="http://mysql.com/">MySQL</a> servers run in master:master configuration on the backend hosts</li>
<li>The backend hosts use <a href="http://www.drbd.org/">DRBD</a> to maintain a mirrored block device between them.</li>
<li>These block devices back a <a href="http://en.wikipedia.org/wiki/Network_File_System_(protocol)">NFS</a> filesystem.</li>
<li><a href="http://www.linux-ha.org/">Heartbeat</a> runs on the backend hosts to do several tasks:
<ol>
<li>Manage which host is the DRBD primary and therefore can be written to.</li>
<li>Manage which host has the DRBD filesystem mounted and exported with NFS.</li>
<li>Manage the IP through which the frontend mounts the filesystem and talks to MySQL.</li>
</ol>
</li>
<li>With all this in place, <a href="http://nginx.net/">Nginx</a> accepts web connections and serves static assets off the NFS mount and passess other requests to <a href="http://mongrel.rubyforge.org/">Mongrel</a>, a HTTP server that&#8217;s well suited to running a <a href="http://www.rubyonrails.org/">Rails</a> instance.</li>
</ul>
<p><strong>Notes</strong>
<ul>
<li>One of the main hazards of MySQL master:master setups is primary key collision if an INSERT occurs on both hosts at once. We avoid that here by letting Hearbeat manage the IP that the frontends connect to.</li>
<li>I&#8217;ve built two of these clusters to date. The second one is now four servers wide on the frontend.</li>
</ul>
<p><strong>Future work</strong>
<ul>
<li>DRBD can now run in dual-primary mode, allowing both hosts to accept writes. This makes it a candidate for filesystems like <a href="http://www.redhat.com/gfs/">GFS</a> that use shared storage to present a filesystem that can be written to on multiple hosts. More <a href="http://www.drbd.org/users-guide/ch-gfs.html">here</a>.</li>
<li>To add some load balancing I&#8217;m considering using <a href="http://haproxy.1wt.eu/">HAProxy</a> or <a href="http://www.linuxvirtualserver.org/">LVS</a> to actively distribute traffic across the frontends.</li>
<li>HA aside, there&#8217;s also some cool things like <a href="http://swiftiply.swiftcore.org/mongrel.html">evented Mongrel</a> that it would be interesting to try.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/08/high-availability-rails-cluster/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Javascript Trac Bookmark</title>
		<link>http://www.zomo.co.uk/2008/07/javascript-trac-bookmark/</link>
		<comments>http://www.zomo.co.uk/2008/07/javascript-trac-bookmark/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 11:16:24 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=36</guid>
		<description><![CDATA[Substitute https://trac.example.com for your Trac instance and drop into a Firefox bookmark, perhaps on the toolbar:
javascript:q='%s';if(q=='%'+'s')void(q=prompt('Trac%20#',''));if(q)location.href='https://trac.example.com/trac/ticket/'+escape(q);else%20location.href='https://trac.example.com/trac/report/1'
Click / select the bookmark to be prompted for a Trac issue number, which you can leave blank to just load /report/1
Extra credit for assigning a keyword (eg &#8216;ktx&#8217;) in the bookmark properties, allowing you to just type, eg, &#8216;ktx [...]]]></description>
			<content:encoded><![CDATA[<p>Substitute <code>https://trac.example.com</code> for your Trac instance and drop into a Firefox bookmark, perhaps on the toolbar:<br />
<code>javascript:q='%s';if(q=='%'+'s')void(q=prompt('Trac%20#',''));if(q)location.href='https://trac.example.com/trac/ticket/'+escape(q);else%20location.href='https://trac.example.com/trac/report/1'</code><br />
Click / select the bookmark to be prompted for a Trac issue number, which you can leave blank to just load /report/1</p>
<p>Extra credit for assigning a keyword (eg &#8216;ktx&#8217;) in the bookmark properties, allowing you to just type, eg, &#8216;ktx 1234&#8242; in the Location bar to achieve the same.</p>
<p>This is a rework of a similar hack for a much older ticketer, <a href="http://transwebtools.com/pts/index.html">PTS</a>, which is amazingly still in use at one of my previous workplaces. You can gauge its age by the fact that it was ported <i>to</i> PHP<strong>3</strong> and was pretty open to most injection attacks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/07/javascript-trac-bookmark/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Moving Dictionary.app</title>
		<link>http://www.zomo.co.uk/2008/05/moving-dictionaryapp/</link>
		<comments>http://www.zomo.co.uk/2008/05/moving-dictionaryapp/#comments</comments>
		<pubDate>Fri, 02 May 2008 08:21:46 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[sw]]></category>

		<category><![CDATA[OS X]]></category>

		<category><![CDATA[Yak shaving]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=34</guid>
		<description><![CDATA[OS X does a good job of tracking what applications are where and what they do. I have little idea how this works, but if I move VLC.app into a new home then all the files that open in VLC still work. Great. I imagine it involves FSEvents and gobs of XML somewhere.
However the magic [...]]]></description>
			<content:encoded><![CDATA[<p>OS X does a good job of tracking what applications are where and what they do. I have little idea how this works, but if I move VLC.app into a new home then all the files that open in VLC still work. Great. I imagine it involves FSEvents and gobs of XML somewhere.</p>
<p>However the magic doesn&#8217;t touch everything. I was so bold as to move Dictionary.app from its default home in<code> /Applications</code> into the <code>Utilities</code> subdirectory. This broke the Ctrl-Cmd-D system-wide (Cocoa-wide?) lookup box. I don&#8217;t use it <em>that</em> much but that irked me nonetheless.</p>
<p>Console logs included this:</p>
<blockquote><p><code>com.apple.launchd[335] (com.apple.DictionaryPanelAgent[490]): posix_spawn(&#8221;/Applications/Dictionary.app/Contents/SharedSupport/DictionaryPanel.app/Contents/MacOS/DictionaryPanel&#8221;, &#8230;): No such file or directory</code></p></blockquote>
<p>Clearly something thinks it knows where the nested DictionaryPanel application should live. This thing is a <code>launchd</code>-managed process used by the keyboard shortcut, configured out of <code>/System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist</code>.</p>
<p>The hoojah to tweak this does of course involve XML:</p>
<blockquote><p><code><br />
$ launchctl unload /System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist</code></p>
<p><code>$ plutil  -convert xml1 -o - /System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist  | perl -pe 's|/Applications/Dictionary.app/|/Applications/Utilities/Dictionary.app/|;' > /var/tmp/com.apple.DictionaryPanelAgent.plist</code></p>
<p><code>$ plutil -lint /var/tmp/com.apple.DictionaryPanelAgent.plist<br />
/var/tmp/com.apple.DictionaryPanelAgent.plist: OK</code><br />
<code><br />
$ plutil -convert binary1 /var/tmp/com.apple.DictionaryPanelAgent.plist</code></p>
<p><code>$ mkdir /Library/LaunchAgents-orig</code></p>
<p><code>$ sudo mv /System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist /Library/LaunchAgents-orig &#038;&#038; sudo cp /var/tmp/com.apple.DictionaryPanelAgent.plist /System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist</code></p>
<p><code>$ launchctl load /System/Library/LaunchAgents/com.apple.DictionaryPanelAgent.plist</code></p>
</blockquote>
<p>The last step was intended to make the change work this session, but it didn&#8217;t work. The DictionaryPanelAgent still loads but didn&#8217;t do anything until logged out and in again. I think this is something to do with <code>launchctl</code> domains / sessiontype. Blunder factor is high.</p>
<p>This violates the &#8220;don&#8217;t frig with stuff in <code>/System</code>&#8221; principle but I don&#8217;t know how else to solve it. The modified plist could go in <code>/Library/LaunchAgents</code> of course, but I&#8217;d still need to disable the system version (with <code>launchctl unload -w</code>) which is equally naughty. I think.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/05/moving-dictionaryapp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>DIY Avocent / Cyclades DB9/RJ45 serial console adapters</title>
		<link>http://www.zomo.co.uk/2008/04/diy-avocent-cyclades-db9rj45-serial-console-adapters/</link>
		<comments>http://www.zomo.co.uk/2008/04/diy-avocent-cyclades-db9rj45-serial-console-adapters/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 16:58:27 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[stash]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=32</guid>
		<description><![CDATA[These are quite pricey if you buy them pre-made. Depending on how fast you can make them up you can save money.
The self-wire kits I found have the RJ45 connections fixed but let you decide the DB9 pin assigments. The Avocent needs a crossover which means the wiring isn&#8217;t one to one. It&#8217;s detailed here.
So [...]]]></description>
			<content:encoded><![CDATA[<p>These are quite pricey if you buy them pre-made. Depending on how fast you can make them up you can save money.</p>
<p>The self-wire kits I found have the RJ45 connections fixed but let you decide the DB9 pin assigments. The Avocent needs a crossover which means the wiring isn&#8217;t one to one. It&#8217;s detailed <a href="http://pinouts.ru/SerialPortsCables/cyclades_cabling_pinout.shtml">here</a>.</p>
<p>So I don&#8217;t lose it again:</p>
<table>
<tr>
<th>Colour</th>
<th>RJ45</th>
<th>DB9</th>
</tr>
<tr>
<td>Blue</td>
<td>1</td>
<td>8</td>
</tr>
<tr>
<td>Orange</td>
<td>2</td>
<td>1&amp;6</td>
</tr>
<tr>
<td>Black</td>
<td>3</td>
<td>2</td>
</tr>
<tr>
<td>Red</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>Green</td>
<td>5</td>
<td>7</td>
</tr>
<tr>
<td>Yellow</td>
<td>6</td>
<td>3</td>
</tr>
<tr>
<td>Brown &amp; White</td>
<td>7&amp;8</td>
<td>4</td>
</tr>
</table>
<p>DB9 pin 9 is unused. No idea how standard the colour / RJ45 assignment is. The merging of brown and white wires, and the splitting of the orange into two pins is the fudge: admittedly I thought I was building straight-through connectors when I set out!</p>
<p><img src="http://www.datalinkcabling.co.uk/images/productImages/SmallReadytowireinMaleofFemaleDtypesimage.jpg" alt="Assembly" /><ins datetime="2008-04-20T16:58:44+00:00"></ins></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/04/diy-avocent-cyclades-db9rj45-serial-console-adapters/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Truncated and borked Thunderbird attachments</title>
		<link>http://www.zomo.co.uk/2008/02/truncated-and-borked-thunderbird-attachments/</link>
		<comments>http://www.zomo.co.uk/2008/02/truncated-and-borked-thunderbird-attachments/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 09:34:40 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[stash]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=31</guid>
		<description><![CDATA[Fixed thus: 
mail.server.default.fetch_by_chunks to false
From here. Unsure if the break is local or on the mailserver, a reasonably normal Courier IMAP deal.
]]></description>
			<content:encoded><![CDATA[<p>Fixed thus: </p>
<p><code>mail.server.default.fetch_by_chunks</code> to <code>false</code></p>
<p>From <a href="http://groups.google.com/group/Gmail-POP-and-Forwarding/browse_thread/thread/afbb5dfec3b07e1a">here</a>. Unsure if the break is local or on the mailserver, a reasonably normal Courier IMAP deal.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/02/truncated-and-borked-thunderbird-attachments/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ZFS on FreeBSD</title>
		<link>http://www.zomo.co.uk/2008/01/zfs-on-freebsd/</link>
		<comments>http://www.zomo.co.uk/2008/01/zfs-on-freebsd/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 16:42:58 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=30</guid>
		<description><![CDATA[&#8230; rocks! However, some early VM-related kernel panics - kmem_map too small panic - knocked confidence a bit. Seems ZFS really nails the kernel&#8217;s memory demands.
Happily &#8220;the vm_kern.c.2 patch&#8221; (it&#8217;s well known!) sorted things. I stressed ZFS-backed IO massively without any further wobbles.
Now I can micro-quota all my jail(8)s with obsession!
]]></description>
			<content:encoded><![CDATA[<p>&#8230; rocks! However, some early VM-related kernel panics - <code>kmem_map too small</code> panic - knocked confidence a bit. Seems ZFS really nails the kernel&#8217;s memory demands.</p>
<p>Happily <a href="http://people.freebsd.org/~pjd/patches/vm_kern.c.2.patch">&#8220;the vm_kern.c.2 patch&#8221;</a> (it&#8217;s well known!) sorted things. I stressed ZFS-backed IO massively without any further wobbles.</p>
<p>Now I can micro-quota all my <code>jail(8)</code>s with obsession!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2008/01/zfs-on-freebsd/feed/</wfw:commentRss>
		</item>
		<item>
		<title>FAM, g++, escalation</title>
		<link>http://www.zomo.co.uk/2007/11/fam-g-escalation/</link>
		<comments>http://www.zomo.co.uk/2007/11/fam-g-escalation/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 14:14:45 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
		
		<category><![CDATA[all]]></category>

		<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://tech.zomo.co.uk/?p=29</guid>
		<description><![CDATA[The full context for this is just too shonky so it&#8217;s omitted here. FAM is a file monitoring system from SGI that some Linux distros link their courier-imapd against (the SGI OSS pages for it needs some love, it&#8217;s seemingly abandoned). The &#8216;drop-in&#8217; FAM replacement, gamin, doesn&#8217;t provide enough FAMness to fly:
Nov  7 14:03:45 [...]]]></description>
			<content:encoded><![CDATA[<p>The full context for this is just too shonky so it&#8217;s omitted here. FAM is a file monitoring system from SGI that some Linux distros link their <code>courier-imapd</code> against (the SGI <a href="http://oss.sgi.com/projects/fam/">OSS pages</a> for it needs some love, it&#8217;s seemingly abandoned). The &#8216;drop-in&#8217; FAM replacement, <a href="http://www.gnome.org/~veillard/gamin/">gamin</a>, doesn&#8217;t provide enough FAMness to fly:</p>
<p><code>Nov  7 14:03:45 localhost imapd: Failed to connect to socket /tmp/fam--<br />
Nov  7 14:03:45 localhost imapd: Failed to create cache file: maildirwatch (lemon@example.com)<br />
Nov  7 14:03:45 localhost imapd: Error: Input/output error</code></p>
<p>So we&#8217;re left with either rebuilding Courier to not link against it (this is a non-starter, no SRPMs available for this version and I can&#8217;t wholesale replace it owing to &#8220;control panel&#8221; sillyness), or installing FAM itself. For which there are no RPMs, and the source RPMs break owing to a <code>g++</code> change that occurred <b>ages</b> ago.</p>
<blockquote><p><code><br />
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <x> header for the </x><x .h> header for C++ includes, or <iostream> instead of the deprecated header </iostream><iostream .h>. To disable this warning use -Wno-deprecated.<br />
../include/BTree.h:240: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
../include/BTree.h:352: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
../include/BTree.h:408: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
../include/BTree.h:503: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
../include/BTree.h:561: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
../include/BTree.h:591: error: expected constructor, destructor, or type conversion before &#8216;BTree&#8217;<br />
make[2]: *** [Client.lo] Error 1</p>
<p></iostream></x></code></p></blockquote>
<p>Struggling to remember C++ resulted in this patch:</p>
<pre>
--- fam-2.6.10.orig/fam/SmallTable.h    2003-04-15 05:21:43.000000000 +0100
+++ fam-2.6.10/fam/SmallTable.h 2007-11-07 13:50:14.000000000 +0000
@@ -98,7 +98,7 @@
 }

 template &lt;class Tkey, class Tvalue&gt;
-SmallTable&lt;Tkey, Tvalue&gt;::Closure
+typename SmallTable&lt;Tkey, Tvalue&gt;::Closure
 SmallTable&lt;Tkey, Tvalue&gt;::position(const Tkey&amp; key) const
 {
     unsigned l = 0, r = n;
Only in fam-2.6.10/: fam-2.6.10.tar.gz
diff -ur fam-2.6.10.orig/include/BTree.h fam-2.6.10/include/BTree.h
--- fam-2.6.10.orig/include/BTree.h     2003-04-15 05:21:19.000000000 +0100
+++ fam-2.6.10/include/BTree.h  2007-11-07 13:55:15.000000000 +0000
@@ -236,7 +236,7 @@
 //  to the right and returns them.

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Closure
+typename BTree&lt;Key, Value&gt;::Closure
 BTree&lt;Key, Value&gt;::Node::remove(unsigned j)
 {
     Key k = key[j];
@@ -348,7 +348,7 @@
 }

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Closure
+typename BTree&lt;Key, Value&gt;::Closure
 BTree&lt;Key, Value&gt;::Node::next(const Key&amp; pred) const
 {
     if (!this)
@@ -404,7 +404,7 @@
 //  nodes as necessary on the way back.

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Closure
+typename BTree&lt;Key, Value&gt;::Closure
 BTree&lt;Key, Value&gt;::insert(Node *p, const Key&amp; key, const Value&amp; value)
 {
     if (!p) return Closure(key, value, NULL);
@@ -499,7 +499,7 @@
 //  Returns UNDER if node p is too small afterward, OK otherwise.

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Status
+typename BTree&lt;Key, Value&gt;::Status
 BTree&lt;Key, Value&gt;::underflow(Node *p, unsigned i)
 {
     assert(p);
@@ -557,7 +557,7 @@

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Closure
+typename BTree&lt;Key, Value&gt;::Closure
 BTree&lt;Key, Value&gt;::remove_rightmost(Node *p)
 {
     int i = p-&gt;n;
@@ -587,7 +587,7 @@
 //  back up.

 template &lt;class Key, class Value&gt;
-BTree&lt;Key, Value&gt;::Status
+typename BTree&lt;Key, Value&gt;::Status
 BTree&lt;Key, Value&gt;::remove(Node *p, const Key&amp; key)
 {
     if (!p)
diff -ur fam-2.6.10.orig/libfam/Client.c++ fam-2.6.10/libfam/Client.c++
--- fam-2.6.10.orig/libfam/Client.c++   2003-04-15 05:21:25.000000000 +0100
+++ fam-2.6.10/libfam/Client.c++        2007-11-07 13:24:28.000000000 +0000
@@ -34,7 +34,7 @@
 #include &lt;syslog.h&gt;
 #include &lt;errno.h&gt;

-#include &lt;iostream.h&gt;
+#include &lt;iostream&gt;

 #include &quot;fam.h&quot;
 #include &quot;Client.h&quot;
</pre>
<p>Well, that was fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2007/11/fam-g-escalation/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
