<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Caffeinated</title>
	<atom:link href="http://cafenate.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cafenate.wordpress.com</link>
	<description>The truth is I have no idea...</description>
	<lastBuildDate>Mon, 16 Jan 2012 08:01:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='cafenate.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/2f76438560d6f98e021a871d6620850b?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Caffeinated</title>
		<link>http://cafenate.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://cafenate.wordpress.com/osd.xml" title="Caffeinated" />
	<atom:link rel='hub' href='http://cafenate.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Running ZFS filesystem backup</title>
		<link>http://cafenate.wordpress.com/2011/12/10/running-zfs-filesystem-backup/</link>
		<comments>http://cafenate.wordpress.com/2011/12/10/running-zfs-filesystem-backup/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 17:48:35 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[backup]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[zfs]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=168</guid>
		<description><![CDATA[If you&#8217;ve read some of my earlier posts regarding ZFS, you&#8217;ll likely know that it is at the heart of my home file server. In some of my other posts, you&#8217;ll notice that I take backups pretty seriously. So combining &#8230; <a href="http://cafenate.wordpress.com/2011/12/10/running-zfs-filesystem-backup/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=168&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve read some of my earlier posts regarding ZFS, you&#8217;ll likely know that it is at the heart of my home file server. In some of my other posts, you&#8217;ll notice that I take backups pretty seriously. So combining both of those interests I developed a small Python script that replicates a ZFS filesystem. It works both for a one-time replication as well as ongoing incremental replications. All that&#8217;s needed is to set up the cron job to run the script. Here is an example entry from the root user&#8217;s crontab:</p>
<pre>
10 1 * * 0 /usr/local/bin/replica.py yubaba/shared safe/shared
</pre>
<p>The <code>yubaba</code> pool is my main RAID-Z file system and the <code>safe</code> pool is on a USB hard drive located in a fire/water-proof safe with a USB pass-through. You can use any two filesystems that you like, as long as there is sufficient space on the destination.</p>
<p>The script will maintain at most two snapshots on both the source and destination filesystems in order to support sending incremental snapshots. It is a zero-maintenance script, there is nothing that you need to do beyond the one-time setup of the cron job. Be sure not to make any changes in the destination filesystem, as they will be automatically rolled back during the next incremental replication.</p>
<p>The script is located on Google Code: <a href="http://code.google.com/p/devscripts/source/browse/trunk/zfs/replica.py" title="replica.py">replica.py</a> &#8212; I&#8217;m running OpenIndiana build 148 and the version of Python there 2.6, so the script most likely requires that version.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/168/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=168&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2011/12/10/running-zfs-filesystem-backup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Newlines in sed on Mac</title>
		<link>http://cafenate.wordpress.com/2010/12/05/newlines-in-sed-on-mac/</link>
		<comments>http://cafenate.wordpress.com/2010/12/05/newlines-in-sed-on-mac/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 00:43:47 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=163</guid>
		<description><![CDATA[For whatever reason, this is harder than it should have been. All I wanted to do was replace a particular expression with a newline character (0x10). My preference is typically to script such tasks, and the sed command is the &#8230; <a href="http://cafenate.wordpress.com/2010/12/05/newlines-in-sed-on-mac/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=163&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For whatever reason, this is harder than it should have been. All I wanted to do was replace a particular expression with a newline character (<code>0x10</code>). My preference is typically to script such tasks, and the <code>sed</code> command is the perfect fit. This would be simple on just about any system, except for Mac OS X, where apparently all the standard advice is difficult to apply. Worse, the sed man page leads you to believe it&#8217;s a very simple matter of putting a newline in the replacement string. Of course, there&#8217;s no explanation as to how you are expected to do that. And not being a bash expert, I was at a loss.</p>
<p>Luckily enough I found a <a href="http://www.culmination.org/2008/02/10/sed-on-mac-os-x-105-leopard/">blog post</a> that discussed, among other things, how to inject a newline using sed on Mac. Although the example is rather complicated given that he&#8217;s solving a different problem, the crux of the matter is this expression: <code>$'\n/g'</code></p>
<pre>$ echo 'foo bar baz quux' | sed -e 's/ /\'$'\n/g'
foo
bar
baz
quux
</pre>
<p>All that is really doing is taking advantage of the bash <code>extquote</code> option where <code>$'string'</code> quoting is performed on the enclosed string. In this case it&#8217;s a <code>\n</code> which expands to a newline character, followed by <code>/g</code> which goes through as-is. The baskslash (<code>\</code>) before the <code>$'\n/g'</code> tells sed to escape the newline character in the replacement string. I&#8217;m no expert here, but my understanding is that the argument to sed consists of two parts, the <code>s/ /\</code> and the <code>[newline]/g</code>, where the latter resulted from the <code>$'\n/g'</code> evaluated by bash. Together this forms the sed expression <code>s/ /\[newline]/g</code>. How the <code>\'</code> doesn&#8217;t escape the quote and go through as-is to sed I&#8217;m not sure. Maybe someone can explain in the comments.</p>
<p>Thanks for reading!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/163/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/163/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/163/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=163&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2010/12/05/newlines-in-sed-on-mac/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Finding unversioned files in Perforce</title>
		<link>http://cafenate.wordpress.com/2010/08/12/finding-unversioned-files-in-perforce/</link>
		<comments>http://cafenate.wordpress.com/2010/08/12/finding-unversioned-files-in-perforce/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 14:10:34 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=161</guid>
		<description><![CDATA[For many years I&#8217;ve used CVS, and my experience with Subversion started during the pre-alpha days, so I am accustomed to the features they provide. In particular, I make heavy use of the Subversion status command to list not only &#8230; <a href="http://cafenate.wordpress.com/2010/08/12/finding-unversioned-files-in-perforce/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=161&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For many years I&#8217;ve used <a href="http://www.nongnu.org/cvs">CVS</a>, and my experience with <a href="http://subversion.apache.org/">Subversion</a> started during the pre-alpha days, so I am accustomed to the features they provide. In particular, I make heavy use of the Subversion <code>status</code> command to list not only the files I&#8217;ve modified locally, but also the files I&#8217;ve created but not yet added to the list of pending changes. Recently I was working for Gracenote, which apparently made their SCM selection at a time when there were very few good choices. As such, they have been using Perforce for 10 years, never having bothered to re-evaluate that decision given that many very good options have become available since then.</p>
<p>Finding myself having to use an SCM that is frozen in time, like a caveman in an ice block, I searched high and low to find a way to get the Perforce command line client provide me with the ability to discover unversioned files. Alas, I found none. Being that I know how to write halfway passable Python I wrote a script that does exactly what I want: <a href="http://code.google.com/p/devscripts/source/browse/trunk/perforce/p4unknown.py">p4unknown.py</a></p>
<p>Admittedly it&#8217;s not the prettiest name for a script, but it works and I used it for several months while I was at Gracenote. Hopefully you may find it useful as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/161/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=161&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2010/08/12/finding-unversioned-files-in-perforce/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Cleaning up Ruby Gems on Mac OS X</title>
		<link>http://cafenate.wordpress.com/2010/08/11/cleaning-up-ruby-gems-on-mac-os-x/</link>
		<comments>http://cafenate.wordpress.com/2010/08/11/cleaning-up-ruby-gems-on-mac-os-x/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 14:21:36 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=155</guid>
		<description><![CDATA[This has come up a few times for me and searching the Internet failed to turn up any satisfying solutions. In particular, I wanted to update the Ruby Gems on my Mac and subsequently remove the old versions. I found &#8230; <a href="http://cafenate.wordpress.com/2010/08/11/cleaning-up-ruby-gems-on-mac-os-x/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=155&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This has come up a few times for me and searching the Internet failed to turn up any satisfying solutions. In particular, I wanted to update the Ruby Gems on my Mac and subsequently remove the old versions. I found that certain gems would not go away when the <code>gem cleanup</code> command was invoked.</p>
<pre># gem list
*** LOCAL GEMS ***
actionmailer (2.3.5, 2.2.2, 1.3.6)
actionpack (2.3.5, 2.2.2, 1.13.6)
actionwebservice (1.2.6)
activerecord (2.3.5, 2.2.2, 1.15.6)
...
# gem cleanup
Cleaning up installed gems...
Attempting to uninstall fastthread-1.0.1
Unable to uninstall fastthread-1.0.1:
	Gem::InstallError: cannot uninstall, check `gem list -d fastthread`
...</pre>
<p>It seems that (Snow) Leopard comes bundled with a plethora of Ruby gems, all of which are installed in <code>/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8</code>. Meanwhile, the <code>gem install</code> command puts new gems in <code>/Library/Ruby/Gems/1.8</code>, as shown with the <code>-d</code> option to <code>gem list</code>:</p>
<pre># gem list -d fastthread
*** LOCAL GEMS ***
fastthread (1.0.7, 1.0.1)
    Author: MenTaLguY
    Rubyforge: http://rubyforge.org/projects/mongrel
    Installed at (1.0.7): /Library/Ruby/Gems/1.8
                 (1.0.1): /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8
    Optimized replacement for thread.rb primitives</pre>
<p>Some folks have said to simply leave the old gems in place, while others have suggested deleting the old gems from the <code>/System/Library</code> location using <code>rm</code>. Neither solution is all that appealing to me.</p>
<p>The solution I was looking for, it seems, is rather simple and involves nothing more than setting the <code>GEM_HOME</code> environment variable before running the <code>gem cleanup</code> command.</p>
<pre># export GEM_HOME=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8
# gem cleanup
...
Attempting to uninstall rake-0.8.3
Executables and scripts will remain installed.
Successfully uninstalled rake-0.8.3
Clean Up Complete
# unset GEM_HOME</pre>
<p>And that will do it, all of the outdated gems are removed and I didn&#8217;t have to perform file system surgery. Yay!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/155/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=155&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2010/08/11/cleaning-up-ruby-gems-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Using OpenSolaris and ZFS with Time Machine</title>
		<link>http://cafenate.wordpress.com/2010/08/09/using-opensolaris-and-zfs-with-time-machine/</link>
		<comments>http://cafenate.wordpress.com/2010/08/09/using-opensolaris-and-zfs-with-time-machine/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 14:42:01 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[time machine]]></category>
		<category><![CDATA[zfs]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=96</guid>
		<description><![CDATA[In earlier posts I described how to set up a file server using OpenSolaris and ZFS. This proved to be a very good choice, at least for me, and it made sense to make this file server be the destination &#8230; <a href="http://cafenate.wordpress.com/2010/08/09/using-opensolaris-and-zfs-with-time-machine/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=96&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In earlier posts I described how to set up a <a href="http://cafenate.wordpress.com/2009/07/13/building-a-nas-box/">file server</a> using OpenSolaris and ZFS. This proved to be a very good choice, at least for me, and it made sense to make this file server be the destination for my Mac&#8217;s Time Machine backups. In this post I&#8217;ll try to cover everything I did to make that possible.</p>
<p>Assuming you&#8217;ve got the hardware set up and the operating system is in place, it&#8217;s time to set up the ZFS pool and file system for the Time Machine backups. The values shown below will almost certainly differ for your system, so use <code>pfexec format</code> to get a list of disk device names; look for those that are not part of a zpool already (use <code>zpool status</code> to see which devices are in which pools).</p>
<pre>$ pfexec bash
# zpool create yubaba raidz c4t0d0 c4t1d0 c5t0d0 c5t1d0
# zfs create yubaba/mac_backup
# zfs set compression=on yubaba/mac_backup
# zfs set com.sun:auto-snapshot=true yubaba/mac_backup</pre>
<p>I chose to use RAID-Z (striping with parity) so as to maximize my disk space while still getting some redundancy. The two <code>zfs set</code> commands are used to enable ZFS supported features for the new file system. The first turns on compression, which if your system is fast enough, is probably a good idea. The second enables the automatic snapshots that OpenSolaris makes possible via a feature called Time Slider. This is a good way to roll back unwanted changes if the need arises.</p>
<p>Now that the file system is ready, set up the <a href="http://cafenate.wordpress.com/2009/02/08/building-netatalk-on-opensolaris-200811/">netatalk</a> daemon so your Mac can talk to the file server. There are other options (e.g. NFS) but this seems the most straightforward approach to me. With netatalk in place, add the following line to the <code>/usr/local/etc/netatalk/AppleVolumes.default</code> file so that the backup volume is mountable on the Mac, then restart the netatalk daemon.</p>
<pre>/yubaba/mac_backup "Mac Backup" allow:@staff cnidscheme:dbd options:usedots,invisibledots,upriv perm:0770</pre>
<p>By default, earlier versions of Mac OS X do not allow unsupported servers to be the destination for Time Machine backups. To convince it otherwise, simply run the following command in Terminal. This is only necessary the first time, as the change is saved permanently.</p>
<pre>$ defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1</pre>
<p>The next step is to create the sparse bundle disk image on the server. If simply pointing Time Machine to the backup server doesn&#8217;t work (i.e. it reports that it could not create the backup disk image), then you will have to create the disk image manually and copy it over to the server. There is a procedure that makes good use of the graphical utilities in OS X, outlined on <a href="http://www.kremalicious.com/2008/06/ubuntu-as-mac-file-server-and-time-machine-volume/">kremalicious</a>, but since we already have the <strong>Terminal</strong> open, let&#8217;s do it from the command line. After all, if you&#8217;re a Solaris fan you probably won&#8217;t mind seeing how this is really done.</p>
<p>Time Machine puts some cryptic pieces of information into the disk image name that it creates on any remote device, be it Time Capsule or our storage server. These are nothing more than the MAC address and the host name, and can be gathered with the following commands.</p>
<pre>$ hostname -s</pre>
<p>This command shows the host name of your Mac in shortened form, which is the first piece of information.</p>
<pre>$ ifconfig en0 | awk '/ether/{gsub(/:/, "", $2); print $2}'</pre>
<p>This command sequence does nothing more than return the MAC address in the format used by Time Machine. You could get this from Network Utility, but then you&#8217;d have to type the numbers by hand.</p>
<p>Now we can create the sparse bundle disk image in which Time Machine will store the backups. This is done with a single, albeit long, command. Where you see the &#8220;300g&#8221; below, feel free to replace that with whatever size specification you like. The &#8216;g&#8217; stands for gigabytes and the 300 indicates the number of gigabytes. Obviously this is a sparse bundle so it won&#8217;t immediately consume 300GB from the start, that&#8217;s just the maximum size to which the image will grow.</p>
<pre>$ sudo hdiutil create -nospotlight -type SPARSEBUNDLE -imagekey sparse-band-size=131072 -size 300g -fs "HFS+J" -volname "MacBackup" hostname_MACADDR.sparsebundle</pre>
<p>That&#8217;s a rather long command, so let&#8217;s take a look at each part. First, the <code>hdiutil</code> command is used to manage disk images of all sorts, and it has a subcommand called <code>create</code> that will create just about any kind of image you could want. The <code>-nospotlight</code> option simply sets an attribute that tells Spotlight to ignore this volume. The <code>-type</code> option is obvious, but the <code>-imagekey</code> is a bit mysterious. That sets up the disk image to use larger files for the &#8220;bands&#8221; that make up the sparse bundle. According to this <a href="http://nslog.com/2008/11/11/formatting_the_drobo_for_time_machine_backups">discussion</a>, Jon Stevens (latchkey) says the larger the band size the better the performance over the network. The <code>-size</code> was alluded to above; use whatever value you like but it should at least be as large as your OS X system disk. The <code>-fs</code> option indicates the type of file system to use within the disk image, in this case it&#8217;s HFS+ with journaling.</p>
<p>The last parts of the command are machine specific and you will need to change their values accordingly. First off, for the <code>-volname</code> option, use whatever name you like, it&#8217;s there for ease of identification, nothing more. The <code>hostname</code> should be replaced with the value returned by <code>hostname -s</code> from the commands shown above. Likewise, the <code>MACADDR</code> must be replaced with the MAC address revealed with the <code>ifconfig</code> command shown above. Note that the underscore (_) and the extension (.sparsebundle) are important, so keep this in the disk image name.</p>
<p>A lot of what I&#8217;ve learned about Time Machine came from using <a href="http://code.google.com/p/backmyfruitup/">BackMyFruitUp</a>, created by Jon Stevens. It includes an AppleScript scriptlet that creates the sparse bundle disk image for you, if you like.</p>
<p>Now that the disk image has been created, you can copy it to the volume you created on your storage box. You can use <code>cp</code> in Terminal, or simply drag and drop it using Finder.</p>
<p>At this point you can open the Time Machine preferences and choose the volume on the storage server as the backup &#8220;disk&#8221;. At first nothing will happen, so you may want to start a backup immediately. If that fails mysteriously, try unmounting the volume in Finder, then start the backup again. From this point onward, Time Machine will automatically mount the volume whenever it performs a backup, and any time you &#8220;enter&#8221; Time Machine to browse its contents.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/96/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=96&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2010/08/09/using-opensolaris-and-zfs-with-time-machine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Improvements to Burstsort for Java</title>
		<link>http://cafenate.wordpress.com/2009/07/19/improvements-to-burstsort-for-java/</link>
		<comments>http://cafenate.wordpress.com/2009/07/19/improvements-to-burstsort-for-java/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 15:02:38 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[burstsort]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=119</guid>
		<description><![CDATA[Recently I had been side tracked by the need to do something about the network attached storage situation at home, so I had taken a break from my software projects. But a gentleman by the name of Kimo Crossman wouldn&#8217;t &#8230; <a href="http://cafenate.wordpress.com/2009/07/19/improvements-to-burstsort-for-java/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=119&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I had been side tracked by the need to do something about the network attached storage situation at home, so I had taken a break from my software projects. But a gentleman by the name of <a href="http://www.linkedin.com/pub/kimo-crossman/0/196/a32">Kimo Crossman</a> wouldn&#8217;t let me forget about <a href="http://en.wikipedia.org/wiki/Burstsort">burstsort</a>. He has been sending me links to research papers on various parallel algorithms and other cache-related subjects, and making suggestions for how to improve my open source Java <a href="http://code.google.com/p/burstsort4j/">implementation</a> of the original burstsort. In particular, Kimo felt that applying principles from parallel algorithms would be the most important means for improving the performance of burstsort. I have very much appreciated his help and I thoroughly enjoy reading academic papers. In return, I&#8217;ve made an effort recently to work on a few improvements for burstsort4j.</p>
<h2>Parallelized</h2>
<p>The first major change was to introduce a parallelized version of burstsort. In this initial attempt, it only parallelizes the bucket sorting. The building of the trie and buckets still happens in a single thread. However, once the structure is built, the multi-threaded version creates a thread pool of size equal to the number of available processors, and creates sort jobs that are then run in parallel. These jobs run independently of one another, copying the sorted output to the original array without any unnecessary synchronization. As a result, the overall runtime is shortened considerably on a dual-core CPU, which in my case is the Intel Core 2 Duo in my MacBook Pro.</p>
<h2>Engineered Burstsort</h2>
<p>With the publication of the WEA 2008 <a href="http://www.springerlink.com/content/35022477853m05v7/">paper</a> by Ranjan Sinha and Anthony Wirth came a newly engineered variation of the original burstsort. In particular, this algorithm made much better use of memory, while still being nearly as fast as the original algorithm. It primarily makes a change in the structure of the buckets, where instead of a single dynamic array they now have an array that points to other arrays of pointers to strings. These sub-buckets, as they are called, are grown at a slower pace and stop growing at a much lower threshold than the original algorithm. Once a sub-bucket is filled, a new sub-bucket is created, and so on until the overall bucket size reaches a threshold equal to that of the original algorithm. As a result, the memory usage is dramatically improved.</p>
<p>Needless to say, my excitement was very high at this point. I desperately wanted to implement this redesigned burstsort in Java as soon as I could. But, certain other <a href="http://code.google.com/p/jswat/">obligations</a> got in the way for a time, and after a few months I finally wrote the Java version of the engineered burstsort. After fixing one small mistake it was working and it was better than I could have imagined. Not only did the memory efficiency go from about 25 percent to 95 percent, it was often a little bit faster than my original implementation.</p>
<h2>What&#8217;s Next</h2>
<p>There are yet more improvements to make. First of all, the WEA 2008 paper offers a second improvement, which is to copy the string tails from a bucket to a string buffer and sort them there. That is, the string buffer would only be used during the bucket sorting phase and would be re-used after each bucket is sorted. I have an idea to use a large character array and an implementation of CharSequence to create lightweight strings.</p>
<p>Secondly, I want to experiment with the parallel version of burstsort. In particular, try out the suggestions made by Kimo to parallelize the building of the trie/bucket structure. I think it can definitely be done, the only question will be how much contention there will be on the trie nodes. As a means to test these parallel algorithms I&#8217;ve bought a quad-core AMD Phenom CPU and mainboard to use as my development machine. I&#8217;m really looking forward to seeing the results.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/119/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/119/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/119/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=119&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2009/07/19/improvements-to-burstsort-for-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Mirroring ZFS root pool with messy disks</title>
		<link>http://cafenate.wordpress.com/2009/07/18/mirroring-zfs-root-pool-with-messy-disks/</link>
		<comments>http://cafenate.wordpress.com/2009/07/18/mirroring-zfs-root-pool-with-messy-disks/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 15:35:24 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[zfs]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=121</guid>
		<description><![CDATA[Recently I needed to re-purpose my old OpenSolaris-based file server as a development box (upgraded to AMD Phenom X4, woohoo!). Since I wasn&#8217;t planning on making backups on reliable schedule, I wanted to mirror the boot disk, which in ZFS &#8230; <a href="http://cafenate.wordpress.com/2009/07/18/mirroring-zfs-root-pool-with-messy-disks/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=121&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I needed to re-purpose my old <a href="http://opensolaris.org/">OpenSolaris</a>-based file server as a development box (upgraded to <a href="http://www.amd.com/us/products/desktop/processors/phenom/Pages/AMD-phenom-processor-X4-features.aspx">AMD Phenom X4</a>, woohoo!). Since I wasn&#8217;t planning on making backups on reliable schedule, I wanted to mirror the boot disk, which in <a href="http://opensolaris.org/os/community/zfs">ZFS</a> is a cinch. Surprisingly this took much longer than I had assumed when reading the ZFS documentation. Mostly this was due to the messy disks I was using, that is, they had been configured as data disks so they all had an EFI label. Since most PC BIOS&#8217;s don&#8217;t support EFI labels, ZFS requires that all rpool devices have an SMI label. What&#8217;s more, the partition table has to be just right, and I couldn&#8217;t figure out how to use the format command to achieve that. Turns out there&#8217;s an easier way.</p>
<ol>
<li>Install OpenSolaris on the first disk as usual.</li>
<li>Make sure the second disk has an SMI label instead of an EFI label so it can be attached to the rpool. Invoke the <code>format -e</code> command (the -e is important, it enables expert options like setting the label type), choose the second disk, type  &#8220;label&#8221;, and choose the SMI option. If it does not allow this change because you have to delete the partitions, then type &#8220;fdisk&#8221; and delete the partitions and create a new one (Solaris2 type), save the changes to disk, and now you can change the label type. Type &#8220;quit&#8221; to save your changes to disk. [<a href="http://www.opensolaris.org/jive/thread.jspa?messageID=379421">opensolaris.org</a>]</li>
<li>The partition table of the second disk needs to be made identical to the first one. As the root user, type <code>prtvtoc /dev/rdsk/disk1 | fmthard -s - /dev/rdsk/disk2</code> where disk1 and disk2 might look like <code>c0d0s2</code> and <code>c0d1s2</code> (note the use of slice 2 here, the &#8220;whole disk&#8221; slice). [<a href="http://mail.opensolaris.org/pipermail/zfs-code/2009-May/000843.html">opensolaris.org</a>]</li>
<li>Attach the second disk to the root pool: <code>zpool attach rpool disk1 disk2</code> (where <code>disk1</code> and <code>disk2</code> are the device names, typically including the slice, such as <code>c7d0s0</code> and <code>c7d1s0</code>). You may find it necessary to force the attach as ZFS may complain about slices overlapping. If <code>s0</code> overlaps <code>s2</code> that&#8217;s actually normal, so just add the <code>-f</code> flag.</li>
<li>Make sure the boot loader is copied to the second disk so it is bootable in the event the first disk becomes unbootable: <code>installgrub /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/disk2</code> [<a href="http://opensolaris.org/jive/thread.jspa?messageID=357125">opensolaris.org</a>]</li>
</ol>
<p>See, it was a cinch after all. That is, once you knew what to do.</p>
<p>[Update: Removed the remark about using s0 or s2 interchangably. So far the posts I've seen mostly lean toward s2, but the prtvtoc output for s0 and s2 on my disks were identical, so it would not have made a difference in my case. Nonetheless, go with the flow. Also added references to original sources in case you were to think I was some kind of genius or something.]</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/121/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=121&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2009/07/18/mirroring-zfs-root-pool-with-messy-disks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Building a Network Attached Storage box</title>
		<link>http://cafenate.wordpress.com/2009/07/13/building-a-nas-box/</link>
		<comments>http://cafenate.wordpress.com/2009/07/13/building-a-nas-box/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 14:58:23 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[drobo]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[zfs]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=103</guid>
		<description><![CDATA[Introduction In an earlier post I compared a Drobo to a custom built storage system based on OpenSolaris, with the conclusion that while a Drobo is convenient, building your own server offers many advantages. In this post I want to &#8230; <a href="http://cafenate.wordpress.com/2009/07/13/building-a-nas-box/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=103&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In an earlier post I compared a Drobo to a custom built storage system based on OpenSolaris, with the conclusion that while a Drobo is convenient, building your own server offers many advantages. In this post I want to show how I went about building a new storage system based on an <a href="http://blogs.sun.com/mebius/entry/diy_home_nas_box_with2">article</a> that came out at the end of last year. Among the improvements over my old server are lower power consumption and a smaller form factor. In fact, the case that I&#8217;ve chosen has the same footprint as the Drobo, and only about five inches taller. In addition, this particular case has hot swappable drive bays, so disks can be replaced while the system is powered on.</p>
<p>Before I get into the particulars, I want to share some useful links that may help if you&#8217;re new to OpenSolaris and/or building a system from parts. First of all, there&#8217;s the <a href="http://lifehacker.com/5151369/the-first+timers-guide-to-building-a-computer-from-scratch">First-Timer&#8217;s Guide to Building a Computer from Scratch</a> at LifeHacker. I find that the hardest part of building your own system is getting the parts list right. To that end, check out <a href="http://arstechnica.com/hardware/guides/2008/09/guide-200809.ars">Ars Technica&#8217;s excellent system buyer&#8217;s guide</a>, which offers recipes for various types of systems and provides advice on choosing suitable parts. Once the system is put together you might be asking yourself which operating system to choose. For me, <a href="http://opensolaris.com/">OpenSolaris</a> with <a href="http://opensolaris.org/os/community/zfs/">ZFS</a> is a no-brainer &#8212; it really is an excellent software stack that gives me piece of mind knowing my that data is as safe as it can be (for the amount of money I&#8217;m willing to spend). But you don&#8217;t have to take my word for it, see what <a href="http://breden.org.uk/2008/03/02/a-home-fileserver-using-zfs/">Simon</a> and <a href="http://scottstuff.net/blog/articles/2007/10/19/why-not-linux-new-server-part-2">Scott</a> have to say about OpenSolaris and ZFS. If setting up and administering OpenSolaris is too daunting for you, then check out <a href="http://freenas.org/">FreeNAS</a> &#8212; it&#8217;s based on <a href="http://www.freebsd.org/">FreeBSD</a> with a port of ZFS and is designed to be easier to set up and maintain.</p>
<h2>Power Consumption</h2>
<p>One of the primary goals with building a new storage server was to minimize power consumption. According to a recently purchased Kill-A-Watt device, my original web server box consumes about 100W while idle, and 120W while the disks are active. During power-on, the consumption peaks at around 260W. This is actually not too bad for a server-class machine. As for the new server, it starts off at around 36W, then hits 117 when everything spins up at once, then levels out at 62. During active reading and writing, the consumption peaks at 71W and typically hovers around 67W. Not too bad, around half of the consumption of my original machine.</p>
<h2>Bill of Materials</h2>
<p>These prices are based on what was available in March of 2009, so these may have changed by now. Nonetheless, it shows just how little there is to buy, with half of the parts available from a single retailer.</p>
<table border="0" width="100%" summary="bom">
<tbody>
<tr>
<td>Chenbro ES34069</td>
<td>eWiz.com</td>
<td>$153</td>
</tr>
<tr>
<td>Intel D945GCLF2</td>
<td>newegg.com</td>
<td>$79</td>
</tr>
<tr>
<td>Kingston 2GB RAM</td>
<td>newegg.com</td>
<td>$22</td>
</tr>
<tr>
<td>Panasonic CD/DVD-ROM</td>
<td>logicsupply.com</td>
<td>$51</td>
</tr>
<tr>
<td>Seagate 80GB 2.5&#8243; HDD</td>
<td>newegg.com</td>
<td>$50</td>
</tr>
<tr>
<td>SYBA SATA II NCQ</td>
<td>eforcity.com</td>
<td>$43</td>
</tr>
<tr>
<td>Flexible PCI riser</td>
<td>logicsupply.com</td>
<td>$22</td>
</tr>
</tbody>
</table>
<p>That adds up to $420 for everything you need to equal a Drobo and DroboShare. That&#8217;s $150 less than the price of the Drobo plus DroboShare on Amazon, and this system is faster and the components can be sourced from multiple vendors. That, by the way, was one of my goals in building a new system; I didn&#8217;t want to be locked in to a particular hardware vendor.</p>
<p>Regarding the selection of the Chenbro case, it was a luxury. It&#8217;s rather pricey for an ITX case, but the <a href="http://www.logicsupply.com/blog/2008/11/05/the-chenbro-es34069-case-review-part-2-the-perfect-mainboard/">LogicSupply review</a> convinced me it was worth it. Another option would be to use the Enlight PR-42A1 which can be had for around $60. The major difference is the Enlight is an ATX case, so you would have to get a different mainboard, and chances are it would not have a low power chipset.</p>
<p>You may have noticed that the mainboard does not support ECC (error-checking and correcting) memory. Yes, that was a bit of a let down, but to get ECC you typically have to go with server-grade parts, which cost more and often consume more power.</p>
<h2>Operating System</h2>
<p>Unlike with pre-built systems, you get to choose your operating system when building your own system. There are many people who go with Windows Home Server, but obviously that costs money. Free options include FreeBSD, FreeNAS, Linux and OpenSolaris. Being a long time user of Solaris, I went with OpenSolaris. It has the advantage of including the reference implementation of ZFS. While I had been a Linux user for 10 years, and ran a software project/web server on Linux for half that time, I know a better solution when I see one.</p>
<h2>Disk Performance</h2>
<p>Given that this system was built to replace a Drobo, I wanted to compare their performance. However, there is no reasonable way to compare the performance of a Drobo with a storage server such as the one I&#8217;ve built here. Firstly, the Drobo does not have native Ethernet, so it has to rely on an external device connected over USB. That alone is going to add delay and turn the comparison into an apples and oranges argument. What I can say though is that the new server feels faster than the Drobo, and is certainly fast enough for my needs. It is on par with the server-grade equipment that this box is replacing, and meets our file sharing and Time Machine backup requirements perfectly.</p>
<h2>Conclusion</h2>
<p>If you&#8217;re new to building a storage server, I hope that I&#8217;ve given you some inspiration to learn more. If you have the time and a handful of tools, building your own system is pretty easy. And if you haven&#8217;t spent a lot of time learning how to configure an operating system, then let <a href="http://www.youtube.com/watch?v=16v4jNYH0GI">FreeNAS</a> come to your aid. In short, you can choose your own parts from any of a number of suppliers, install whatever operating system you like, and set up a pretty reliable vault for your data.</p>
<p><strong>Update</strong>: Check out the <a href="http://blogs.sun.com/drapeau/entry/draft_2_my_home_media">media storage system</a> George Drapeau built based on OpenSolaris and ZFS.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=103&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2009/07/13/building-a-nas-box/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Installing Logwatch on OpenSolaris</title>
		<link>http://cafenate.wordpress.com/2009/03/01/installing-logwatch-on-opensolaris/</link>
		<comments>http://cafenate.wordpress.com/2009/03/01/installing-logwatch-on-opensolaris/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 15:21:46 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[solaris]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=90</guid>
		<description><![CDATA[Typically, installing Logwatch is fairly trivial. On Linux, you&#8217;d just use the package installer command and you&#8217;re done. On OpenSolaris, there doesn&#8217;t seem to be a packaged version of Logwatch (yet), so installing from the source tarball is necessary. Fortunately, &#8230; <a href="http://cafenate.wordpress.com/2009/03/01/installing-logwatch-on-opensolaris/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=90&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Typically, installing <a href="http://www.logwatch.org/">Logwatch</a> is fairly trivial. On Linux, you&#8217;d just use the package installer command and you&#8217;re done. On OpenSolaris, there doesn&#8217;t seem to be a packaged version of Logwatch (yet), so installing from the source tarball is necessary. Fortunately, there&#8217;s a shell script that performs the installation. The bad news is this script finds <code>/usr/sbin/install</code> which is the Solaris version of <code>install</code>. This version behaves very differently from those found in other Unix variants. The Logwatch installer is expecting the behavior of the <code>install</code> script found on Linux, so it fails miserably on OpenSolaris.</p>
<p>The good news is, there&#8217;s a simple solution. Just install the <code>SUNWscp</code> package. This is the &#8220;source compatibility package&#8221;, which installs numerous commands that help OpenSolaris behave more like other Unix systems. The Logwatch installer script prepends the <code>/usr/ucb</code> directory to the <code>PATH</code> when it runs, so it finds the <code>install</code> script that it is expecting, and thus it installs Logwatch perfectly. The only thing left is to add the <code>crontab</code> entry, as shown at the end of the install output.</p>
<p>One last note about Logwatch, and it concerns that crontab entry. It seems that the default configuration for Logwatch is to print the report rather than sending an email to the default recipient, root. However, the example crontab entry is redirecting all output to <code>/dev/null</code>. So how exactly is one supposed to get a daily report? The answer is to edit the <code>/etc/logwatch/conf/logwatch.conf</code> file, adding <code>Print = no</code> at the end of the file. That tells Logwatch to email the report rather than printing. It&#8217;s a mystery to me why that&#8217;s the default given the example crontab entry they display during the installation process. But at least it&#8217;s easy to fix, and nicely demonstrates how easy it is to customize Logwatch without touching the default configuration files.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/90/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/90/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/90/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=90&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2009/03/01/installing-logwatch-on-opensolaris/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
		<item>
		<title>Making netatalk discoverable in OpenSolaris</title>
		<link>http://cafenate.wordpress.com/2009/02/26/making-netatalk-discoverable-in-opensolaris/</link>
		<comments>http://cafenate.wordpress.com/2009/02/26/making-netatalk-discoverable-in-opensolaris/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 16:00:15 +0000</pubDate>
		<dc:creator>nlfiedler</dc:creator>
				<category><![CDATA[afp]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[netatalk]]></category>
		<category><![CDATA[opensolaris]]></category>

		<guid isPermaLink="false">http://cafenate.wordpress.com/?p=83</guid>
		<description><![CDATA[Previously I described how I had set up netatalk on my OpenSolaris storage server. That step went a long way to making it easy to use Time Machine to backup my Mac to the server. But having read kremalicious, I &#8230; <a href="http://cafenate.wordpress.com/2009/02/26/making-netatalk-discoverable-in-opensolaris/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=83&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Previously I described how I had set up <a href="http://netatalk.sourceforge.net/">netatalk</a> on my <a href="http://www.opensolaris.com/">OpenSolaris</a> storage server. That step went a long way to making it easy to use Time Machine to backup my Mac to the server. But having read <a href="http://www.kremalicious.com/2008/06/ubuntu-as-mac-file-server-and-time-machine-volume/">kremalicious</a>, I wanted to find a way to make the netatalk daemon <a href="http://opensolaris.org/os/project/nwam/service-discovery/">discoverable</a> by the Macs on my network. The same technique that Matthias used on Linux was not going to work on OpenSolaris. For starters, OpenSolaris doesn&#8217;t use <a href="http://avahi.org/">avahi</a>, it has it&#8217;s own solution in the form of the dns/multicast service. In place of creating a static configuration file, you use the <code>dns-sd</code> command line client on OpenSolaris. While this tool is not meant to be used to register long running services, it&#8217;s the only <a href="http://www.opensolaris.org/jive/thread.jspa?threadID=93112">feasible solution</a> at the moment. But just running that command in the background and leaving its fate to the gods is not good enough for me. It should be monitored using the Service Management Framework. This turns out to be surprisingly easy once you&#8217;ve read the <a href="http://www.sun.com/bigadmin/content/selfheal/sdev_intro.jsp">SMF guide</a> on <a href="http://www.sun.com/bigadmin/">BigAdmin</a>.</p>
<p>Start by installing netatalk, if you haven&#8217;t already, as described in an earlier <a href="http://cafenate.wordpress.com/2009/02/08/building-netatalk-on-opensolaris-200811/">post</a>. Next, create the SMF manifest file that will register the AFP daemon as a discoverable service. Name the file <code>dnssd-afp.xml</code> and place it in the <code>/var/svc/manifest/site</code> directory.</p>
<pre>&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"&gt;
&lt;service_bundle type="manifest" name="dnssd-afp"&gt;
  &lt;service
     name="site/dnssd-afp"
     type="service"
     version="1"&gt;

    &lt;single_instance/&gt;

    &lt;dependency
       name="filesystem-local"
       grouping="require_all"
       restart_on="none"
       type="service"&gt;
      &lt;service_fmri value="svc:/system/filesystem/local:default"/&gt;
    &lt;/dependency&gt;

   &lt;dependency
       name="dns-multicast"
       grouping="require_all"
       restart_on="none"
       type="service"&gt;
      &lt;service_fmri value="svc:/network/dns/multicast:default"/&gt;
    &lt;/dependency&gt;

    &lt;exec_method
       type="method"
       name="start"
       exec="/lib/svc/method/dnssd-afp"
       timeout_seconds="60"&gt;
      &lt;method_context&gt;
        &lt;method_credential user="root" group="root"/&gt;
      &lt;/method_context&gt;
    &lt;/exec_method&gt;

    &lt;exec_method
       type="method"
       name="stop"
       exec=":kill"
       timeout_seconds="60"&gt;
    &lt;/exec_method&gt;

    &lt;instance name="default" enabled="false" /&gt;

    &lt;stability value="Unstable" /&gt;

    &lt;template&gt;
      &lt;common_name&gt;
        &lt;loctext xml:lang="C"&gt;
          dns-sd registration of afp daemon
        &lt;/loctext&gt;
      &lt;/common_name&gt;
      &lt;documentation&gt;
        &lt;manpage title="dns-sd" section="1M" manpath="/usr/man"/&gt;
      &lt;/documentation&gt;
    &lt;/template&gt;
  &lt;/service&gt;
&lt;/service_bundle&gt;</pre>
<p>Change the ownership of the manifest to <code>root:sys</code> and make it read-only by all but the root user. For this service, we&#8217;ll need to write a shell script that spawns <code>dns-sd</code> as a background process, otherwise SMF will timeout waiting for the service to start (the SMF documentation is better at explaining this than I am). <em>Note that <code>chihiro</code> in the script is the hostname that will be advertised; you may want to change this to suit your needs.</em></p>
<pre>#!/sbin/sh
#
# Registers the AFP daemon with dns-sd.
#
/usr/bin/dns-sd -R chihiro _afpovertcp._tcp local 548 &amp;
/usr/bin/dns-sd -R chihiro _device-info._tcp. local 548 model=Xserve &amp;
# Sleep to ensure service has enough time to start up,
# otherwise SMF will timeout waiting for it to be ready.
sleep 5</pre>
<p>Place the shell script in the <code>/lib/svc/method</code> directory, give it the name <code>dnssd-afp</code>, change the ownership to <code>root:bin</code>, and make the file executable by all and writable only by root. Now we&#8217;re ready to import the service configuration and start the service. Import it using the command <code>pfexec svccfg -v import /var/svc/manifest/site/dnssd-afp.xml</code>, then start the service using <code>pfexec svcadm enable dnssd-afp</code>, and finally check that the service is running with <code>svcs dnssd-afp</code>. At this point, if the <code>dns-sd</code> process were to unexpectedly die, SMF will immediately restart it. That&#8217;s one of the many advantages of SMF over initd, which does not monitor the processes that it initiates. With the AFP service now registered, any Mac on your network should see your storage server as a Mac-compatible file share, which will appear automatically in the Finder sidebar. If you&#8217;ve added a shared volume to your Login Items previously, you can remove it, you won&#8217;t need it any more.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cafenate.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cafenate.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cafenate.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cafenate.wordpress.com&amp;blog=6659817&amp;post=83&amp;subd=cafenate&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cafenate.wordpress.com/2009/02/26/making-netatalk-discoverable-in-opensolaris/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">nlfiedler</media:title>
		</media:content>
	</item>
	</channel>
</rss>
