<?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/"
	>

<channel>
	<title>Record and Reverie &#187; General</title>
	<atom:link href="http://www.cod3r.com/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cod3r.com</link>
	<description>General things I find interesting</description>
	<lastBuildDate>Sat, 07 Jan 2012 15:44:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Goodbye Roku, Hello GoogleTV</title>
		<link>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/</link>
		<comments>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 16:37:46 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=509</guid>
		<description><![CDATA[In my previous post, I said &#8220;I think I’ll elect to forgo a player for an external drive and rip every disk that I might buy.&#8221; That thought didn&#8217;t last very long. I decided to buy a Sony NSZ-GT1 which contains both a BluRay player and a GoogleTV together. I did this because I finally [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post, I said &#8220;I think I’ll elect to forgo a player for an external drive and rip every disk that I might buy.&#8221;  That thought didn&#8217;t last very long.  I decided to buy a Sony NSZ-GT1 which contains both a BluRay player and a GoogleTV together.  I did this because I finally realized that the Roku that bought was never going to live up to my requirements, especially amid their numerous regressions in firmware updates.</p>
<p>So, I bought a Roku a few months ago after my dad bought one.  He got one of the first generation devices, as well as a second.  It was able to play his ripped media, with a little coaxing, but the feature that caught both of our attentions was the 1080p playback.  I decided to buy a second generation as well, since it had the ability to create third-party apps (they call them channels).</p>
<p>I started to program for the Roku, only to be first struck by the programming language.  While it has similarities to several other scripting languages, it is a new programming language.  Those out there familiar with the realities in computer science are screaming in the heads how this is a poor decision, but they made it anyway.  I was then struck by the complete lack of library availability.  Unfortunately, I had allowed myself to accept the premise that I had no choice in the matter and tried my best to plow on.  My father and I had designed a Java server, which facilitated transcoding of files to be served to the Roku.  I then started to add in the metadata features found in <a href="http://appletv.nanopi.net">Sapphire</a> to this server.  I had browsing working from the device as well as playback initiated from the device.  It was starting to look like a replacement for my AppleTV running Sapphire.</p>
<p>Then came the updates.  Roku issues a firmware update, which caused numerous problems.  The most notable was when one would play an MP3 on the first generation device (streaming a radio station for instance), then later played an MP4 with H.264, the device locked up requiring a reboot.  This bug took a month and a half to fix.  Additionally, the HLS streaming, which is what&#8217;s used to deliver the transcoded data to the device, was suffering from numerous audio dropouts.  Supposedly, this bug was fixed in the update that was released today, but I&#8217;ve found reports of this bug in the firmware betas dating as far back as May.  This means that roku was aware of the regression for 5 months before releasing the firmware.  Furthermore, try to report this bug on their forums, and the fanbois descend on you like a coming plague, insisting that nothing is broken, or that a fix is coming and you must be patient.  I&#8217;ve even seen some do both, even though they are diametrically apposed positions.  I then noticed a firmware update on my second generation roku including some of the same regressions.</p>
<p>I&#8217;ve had it.</p>
<p>I decided to get something else.  When I looked at the list of options, I narrowed my choice down to AndroidTV and GoogleTV.  AndroidTV is essentially hardware vendors taking the open sourced Android OS (the versions that are), and putting in on their devices.  GoogleTV is the Android OS, with some additional addons including a large host of codec/container support.  I went with the latter, so I now had to pick which device.  Sony makes a BluRay player and several TVs, and Logitech used to make their Revue.  I went with the BluRay player since it was not discontinued and I didn&#8217;t want to buy a TV right now.  Also, the GoogleTV&#8217;s new firmware is based on Android 3.1, and the AndroidTV devices are mostly on 2.2 or 2.3.</p>
<p>When the device arrived, I started doing some tests.  It played nearly everything I threw at it without issue.  I played everything over http, just giving the built-in VideoView class a URL to play, and it played it.  I tested MKV, AVI, MP4, and MKV files.  All had no issues.  It even played the killa sample, which is something that the roku failed to play.  The programming language is far better, since they used Java, and the programming environment actually works instead of the occasional lockup of the device in the debugger from which the roku suffers.  It&#8217;s also much faster, and stable.  My dad found that Amazon was still selling the Revue, so he bought one based on these results.  I don&#8217;t know what we are going to do with our roku devices.  I expect I may finish the Angry Birds levels, then call it failed experiment and box it up.</p>
<p>In short, don&#8217;t buy from roku.  Buy a GoogleTV instead.  Yes, they are more expensive, but you truly get what you pay for here.  The programming environment is far superior, which means the apps will be better.  The device works, and it appears that Google actually does regression testing.  Additionally, Google appears to be <a href="http://www.engadget.com/2011/12/07/googles-eric-schmidt-sees-google-tv-embedded-in-most-new-tvs-by/">ambitious in the devices future</a>.  It looks like GoogleTV truly is the route to go.  I just wish I had seen it earlier.</p>
<p>BTW, I plan on fully porting Sapphire over to work on the GoogleTV in a client-server relationship.  I&#8217;m doing this because I plan to allow sharing a single library across multiple devices.  I don&#8217;t know yet whether I intend to release it to the public.  Sometimes it is nice not having to deal with &#8220;customer&#8221; support.  Browsing and playback is done, as well as an importer to read the previous version&#8217;s metadata.  All that&#8217;s left is the metadata importing of new files.  Time will tell on where I go with this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/12/goodbye-roku-hello-googletv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Case for Ripping Media</title>
		<link>http://www.cod3r.com/2011/11/the-case-for-ripping-media/</link>
		<comments>http://www.cod3r.com/2011/11/the-case-for-ripping-media/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 02:17:23 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=501</guid>
		<description><![CDATA[As some of you may know, I&#8217;ve ripped every DVD I own and store them on a file server. It&#8217;s a lot of space and it took a lot of time, but for my uses, it&#8217;s worth it. I started this because one movie, I don&#8217;t remember which one, forced me to wait on FBI [...]]]></description>
			<content:encoded><![CDATA[<p>As some of you may know, I&#8217;ve ripped every DVD I own and store them on a file server.  It&#8217;s a lot of space and it took a lot of time, but for my uses, it&#8217;s worth it.</p>
<p>I started this because one movie, I don&#8217;t remember which one, forced me to wait on FBI warning, another copyright violation warning, the same in French, and a disclaimer.  Then it displayed two previews and a lengthy menu before I could hit play.  This was followed by another lengthy menu animation, studio logos, and finally the movie.  In the whole process, the studio logos and the previews were the only portions I was able to skip, the other screens marked as not skippable on the DVD.  Now that I have my DVDs ripped, when I want to watch a movie, I browse my collection on the TV, and play the movie.  No warnings, no menus, just the movie.  I actually moved 8 months ago, and I have yet to unpack the DVD player.</p>
<p>This past weekend, I was at my parents&#8217; house and I played a few of their BluRay disks.  One movie, I think it was Flyboys, spent a considerable amount of time on the loading screen, had large sections of menus/screens that were not skippable, even included a section where it tried to download a trailer.  Once the movie started playing, I paused it and to help feed some kitties and give them attention for a few minutes only to return to a custom screen saver of some sort.  The movie would <strong>not resume</strong>.  Upon repeating the process, a total of 15 minutes was wasted excluding the time spent with the movie paused.</p>
<p>So now, I seriously question the value of keeping media in these physical formats.  I was considering BluRay in the near future, but now I think I&#8217;ll elect to forgo a player for an external drive and rip every disk that I might buy.  Now I just need to find a good external drive that allows easy ripping.  Thoughts?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/11/the-case-for-ripping-media/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FreeBSD with ZFS root</title>
		<link>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/</link>
		<comments>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 02:00:55 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=489</guid>
		<description><![CDATA[It&#8217;s been a while since I posted here. I&#8217;ve been busy with a new job, new house, and a bunch of other things. One of these things was setting up my new file server. This is something that&#8217;s been in the works for a long time, as can be seen from the various posts on [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I posted here.  I&#8217;ve been busy with a new job, new house, and a bunch of other things.  One of these things was setting up my new file server.  This is something that&#8217;s been in the works for a long time, as can be seen from the various posts on <a href="http://www.cod3r.com/tag/zfs/">ZFS</a>.  I spent a long time researching this, and finally came up with my solution:</p>
<p>I did consider <a href="http://www.freenas.org/">FreeNAS</a> for a really long time.  It is essentially a <a href="http://freebsd.org">FreeBSD</a> install with most of the administrative work done for you through a web-based GUI.  It hit most of my checkboxes in that it supported ZFS, AFP, Bonjour, and a few others.  While this is nice, I found it also to be limiting when one wants to stray off the beaten path.  I didn&#8217;t want to lose ZFS, but I wanted something where I could tinker.  I decided to go with FreeBSD.</p>
<p>One of the first things I tried with FreeBSD, as the topic indicates, is to put the root filesystem on ZFS.  I followed an <a href="http://wiki.freebsd.org/RootOnZFS/GPTZFSBoot/RAIDZ2">excellent tutorial</a> to start, but decided to make a few modifications:</p>
<ul>
<li>I wanted to put the root filesystem some place other than the root of the pool.  Since my large media collection is going to be stored on the same pool, I wanted the ability to selectively snapshot the boot filesystem, and possibly revert it, without affecting the media partition.  So, I put the root filesystem on on a sub filesystem of the pool.</li>
<li>The trend in disk storage is looking like it will go to 4K sector sizes in the future.  ZFS cannot migrate a pool from 512 byte sector sizes to 4K sector sizes without a reformat/restore.  I wanted a 4K sector size pool from the start.</li>
<li>I wanted to use ZFS swap instead of swap partitions.</li>
<li>I was going to spent several iterations getting things right and didn&#8217;t want to type on that blasted 12 year old keyboard the same commands over and over.</li>
</ul>
<p>So, I accomplished this whole task through a series of scripts, that I would modify.  If the script did something wrong, I&#8217;d destroy the pool and start over.  The end result is a simple setup that I decided to share with the world:</p>
<ol>
<li>Download and burn/image one of the FreeBSD <a href="http://www.freebsd.org/where.html">iso images or USB images</a>.  I used 8.2, the most recent at the time of this writing, and did the USB image since I had flash drives to spare but no DVD ROM drives.</li>
<li>Boot the machine and enter the recovery mode (Fixit).</li>
<li>Start the networking:<br />
<code>mkdir /var/db<br />
dhclient em0<br />
ln -s /dist/usr/bin /usr/bin<br />
</code></li>
<li>Transfer over the script directory:<br />
<code>scp -r username@10.0.0.10:Desktop/FreeBSD/\* .</code><br />
In this case, 10.0.0.10 is my laptop with sshd running.</li>
<li>Start sshd: <code>./FreeBSDSSHSetup.sh</code></li>
<li>ssh into the machine from my laptop and execute: <code>./FreeBSDInstall.sh</code></li>
<li>Reboot the server and enjoy.</li>
</ol>
<p>The <a href="http://www.cod3r.com/FreeBSDRaidSetup.zip">FreeBSD directory is available</a> for those who would like to copy my efforts, though they will likely need some modification to suit your needs.  The <em>gptzfsboot</em>, <em>pmbr</em>, and <em>zfsloader</em> files came from <a href="http://people.freebsd.org/~pjd/zfsboot/">this site</a> which are modified versions that work with 4K drives.  The versions available in 8.2 do not work with 4K sector sizes, but future versions will.  My install script
<ul>
<li>Partitions ad8, 10, 12, 14, 16, 18 to contain the boot loader and zpool information (6 SATA drives),</li>
<li>Loads kernel modules and sets up a gnop drive with 4K sectors,</li>
<li>Creates a raidz2 pool using the gnop drive as one of the drives forcing 4K sectors, exports the pool,</li>
<li>Destroys the gnop drive, re-import the pool, which had been forced to 4K sectors,</li>
<li>Sets up root filesystem on zroot/root (zroot is the root of the pool, root is the root filesystem, as discussed above), and</li>
<li>Performs a standard zroot install, except no swap partition.</li>
</ul>
<p>I actually added the swap later, which is simply:<br />
<code>zfs create -V 2G zroot/swap<br />
zfs set org.freebsd:swap=on zroot/swap<br />
zfs set checksum=off zroot/swap<br />
</code></p>
<p>And that&#8217;s it.  I have my 8TB raid running, with 2 drive redundancy, booting off the raid.  Setting up AFP and the like requires more tinkering than with FreeNAS, but the instructions are easy to find and would be redundant to list here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/10/freebsd-with-zfs-root/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What Objective-C can learn from Java, Part 4 (Namespace)</title>
		<link>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/</link>
		<comments>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 21:18:40 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=464</guid>
		<description><![CDATA[This is the last is a series of blog posts I’m writing on things that Objective-C can learn from Java. The other parts can be found here: Part 1 (Generics) Part 2 (Abstract Classes) Part 3 (Single Source File) Part 4 (Namespace) For one who has programmed in other object oriented languages, Objective-C stands out [...]]]></description>
			<content:encoded><![CDATA[<p>This is the last is a series of blog posts I’m writing on things that Objective-C can learn from Java.  The other parts can be found here:<br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-1-generics/">Part 1 (Generics)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-2-abstract-classes/">Part 2 (Abstract Classes)</a><br />
<a href="http://www.cod3r.com/2010/12/what-objective-c-can-learn-from-java-part-3-single-source-file/">Part 3 (Single Source File)</a><br />
Part 4 (Namespace)</p>
<p>For one who has programmed in other object oriented languages, Objective-C stands out with its complete lack of namespace.  As a result, classes have a prefix, such as Apple&#8217;s common <em>NS</em> and <em>UI</em> prefixes.  On the mac side of things, every class under the sun seemed to start with <em>NS</em>, such as <code>NSString</code>, and confusion is added when on the iOS side, several classes start with <em>UI</em>, such as <code>UIView</code>.  This is due to the fact that without a concept of namespace, Objective-C cannot have two classes with the same name, regardless of whether the classes are public or not.</p>
<p>If I were designing an application which communicated on a network as well as talked to a database, I would split the two pieces into separate segments, or in Java, packages.  Inside each package, I would likely have a <code>Connection</code> class, which has completely different meanings within the network and database packages.  Inside those packages, especially if the <code>Connection</code> class was internal to the package only, I could name both classes <code>Connection</code> without any concern and the code inside the package would immediately understand what <code>Connection</code> actually meant.  This is possible in Java because the actual class names are <code>com.cod3r.app.network.Connection</code> and <code>com.cod3r.app.database.Connection</code>.  Since Objective-C does not have namespaces, I would have to name these <code>NetworkConnection</code> and <code>DatabaseConnection</code>.</p>
<p>Now, take the above scenario, and add another type of network connection.  Then take that new network connection and add new specific case to it, making a new class.  In Java, the package name gets longer where as in Objective-C the class name gets longer.  I have run into cases where this borders on ridiculous if one wants the class name to define what it actually does without ambiguity.  The class is within the <a href="http://appletv.nanopi.net">Sapphire</a> plugin.  In the project, all classes had the prefix <code>Sapphire</code> since it was a bundle included in another application and had to make sure there was never a class conflict.  The project has the concept of a <code>Directory</code> and a <code>VirtualDirectory</code> was a directory which wasn&#8217;t associated with a directory in the file system.  There is a type of <code>VirtualDirectory</code> that was <code>Custom</code> meaning it was defined by the user instead of already in the code.  Finally, this particular class is responsible for importing these <code>CustomVirtualDirectory</code> objects, making the final class titled <code>SapphireCustomVirtualDirectoryImporter</code>.  In Java, this class would have been <code>Importer</code> within the <code>net.nanopi.sapphire.directory.virtual.custom</code> package.  The difference is the fully qualified classname would only be used in the import statement, and the short class name would be used in the code, instead of the really long classname used in every location as seen in Objective-C.  This becomes particularly relevant when it comes to code completion that produces a terribly long list until nearly the entire class name is typed.</p>
<p>The lack of namespace becomes problematic when one uses third party libraries.  Take the above Sapphire example and another plugin developer finds a completely unrelated library titled Sapphire.  If that library happened to have a directory titled <code>SapphireDirectory</code>, then both plugins cannot be loaded at the same time.  Java goes even further with a two-level namespace such that two jars (bundles) with the same fully-qualified classname still don&#8217;t interfere since they are in separate jars.</p>
<p>Adding namespace is necessary for adding inner-classes, which Objective-C outright doesn&#8217;t use, but could in proper circumstances.  Inner classes are useful for implementing delegate methods.  When setting a delegate, one typically passed in the instance of an inner class rather than the current instance.  Not adopting this model has the issue when a single class is set to be the delegate to multiple objects, such as being the delegate to two table views.  Apple works around this design by making each delegate method have the first parameter be that of the object calling it&#8217;s delegate, such as the table view.  This means if the code is different between the two, every single delegate method needs have an if statement to determine which table view is being processed, and eliminates the ability of one to skip implementing an optional method for one table but not the other.  Both of these problems are eliminated with inner-classes.  Finally, the lack of inner-classes severely cripples the ability of a super-class to use the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/Concepts/KVOBasics.html">Key Value Observing</a> within Objective-C since the delegate and unregister methods were written in a way that really require an inner-class to work properly (I can see how to easily break some code in a sub-class or super-class since this was designed so badly).</p>
<p>Impact on Runtime:<br />
Small.  I don&#8217;t know the specifics of the runtime, so I can&#8217;t judge the exact impact, but this will result in longer effective class names, which may increase lookup times.  Inner-classes would need an instance variable for their outer-class to access it&#8217;s instance variables, resulting in additional pointer deference for accessing outer-class variables.</p>
<p>Impact on Code:<br />
No longer need to create necessarily long class names; programmer can use short class name without concern.  Frameworks need not have a class prefix.  More flexibility in object design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2011/01/what-objective-c-can-learn-from-java-part-4-namespace/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why you shouldn&#8217;t buy A Flip Camera</title>
		<link>http://www.cod3r.com/2010/09/why-you-shouldnt-buy-a-flip-camera/</link>
		<comments>http://www.cod3r.com/2010/09/why-you-shouldnt-buy-a-flip-camera/#comments</comments>
		<pubDate>Sun, 05 Sep 2010 22:59:54 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=376</guid>
		<description><![CDATA[So, my parents were using a Flip Ultra HD to record sermons. This camera has a serious flaw which the company has acknowledged and failed to fix. First, the camera has 8GB of memory which it formats into a FAT-32 filesystem. This filesystem has a well known limitation where it cannot have a file which [...]]]></description>
			<content:encoded><![CDATA[<p>So, my parents were using a Flip Ultra HD to record sermons.  This camera has a <strong>serious flaw</strong> which the company has acknowledged and failed to fix.  First, the camera has 8GB of memory which it formats into a FAT-32 filesystem.  This filesystem has a well known limitation where it cannot have a file which exceeds 4GB in size.  The Flip camera, when recoding in HD, will hit this limitation in about an hour (depending on the motion in the video).  The simple solution to this is to simply split the recording into multiple files so as to not cause any issues.  Pure Digital Technologies, Inc, unlike their competitors, doesn&#8217;t seem to have figured out this simple solution but instead elected to have the camera beep and turn itself off.  This completely violates what a consumer would expect out of a camera in that it will continually record until it is out of power or out of memory, or in the old days, tape.</p>
<p>I talked with their live support to confirm this flaw, and amid a bastardized, CPU-hogging chat client, I managed to get confirmation that this flaw is known, and no explanation as to why it has not been fixed aside from &#8220;I&#8217;m sorry, that&#8217;s what the camcorder can handle.&#8221;</p>
<p>I later found out that the company is owned by Cisco, and considering my history with their lousy products in the past, I should have already known.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/09/why-you-shouldnt-buy-a-flip-camera/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ZFS on Western Digital EARS drives</title>
		<link>http://www.cod3r.com/2010/06/zfs-on-western-digital-ears-drives/</link>
		<comments>http://www.cod3r.com/2010/06/zfs-on-western-digital-ears-drives/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 21:21:23 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=351</guid>
		<description><![CDATA[According to the stats, my previous post was one of the more popular on this site. This was in response to a question I was asking myself before building a NAS box at home. In looking at the components to use in building it, I came across another question. How does one fix the performance [...]]]></description>
			<content:encoded><![CDATA[<p>According to the stats, <a href="http://www.cod3r.com/2010/04/zfs-on-different-sized-disks/">my previous post</a> was one of the more popular on this site.  This was in response to a question I was asking myself before building a NAS box at home.  In looking at the components to use in building it, I came across another question.  How does one fix the performance of ZFS on Western Digital&#8217;s green drives with model numbers ending in &#8220;EARS&#8221; (WD15EARS, WD20EARS, etc)?  I&#8217;ve split this into sections, with a bold title, so readers can read the parts that are most interesting.  I&#8217;ve described why WD changed their drives, why this is a problem, what the solutions are.  Hope you enjoy this.</p>
<p><strong>Background</strong><br />
First, some background on how drives work internally:  A hard drive stores data on the platters in blocks, or sectors.  The sector size is typically 512 bytes for a magnetic disk.  With each sector, the disk must store a start code and an Error Correction Code (ECC).  The start code is necessary so the disk can find a particular sector, and the ECC is necessary to correct any errors in the data read from the disk.<br />
Western Digital decided to change from 512 byte sectors to 4096 byte sectors.  This means that the new sector  can store the same amount of data as 8 of the previous sectors.  Since each sector needs a start code, this means there are now 7 fewer start codes for each new sector.<br />
The ECC of the 4096 byte sector needs to be larger than the ECC of a 512 byte sector, but it doesn&#8217;t need to be 8 times as big.  This is due to the fact that ECC is better at correcting errors with larger block sizes and thus a lower rate (or percentage in size) ECC can achieve the same Bit Error Rate (BER).  Interesting side note: Hard drives are designed to store data so compactly and so close to the limits of the hardware that data is expected to have some corruption as it was stored, and rely on the ECC to correct the corruption.  In fact, the manufactures intentionally design the drives so that it will have a few corruptions but few enough that the ECC can handle it.<br />
With the reduction in the number of start codes, and decrease in ECC rate, larger sector sizes allow for greater density of data on the drive itself.</p>
<p><strong>Writing Sectors</strong><br />
When a computer does a read, it reads an entire sector at a time.  When it does a write, it, again, writes an entire sector at a time.  There is no such mechanism to write only a part of a sector.  Western Digital&#8217;s EARS drives have 4096-byte sectors, but the drive claims it has 512-byte sectors (since some opperating systems still in use cannot handle different sector sizes).  This means that the drive does some work internally to handle this difference.  Often, when writing data to a hard drive, multiple consecutive sectors are written.  If a computer writes 8 512-byte sectors in a row, which all correspond to the same 4096-byte sector, then the drive can simply wait until all 8 sectors are written and write out all the data as a single 4096-byte sector.  This is what the EARS drives do when sectors are written.  If not all 8 sectors are written, then the drive has to do a partial sector write.  This is typically not the case since many file system operate on 4096-byte blocks, and thus write 4096 bytes at a time.</p>
<p><strong>Partial Sector Write</strong><br />
If not all 8 512-byte sectors in a 4096-byte sector are written, then the drive has to write part of a sector.  So, the drive must find the data on the drive, and write the part of the sector that has changed, right?<br />
Wrong.  The problem is the ECC was written with the 4096 bytes that was there previously, so it must be updated.  Due to the nature of how the ECC is computed, one cannot write a new ECC without first reading at least some of the data that was in the original sector.  While it is possible to read the data to be overwritten, the old ECC, and compute the new ECC, this can propagate errors beyond the ECC&#8217;s ability to correct.  So, the drive must read the 4096-byte sector, correct any data errors in the sector, substitute in the changed data, compute the new ECC, wait for that part of the drive to spin around again, and write the data to the drive.  In comparison, if all 8 512-byte sectors were written, then the drive need only compute the new ECC and write the data.<br />
So, if a single 512-byte sector is written, the drive must read 4096 bytes, wait for a rotation, and then write 4096 bytes.  On a 7200 RPM drive, the waiting for a single rotation is 8.333 ms.  If one assumes no smart scheduling, this results in a maximum throughput of a megabyte every 2 seconds, which is reminiscent of drives from the previous decade.  Obviously, intelligent scheduling is utilized, but in the best case scenario, the drives performance will be dropped to half.  From this, one can see that it is crucial to always write 4096 bytes at a time to get the best performance.</p>
<p><strong>Alignment</strong><br />
As stated in the previous section, the best performance comes when 4096 bytes is written at a time, but this data must also be properly aligned.  If 2048 bytes is written to one sector and 2048 to the next, then this involves 2 reads and 2 writes of 4096 bytes each.  So all writes must be aligned on 8 sector boundaries (sector 0, 8, 16, 24, 32, etc)  This is why Western Digital put in a jumper to help with the alignment since some formatting methods start on sector 63, which is not an 8 sector boundary.  Those on Unix/Linux systems must pay special attention to this when formatting the drive.</p>
<p><strong>Solutions</strong><br />
The solutions depend on the file system you are using.  If you know your file system uses 4096-byte blocks, then you only need to ensure that the file system is properly aligned on 8-sector boundaries.  So, when partitioning the drive, ensure that the partition offsets are divisible by 8.</p>
<p><strong>ZFS</strong><br />
So, what does this have to do with ZFS?  ZFS doesn&#8217;t have a pre-set block size.  It uses variable sized blocks depending on the amount of data it is writing.  If it&#8217;s writing 1000 bytes, then it will write the minimum number of sectors necessary to fit that data, which in the case of 512-byte sectors, is 2.  This means that writing 1000 bytes requires reading and writing 4096 bytes or maybe 8192 depending on alignment.  This means that properly aligning the partition will not solve the issue with ZFS.  Here we need a different solution.</p>
<p><strong>File System Agnostic Solution</strong><br />
The best solution is for the file system to think the drive has 4096-byte sectors.  Since the drive will not claim this it needs to be done in software (really Western Digital, did you think this was not worthy of a jumper on the drive?  It would have made things much easier).  Since ZFS has performance issues on Linux anyway due to it&#8217;s kernel&#8217;s license, I won&#8217;t cover it at all.  The primary case I&#8217;ve seen this issue raised is from those using FreeNAS on FreeBSD.  Here, there are two solutions, depending on whether you want your drive encrypted or not.  Both of these solutions give a new device, which the rest of the OS sees as a normal drive, but the drive has 4096-byte sectors, which are properly aligned.  Warning, both of these methods destroy the data on the drive.<br />
<strong>Not Encrypted</strong><br />
The drive can be presented as a drive with 4096-byte sectors by using gnop.  Here is how one would create a raidz1 pool for da1-4:<br />
<code>for i in da1 da2 da3 da4; do gnop create -S 4096 $i; done<br />
zpool create tank da1.nop da2.nop da3.nop da4.nop</code><br />
The for loop must be run on each reboot otherwise ZFS will not see the da*.nop devices.<br />
<strong>Encrytped</strong><br />
The encryption setup is similar:<br />
<code>for i in da1 da2 da3 da4; do geli init -s 4096 $i; done<br />
for i in da1 da2 da3 da4; do geli attach $i; done<br />
zpool create tank da1.eli da2.eli da3.eli da4.eli</code><br />
Here the second for loop needs to be executed on each reboot.  On FreeNAS, the encryption can be made simpler by setting up the drives in the GUI to use encryption, then after the encryption is setup, go into the shell, and execute the two for loops, then continue setting up the encrypted drive in the gui to use ZFS.</p>
<p>So, that&#8217;s how to handle ZFS on WD EARS drives.  I&#8217;ve read reports that some, if not all, of what I described in the solutions will be in the next version of FreeNAS.  Here&#8217;s hoping that it will.</p>
<p>BTW, the primary legacy Operating System that cannot properly handle the 4096-byte sector is Windows XP.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/06/zfs-on-western-digital-ears-drives/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ZFS on different sized disks</title>
		<link>http://www.cod3r.com/2010/04/zfs-on-different-sized-disks/</link>
		<comments>http://www.cod3r.com/2010/04/zfs-on-different-sized-disks/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 00:04:20 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=310</guid>
		<description><![CDATA[Note: Following this is not for the faint of heart. If you aren&#8217;t comfortable with partitioning, then don&#8217;t follow the steps here. I&#8217;ve read many posts on how to handle ZFS/Raid-Z on differently sized disks. The goal is to gain the most disk space availability while still retaining the redundancy of surviving a single disk [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note</strong>: Following this is not for the faint of heart.  If you aren&#8217;t comfortable with partitioning, then don&#8217;t follow the steps here.<br />
I&#8217;ve read many posts on how to handle <a href="http://en.wikipedia.org/wiki/ZFS">ZFS</a>/<a href="http://en.wikipedia.org/wiki/RAID-Z">Raid-Z</a> on differently sized disks.  The goal is to gain the most disk space availability while still retaining the redundancy of surviving a single disk failure.  The posts I&#8217;ve read either would achieve the theoretical capacity, or be capable of expansion, but not both.  I devised a way to get both at the same time, and it&#8217;s relatively simple.</p>
<p>The problem is the following:  A Raid-Z configuration uses n partitions, giving the user the capacity of n-1 of those partitions, with the nth being the redundant to survive a failure.  If the n partitions are not the same size, with the smallest being x, only the first x bytes of each partition is used.  One cannot remove a Raid-Z from an active pool without a backup/restore.  One cannot add a disk to a Raid-Z without a backup/restore (<a href="http://blogs.sun.com/ahl/entry/expand_o_matic_raid_z">maybe in the future</a>).  The only expansion that can be done is to replace the partitions with larger ones, and once the smallest partition is increased, the available space increases.</p>
<p>For the purposes of demonstrating this technique, I will use an example with 4 disks:</p>
<ul>
<li>125G</li>
<li>250G</li>
<li>500G</li>
<li>750G</li>
</ul>
<p>The biggest theoretical capacity of the array, while retaining single disk failure resiliency, is simply the total size of the array minus the largest disk.  This means that the capacity of the above example is 875G.  So, how does one achieve this capacity?  I proposed the following structure using 3 raids:</p>
<p><a href="http://www.cod3r.com/images/2010/04/Initial-Disks.png"><img src="http://www.cod3r.com/images/2010/04/Initial-Disks-300x165.png" alt="" title="Initial Disks" width="300" height="165" class="aligncenter size-medium wp-image-331" /></a></p>
<p>If you add the capacity in the above, you can see it is 3*125G + 2*125G + 250G = 875G, which is the theoretical capacity.</p>
<p>Suppose I wish to replace the smallest disk, 125G, with a new disk, say 1T.  Using the same layout, I should see something like this:</p>
<p><a href="http://www.cod3r.com/images/2010/04/Final-Disks.png"><img src="http://www.cod3r.com/images/2010/04/Final-Disks-300x210.png" alt="" title="Final Disks" width="300" height="210" class="aligncenter size-medium wp-image-334" /></a><br />
If you add the capacity in the above, you can see it is 3*250G + 2*250G + 250G = 1500G, which again is the theoretical capacity.</p>
<p>The question is, can I migrate from the first configuration to the last without a backup/restore process?  The answer is <strong>YES</strong>, and data is moved/copied at most once.</p>
<p>For the purposes of demonstration, I&#8217;m going to show the expansion with 5 drives connected, but the expansion can be done by immediately replacing the smallest drive with the largest and relying on the redundancy to keep things intact in the process.</p>
<p>First, connect the 1T drive and partition it as 250G, 250G, 250G, leaving the rest free.  Replace the first 125G partition on 750G disk with the first 250G partition on the 1T disk:<br />
<a href="http://www.cod3r.com/images/2010/04/Step-1.png"><img src="http://www.cod3r.com/images/2010/04/Step-1-300x171.png" alt="" title="Step 1" width="300" height="171" class="aligncenter size-medium wp-image-335" /></a></p>
<p>Continue the replacement:<br />
<a href="http://www.cod3r.com/images/2010/04/Step-2.png"><img src="http://www.cod3r.com/images/2010/04/Step-2-300x171.png" alt="" title="Step 2" width="300" height="171" class="aligncenter size-medium wp-image-336" /></a></p>
<p><a href="http://www.cod3r.com/images/2010/04/Step-3.png"><img src="http://www.cod3r.com/images/2010/04/Step-3-300x171.png" alt="" title="Step 3" width="300" height="171" class="aligncenter size-medium wp-image-337" /></a></p>
<p>Repeat the same process with the 3 partitions on the 500G disk:<br />
<a href="http://www.cod3r.com/images/2010/04/Step-4.png"><img src="http://www.cod3r.com/images/2010/04/Step-4-300x171.png" alt="" title="Step 4" width="300" height="171" class="aligncenter size-medium wp-image-338" /></a><br />
At this point, the move of the blue raid is complete.  Depending on the sizes of the disks, the blue raid may be bigger, at which point the pool immediately increases in size.  In this example, it does not change size.</p>
<p>Repeat with the 2 partitions on the 250G disk:<br />
<a href="http://www.cod3r.com/images/2010/04/Step-5.png"><img src="http://www.cod3r.com/images/2010/04/Step-5-300x171.png" alt="" title="Step 5" width="300" height="171" class="aligncenter size-medium wp-image-339" /></a><br />
At this point, the red raid is complete.  In this example, the red raid has changed from 250G to 500G, and the job isn&#8217;t complete yet!</p>
<p>Repeat for the final time with partition on the 125G disk:<br />
<a href="http://www.cod3r.com/images/2010/04/Step-6.png"><img src="http://www.cod3r.com/images/2010/04/Step-6-300x171.png" alt="" title="Step 6" width="300" height="171" class="aligncenter size-medium wp-image-340" /></a><br />
Now we are done, and can disconnect the 125G disk if not done already.  In this example, the green raid has changed from 375G to 750G, yielding a total change of 875G to 1500G.</p>
<p><strong>Note:</strong> There is one limitation with this structure.  Ordering the disks in increasing size, disk(n) must be at least as big as 2*(disk(n-1))-disk(n-2).  This essentially means that if a disk is xG bigger than it&#8217;s previous disk, then the next disk must be at least xG bigger than this disk.  Since disk sizes tend to grow exponentially, this assumption shouldn&#8217;t be much of a problem since the requirement is at least linear growth.</p>
<p>The disk sizes in this example meet the requirement I listed above.  Given the requirements of this expansion, the disk added in this example must be at least 1000G, since disk 4 is 250G bigger than disk 3, disk 5 must be at least 250G bigger than disk 4, or 1000G.</p>
<p>This technique also allows adding another disk, under the same conditions.  Consider adding a 1T disk and creating another Raid-Z:<br />
<a href="http://www.cod3r.com/images/2010/04/Add-Disk.png"><img src="http://www.cod3r.com/images/2010/04/Add-Disk-300x171.png" alt="" title="Add Disk" width="300" height="171" class="aligncenter size-medium wp-image-341" /></a><br />
I didn&#8217;t structure the partitions in nice pretty rows to demonstrate the fact that not all of the data needs to be moved (in this case, 750G of data is not moved).  In this example, the capacity increased from 875G to 1625G, again the theoretical capacity.</p>
<p>Anyway, I thought of this while considering using ZFS/Raid-Z in a <a href="http://freenas.org">FreeNAS</a> setup.  I haven&#8217;t tested any of this; it&#8217;s theoretical only.  What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/04/zfs-on-different-sized-disks/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Passed My Defense</title>
		<link>http://www.cod3r.com/2010/02/passed-my-defense/</link>
		<comments>http://www.cod3r.com/2010/02/passed-my-defense/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 00:29:44 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[School]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=290</guid>
		<description><![CDATA[I haven&#8217;t posted here in a while, and with good reason. About two weeks ago, I passed my Ph.D. defense. So, come May, I will officially have a doctorate in Computer Engineering, though I am effectively done with my degree.]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t posted here in a while, and with good reason.  About two weeks ago, I passed my Ph.D. defense.  So, come May, I will officially have a doctorate in Computer Engineering, though I am effectively done with my degree.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2010/02/passed-my-defense/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Incorrect Podcast Order on my iPod</title>
		<link>http://www.cod3r.com/2009/09/incorrect-podcast-order-on-my-ipod/</link>
		<comments>http://www.cod3r.com/2009/09/incorrect-podcast-order-on-my-ipod/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 23:00:05 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=279</guid>
		<description><![CDATA[One of these days I will learn not to grab the latest and &#8220;greatest&#8221; software the moment it comes out. Yesterday, I upgraded my iTunes to version 9 and my iPod Touch&#8217;s firmware to 3.1.1. Then, I noticed that one of my podcasts was out of order, and furthermore, the release date was no longer [...]]]></description>
			<content:encoded><![CDATA[<p>One of these days I will learn not to grab the latest and &#8220;greatest&#8221; software the moment it comes out.  Yesterday, I upgraded my iTunes to version 9 and my iPod Touch&#8217;s firmware to 3.1.1.  Then, I noticed that one of my podcasts was out of order, and furthermore, the release date was no longer showing up on the iPod itself.  Strangely, only one podcast was having this issue.</p>
<p>I started to suspect that this was my fault, since this one podcast, <a href="http://escapepod.org/">Escape Pod</a> was a podcast I was listening by going through its archives.  I had written a program which downloads the archived episodes, and modifies the ID3 tags so iTunes will properly recognize the file as a podcast and insert it into its database as if it had downloaded it itself.  Getting the release date working correctly was one of the harder points, so I figured that I still didn&#8217;t have it quite correct and the new iPod firmware was being more sensitive to it.  I got even more annoyed by the fact that iTunes, after upgrading my iPod&#8217;s firmware, decided to trash the old firmware versions preventing me from ever downgrading.</p>
<p>Then, I read online discussions where others were having this problem.  Now I know that it is not my fault, but rather something that Apple screwed up.  I also saw someone who noted that they had upgraded their iTunes, but not their iPod, and had the same issue.  So, I trashed iTunes, pulled out my Snow Leopard disk, found the iTunes package on the disk, installed it, reverted my iTunes library to the backup prior to the upgrade, and voila, my podcasts are sorting correctly again.</p>
<p>Now if only I will learn to let others try first, and upgrade myself after reading their reports.  This is a really sloppy bug on Apple&#8217;s part, and likely means that iTunes 9 was rush.  I&#8217;m actually happier back on 8, especially since the window zoom still functions as a toggle between the mini player and the normal window, which was changed in 9.</p>
<p>Hopefully someone will benefit from this post, and not upgrade to iTunes 9 until this regression is resolved.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2009/09/incorrect-podcast-order-on-my-ipod/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New Car</title>
		<link>http://www.cod3r.com/2009/07/new-car/</link>
		<comments>http://www.cod3r.com/2009/07/new-car/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 22:33:22 +0000</pubDate>
		<dc:creator>Graham Booker</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cod3r.com/?p=256</guid>
		<description><![CDATA[Well, after much hassle, I now have a new car. Here are some pictures: The whole ordeal was mostly due to the CARS program, which is often known by &#8220;Cash for Clunkers&#8221;. Anyway, I finally got that resolved and got a lot more for my old truck than I would have ever gotten in trade-in [...]]]></description>
			<content:encoded><![CDATA[<p>Well, after much hassle, I now have a new car.  Here are some pictures:<br />
<a href="http://www.cod3r.com/images/2009/07/New-Car-Front.jpg"><img src="http://www.cod3r.com/images/2009/07/New-Car-Front-300x200.jpg" alt="New Car Front" title="New Car Front" width="300" height="200" class="alignnone size-medium wp-image-258" /></a><br />
<a href="http://www.cod3r.com/images/2009/07/New-Car-Side.jpg"><img src="http://www.cod3r.com/images/2009/07/New-Car-Side-300x200.jpg" alt="New Car Side" title="New Car Side" width="300" height="200" class="alignnone size-medium wp-image-259" /></a></p>
<p>The whole ordeal was mostly due to the <a href="http://www.cars.gov">CARS</a> program, which is often known by &#8220;Cash for Clunkers&#8221;.  Anyway, I finally got that resolved and got a lot more for my old truck than I would have ever gotten in trade-in value.  So now I have a VW Jetta, and so far I&#8217;m happy with it.  I just need to get used to driving a car instead of a truck, but otherwise it drives well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cod3r.com/2009/07/new-car/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

