<?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 &#187; solaris</title>
	<atom:link href="http://thestaticvoid.com/tag/solaris/feed/" rel="self" type="application/rss+xml" />
	<link>http://thestaticvoid.com</link>
	<description>Explorations in Computing</description>
	<lastBuildDate>Wed, 07 Dec 2011 16:15:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<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>2</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>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>DTrace to the Rescue Again!</title>
		<link>http://thestaticvoid.com/post/2010/03/30/dtrace-to-the-rescue-again/</link>
		<comments>http://thestaticvoid.com/post/2010/03/30/dtrace-to-the-rescue-again/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 16:33:30 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[dtrace]]></category>
		<category><![CDATA[solaris]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=278</guid>
		<description><![CDATA[I am really beginning to understand just how powerful and important this tool is. I ran into another problem at work where I was seeing errors, but the details weren&#8217;t very helpful. I recently made a NFS mounted filesystem read-only, and some errors started to pop up in the system log: # dmesg ... Mar [...]]]></description>
			<content:encoded><![CDATA[<p>I am really beginning to understand just how powerful and important this tool is.  I ran into another problem at work where I was seeing errors, but the details weren&#8217;t very helpful.  I recently made a NFS mounted filesystem read-only, and some errors started to pop up in the system log:</p>
<pre class="terminal">
# <kbd>dmesg</kbd>
...
Mar 30 12:09:00 ragno nfs: [ID 808668 kern.notice] NFS write error on host nasfb: Read-only file system.
Mar 30 12:09:00 ragno nfs: [ID 702911 kern.notice] (file handle: 1d010000 1000000 e10d1300 a5122c4b 1d010000 1000000 15000000 5c179c4a)
...
</pre>
<p>I wanted to know which file is being written to.  The file handle isn&#8217;t very useful for me.  I tried using <tt>lsof</tt> like:</p>
<pre class="terminal">
# <kbd>lsof -N -z ragno /zones/ragno/root/home</kbd>
lsof: WARNING: can't stat() 5 zone file systems; using dev= options
COMMAND     PID ZONE      USER   FD   TYPE        DEVICE             SIZE/OFF       NODE NAME
httpd      3065 ragno webservd  cwd   VDIR     256,65718                    0          0 /zones/ragno (ragno)
httpd      3065 ragno webservd  rtd   VDIR     256,65718                    0          0 /zones/ragno (ragno)
httpd      3065 ragno webservd  txt   VREG     256,65718                    0          0 /zones/ragno (ragno)
httpd      3065 ragno webservd  txt   VREG     256,65718                    0          0 /zones/ragno (ragno)
...
</pre>
<p>but it didn&#8217;t give me any useful information either.  Maybe I&#8217;m not using it correctly?</p>
<p>Then I found the <a href="http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/nfs/nfs_client.c#nfs_write_error">function</a> in the kernel which is responsible outputting the NFS write errors that appear in the system log:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
<span style="color: #993333;">void</span><br />
nfs_write_error<span style="color: #009900;">&#40;</span>vnode_t <span style="color: #339933;">*</span>vp<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> error<span style="color: #339933;">,</span> cred_t <span style="color: #339933;">*</span>cr<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
...</div></div>
<p>This function gets passed a <a href="http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/sys/vnode.h#227"><tt>vnode_t</tt></a> pointer which has tons of data on the current I/O operation, including the file name.  DTrace enabled me to access this data dynamically:</p>
<pre class="terminal">
# <kbd>dtrace -n 'fbt:nfs:nfs*_write_error:entry /zonename == "ragno"/ {vp = (vnode_t*) arg0; printf("%s", stringof(vp->v_path));}'</kbd>
dtrace: description 'fbt:nfs:nfs*_write_error:entry ' matched 2 probes
CPU     ID                    FUNCTION:NAME
  0  56891            nfs_write_error:entry /zones/ragno/root/home/rmserver/Logs/rmaccess.log
  0  56891            nfs_write_error:entry /zones/ragno/root/home/rmserver/Logs/rmaccess.log
  0  56891            nfs_write_error:entry /zones/ragno/root/home/rmserver/Logs/rmaccess.log
  0  56891            nfs_write_error:entry /zones/ragno/root/home/rmserver/Logs/rmaccess.log
  0  56891            nfs_write_error:entry /zones/ragno/root/home/rmserver/Logs/rmaccess.log
</pre>
<p>And there&#8217;s the culprit.  Now I know which file needs to be relocated to local read/write storage.  Neato!</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2010/03/30/dtrace-to-the-rescue-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Watching Network Connections with DTrace</title>
		<link>http://thestaticvoid.com/post/2009/12/14/watching-network-connections-with-dtrace/</link>
		<comments>http://thestaticvoid.com/post/2009/12/14/watching-network-connections-with-dtrace/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 19:44:02 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[dtrace]]></category>
		<category><![CDATA[solaris]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=221</guid>
		<description><![CDATA[DTrace is one of those magical tools that I sort of know how to use but never had the chance to. Usually, firing up truss is sufficient to figure out what&#8217;s happening in a process. But recently, a team at GW was setting up a web application and having some problems. It would hang whenever [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://hub.opensolaris.org/bin/view/Community+Group+dtrace/WebHome">DTrace</a> is one of those magical tools that I sort of know how to use but never had the chance to.  Usually, firing up <a href="http://docs.sun.com/app/docs/doc/816-0210/6m6nb7mnl">truss</a> is sufficient to figure out what&#8217;s happening in a process.</p>
<p>But recently, a team at GW was setting up a web application and having some problems.  It would hang whenever it was accessed.  The application is highly modular and accesses several other servers for resources, so I suspected there must have been some sort of network problem, probably a blocked firewall port somewhere.  Unfortunately, the application produces no logs (!) so it was pretty much guesswork.</p>
<p>I started <a href="http://docs.sun.com/app/docs/doc/819-2240/snoop-1m?a=view">snoop</a> to watch for traffic generated by the application.  I knew from watching the production application that there should be communication between two servers over port 9300, but I wasn&#8217;t seeing anything.  I thought of using truss to determine if the application was at least trying to connect, but being a web application, the process was way too short-lived to attach to.  Even if I was able to attach to it, all I might have learned was that the application was calling the &#8216;connect&#8217; system call and possibly getting a return value.</p>
<p>DTrace, on the other hand, doesn&#8217;t have to attach to a particular process.  It just sits in the kernel and dynamically observes what your scripts tell it to.  It also has the ability to look into data structures so you can actually see what values are passed to functions and system calls.  I used this ability to watch every call to the <a href="http://docs.sun.com/app/docs/doc/816-0214/6m6nf1oeq?a=view">connect</a> system call.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#!/usr/sbin/dtrace -qs</span><br />
<br />
syscall<span style="color: #339933;">::</span><span style="color: #202020;">connect</span><span style="color: #339933;">:</span>entry<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; socks <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> copyin<span style="color: #009900;">&#40;</span>arg1<span style="color: #339933;">,</span> arg2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; hport <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>uint_t<span style="color: #009900;">&#41;</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; lport <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>uint_t<span style="color: #009900;">&#41;</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; hport <span style="color: #339933;">&lt;&lt;=</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port <span style="color: #339933;">=</span> hport <span style="color: #339933;">+</span> lport<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s: %d.%d.%d.%d:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> execname<span style="color: #339933;">,</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> socks<span style="color: #339933;">-&gt;</span>sa_data<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>This script copies <tt>arg2</tt> bytes from the address pointed to by <tt>arg1</tt> into kernel space and uses the data to determine the port (big endian order) and destination address.</p>
<p>When run, the script immediately revealed that the web application was trying to connect to itself rather than a database server, a simple configuration mistake made difficult to diagnose due to poor logging facilities in the application.</p>
<p>In the future, there will be a <a href="http://hub.opensolaris.org/bin/view/Community+Group+dtrace/NetworkProvider">network provider</a> for DTrace which will simplify the job of extracting data from network calls.  It should then be possible to rewrite the script to simply:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#!/usr/sbin/dtrace -qs</span><br />
<br />
tcp<span style="color: #339933;">:::</span><span style="color: #202020;">connect</span><span style="color: #339933;">-</span>request<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s: %s:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> execname<span style="color: #339933;">,</span> args<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>ip_daddr<span style="color: #339933;">,</span> args<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>tcp_dport<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Hopefully I&#8217;ll have more opportunities to use DTrace in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2009/12/14/watching-network-connections-with-dtrace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

