<?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>Unwinding the Stack</title>
	<atom:link href="http://thestaticvoid.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thestaticvoid.com</link>
	<description>Explorations in Computing</description>
	<lastBuildDate>Wed, 09 May 2012 21:22:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>My Homemade LOM</title>
		<link>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/</link>
		<comments>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/#comments</comments>
		<pubDate>Wed, 09 May 2012 21:17:42 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=798</guid>
		<description><![CDATA[In one of the final classes of my CS master&#8217;s program, Embedded Computing, we were required to complete a semester project of our choosing involving embedded systems. Like in previous semester projects, I wanted to do something that I would actually be able to use after the class ended. This time around I chose to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/lom.jpg"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/lom-300x199.jpg" alt="" title="My homemade LOM installed in an Ultra 24" width="300" height="199" class="alignright size-medium wp-image-809" /></a>In one of the final classes of my CS master&#8217;s program, Embedded Computing, we were required to complete a semester project of our choosing involving embedded systems.  Like in <a href="http://thestaticvoid.com/post/2011/06/09/wireless-802-1x-support-in-solaris/">previous semester projects</a>, I wanted to do something that I would actually be able to use after the class ended.</p>
<p>This time around I chose to build a <a href="http://en.wikipedia.org/wiki/Out-of-band_management">lights-out manager</a> for my Sun Ultra 24 server (which this blog is hosted on).  With a LOM I can control the system&#8217;s power and access its serial console so I will be able to perform OS updates remotely, among other things.</p>
<p>Since I already owned one and I didn&#8217;t want to spend a lot of money, I chose to develop the project on top of the <a href="http://arduino.cc/en/Main/arduinoBoardUno">Arduino</a> platform.  I like the size of the Arduino, and the availability of different shields to minimize soldering.  It&#8217;s also able to be powered by USB, which is perfect because the Ultra 24 has an internal USB port that always supplies power.</p>
<p>To make things a little more challenging for myself (because the Arduino is pretty easy on its own), I chose to implement a hardware UART to communicate with the Ultra 24&#8242;s serial port.  Specifically, I chose to use the <a href="http://www.maxim-ic.com/datasheet/index.mvp/id/2052">Maxim MAX3110E</a> SPI UART and RS-232 transceiver.  Great little chip.</p>
<p>For communication with the outside world, I bought an <a href="http://www.freetronics.com/products/ethernet-shield-with-poe">Ethernet shield</a> from Freetronics.  It&#8217;s compatible with the official Arduino Ethernet shield, but includes a fix to allow the network module to work with other SPI devices (such as my UART) on the same bus.  I started to implement the network UI using Telnet, but after realizing I would have to translate the serial console data from VT100 to <a href="http://www.ietf.org/rfc/rfc854.txt">NVT</a>, I switched to <a href="http://www.ietf.org/rfc/rfc1282.txt">Rlogin</a>, which is like Telnet, but assumes like-to-like terminal types.</p>
<p>Lastly, for controling the system&#8217;s power, I figured out how to tap into the Ultra 24&#8242;s power LED and switch.  Using the LED, I can check whether the system is on or off, and using the switch circuit and a transistor, I can power the system on and off.  I managed to do this without affecting the operation of the front panel buttons/LEDs.</p>
<p>I&#8217;ll spare you all of the implementation details (if you&#8217;re interested, you can read <a href="https://github.com/MrStaticVoid/school/raw/master/CSCI6907/project/final-report/final-report.pdf">my report</a>).  Suffice it to say, the thing works as well as I could have imagined.  Here is a screenshot of me using the serial console on my workstation:</p>
<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/session.png"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/session.png" alt="" title="LOM Session" width="652" height="1050" class="aligncenter size-full wp-image-804" /></a></p>
<p>From my research, the serial and power motherboard headers are the same on most modern Intel systems, so this LOM should work on more than just an Ultra 24.  If you want to build one of your own, my code is available on <a href="https://github.com/MrStaticVoid/school/tree/master/CSCI6907/project/sketch">GitHub</a> and the hardware schematic is in the report I linked to above.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ITT I Try to Justify Upgrading My Camera</title>
		<link>http://thestaticvoid.com/post/2012/03/21/itt-i-try-to-justify-upgrading-my-camera/</link>
		<comments>http://thestaticvoid.com/post/2012/03/21/itt-i-try-to-justify-upgrading-my-camera/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 04:39:52 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Photography]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=757</guid>
		<description><![CDATA[I&#8217;ve said it before, and I&#8217;ll say it again: I am not a photographer. I am just a guy who enjoys taking high quality photos of the places I go and the things I enjoy doing. A couple years ago I picked up a Canon EOS Rebel T2i, a sharp 15-85mm f/3.5-5.6 zoom lens, and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve said it before, and I&#8217;ll say it again: I am not a photographer.  I am just a guy who enjoys taking high quality photos of the places I go and the things I enjoy doing.  A couple years ago I picked up a Canon EOS Rebel T2i, a sharp 15-85mm f/3.5-5.6 zoom lens, and everyone&#8217;s favorite, the 50mm f/1.4, before a two-week trip to Japan.  In the time since, I&#8217;ve taken thousands of photos and really enjoyed learning the technology and different photographic techniques.  The T2i is really impressive, and is still a better camera than I am a photographer.  That said, I&#8217;ve always known that I would want to upgrade at some point.  The T2i is too small for my large hands to hold securely or comfortably, and I am not really fond of its plasticky build.</p>
<p><strong>Meanwhile,</strong> I went through a couple hundred photos from a recent trip to Belgium with my girlfriend, and though I really like what I was able to capture, and I&#8217;m satisfied with the way they turned out, I can&#8217;t help but notice a distinct point-and-shoot quality about them.  Obviously they can&#8217;t all be winners, but in the spur of the moment, it&#8217;s all too easy for me to let my zoom lens do all the work at the expense of good composition.</p>
<p>Looking back at my photos, I noticed that I like the ones I&#8217;ve taken with my 50mm lens the most.  The fixed focal length forces me to really think about how I want the photo to look, and I have to move my feet in order to get it.  Its large aperture allows me to take photos at a lower ISO level in low light, which means less sensor noise.  And its shallow depth-of-field potential stimulates my creativity.  I think Kai from DigitalRev explains it best:</p>
<div style="text-align: center"><iframe width="560" height="315" src="http://www.youtube.com/embed/PwmCrGVS3ZQ" frameborder="0" allowfullscreen></iframe></div>
<p>However, with my T2i&#8217;s APS-C-sized sensor, the field-of-view of the 50mm lens is more like an 80mm lens on a full-frame sensor, which is really narrow for indoor shooting.  I would have to stand all the way across the room to get anything more than just a headshot.  So I started to look at what equivalent &#8220;normal&#8221; lenses I could get for my T2i.</p>
<div style="text-align: center"><iframe width="560" height="315" src="http://www.youtube.com/embed/SoN1GDhRjDg" frameborder="0" allowfullscreen></iframe></div>
<p>I settled on the Canon EF 28mm f/1.8, and I&#8217;m generally very happy with it.  It&#8217;s sharp, fast, and well made.  However, the difference in the depth-of-field between the 50mm and 28mm is very noticeable, even at f/1.8.  It&#8217;s much harder to get that nicely blurred background unless you&#8217;re within a couple feet of your subject with the 28mm.  That is just the nature of wider angle lenses.</p>
<p><strong>Meanwhile,</strong> Canon just released the brand-new full-frame EOS 5D Mark III and prices for the three-year-old 5D Mark II are dropping.  I never would have considered getting a full-frame camera before (that&#8217;s just silly&#8212;I&#8217;m an amateur and full-frame cameras are for the pros, right?), but the prices are not much more than the 7D now.  The 5D Mark II is still a great camera.  One of the few things people complain about is its poor auto-focus performance.  Fortunately, I learned early to use center-point and <a href="http://www.learn.usa.canon.com/resources/articles/2011/backbutton_af_article.htmlp">back-button focus</a>, and I don&#8217;t shoot sports, so I couldn&#8217;t care less about auto-focus performance.</p>
<p>The 5D Mark II is better in almost every way compared to my T2i.  It&#8217;s very well built and will fit my hands, so I&#8217;ll enjoy holding and using it.  And as a bonus, the full-frame sensor will enable me to get the depth-of-field I&#8217;m used to on my 50mm lens with the field-of-view similar to my 28mm, which can open a whole new world of possibilities for me.</p>
<p>All of this is just to say: I think I&#8217;m going to upgrade to a 5D Mark II.  I think now is the time.  I am serious about improving my photography and I think sticking with only prime lenses for a while will help.  It takes a huge variable out of the equation (focal length) so hopefully I can concentrate on the more important things.  In fact, I&#8217;ve already sold my zoom lens.  Between the money from the sale of my lens, the money I should be able to get from selling my T2i, and some credit card cash back, I will be able to pick up the 5D Mark II for a good price.  It will be an early graduation present to myself.  And if it turns out not to be right for me, photo gear keeps its value pretty well, so I can always sell it.</p>
<p>I&#8217;m not crazy for wanting to upgrade, am I?</p>
<p><strong>UPDATE 05/09/2012:</strong> I managed to pick up a factory refurbished 5D Mark II during Canon&#8217;s friends and family sale for a ridiculously good price ($1596 after taxes and shipping).  Canon&#8217;s refurbs, if you don&#8217;t know, are like new and mine was no exception.  I sold my T2i and 15-85mm lens for $1000 after eBay and Paypal took their cut, and I allowed myself to buy a refurbed EF 100mm f/2 USM lens and Speedlite 580EX II during the same Canon sale.</p>
<p>And the result?  Well, I feel like I&#8217;m already starting to make some good improvements.  Shooting with primes often forces me to think more creatively about composition and perspective to get the shot I want.  Then taking the shots into Lightroom helps me do minor white balance and color corrections to really make them pop.  And finally, the flash is just a lot of fun.</p>
<table style="margin-left: auto; margin-right: auto; border-spacing: 10px;">
<tr>
<td rowspan="2"><a href="http://www.flickr.com/photos/mrstaticvoid/7049733515/" title="The Pit by MrStaticVoid, on Flickr"><img src="http://farm6.staticflickr.com/5453/7049733515_5e706c38b6_n.jpg" width="213" height="320" alt="The Pit"></a></td>
<td><a href="http://www.flickr.com/photos/mrstaticvoid/7089329903/" title="Taking in the Scenery by MrStaticVoid, on Flickr"><img src="http://farm8.staticflickr.com/7126/7089329903_b73cdf81ce_n.jpg" width="320" height="213" alt="Taking in the Scenery"></a></td>
</tr>
<tr>
<td><a href="http://www.flickr.com/photos/mrstaticvoid/7004047878/" title="Mean Rabbit by MrStaticVoid, on Flickr"><img src="http://farm8.staticflickr.com/7267/7004047878_3fcc967a3d_n.jpg" width="320" height="213" alt="Mean Rabbit"></a></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2012/03/21/itt-i-try-to-justify-upgrading-my-camera/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Setting Up My Retirement Investments with TIAA-CREF</title>
		<link>http://thestaticvoid.com/post/2011/12/05/setting-up-my-retirement-investments-with-tiaa-cref/</link>
		<comments>http://thestaticvoid.com/post/2011/12/05/setting-up-my-retirement-investments-with-tiaa-cref/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 05:15:30 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[fidelity]]></category>
		<category><![CDATA[investment]]></category>
		<category><![CDATA[retirement]]></category>
		<category><![CDATA[tiaa-cref]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=619</guid>
		<description><![CDATA[This is a long post mostly so I can look back and remember what I did, but I&#8217;m posting it publicly in case anyone is in a similar position and could benefit from my research. About a year ago I became eligible for my employer&#8217;s retirement plan, and at the time I was completely overwhelmed [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a long post mostly so I can look back and remember what I did, but I&#8217;m posting it publicly in case anyone is in a similar position and could benefit from my research.</em></p>
<p>About a year ago I became eligible for my employer&#8217;s retirement plan, and at the time I was completely overwhelmed by this whole new world of mutual fund investments.  Not only was I given a large selection of funds to choose from, but I was also given the choice of providers: Fidelity and TIAA-CREF.  I did a little research, but couldn&#8217;t really decide what to do, so I just selected the defaults, Fidelity with the 2050 target fund, and let it sit.</p>
<p>Then, over the Thanksgiving weekend, I started reading the <a href="http://forums.somethingawful.com/showthread.php?threadid=2892928">long-term investment</a> thread at Something Awful where it quickly became apparent that (1.) choosing assets to invest in doesn&#8217;t have to be that hard, (2.) expense ratios (what a fund costs) matter a lot, and (3.) high-cost actively managed funds in general don&#8217;t perform better than their lower-cost index-based equivalents.</p>
<p>So I took another look at what was <a href="http://financeoffice.gwu.edu/taxpayrollbenefits/benefits/Retirement%20Docs/Retirement%20Benefit%20Docs/2011/Fidelity%20Fund%20Performance%20093011.pdf">available to me</a> in Fidelity, and I didn&#8217;t like what I saw.  Two stock <a href="http://quote.morningstar.com/fund/f.aspx?t=FUSEX">index</a> <a href="http://quote.morningstar.com/fund/f.aspx?t=VINIX">funds</a>, each tracking the S&#038;P 500; one <a href="http://quote.morningstar.com/fund/f.aspx?t=VGRSX">REIT index fund</a>, and one <a href="http://quote.morningstar.com/fund/f.aspx?t=FBIDX">bond index fund</a>.  The rest of the funds available were actively managed with expenses around 0.8% or more.  Even the few Vanguard funds available to me through Fidelity seemed obscure and expensive.</p>
<p>Then I remembered about TIAA-CREF.  I pulled up a list of <a href="http://enroll.tiaa-cref.org/Resources/PPC/PDF/PPC_0291503253_6070.pdf">their offerings</a>, and it made me a little more optimistic.  Not only are their options cheaper overall, but they also have index funds available for more market segments.  Really the worst thing that could be said after an initial look is that they could have more international representation, but it would turn out that, for me, it doesn&#8217;t really matter.</p>
<p>I started reading TIAA-CREF&#8217;s literature and taking their asset allocation (AA) quizzes, you know the ones.  Well, considering I&#8217;m only 25 and I have a good 40 years until retirement, I would consider myself more willing to take on risk than someone a little older.  Their quiz would have me put 86% into equities, 9% in real estate, and 5% in bonds.  Why 9% real estate?  Why not ten, or eight?  And can 5% of your portfolio really affect anything?</p>
<p>At this point, I should note that TIAA&#8217;s <a href="http://www.tiaa-cref.org/public/performance/retirement/profiles/1009.html">Real Estate Account</a> (TREA) is a unique investment vehicle among providers in that it invests directly in commercial real estate, rather than in companies that manage real estate as the more risky <a href="http://en.wikipedia.org/wiki/Real_estate_investment_trust">REIT</a> funds do.  There is really nothing else like it, and that made it hard to reconcile with other popular AA tips I found on the internet, such as having a simple <a href="http://www.bogleheads.org/wiki/Three-fund_portfolio">three-fund portfolio</a>.  I wanted to know whether I should include real estate, if I should follow TIAA-CREF&#8217;s advice for AA, why they chose the numbers they did, and also why the <a href="http://www.bogleheads.org/wiki/Main_Page">Bogleheads</a> advocate slightly more conservatives allocations.  I may be young, but I don&#8217;t want to turn the risk up to 11 just because I can.  I want managed risk that I can understand.</p>
<p>So I picked up a copy of <em><a href="http://www.amazon.com/Intelligent-Asset-Allocator-Portfolio-Maximize/dp/0071362363">The Intelligent Asset Allocator</a></em> by William Bernstein, hoping it would shed some light on my questions.  To be honest, I was hoping it would have The Answer in it, that it would point me to The Optimal Asset Allocation.  Thankfully, it did a whole lot better than that.  It stated in no uncertain terms that there is no such thing as an optimal asset allocation, and anyone claiming to have one is conning you.  The book started off by providing useful metrics for measuring the performance (in terms of annual return) and risk (in terms of standard deviation) of different asset classes.  It was an easy, quick read that gave me a few techniques for understanding the behavior of different asset classes, and how they&#8217;ve historically interacted with each other in portfolios.  Best of all, it gave me the confidence to tackle the same sort of research on my own.</p>
<p><span id="more-619"></span></p>
<p>I sat down and took another look at the asset classes available to me with TIAA-CREF:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th>Asset Class</th>
</tr>
<tr>
<td>Domestic Equities</td>
</tr>
<tr>
<td>International Equities</td>
</tr>
<tr>
<td>Real Estate</td>
</tr>
<tr>
<td>Bonds</td>
</tr>
<tr>
<td><del>Money Market</del></td>
</tr>
<tr>
<td>TIAA Traditional</td>
</tr>
</table>
<p><a href="http://www.tiaa-cref.org/public/performance/retirement/profiles/4001.html">TIAA Traditional</a> is fixed annuity that guarantees at least 3% interest which, like TREA, is a unique offering that complicated things for me.  More on that later.  Money markets are, as I understand them, good places to keep cash for liquidity purposes, and they&#8217;re currently returning 0.0%.  I could scratch that off my list right away&#8212;I&#8217;m in this for the long haul.  The next step was to decide which assets were &#8220;high risk&#8221; and which ones were &#8220;low risk.&#8221;  Bernstein says that you control the risk of your overall portfolio by your total allocation of low risk assets.  Typically people consider equities as high risk and bonds as low risk.  TREA was a bit of a mystery which required more investigation (and believe me, I read every document, article, and forums topic I could find about it), but ultimately my gut told me the answer.  Anyone who owns a house or has watched the news in the past few years could tell you, real estate is a risky asset.  And one look at the account&#8217;s growth in the past decade makes it clear:</p>
<p><a href="http://quote.morningstar.com/fund/f.aspx?t=US8780942004"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/12/trea-growth.png" alt="" title="TIAA Real Estate Account Growth" width="576" height="399" class="aligncenter size-full wp-image-630" /></a></p>
<p>All I had to do was ask myself, &#8220;if I were nearing retirement and that dip happened, would I be okay with it?&#8221;  Because, if I classified it as a low risk asset, then in the future I would own more of it than I do today as one increases the total allocation of low risk assets to control risk approaching retirement.  Clearly I would want to own decreasing amounts of real estate as I age, so it belongs in the high risk category:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
</tr>
<tr>
<th rowspan="3">High Risk</th>
<td>Domestic Equities</td>
</tr>
<tr>
<td>International Equities</td>
</tr>
<tr>
<td>Real Estate</td>
</tr>
<tr>
<th rowspan="2">Low Risk</th>
<td>Bonds</td>
</tr>
<tr>
<td>TIAA Traditional</td>
</tr>
</table>
<p>Now I could take on the actual asset allocation by process of simplification.  First I looked at domestic vs. international equities.  As an aside, some people will further break down equities into the various classes of stock (large vs. small-cap, value vs. growth, etc.), and  though Bernstein clearly shows that the different sub-classes have different behaviors and play different roles in a portfolio, he also makes it painfully clear that past performance is no guarantee of future performance, and that the behaviors of the different sub-classes have changed over time, so it makes the most sense to own the whole market as it is rather that weighting it.  There are funds which track indices that represent the whole market, such as the <a href="http://en.wikipedia.org/wiki/Russell_3000_Index">Russell 3000</a> or <a href="http://en.wikipedia.org/wiki/MSCI_EAFE">MSCI EAFE</a>.  Makes things a lot simpler.</p>
<p>Back to the task at hand, I downloaded the annual returns for the <a href="http://en.wikipedia.org/wiki/Wilshire_5000">Wilshire 5000</a> (an index similar to Russell 3000) and the EAFE all the way back to 1971 and plotted the risk vs. return for all of the different allocations of domestic and international equities:</p>
<p><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/12/dom-int.png" alt="" title="Domestic and International Equities Allocations for 1971-2010" width="640" height="480" class="aligncenter size-full wp-image-640" /></p>
<p>The endpoints on the left of the curve represent portfolios of all domestic stock.  The right endpoints represent portfolios of all international stock.  Each point in between going from left to right represents replacing 10% of the domestic stock with international stock in the portfolio.  The position of each point on the X-Y grid shows the amount of risk vs. return of that portfolio during the specified time period.</p>
<p>Looking at the first time period (in green), the plot would suggest I own a larger chunk of international stock for my level of risk tolerance; however, the next time period (in red) shows that that would have hurt me.  Bernstein says that a lot of the change in the behavior of international stocks in the late 80s can be attributed to the rise and fall of the Japanese stock market, and emphasizes that if the past shows us anything, it&#8217;s that you can&#8217;t predict what will happen in the future, and thus, why not just split the difference?  Looking at the long-term picture, a 50-50 allocation of domestic and international equities probably wouldn&#8217;t hurt you, and considering that is also about the ratio of the US to international market caps, it fits with the philosophy of &#8220;owning the market as it is.&#8221;</p>
<p>As another aside, Bernstein&#8217;s book has similar charts, and I can&#8217;t tell you how satisfying it was to see how much my own findings matched his.</p>
<p>With a 50-50 equities allocation in mind, I can replace two asset classes with one, simplifying my table a bit:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
</tr>
<tr>
<th rowspan="2">High Risk</th>
<td><em>Global Equities (50-50 Dom./Intl.)</em></td>
</tr>
<tr>
<td>Real Estate</td>
</tr>
<tr>
<th rowspan="2">Low Risk</th>
<td>Bonds</td>
</tr>
<tr>
<td>TIAA Traditional</td>
</tr>
</table>
<p>My next task was to determine how much, if any, real estate in the form of TREA I should own.  This was a challenge for many reasons.  First, as mentioned before, TREA is a unique offering that is hard to compare to other asset classes.  Second, it was created in 1995, so it is hard to get an understanding of how it might behave long-term.  And third, while the account does <a href="http://www.tiaa-cref.org/public/pdf/performance/rea_composite_comparison.pdf">track a benchmark index</a>, the REA Composite Index, which could help me gain some insight into its long term behavior, it systemically underperforms it due to the way the account&#8217;s properties are appraised.  The result was a little guess work and hand waving, but that&#8217;s investing, I guess.</p>
<p>I downloaded the annual returns for TREA since its inception in &#8217;95, and the returns for the components of the REA Composite Index which go back to 1978.  (The iMoneyNet money market index component is proprietary, so I substituted it with returns from the Vanguard Prime Money Market Fund, which goes back to 1977, and tracks the same index.)  Then I plotted the performance of all the various allocations of TREA, the REA Composite Index, and my chosen allocation of equities, after subtracting all of the associated costs (such as the 1.01% expense charge for TREA).</p>
<p><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/12/re-eq.png" alt="" title="Real Estate and Equities Allocations for 1978-2010" width="640" height="480" class="aligncenter size-full wp-image-654" /></p>
<p>The first thing to note is how wildly different TREA (in green) is from its benchmark index (in red).  They&#8217;re highly correlated from 1996 on with a correlation coefficient of 0.98, so I don&#8217;t think I&#8217;m out of line to use a linear approximation between the two to extrapolate what TREA might have looked like from 1978 (in teal).  The second thing to note is how stable the REA Composite is.  Look at how close together the two REA Comp endpoints are compared to the equities endpoints.</p>
<p>Anyway, this chart, along with a couple of other calculations, was revealing.  Should I invest in TREA?  Well TREA and my choice of equities have demonstrated a very low correlation coefficient of 0.16 since its inception, so it should be a good candidate for diversification.  This is apparent in the graph above.  If you had invested in 40% TREA, 60% global equities in 1996, you would have realized the same amount of returns by 2010 as someone who invested 100% in global equities without as many, or as large of ups and downs.  The long-term model shows, however, that the benefits of real estate drop off very quickly.  In the end, all this can tell me is what <em>has</em> happened, and tells me nothing about the future, but it also says that real estate can be a good diversifier in the bear economy we&#8217;ve had the past decade, and if I expect there to be more bad economies in my future, then TREA should have a place in it.</p>
<p>The next question, how much TREA, is a little easier.  If I look at the past 15 years, I might be tempted to choose 40%, but I also expect (rather I hope) equities will return to historical levels of performance, so I should choose a much smaller allocation of real estate.  Looking at the long term graph, by 20% TREA I would have sacrificed about 1% return compared to a portfolio of all equities.  10% seems to be a good compromise between the portfolio stabilization effect of TREA and the loss of returns.   One of the most reassuring lines in Bernstein&#8217;s book is:</p>
<blockquote><p>
There is plenty of margin for error available in asset allocation policy.  If you are off 10% or 20% from what in retrospect turned out to be the best allocation, you have not lost that much&#8230;sticking by your asset allocation policy through thick and thin is much more important than picking the &#8220;best&#8221; allocation.
</p></blockquote>
<p>So what does it mean to stick with your AA through thick and thin?  Well first, I think it means having a rational basis for your choices in the first place, as I hope I&#8217;m establishing for my choices here.  That should reduce the temptation to make major changes down the line.  Second, I think it means that you should maintain your chosen allocations by rebalancing once a year.</p>
<p>Rebalancing is the process of moving money from assets that did well for the year to others that did not.  If stocks did really well, it would weight your portfolio more towards stocks than originally planned.  Rebalancing brings your portfolio back in line with your accepted level of risk and reinforces the idea of selling high and buying low.</p>
<p>That brings me to my comments about the TIAA Traditional Retirement Annuity, which I am eligible for under my 401(a) plan.  As I said it&#8217;s a unique opportunity that delivers a guaranteed 3% interest (based on TIAA&#8217;s stellar claims-paying ability) and has delivered additional earnings over the guaranteed minimum every year since 1948.  A lot of people really like this annuity, and for good reason.  It delivers performance similar to that of an intermediate bond fund with even lower risk, historically.  It also has a very low correlation with the performance of stocks, bonds, and real estate (a very rare thing), so it could make it an excellent diversifier, and one that I wanted in my portfolio.  Unfortunately, that performance comes at the cost of reduced liquidity.  Once your money&#8217;s in, for all intents and purposes, it&#8217;s in until you retire.  And even that wouldn&#8217;t bother me, except that you can&#8217;t even do what you want with the interest.  That means, you can&#8217;t rebalance its earnings into lower performing assets which makes it a non-starter as a diversifier.</p>
<p>The TIAA Traditional Group Supplemental Retirement Annuity, which I am eligible for under my 403(b) does not have the same liquidity restrictions, but it comes at a reduced interest rate.  If I were to include any Traditional under my 403(b) plan, it would make it harder to analyze and compare to my 401(a).  Also, because I can&#8217;t move money between the plans, the same limitations on rebalancing would apply.</p>
<p>Based on all of its complications, I decided not to include any TIAA Traditional in my portfolio.  My table is looking a whole lot simpler now:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
</tr>
<tr>
<th>High Risk</th>
<td><em>High Risk Pool (90-10 Equities/TREA)</em></td>
</tr>
<tr>
<th rowspan="2">Low Risk</th>
<td>Bonds</td>
</tr>
<tr>
<td><del>TIAA Traditional</del></td>
</tr>
</table>
<p>All that&#8217;s left is to figure out the ratio of my chosen high risk assets to bonds.  For the purposes of my analysis, I use &#8220;bonds&#8221; to mean the entire bond market as tracked by the <a href="http://www.bogleheads.org/wiki/Barclays_Capital_US_Aggregate_Bond_Index">Barclays Capital US Aggregate Bond Index</a> and available to me as the <a href="http://www.tiaa-cref.org/public/fyi/performance/premier/profiles/1538.html">TIAA-CREF Bond Index Fund</a>.  Just as I want to own the entire stock market as it is, I want to own the entire bond market as it is.</p>
<p>I downloaded the annual returns of the bond index back to 1976 and generated a graph similar to the ones above, showing different allocations of bonds and my chosen mix of high risk assets.</p>
<p><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/12/hr-bond.png" alt="" title="High Risk and Bond Fund Allocations for 1978-2010" width="640" height="480" class="aligncenter size-full wp-image-728" /></p>
<p>I did this over two time periods because, for one thing, the recent data (in green) more clearly shows the behavior of the allocation in our crappy market, and the long-term data (in blue) includes that TREA extrapolation I did earlier.  I just wanted to make sure I didn&#8217;t miss anything.</p>
<p>A lot of literature would suggest young investors go all in with high-risk equities, and that is the sentiment among a lot of posters at Something Awful.  Bernstein suggested the same thing in the first edition of his book, but changed it to a 20% bond allocation in the second edition.  The Bogleheads suggest having your age in percent of bonds (25% for me).  My findings confirm the recommendations of Bernstein and the Bogleheads.  Clearly, a person who invested more heavily in bonds the past 15 years was rewarded with the same returns and significantly lower risk than a person more in invested my chosen mix of high risk assets.  But I should really be looking at the long term picture, where a 20-30% allocation of bonds can reduce the portfolio&#8217;s risk without affecting returns by much.  Since I am more willing to take on risk, and I like nice round numbers, I will choose 20%.</p>
<p>Let&#8217;s take another look at my table:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th>Asset Class</th>
</tr>
<tr>
<td><em>My Asset Allocation (80-20 High Risk/Bonds)</em></td>
</tr>
</table>
<p>Wow!  It has been simplified down to one line.  I think that means I&#8217;m done!  Let&#8217;s blow it back up and see what we&#8217;ve got:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
<th>Allocation</th>
</tr>
<tr>
<th rowspan="3">High Risk</th>
<td>Domestic Equities</td>
<td>36%</td>
</tr>
<tr>
<td>International Equities</td>
<td>36%</td>
</tr>
<tr>
<td>Real Estate</td>
<td>8%</td>
</tr>
<tr>
<th>Low Risk</th>
<td>Bonds</td>
<td>20%</td>
</tr>
</table>
<p>TREA itself contains up to 25% low-risk liquid assets, so in my portfolio there is more like 20 + 0.25 * 8 = 22.5% lower-risk assets, but that&#8217;s a technicality.  I only mention it because it is exactly between Bernstein&#8217;s recommendation and the Boglehead&#8217;s recommendation of &#8220;your age in bonds,&#8221; and it was nice to arrive about the same figures independently.</p>
<p>Speaking of &#8220;your age in bonds,&#8221; that is something I will try to do every year when I rebalance.  I will increase my percentage of low-risk assets by 1% per year.  That way, by the time I retire, my allocation would theoretically look like:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
<th>Allocation</th>
</tr>
<tr>
<th rowspan="3">High Risk</th>
<td>Domestic Equities</td>
<td>18%</td>
</tr>
<tr>
<td>International Equities</td>
<td>18%</td>
</tr>
<tr>
<td>Real Estate</td>
<td>4%</td>
</tr>
<tr>
<th>Low Risk</th>
<td>Bonds</td>
<td>60%</td>
</tr>
</table>
<p>Remember, the ratio of high-risk to low-risk assets is how you control risk, not the allocation of assets within those categories.  If you think of that ratio as a volume knob, I would say I&#8217;m at an 8 right now, and I want to be around 3 or 4 when I retire.</p>
<p>One other thing I want to mention is that when I said the bond index represents the entire bond market, I lied.  There is a fairly new invention of the US Treasury called the Treasury Inflation-Protected Security (TIPS) which is not represented by the bond index.  It is a type of government bond which guarantees its principal will rise and fall with the consumer price index.  They are a great way to hedge against the risk of inflation, but as they&#8217;re so new, and a bit complicated, I&#8217;m having a hard time understanding the way they work and how they might behave in the long term.  For now I&#8217;ve excluded them from my portfolio (with my long time horizon and a large allocation of equities, I&#8217;m reasonably protected from inflation), but I hope to gain a better understanding of them soon to see where they might fit in.</p>
<p>Now that I&#8217;ve decided on an AA, let&#8217;s match them up to their low-cost index fund equivalents where possible:</p>
<table style="margin-left: auto; margin-right: auto" border="1">
<tr>
<th></th>
<th>Asset Class</th>
<th>Allocation</th>
<th>Fund</th>
<th>Symbol</th>
<th>ER</th>
</tr>
<tr>
<th rowspan="3">High Risk</th>
<td>Domestic Equities</td>
<td>36%</td>
<td><a href="http://www.tiaa-cref.org/public/fyi/performance/premier/profiles/1528.html">TIAA-CREF Equity Index Fund</a></td>
<td><a href="http://quote.morningstar.com/fund/f.aspx?t=TCEPX">TCEPX</a></td>
<td>0.24%</td>
</tr>
<tr>
<td>International Equities</td>
<td>36%</td>
<td><a href="http://www.tiaa-cref.org/public/fyi/performance/premier/profiles/1531.html">TIAA-CREF International Equity Index Fund</a></td>
<td><a href="http://quote.morningstar.com/fund/f.aspx?t=TRIPX">TRIPX</a>
<td>0.25%</td>
</tr>
<tr>
<td>Real Estate</td>
<td>8%</td>
<td><a href="http://www.tiaa-cref.org/public/fyi/performance/retirement/profiles/1009.html">TIAA Real Estate Account</a></td>
<td><a href="http://quote.morningstar.com/fund/f.aspx?t=US8780942004">None</a></td>
<td>1.01%</td>
</tr>
<tr>
<th>Low Risk</th>
<td>Bonds</td>
<td>20%</td>
<td><a href="http://www.tiaa-cref.org/public/fyi/performance/premier/profiles/1538.html">TIAA-CREF Bond Index Fund</a></td>
<td><a href="http://quote.morningstar.com/fund/f.aspx?t=TBIPX">TBIPX</a></td>
<td>0.28%</td>
</tr>
<tr>
<th colspan="5" style="text-align: right;">Weighted Expense Ratio (ER)</th>
<td>0.31%</td>
</tr>
</table>
<p>My portfolio will cost me 0.31% per year which is less than half of the 0.80% I was paying Fidelity.  To see just how much of a difference that makes, let&#8217;s assume I put in $10,000 per year for the next 40 years and average an annual return of 8% and that the costs of the funds stay the same.  <strong>At the end of 40 years, I would have $2,388,152 with TIAA-CREF and $2,102,199 with Fidelity.  That is a difference of $285,953!</strong>  Expense ratios matter a lot.</p>
<p>So what did I actually get out of all this complicated analysis?  Well, as I just demonstrated, my portfolio will have provably lower costs.  Beyond that, it put me in control of my future.  I now understand the behavior of different asset classes, the indices that represent them, and the funds that I am putting my hard-earned money into.  Because I know how they&#8217;ve performed in the past, I have an idea of what to expect in the future.  So when shit hits the fan again, I will be able to sleep soundly knowing that in the long-run it will work itself out, rather than endlessly fretting about whether I made sound investments.  Isn&#8217;t that worth a few days of your time?</p>
<h4>Stray Thoughts</h4>
<ul>
<li>Obviously, none of this matters one bit if you aren&#8217;t contributing enough to meet your retirement goals.  There are tons of calculators out there that will tell you how much to be saving based on how you want to live in retirement.  <a href="http://www.tiaa-cref.org/public/calcs/retire/index.html">TIAA-CREF has a good one.</a>  Thanks to my employer&#8217;s generous matching program, I am on track to meet my goal of retiring at 65.  I could be doing better, but I think I&#8217;m probably doing better than most other people my age.</li>
<li>Since this is a post about TIAA-CREF, I would be remiss not to mention how pleased I&#8217;ve been with their customer service so far as I&#8217;m transferring my meager sum from Fidelity.  They&#8217;ve assigned me an advisor who helped me fill out all of the necessary forms, and who will keep me up-to-date on the status of the transfer until it is complete and then get out of my hair.</li>
<li>The MATLAB code I wrote to generate the graphs is available from <a href="https://github.com/MrStaticVoid/portfolio">my GitHub account</a>.</li>
<li>This investing stuff is addictive.  Maybe I&#8217;ll look into taking some classes next fall.</li>
<li>And I have to say thanks to my girlfriend who barely saw me last week and dealt with me staying up until 2 or 3 AM every night researching this.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/12/05/setting-up-my-retirement-investments-with-tiaa-cref/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Solaris 11 Experience So Far</title>
		<link>http://thestaticvoid.com/post/2011/11/15/the-solaris-11-experience-so-far/</link>
		<comments>http://thestaticvoid.com/post/2011/11/15/the-solaris-11-experience-so-far/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 17:40:05 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[nwam]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[solaris]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=598</guid>
		<description><![CDATA[I have a system (a zone on which this blog is hosted) that has been running the same installation of Solaris since 11/11/2009, starting with OpenSolaris 2009.06. In the time since, it has seen every public build of OpenSolaris, then OpenIndiana, and finally Solaris 11 Express. Now, exactly two years later, I&#8217;ve updated it to [...]]]></description>
			<content:encoded><![CDATA[<p>I have a system (a zone on which this blog is hosted) that has been running the same installation of Solaris since 11/11/2009, starting with OpenSolaris 2009.06.  In the time since, it has seen every public build of OpenSolaris, then OpenIndiana, and finally Solaris 11 Express.  Now, exactly two years later, I&#8217;ve updated it to Solaris 11 11/11, and I&#8217;d like to share my experience so far.</p>
<p>The update itself did not go smoothly.  I was sitting at Solaris 11 Express SRU 8 and thought, like every update I&#8217;ve done in the past, that I could just run <tt>pkg image-update</tt>.  Silly me, because when I did and then rebooted, the kernel panicked.  No big deal, that&#8217;s what boot environments are for.  I reverted to the previous boot environment and found some <a href="http://download.oracle.com/docs/cd/E23824_01/html/E23811/glpgv.html#glpdr">helpful documentation</a> that told me to do exactly what I just did.  It turns out that there is no way to update to SRU 13 using the support repositories because they already contain the Solaris 11 11/11 packages, and <tt>pkg</tt> tries to pull some of them in.  And there is no way to update just <tt>pkg</tt> because the <tt>ips-consolidation</tt> prevents it, and trying to update the <tt>ips-consolidation</tt> pulls the <tt>entire</tt> package which breaks everything just the same.  In short, Oracle bungled it.  The only way to update to SRU 13 that I could see was to download the SRU 13 repository ISO from My Oracle Support and set up a local repository.  Once I was on SRU 13, I could continue with the update to the 11/11 release.  But there were more surprises in store for me.</p>
<p>First, it looks like <tt>pkg</tt> decided to start enforcing consistent attributes on files shared by multiple packages.  Fine, I can understand that.  As a result, I had to remove a lot of my custom packages (mostly from spec-files-extra) which I&#8217;ll have to rebuild.  Second, <tt>pkg</tt> decided it doesn&#8217;t like the opensolaris.org packages anymore so I had to uninstall OpenOffice.org.  Also fair enough.</p>
<p>Happily, after that, the updates got applied successfully and the system rebooted into the 11/11 release.  Next came the zone updates.  When I did the normal <tt>zoneadm -z foo detach &#038;&#038; zoneadm -z foo attach -u</tt> deal, I was told I had to convert my zones to a new ZFS structure which more closely matches the global zone.  The script <tt>/usr/lib/brand/shared/dsconvert</tt> actually worked flawlessly and the updated zones came up fine.</p>
<p>Unfortunately I couldn&#8217;t SSH into my zones because my DNS server didn&#8217;t know where they were.  It seems that with the updated networking framework, DHCP doesn&#8217;t request a hostname anymore.  (<tt>/etc/default/dhcpagent</tt> still says <tt>inet &lt;hostname&gt;</tt> can be put in <tt>/etc/hostname.&lt;if&gt;</tt> to request the hostname.)  I found that you can create an <tt>addr</tt> object that requests a hostname with <tt>ipadm create-addr -T dhcp -h &lt;hostname&gt; &lt;addrobj&gt;</tt>, but NWAM pretty much won&#8217;t let you create or modify anything with <tt>ipadm</tt>, and there were no options for requesting hostnames with <tt>nwamcfg</tt>.  As a result, I had to disable NWAM (<tt>netadm enable -p ncp DefaultFixed</tt>) and then I could set up the interface with <tt>ipadm</tt>.  Why doesn&#8217;t Solaris request hostnames by default?  Not very &#8220;cloud-like&#8221; if you ask me.</p>
<p>I have to say, I&#8217;m impressed by the way global zones and non-global zones are linked in the new release.  Zone updates were an obvious shortcoming of previous releases.  We&#8217;ll see how well it works when Solaris 11 Update 1 comes out.</p>
<p>What else&#8230;I lost my ability to <tt>pfexec</tt> to root.  Oracle removed the &#8220;Primary Administrator&#8221; profile for security reasons so I had to install sudo.  Not a big deal, I just wish they had said something a little louder about it.</p>
<p>Also, whatever update to <tt>pkg</tt> happened, it wiped out my repositories under <tt>/var/pkg</tt>.  I had to restore them from a snapshot.  Bad Oracle!</p>
<p>I&#8217;m also a little confused about some of the changes to the way networking settings are stored.  For example, when I first booted the global zone, I found that my NFSv4 domain name was reset by NWAM.  I set it to what it should be with <tt>sharectl set -p nfsmapid_domain=thestaticvoid.com nfs</tt>, but is that going to be overwritten again by NWAM?  Also, the name resolver settings are now stored in the <tt>svc:/network/dns/client:default</tt> service, and according to the documentation, DHCP will set the service properties properly, but I have yet to see this work.</p>
<p>And the last problem I&#8217;ll mention is that the update removed my virtual consoles.  I had to install the <tt>virtual-console</tt> package to restore them.</p>
<p>Overall, I&#8217;m happy that I was at least able to update to the latest release.  Oracle could have cut off any update path from OpenSolaris.  However, the update should have been a lot smoother.  It doesn&#8217;t speak well of future updates when I can&#8217;t even update from one supported release (SRU 8<span></span>) to another.  I also wish Oracle were more open about upcoming changes (as in, having more preview releases or, dare I say it, opening development the way OpenSolaris was).  Even to me, a long time pre-Solaris 11 user, the changes to zones and networking are huge in this release, and I would rather have not been so surprised by them.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/11/15/the-solaris-11-experience-so-far/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Wireless 802.1X Support in Solaris</title>
		<link>http://thestaticvoid.com/post/2011/06/09/wireless-802-1x-support-in-solaris/</link>
		<comments>http://thestaticvoid.com/post/2011/06/09/wireless-802-1x-support-in-solaris/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 01:53:29 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[wireless]]></category>
		<category><![CDATA[wpa]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=557</guid>
		<description><![CDATA[The George Washington University (where I work and go to school) has recently implemented 802.1X to secure its wireless networks. 802.1X defines support for EAP over Ethernet (including wireless) and the WPA standards define several modes of EAP that can be used. Solaris (I&#8217;m referring to version 11, OpenSolaris, OpenIndiana, and Illumos) supports WPA. It [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/06/wifi.jpg" alt="" title="WiFi" width="300" height="200" class="alignright size-full wp-image-583" /></p>
<p>The George Washington University (where I work and go to school) has recently implemented <a href="http://en.wikipedia.org/wiki/IEEE_802.1X">802.1X</a> to secure its wireless networks.   802.1X defines support for <a href="http://en.wikipedia.org/wiki/Extensible_Authentication_Protocol">EAP</a> over Ethernet (including wireless) and the <a href="http://en.wikipedia.org/wiki/Wi-Fi_Protected_Access">WPA</a> standards define several modes of EAP that can be used.</p>
<p>Solaris (I&#8217;m referring to version 11, OpenSolaris, OpenIndiana, and Illumos) supports WPA.  It modified an early version of <a href="http://hostap.epitest.fi/wpa_supplicant/">wpa_supplicant</a> and called it &#8220;<a href='http://src.illumos.org/source/xref/illumos-gate/usr/src/cmd/cmd-inet/usr.lib/wpad/'>wpad</a>&#8220;.  However, they seemed to make a point of stripping out all EAP support in wpad.</p>
<p>So when my Network Security instructor said we had to do a term project of our choosing relating to network security, I decided I&#8217;d try to get 802.1X working in Solaris.  To do this, I decided I could either add the EAP bits back into wpad, or add the Solaris-specific bits to the latest version of wpa_supplicant.  wpad is based on very old code.  It&#8217;s not even clear which version of wpa_supplicant it is based on, and there is no record of the massive amount of changes they made.  It would be too hard for me to figure out where to plug EAP back in, and who knows how many bugs and security vulnerabilities were fixed upstream that we&#8217;d be missing out on.</p>
<p>Fortunately, wpa_supplicant is very modular, and reasonably <a href="http://hostap.epitest.fi/wpa_supplicant/devel/porting.html">well documented</a>.  I was able to graft the older Solaris code onto the newer interfaces.  The result of my work is currently maintained in my own <a href="https://github.com/MrStaticVoid/hostap/compare/master...solaris">branch</a> at GitHub.  It&#8217;s not perfect, but it works (and I&#8217;ll explain how).  Solaris has a very limited public API for wireless support and my goal was to get wpa_supplicant working without having to modify any system libraries or the kernel.  I struggled to figure out some idiosyncrasies such as:</p>
<ul>
<li>Events (association, disassociation, etc.) are only sent to wpa_supplicant when WPA is <strong>enabled</strong> in the driver.</li>
<li>Full scan results are only available when WPA is <strong>disabled</strong> in the driver.</li>
<li>Scan results don&#8217;t provide nearly as much information as their Linux counterparts do, such as access point capabilities, signal strength, noise levels, etc.  I was very worried I wouldn&#8217;t be able to fill out the <a href="http://hostap.epitest.fi/wpa_supplicant/devel/structwpa__scan__res.html">scan results structure</a> fully and wpa_supplicant would refuse to work without complete information.</li>
</ul>
<p>Here is how you can get 802.1X support working on your Solaris laptop:</p>
<ol>
<li>Install the wpa_supplicant package from my package repository:
<pre class="terminal">
# <kbd>pkg set-publisher -p http://pkg.thestaticvoid.com/</kbd>
# <kbd>pkg install wpa_supplicant</kbd>
</pre>
</li>
<li>
<p>Add the configuration for your protected wireless networks to <tt>/etc/wpa_supplicant.conf</tt>.  Here is mine:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ctrl_interface=/var/run/wpa_supplicant<br />
ctrl_interface_group=0<br />
ap_scan=0<br />
<br />
network={<br />
&nbsp; &nbsp; ssid=&quot;prey&quot;<br />
&nbsp; &nbsp; key_mgmt=WPA-PSK<br />
&nbsp; &nbsp; psk=&quot;&lt;network key&gt;&quot;<br />
}<br />
<br />
network={<br />
&nbsp; &nbsp; ssid=&quot;GW1X&quot;<br />
&nbsp; &nbsp; key_mgmt=WPA-EAP<br />
&nbsp; &nbsp; eap=TTLS<br />
&nbsp; &nbsp; identity=&quot;jameslee&quot;<br />
&nbsp; &nbsp; anonymous_identity=&quot;anonymous&quot;<br />
&nbsp; &nbsp; password=&quot;&lt;personal password&gt;&quot;<br />
&nbsp; &nbsp; phase2=&quot;auth=PAP&quot;<br />
}</div></div>
<p>The most important thing here is <code class="codecolorer text default"><span class="text">ap_scan=0</span></code>.  This tells wpa_supplicant not to do any scanning or association of its own.  Those tasks will be handled by dladm and NWAM.
</li>
<li>
Backup <tt>/usr/lib/inet/wpad</tt> and replace it with this script:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/bin/sh</span><br />
<br />
<span style="color: #007800;">interface</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #000000; font-weight: bold;">@</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/.*-i *\([a-z0-9]*\).*/\1/'</span><span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>wpa_supplicant <span style="color: #660033;">-Dsolaris</span> -i<span style="color: #007800;">$interface</span> -c<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>wpa_supplicant.conf <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">&amp;</span></div></div>
</li>
</ol>
<p>Now connect to a wireless network with NWAM or dladm.  When prompted for a network key, enter anything; it won&#8217;t be used.  The actual keys will be looked up in <tt>/etc/wpa_supplicant.conf</tt>.  Here is an example of me connecting to my 802.1X-secured network using dladm:</p>
<pre class="terminal">
# <kbd>dladm connect-wifi -e GW1X -s wpa -k nwam-GW1X iwh0</kbd>
# <kbd>dladm show-wifi</kbd>
LINK       STATUS            ESSID               SEC    STRENGTH   MODE   SPEED
iwh0       connected         GW1X                wpa    excellent  g      54Mb
</pre>
<p>&#8220;<tt>-k nwam-GW1X</tt>&#8221; refers to a dummy key setup by NWAM.  dladm will complain if it&#8217;s not supplied a key.</p>
<p>That should be it!</p>
<h4>Future Directions</h4>
<p>Obviously, the integration of wpa_supplicant and NWAM/dladm leaves a lot to be desired.  If there is sufficient interest, I will start looking into how to modify the dladm security framework in Illumos to include EAP related configurations (keys, certificates, identities; it&#8217;s all much more complicated than the single pre-shared key that dladm supports now).  My hope, though, is that Oracle is already working on this.  <em>Do you hear that Oracle?</em></p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/06/09/wireless-802-1x-support-in-solaris/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Automounting NFSv4 over SSH</title>
		<link>http://thestaticvoid.com/post/2011/05/31/automounting-nfsv4-over-ssh/</link>
		<comments>http://thestaticvoid.com/post/2011/05/31/automounting-nfsv4-over-ssh/#comments</comments>
		<pubDate>Tue, 31 May 2011 17:17:09 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[autofs]]></category>
		<category><![CDATA[autossh]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=517</guid>
		<description><![CDATA[For the past couple of years, I&#8217;ve used SSHFS to access my fileserver remotely (mostly from work). It&#8217;s always been pretty slow and it isn&#8217;t very stable on Solaris, so I&#8217;ve switched to NFSv4 over SSH. My biggest hangup of using NFS was how to secure it over the internet. Its Kerberos support is completely [...]]]></description>
			<content:encoded><![CDATA[<p>For the past couple of years, I&#8217;ve used <a href="http://en.wikipedia.org/wiki/SSHFS">SSHFS</a> to access my fileserver remotely (mostly from work).  It&#8217;s always been pretty slow and it isn&#8217;t very stable on Solaris, so I&#8217;ve switched to NFSv4 over SSH.  My biggest hangup of using NFS was how to secure it over the internet.  Its Kerberos support is completely overkill for my needs and I never really wanted to deal with the complications of scripting the set up of an SSH tunnel, either.  It all seemed so fragile.</p>
<p>Then I discovered <a href="http://www.harding.motd.ca/autossh/">autossh</a> which does all the work of setting up and maintaining the tunnel for me.  I coupled that with an executable autofs map to automatically start the tunnel just before trying to mount a share, like:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/bin/bash</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">AUTOSSH_PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>falcon-tunnel.pid<br />
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">AUTOSSH_GATETIME</span>=<span style="color: #000000;">0</span><br />
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">AUTOSSH_DEBUG</span>=<span style="color: #000000;">1</span> <br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #007800;">$AUTOSSH_PIDFILE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
&nbsp; &nbsp; <span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #660033;">-HUP</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$AUTOSSH_PIDFILE</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; autossh <span style="color: #660033;">-f</span> <span style="color: #660033;">-M</span> <span style="color: #000000;">0</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">ServerAliveInterval</span>=<span style="color: #000000;">5</span> <span style="color: #660033;">-NL</span> <span style="color: #000000;">2050</span>:localhost:<span style="color: #000000;">2049</span> jlee<span style="color: #000000; font-weight: bold;">@</span>falcon<br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;-fstype=nfs4,port=2050 localhost:/nest/$1&quot;</span></div></div>
<p>Using an executable autofs map allows me to avoid reconciling the differences between service managers like SMF and Upstart, offering a consistent way to start the tunnel exactly when it&#8217;s needed on both Solaris and Linux.  When you &#8216;cd&#8217; into a directory managed by autofs, autossh is started or woken up, then the share is mounted over the tunnel.  If there is a network interruption or change (from wired to wireless, for example), ssh will disconnect after 15 seconds of inactivity and autossh will restart it.  NFS is smart enough to resume its operation when the tunnel is reestablished.</p>
<p>autossh has built-in support for heartbeat monitoring, but I&#8217;ve found SSH&#8217;s built-in <tt>ServerAliveInterval</tt> feature to be more reliable.</p>
<p>With this setup I have very simple, robust, and secure remote access to my fileserver.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/05/31/automounting-nfsv4-over-ssh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Nitrogen as a Library Under Yaws</title>
		<link>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/</link>
		<comments>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 20:58:23 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[nitrogen]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[yaws]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=477</guid>
		<description><![CDATA[Motivation I&#8217;ve been working on a project off and on for the past year which uses the Spring Framework extensively. I love Spring for how easy it makes web development, from wiring up various persistence and validation libraries, to dependency injection, and brainless security and model-view-controller functionality. However, as the project has grown, I&#8217;ve become [...]]]></description>
			<content:encoded><![CDATA[<h4>Motivation</h4>
<p>I&#8217;ve been working on a project off and on for the past year which uses the <a href="http://www.springsource.org/">Spring Framework</a> extensively.  I love Spring for how easy it makes web development, from wiring up various persistence and validation libraries, to dependency injection, and brainless security and model-view-controller functionality.  However, as the project has grown, I&#8217;ve become more and more frustrated with one aspect of Spring and Java web development in general: performance and resource usage.  It&#8217;s so bad, I&#8217;ve pretty much stopped working on it altogether.  Between Eclipse and Tomcat, you&#8217;ve already spent over 2 GB of memory, and every time you make a source code change, Tomcat has to reload the application which takes up to 30 seconds on my system, if it doesn&#8217;t crash first.  This doesn&#8217;t suit my development style of making and testing lots of small, incremental changes.</p>
<p>So rather than buy a whole new computer, I&#8217;ve started to look for a new lightweight web framework to convert the project to.  I really like Erlang and have wanted to write something big in it for a while, so when I found the <a href="http://nitrogenproject.com/">Nitrogen Web Framework</a>, I thought this might be my opportunity to do so.  Erlang is designed for performance and fault-tolerance and has a great standard library in <a href="http://www.erlang.org/doc/">OTP</a>, including a distributed database, <a href="http://www.erlang.org/doc/man/mnesia.html">mnesia</a>, which should eliminate my need for an object-relational mapper (it stores Erlang terms directly) and enable me to make my application highly available in the future without much fuss.  Nitrogen has the added benefit of simplifying some of the fancy things I wanted to do with AJAX but found too difficult with Spring MVC.</p>
<p>The thing I don&#8217;t like about Nitrogen is that it is designed to deliver a complete, stand-alone application with a built-in web server of your choosing and a copy of the entire Erlang runtime.  This seems to be The Erlang/OTP Way of doing things, but it seems very foreign to me.  I already have Erlang installed system-wide and a web server, Yaws, that I have a lot of <a href="http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/">time invested in</a>.  I&#8217;d rather use Nitrogen as a library in my application under Yaws just like I was using Spring as a library in my application under Tomcat.</p>
<h4>Procedures</h4>
<p>I start my new project with <a href="https://bitbucket.org/basho/rebar/wiki/Home">Rebar</a>:</p>
<pre class="terminal">
$ <kbd>mkdir test &#038;&#038; cd test</kbd>
$ <kbd>wget https://bitbucket.org/basho/rebar/downloads/rebar &#038;&#038; chmod +x rebar</kbd>
$ <kbd>./rebar create-app appid=test</kbd>
==> test (create-app)
Writing src/test.app.src
Writing src/test_app.erl
Writing src/test_sup.erl
$ <kbd>mkdir static include templates</kbd>  <span class="comment"># These directories will be used later</span>
</pre>
<p>Now I define my project&#8217;s dependencies in <tt>rebar.config</tt> in the same directory:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #109ab8;">&#123;</span>deps<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>nitrogen_core<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;2.1.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/nitrogen_core.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>nprocreg<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;0.2.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/nprocreg.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>simple_bridge<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;1.2.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/simple_bridge.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>sync<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;0.1.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/rklophaus/sync.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><br />
<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></div></div>
<p>These dependencies are taken from Nitrogen&#8217;s <a href="https://github.com/nitrogen/nitrogen/blob/master/rebar.config">rebar.config</a>.  Next I write a Makefile to simplify common tasks:</p>
<div class="codecolorer-container make default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="make codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">default<span style="color: #004400;">:</span> compile static<span style="color: #004400;">/</span>nitrogen<br />
<br />
get<span style="color: #004400;">-</span>deps<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar get<span style="color: #004400;">-</span>deps<br />
<br />
<span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; echo <span style="color: #CC2200;">'-define(BASEDIR, &quot;$(PWD)&quot;).'</span> <span style="color: #004400;">&gt;</span> <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<br />
<br />
static<span style="color: #004400;">/</span>nitrogen<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ln <span style="color: #004400;">-</span>sf <span style="color: #004400;">../</span>deps<span style="color: #004400;">/</span>nitrogen_core<span style="color: #004400;">/</span>www static<span style="color: #004400;">/</span>nitrogen<br />
<br />
compile<span style="color: #004400;">:</span> <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl get<span style="color: #004400;">-</span>deps<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar compile<br />
<br />
clean<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">-</span>rm <span style="color: #004400;">-</span>f static<span style="color: #004400;">/</span>nitrogen <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar delete<span style="color: #004400;">-</span>deps<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar clean<br />
<br />
distclean<span style="color: #004400;">:</span> clean<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">-</span>rm <span style="color: #004400;">-</span>rf deps ebin</div></div>
<p>I expect I&#8217;ll be tweaking this Makefile some more in the future, but it demonstrates the absolute minimum to compile the application.  When I run <tt>make</tt>, four things happen the first time:</p>
<ol>
<li><tt>BASEDIR</tt> is defined as the current directory in <tt>include/basedir.hrl</tt>.  We&#8217;ll use this later.</li>
<li>All of the Nitrogen dependencies are pulled from Git to the <tt>deps</tt> directory.</li>
<li>All of the code is compiled.</li>
<li>The static content from Nitrogen (mostly Javascript files) is symlinked into our <tt>static</tt> content directory.</li>
</ol>
<p>Next I prepare the code for running under Yaws.  First I create the Nitrogen appmod in <tt>src/test_yaws.erl</tt>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>test_yaws<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #ff3c00;">export</span> <span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>out<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">out</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #45b3e6;">RequestBridge</span> <span style="color: #014ea4;">=</span> simple_bridge:<span style="color: #ff3c00;">make_request</span><span style="color: #109ab8;">&#40;</span>yaws_request_bridge<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #45b3e6;">ResponseBridge</span> <span style="color: #014ea4;">=</span> simple_bridge:<span style="color: #ff3c00;">make_response</span><span style="color: #109ab8;">&#40;</span>yaws_response_bridge<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; nitrogen:<span style="color: #ff3c00;">init_request</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">RequestBridge</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">ResponseBridge</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; nitrogen:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>This is taken from <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/yaws/site/src/test_yaws.erl">Nitrogen repository</a>.  I also modify the <code class="codecolorer erlang default"><span class="erlang">init<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span></span></code> function in <tt>src/test_sup.erl</tt> to start the <tt>nprocreg</tt> application, similar to how it is done in <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/yaws/site/src/nitrogen_sup.erl">Nitrogen proper</a>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff4e18;">application</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span>nprocreg<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span> <span style="color: #109ab8;">&#123;</span>one_for_one<span style="color: #6bb810;">,</span> <span style="color: #ff9600;">5</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">10</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></div></div>
<p>Lastly, I add a function to <tt>src/test_app.erl</tt> which can be used by Yaws to start the application:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff4e18;">application</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span>test<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>One other thing that I do before loading the application up in Yaws is create a sample page, <tt>src/index.erl</tt>.  This is downloaded from <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/common/site/src/index.erl">Nitrogen</a>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #ff3c00;">module</span> <span style="color: #109ab8;">&#40;</span>index<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">compile</span><span style="color: #109ab8;">&#40;</span>export_all<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;nitrogen_core/include/wf.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;basedir.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">main</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> #template <span style="color: #109ab8;">&#123;</span> file<span style="color: #014ea4;">=</span>?<span style="color: #6941fd;">BASEDIR</span> <span style="color: #014ea4;">++</span> <span style="color: #ff7800;">&quot;/templates/bare.html&quot;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">title</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff7800;">&quot;Welcome to Nitrogen&quot;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; #container_12 <span style="color: #109ab8;">&#123;</span> body<span style="color: #014ea4;">=</span><span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #grid_8 <span style="color: #109ab8;">&#123;</span> alpha<span style="color: #014ea4;">=</span>true<span style="color: #6bb810;">,</span> prefix<span style="color: #014ea4;">=</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> suffix<span style="color: #014ea4;">=</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> omega<span style="color: #014ea4;">=</span>true<span style="color: #6bb810;">,</span> body<span style="color: #014ea4;">=</span><span style="color: #ff3c00;">inner_body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">inner_body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #h1 <span style="color: #109ab8;">&#123;</span> text<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;Welcome to Nitrogen&quot;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7800;">&quot;<br />
If you can see this page, then your Nitrogen server is up and<br />
running. Click the button below to test postbacks.<br />
&quot;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #button <span style="color: #109ab8;">&#123;</span> id<span style="color: #014ea4;">=</span>button<span style="color: #6bb810;">,</span> text<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;Click me!&quot;</span><span style="color: #6bb810;">,</span> postback<span style="color: #014ea4;">=</span>click <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7800;">&quot;<br />
Run &lt;b&gt;./bin/dev help&lt;/b&gt; to see some useful developer commands.<br />
&quot;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">event</span><span style="color: #109ab8;">&#40;</span>click<span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #006600;">wf</span>:<span style="color: #ff3c00;">replace</span><span style="color: #109ab8;">&#40;</span>button<span style="color: #6bb810;">,</span> #panel <span style="color: #109ab8;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;You clicked the button!&quot;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; actions<span style="color: #014ea4;">=</span>#effect <span style="color: #109ab8;">&#123;</span> effect<span style="color: #014ea4;">=</span>highlight <span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>I make sure to include <tt>basedir.hrl</tt> (generated by the Makefile, remember?) and modify the template path to start with <code class="codecolorer erlang default"><span class="erlang">?<span style="color: #6941fd;">BASEDIR</span></span></code>.  Since where Yaws is running is out of our control, we must reference files by absolute pathnames.  Speaking of templates, I downloaded mine from the <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/common/site/templates/bare.html">Nitrogen repository</a>.  Obviously, it can be modified however you want or you could create one from scratch.</p>
<p>Before we continue, I recompile everything by typing <tt>make</tt>.</p>
<p>Now the fun begins: wiring it all up in Yaws.  I use <a href="http://pkg.thestaticvoid.com/en/search.shtml?token=yaws&#038;action=Search">my package</a> for OpenSolaris which puts the configuration file in <tt>/etc/yaws/yaws.conf</tt>.  I add the following to it:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ebin_dir = /docs/test/deps/nitrogen_core/ebin<br />
ebin_dir = /docs/test/deps/nprocreg/ebin<br />
ebin_dir = /docs/test/deps/simple_bridge/ebin<br />
ebin_dir = /docs/test/deps/sync/ebin<br />
ebin_dir = /docs/test/ebin<br />
<br />
runmod = test_app<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> test.thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; docroot = /docs/test/static<br />
&nbsp; &nbsp; appmods = <span style="color: #009900;">&lt;/, test_yaws<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Obviously, your paths will probably be different.  The point is to tell Yaws where all of the compiled code is, tell it to start your application (where the business logic will be contained), and tell it to use the Nitrogen appmod.  Restart Yaws and it should all be working!</p>
<p>Now for some cool stuff.  If you run the <tt>svc:/network/http:yaws</tt> service from my package, or you start Yaws like <tt>yaws --run_erl svc</tt>, you can run <tt>yaws --to_erl svc</tt> (easiest to do with root privileges) and get access to Yaws&#8217;s Erlang console.  From here you can hot-reload code.  For example, modify the title in <tt>index.erl</tt> and recompile by running <tt>make</tt>.  In the Erlang console, you can run <code class="codecolorer erlang default"><span class="erlang"><span style="color: #ff3c00;">l</span><span style="color: #109ab8;">&#40;</span>index<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></span></code> and it will pick up your changes.  But there is something even cooler.  From the Erlang console, type <code class="codecolorer erlang default"><span class="erlang">syn<span style="color: #ff4e18;">c</span>:<span style="color: #ff3c00;">go</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></span></code> and now whenever you make a change to a loaded module&#8217;s source code, it will automatically be recompiled and loaded, almost instantly!  It looks something like:</p>
<pre class="terminal">
# <kbd>yaws --to_erl svc</kbd>
Attaching to /var//run/yaws/pipe/svc/erlang.pipe.1 (^D to exit)

1> <kbd>sync:go().</kbd>
Starting Sync (Automatic Code Reloader)
ok
2>
=INFO REPORT==== 17-Feb-2011::15:03:10 ===
/docs/test/src/index.erl:0: Recompiled. (Reason: Source modified.)

=INFO REPORT==== 17-Feb-2011::15:04:20 ===
/docs/test/src/index.erl:11: Error: syntax error before: body

=INFO REPORT==== 17-Feb-2011::15:04:26 ===
/docs/test/src/index.erl:0: Fixed!

2> <kbd>sync:stop().</kbd>

=INFO REPORT==== 17-Feb-2011::15:07:17 ===
    application: sync
    exited: stopped
    type: temporary
ok
</pre>
<p>One gotcha that may or may not apply to you, is that Yaws should have permission to write to your application&#8217;s <tt>ebin</tt> directory if you want to save the automatically compiled code.  In my case, Yaws runs as a different user than I develop as, a practice that I would highly recommend.  So I use a ZFS ACL to allow the web server user read and write access:</p>
<pre class="terminal">
$ <kbd>/usr/bin/chmod -R A+user:webservd:rw:f:allow /docs/test/ebin</kbd>
$ <kbd>/usr/bin/ls -dv /docs/test/ebin</kbd>
drwxr-xr-x+  2 jlee     staff          8 Feb 17 15:04 /docs/test/ebin
     0:user:webservd:read_data/write_data:file_inherit:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow
</pre>
<p>ACLs are pretty scary to some people, but I love &#8216;em <img src='http://thestaticvoid.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Other Thoughts</h4>
<p>You would not be able to run multiple Nitrogen projects on separate virtual hosts using this scheme.  Nitrogen maps request paths to module names (for example, requesting &#8220;/admin/login&#8221; would load a module <tt>admin_login</tt>) and module names must be unique in Erlang.  I think it would be possible to work around this using a Yaws <a href="http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/#trac-rewrite">rewrite module</a>, though I haven&#8217;t tested it.  I imagine if one virtual host maps &#8220;/admin/login&#8221; to &#8220;/foo/admin/login&#8221; and another maps it to &#8220;/bar/admin/login&#8221;, then Nitrogen would search for <tt>foo_admin_login</tt> and <tt>bar_admin_login</tt>, respectively, eliminating the conflicting namespace problem.</p>
<p>Now that I&#8217;ve gone through all the trouble of setting up Nitrogen the way I like, I should start converting my application over.  Hopefully I&#8217;ll like it.  It would be a shame to have done all this work for naught.  I&#8217;m sure there will be posts to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Persistent Search Domains With NWAM and DHCP</title>
		<link>http://thestaticvoid.com/post/2011/01/11/persistent-search-domains-with-nwam-and-dhcp/</link>
		<comments>http://thestaticvoid.com/post/2011/01/11/persistent-search-domains-with-nwam-and-dhcp/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 23:34:04 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[nwam]]></category>
		<category><![CDATA[smf]]></category>
		<category><![CDATA[solaris]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=432</guid>
		<description><![CDATA[What I Want I want to be able to refer to systems on both my home and work networks by their hostnames rather than their fully-qualified domain names, so, &#8216;prey&#8217; instead of &#8216;prey.thestaticvoid.com&#8217; and &#8216;acad2&#8242; instead of &#8216;acad2.es.gwu.edu&#8217;. The Problem I would typically set my home and work domains as the search setting in /etc/resolv.conf. [...]]]></description>
			<content:encoded><![CDATA[<h4>What I Want</h4>
<p>I want to be able to refer to systems on <strong>both</strong> my home and work networks by their hostnames rather than their fully-qualified domain names, so, &#8216;prey&#8217; instead of &#8216;prey.thestaticvoid.com&#8217; and &#8216;acad2&#8242; instead of &#8216;acad2.es.gwu.edu&#8217;.</p>
<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/01/nwam.png"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2011/01/nwam-270x300.png" alt="" title="NWAM Settings" width="270" height="300" class="alignright size-medium wp-image-440" /></a></p>
<h4>The Problem</h4>
<p>I would typically set my home and work domains as the <tt>search</tt> setting in <tt>/etc/resolv.conf</tt>.  Unfortunately, either NWAM or the Solaris DHCP client (I haven&#8217;t decided which) overwrites <tt>resolv.conf</tt> on every new connection.  DHCP on Linux does the same thing, but I can configure it by editing <tt>dhclient.conf</tt> (or whatever is being used these days, it&#8217;s been a while.  I think I just set my domains in the NetworkManager GUI and forget about it).</p>
<p>The Solaris DHCP client <a href="http://docs.sun.com/app/docs/doc/821-1462/dhcpagent-1m?l=en&#038;a=view">configuration</a> is not nearly as flexible, and neither is NWAM which gives you the option of replacing <tt>resolv.conf</tt> with information supplied by the DHCP server, or provided by you, but not a mix of both.  I do like having the nameservers set by the DHCP server, so supplying a manual configuration is not an option.</p>
<h4>What I Tried</h4>
<p>The first thing I tried was setting the <tt>LOCALDOMAIN</tt> environmental variable in <tt>/etc/profile</tt>.  From the <tt>resolv.conf</tt> <a href="http://docs.sun.com/app/docs/doc/819-2251/resolv.conf-4?l=all&#038;a=view">man page</a>:</p>
<blockquote><p>
<tt>You  can  override  the  search  keyword   of   the   system<br />
resolv.conf  file  on  a  per-process  basis  by setting the<br />
environment variable LOCALDOMAIN to a  space-separated  list<br />
of search domains.</tt>
</p></blockquote>
<p>I thought, great, a way to manage domain search settings without worrying about what&#8217;s doing what to <tt>resolv.conf</tt>.  It didn&#8217;t work as advertised:</p>
<pre class="terminal">
% <kbd>LOCALDOMAIN=thestaticvoid.com ping prey</kbd>
ping: unknown host prey
% <kbd>s touch /etc/resolv.conf</kbd>
% <kbd>LOCALDOMAIN=thestaticvoid.com ping prey</kbd>
prey is alive
% <kbd>LOCALDOMAIN=thestaticvoid.com ping prey</kbd>
ping: unknown host prey
</pre>
<p>Next, I considered adding an NWAM <a href="http://docs.sun.com/app/docs/doc/821-1458/giwwe?a=view">Network Modifier</a> to set my search string in <tt>resolv.conf</tt> after a new connection is established.  This worked reasonably well, but didn&#8217;t handle the case when you switch from one network to another, for example, from wireless to wired.  The only events in NWAM that can trigger a script when the network connection changes happens before DHCP messes up <tt>resolv.conf</tt>.</p>
<p>Finally, in the course of my testing, I discovered that the <tt>svc:/network/dns/client</tt> service was restarting with every network connection change.  I looked into its manifest and saw that it was designed to wait for changes to <tt>resolv.conf</tt>:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">&lt;!--</span><br />
<span style="color: #808080; font-style: italic;"> &nbsp;Wait for potential DHCP modification of resolv.conf.</span><br />
<span style="color: #808080; font-style: italic;">--&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">name</span>=<span style="color: #ff0000;">'net'</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">grouping</span>=<span style="color: #ff0000;">'require_all'</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">restart_on</span>=<span style="color: #ff0000;">'none'</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">type</span>=<span style="color: #ff0000;">'service'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service_fmri</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">'svc:/network/service'</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>So I could write another service which depends on <tt>dns/client</tt> and restarts whenever <tt>dns/client</tt> does and I would have the last word about what goes into my configuration file!</p>
<h4>My Solution</h4>
<p>I wrote a service, <tt>svc:/network/dns/resolv-conf</tt>, with the following manifest:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #00bbdd;">&lt;!DOCTYPE service_bundle SYSTEM &quot;/usr/share/lib/xml/dtd/service_bundle.dtd.1&quot;&gt;</span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service_bundle</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;manifest&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;dns-resolv-conf&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;network/dns/resolv-conf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;service&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;create_default_instance</span> <span style="color: #000066;">enabled</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;single_instance</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;dns-client&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">grouping</span>=<span style="color: #ff0000;">&quot;require_all&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">restart_on</span>=<span style="color: #ff0000;">&quot;restart&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;service&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service_fmri</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;svc:/network/dns/client&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependent</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;resolv-conf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">grouping</span>=<span style="color: #ff0000;">&quot;optional_all&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">restart_on</span>=<span style="color: #ff0000;">&quot;restart&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service_fmri</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;svc:/milestone/name-services&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec_method</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;method&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;start&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">exec</span>=<span style="color: #ff0000;">&quot;/lib/svc/method/dns-resolv-conf start&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">timeout_seconds</span>=<span style="color: #ff0000;">&quot;60&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec_method</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;method&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;stop&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">exec</span>=<span style="color: #ff0000;">&quot;/lib/svc/method/dns-resolv-conf stop&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">timeout_seconds</span>=<span style="color: #ff0000;">&quot;60&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property_group</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;options&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;application&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;propval</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;search&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;astring&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property_group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property_group</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;startd&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;framework&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;propval</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;duration&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;astring&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;transient&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property_group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;stability</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Unstable&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;common_name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;loctext</span> <span style="color: #000066;">xml:lang</span>=<span style="color: #ff0000;">&quot;C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>resolv.conf Settings<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/loctext<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/common_name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;documentation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;manpage</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;resolv.conf&quot;</span> <span style="color: #000066;">section</span>=<span style="color: #ff0000;">&quot;4&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">manpath</span>=<span style="color: #ff0000;">&quot;/usr/share/man&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/documentation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/template<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/service_bundle<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>which calls the script, <tt>/lib/svc/method/dns-resolv-conf</tt> containing:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/sbin/sh</span><br />
<br />
. <span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>svc<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>smf_include.sh<br />
<br />
<span style="color: #007800;">search</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>svcprop <span style="color: #660033;">-p</span> options<span style="color: #000000; font-weight: bold;">/</span>search <span style="color: #007800;">$SMF_FMRI</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span><br />
&nbsp; &nbsp; <span style="color: #ff0000;">&quot;start&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Don't do anything if search option not provided.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$search</span>&quot;</span> == <span style="color: #ff0000;">'&quot;&quot;'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$SMF_EXIT_OK</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Reverse the lines because we either want to:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># &nbsp; add the search line after the *last* domain line or</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># &nbsp; add it to the very top of the file if there is no domain line</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #c20cb9; font-weight: bold;">tac</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;^search&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">gawk</span> <span style="color: #ff0000;">'<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /^domain/ { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isset) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print &quot;search&quot;, $2, search<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isset=1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isset) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print &quot;search&quot;, search<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; '</span> <span style="color: #007800;">search</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$search</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tac</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf.new <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf.new <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff0000;">&quot;stop&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Just get rid of any search lines, I guess.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-v</span> <span style="color: #ff0000;">&quot;^search&quot;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf.new <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf.new <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>resolv.conf<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: $0 { start | stop }&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$SMF_EXIT_ERR_CONFIG</span><br />
<span style="color: #000000; font-weight: bold;">esac</span><br />
<br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$SMF_EXIT_OK</span></div></div>
<p>So now I can set my search options like:</p>
<pre class="terminal">
% <kbd>svccfg -s resolv-conf setprop 'options/search="thestaticvoid.com es.gwu.edu"'</kbd>
% <kbd>svcadm refresh resolv-conf</kbd>
% <kbd>svcadm enable resolv-conf</kbd>
% <kbd>cat /etc/resolv.conf</kbd>
domain  iss.gwu.edu
search iss.gwu.edu thestaticvoid.com es.gwu.edu
nameserver  161.253.152.50
nameserver  128.164.141.12
</pre>
<p>Problem solved!  Or at least worked-around in the least hacky way I can!</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/01/11/persistent-search-domains-with-nwam-and-dhcp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CrashPlan</title>
		<link>http://thestaticvoid.com/post/2010/12/14/crashplan/</link>
		<comments>http://thestaticvoid.com/post/2010/12/14/crashplan/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 21:28:10 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[crashplan]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=400</guid>
		<description><![CDATA[I have a little storage array that I store my life on. Music, movies, photographs, projects, school work&#8212;I&#8217;d be devastated if I lost any of it. And yet, I don&#8217;t have any sort of backup for it. Last year I evaluated various online backup services but concluded that my 5 Mbps (~600 KB/s) upload bandwidth [...]]]></description>
			<content:encoded><![CDATA[<p>I have a little storage array that I store my life on.  Music, movies, photographs, projects, school work&#8212;I&#8217;d be devastated if I lost any of it.  And yet, I don&#8217;t have any sort of backup for it.  Last year I evaluated various online backup services but concluded that my 5 Mbps (~600 KB/s) upload bandwidth was just too slow to feasibly backup all of my data.  Now I have a 25 Mbps (~3 MB/s) symmetric connection, so last week when I got a promotional email from <a href="http://www.crashplan.com/">CrashPlan</a> announcing their new version and prices, I decided to give it another try.</p>
<p>CrashPlan is, as far as I know, the only online backup solution that officially supports Solaris, and it&#8217;s not half-assed either.  The software is delivered as a standard SVR4 package which installs to <tt>/opt/sfw/crashplan</tt> and includes an SMF manifest.  Normally I&#8217;d never trust consumer-oriented proprietary software like this, but their Solaris support instills confidence in me.  I can only hope that they continue to maintain it, despite the uncertainty surrounding Solaris&#8217;s future.</p>
<p>Like I said, installation was a breeze.  Looking back at my shell history, it was as easy as:</p>
<pre class="terminal">
# <kbd>cd /tmp</kbd>
# <kbd>wget http://download.crashplan.com/installs/solaris/install/CrashPlan/CrashPlan_3.0_Solaris.tar.gz</kbd>
# <kbd>tar -xvzf CrashPlan_3.0_Solaris.tar.gz</kbd>
# <kbd>pkgadd -d . CrashPlan</kbd>
# <kbd>svccfg import /opt/sfw/crashplan/bin/crashplan.xml</kbd>
# <kbd>svcadm enable crashplan</kbd>
</pre>
<p>From there the GUI can be launched as a regular user by running <tt>/opt/sfw/crashplan/bin/CrashPlanDesktop</tt>.  The user interface is clean and simple.  On the first run, it walks you through setting up an account.  New users get a 30-day free trial to CrashPlan+, which includes unlimited online backups.  I&#8217;m still on my trial, but as long as it continues to work for me, I expect I&#8217;ll purchase a subscription for $5/month.</p>
<p>First thing I did after registering was to go into the security settings and change the <a href="http://support.crashplan.com/doku.php/articles/encryption_key">archive encryption key type</a> to use a private password.  This encrypts the key which encrypts my data with a separate password so even if someone hijacks my CrashPlan account, they will not be able to restore any of my files.  The other advanced option, supplying your own private data key, I would argue is less secure since the key is stored in-the-clear on the local system and it cannot be changed without invalidating all of your backups.  Security is very important to me, so I am happy to see that they give control over these settings to the user, though I wish the backup agent were open-source to enable more public scrutiny.  At the very least, I&#8217;d like for CrashPlan to provide more details about their encryption methods similar to <a href="https://spideroak.com/engineering_matters#encryption_specifications">SpiderOak</a>.</p>
<p>Next I directed the software to backup my storage array mounted at <tt>/nest</tt> to CrashPlan Central and off it went.  I&#8217;m currently seeing speeds around 6 Mbps (750 KB/s) which is slightly disappointing on my fast connection, but not unacceptable.  They claim that they do not cap or throttle connections, though from what I&#8217;ve read, speed is largely dependent on which of CrashPlan&#8217;s many datacenters you are provisioned to.  They&#8217;ve been experiencing much higher volume than normal with last week&#8217;s release of CrashPlan 3, so I hope to see increased speed when that activity subsides.</p>
<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2010/12/crashplan.png"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2010/12/crashplan-300x219.png" alt="" title="CrashPlan" width="300" height="219" class="aligncenter size-medium wp-image-419" /></a></p>
<p>I do like that the backup actually takes place in the background, so the GUI is only ever necessary for changing settings and performing restores.  I tested a restore and saw much better speeds around 16 Mbps (2 MB/s), though still not even close to saturating my internet connection.</p>
<p>My backup should hopefully be done by the new year and then it&#8217;ll just be a matter of performing small nightly incrementals.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2010/12/14/crashplan/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fun With vpnc</title>
		<link>http://thestaticvoid.com/post/2010/07/22/fun-with-vpnc/</link>
		<comments>http://thestaticvoid.com/post/2010/07/22/fun-with-vpnc/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 20:20:20 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[snoop]]></category>
		<category><![CDATA[vpnc]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=337</guid>
		<description><![CDATA[I recently got a new laptop at work and I decided to put OpenSolaris on it. This meant I had to setup vpnc in order to access the server networks and wireless here. I installed my vpnc package, copied the profile from my Ubuntu workstation, and started it up. It connected, but no packets flowed. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got a new laptop at work and I decided to put OpenSolaris on it.  This meant I had to setup vpnc in order to access the server networks and wireless here.  I installed <a href="http://thestaticvoid.com/post/2010/02/26/vpnc-for-opensolaris/">my vpnc package</a>, copied the profile from my Ubuntu workstation, and started it up.  It connected, but no packets flowed.  I didn&#8217;t have time to investigate, so I decided to work on it some more at home.</p>
<p>The strange thing is that it connected from home with the very same profile and everything worked fine.  I immediately suspected something was wrong with the routing tables, like maybe some of the routes installed by <tt>vpnc-script</tt> were conflicting with the routes necessary to talk to the VPN concentrator.  I endlessly compared the routing tables between work and home and my working Ubuntu workstation, removing routes, adding routes, and manually constructing the routing table until I was positive it could not be that.</p>
<p>Everything I pinged worked.  I could ping the concentrator.  I could ping the gateway.  I could ping the tunnel device.  I could ping the physical interface&#8212;or so I thought.</p>
<p>As I was preparing to write a message to the <a href="http://news.gmane.org/gmane.network.vpnc.devel">vpnc-devel mailing list</a> requesting help, I did some pings to post the output in the email.  I ran</p>
<pre class="terminal">
$ <kbd>ping &lt;concentrator ip&gt;</kbd>
&lt;concentrator ip&gt; is alive
</pre>
<p>which looked good, but I wanted the full ping output, so I ran</p>
<pre class="terminal">
$ <kbd>ping -s &lt;concentrator ip&gt;</kbd>
PING &lt;concentrator ip&gt;: 56 data bytes
^C
----&lt;concentrator ip&gt; PING Statistics----
4 packets transmitted, 1 packets received, 75% packet loss
round-trip (ms)  min/avg/max/stddev = 9223372036854776.000/0.000/0.000/-NaN
</pre>
<p>For some reason, only the first ping was getting through.  The rest were getting hung up somewhere.  The really strange thing was that I saw the same behavior on the local physical interface:</p>
<pre class="terminal">
$ <kbd>ifconfig bge0</kbd>
bge0: flags=1004843<UP,BROADCAST,RUNNING,MULTICAST,DHCP,IPv4> mtu 1500 index 3
        inet 161.253.143.151 netmask ffffff00 broadcast 161.253.143.255
$ <kbd>ping -s 161.253.143.151</kbd>
PING 161.253.143.151: 56 data bytes
^C
----161.253.143.151 PING Statistics----
5 packets transmitted, 1 packets received, 80% packet loss
round-trip (ms)  min/avg/max/stddev = 9223372036854776.000/0.000/0.000/-NaN
</pre>
<p>I have never seen a situation where you couldn&#8217;t even ping a local physical interface!  I checked and double checked that IPFilter wasn&#8217;t running.  Finally I started a packet capture of the physical interface to see what was happening to my pings:</p>
<pre class="terminal">
# <kbd>snoop -d bge0 icmp</kbd>
Using device bge0 (promiscuous mode)
161.253.143.151 -> &lt;concentrator ip&gt; ICMP Destination unreachable (Bad protocol 50)
161.253.143.151 -> &lt;concentrator ip&gt; ICMP Destination unreachable (Bad protocol 50)
161.253.143.151 -> &lt;concentrator ip&gt; ICMP Destination unreachable (Bad protocol 50)
^C
</pre>
<p>That&#8217;s when by chance I saw messages being sent to the VPN concentrator saying &#8220;bad protocol 50.&#8221;  <a href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml">IP protocol</a> 50 represents &#8220;ESP&#8221;, commonly used for IPsec.  Apparently Solaris eats these packets.  Haven&#8217;t figured out why.</p>
<p>I remembered seeing something in the vpnc manpage about ESP packets:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--natt-mode &lt;natt/none/force-natt/cisco-udp&gt;<br />
<br />
&nbsp; &nbsp; &nbsp; Which NAT-Traversal Method to use:<br />
&nbsp; &nbsp; &nbsp; o &nbsp; &nbsp;natt -- NAT-T as defined in RFC3947<br />
&nbsp; &nbsp; &nbsp; o &nbsp; &nbsp;none -- disable use of any NAT-T method<br />
&nbsp; &nbsp; &nbsp; o &nbsp; &nbsp;force-natt -- always use NAT-T encapsulation &nbsp;even<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;without presence of a NAT device (useful if the OS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;captures all ESP traffic)<br />
&nbsp; &nbsp; &nbsp; o &nbsp; &nbsp;cisco-udp -- Cisco proprietary UDP &nbsp;encapsulation,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;commonly over Port 10000</div></div>
<p>I enabled <tt>force-natt</tt> mode, which encapsulates the ESP packet in a UDP packet, normally to get past NAT, and it started working!  In retrospect, I should have been able to figure that out much easier.  First, it pretty much says it on the <a href="http://www.unix-ag.uni-kl.de/~massar/vpnc/">vpnc homepage</a>: &#8220;Solaris (7 works, 9 only with &#8211;natt-mode forced).&#8221;  I didn&#8217;t even notice that.  Second, I should have realized that I was behind a NAT at home and not at work, so they would be using a different NAT-traversal mode by default.  Oh well, it was a good diagnostic exercise, hence the post to share the experience.</p>
<p>In other vpnc related news, I&#8217;ve ported <a href="http://www.whiteboard.ne.jp/~admin2/tuntap/">Kazuyoshi&#8217;s</a> <a href="http://www.whiteboard.ne.jp/~admin2/tuntap/source/openvpn/patch.openvpn-2.1.1.tun.c">patch</a> to the <tt>open_tun</tt> and <tt>solaris_close_tun</tt> functions of OpenVPN to the <tt>tun_open</tt> and <tt>tun_close</tt> functions of vpnc.  His sets up the tunnel interface a little bit differently and adds TAP support.  It solves the random problems vpnc had with bringing up the tunnel interface such as:</p>
<pre class="terminal">
# <kbd>ifconfig tun0</kbd>
tun0: flags=10010008d0&lt;POINTOPOINT,RUNNING,NOARP,MULTICAST,IPv4,FIXEDMTU&gt; mtu 1412 index 8
        inet 128.164.xxx.yy --> 128.164.xxx.yy netmask ffffffff
        ether f:ea:1:ff:ff:ff
# <kbd>ifconfig tun0 up</kbd>
ifconfig: setifflags: SIOCSLIFFLAGS: tun0: no such interface
# <kbd>dmesg | grep tun0</kbd>
Jul 23 14:56:05 swan ip: [ID 728316 kern.error] tun0: DL_BIND_REQ failed: DL_OUTSTATE
</pre>
<p>The changes are in the latest vpnc package available from my <a href="http://pkg.thestaticvoid.org:10000/">package repository</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2010/07/22/fun-with-vpnc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

