<?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; System Administration</title>
	<atom:link href="http://thestaticvoid.com/category/system-administration/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>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>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>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>
		<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>VPNC for OpenSolaris</title>
		<link>http://thestaticvoid.com/post/2010/02/26/vpnc-for-opensolaris/</link>
		<comments>http://thestaticvoid.com/post/2010/02/26/vpnc-for-opensolaris/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 20:02:16 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[vpnc]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=260</guid>
		<description><![CDATA[I&#8217;ve compiled VPNC and the requisite TUN/TAP driver for OpenSolaris so that I can access my work network from home. Kazuyoshi&#8217;s driver adds TAP functionality to the original TUN driver which hasn&#8217;t been updated in nine years. It&#8217;s a real testament to the stability of the OpenSolaris kernel ABI that the module still compiles, loads, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve compiled <a href="http://www.unix-ag.uni-kl.de/~massar/vpnc/">VPNC</a> and the requisite <a href="http://www.whiteboard.ne.jp/~admin2/tuntap/">TUN/TAP driver</a> for OpenSolaris so that I can access my work network from home.  Kazuyoshi&#8217;s driver adds TAP functionality to the original <a href="http://vtun.sourceforge.net/tun/">TUN driver</a> which hasn&#8217;t been updated in nine years.  It&#8217;s a real testament to the stability of the OpenSolaris kernel ABI that the module still compiles, loads, and works properly.</p>
<p>All of the software can be installed from my repository onto build 111 or higher:</p>
<pre class="terminal">
$ <kbd>pfexec pkg set-publisher -O http://pkg.thestaticvoid.com/ thestaticvoid</kbd>
$ <kbd>pfexec pkg install vpnc</kbd>
</pre>
<p>The tun driver should load automatically and create <tt>/dev/tun</tt>.  Now create a VPN profile configuration in <tt>/etc/vpnc/</tt>.  The configuration contains a lot of private information so I&#8217;m not going to share mine here, but <tt>/etc/vpnc/default.conf</tt> is a good start.</p>
<p>One thing I do like to do is make sure only certain subnets are tunneled through the VPN.  That way connecting to the VPN doesn&#8217;t interrupt any connections that are already established (for example, AIM).  To do that I create a script <tt>/etc/vpnc/gwu-networks-script</tt> containing</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: #666666; font-style: italic;"># Only tunnel GWU networks through VPN</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC</span>=<span style="color: #000000;">2</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_ADDR</span>=161.253.0.0<br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_MASK</span>=255.255.0.0<br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_MASKLEN</span>=<span style="color: #000000;">16</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_PROTOCOL</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_SPORT</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_0_DPORT</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_ADDR</span>=128.164.0.0<br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_MASK</span>=255.255.0.0<br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_MASKLEN</span>=<span style="color: #000000;">16</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_PROTOCOL</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_SPORT</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">CISCO_SPLIT_INC_1_DPORT</span>=<span style="color: #000000;">0</span><br />
<br />
. <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>vpnc<span style="color: #000000; font-weight: bold;">/</span>vpnc-script</div></div>
<p>then add <tt>Script /etc/vpnc/gwu-networks-script</tt> to the end of my VPN profile configuration.</p>
<p>Connecting to the VPN you should see messages like:</p>
<pre class="terminal">
$ <kbd>pfexec vpnc gwu</kbd>
Enter password for jameslee@&lt;no&gt;:
which: no ip in (/sbin:/usr/sbin:/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin)
which: no ip in (/sbin:/usr/sbin:/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin)
add net 128.164.&lt;no&gt;: gateway 128.164.&lt;no&gt;
add host 128.164.&lt;no&gt;: gateway 161.253.&lt;no&gt;
add net 161.253.0.0: gateway 128.164.&lt;no&gt;
add net 128.164.0.0: gateway 128.164.&lt;no&gt;
add net 128.164.&lt;no&gt;: gateway 128.164.&lt;no&gt;
add net 128.164.&lt;no&gt;: gateway 128.164.&lt;no&gt;
VPNC started in background (pid: 594)...
</pre>
<p>The <tt>vpnc-script</tt> will modify your <tt>/etc/resolv.conf</tt> and routing tables so be sure to run <tt>vpnc-disconnect</tt> when you are done with the connection to restore the original configuration.</p>
<p>Thanks to the good folks at <a href="http://www.infradead.org/openconnect.html">OpenConnect</a> for a well-maintained <a href="http://git.infradead.org/users/dwmw2/vpnc-scripts.git/blob/HEAD:/vpnc-script"><tt>vpnc-script</tt></a> which works on Solaris.  Spec files for these packages are available from my <a href="https://github.com/MrStaticVoid/specs/blob/master/vpnc.spec">GitHub</a> <a href="https://github.com/MrStaticVoid/specs/blob/master/tuntap.spec">repository</a> if you want to roll your own.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2010/02/26/vpnc-for-opensolaris/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Start Virtual NICs on OpenSolaris Boot</title>
		<link>http://thestaticvoid.com/post/2009/12/23/start-virtual-nics-on-opensolaris-boot/</link>
		<comments>http://thestaticvoid.com/post/2009/12/23/start-virtual-nics-on-opensolaris-boot/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 16:12:51 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[crossbow]]></category>
		<category><![CDATA[opensolaris]]></category>
		<category><![CDATA[smf]]></category>
		<category><![CDATA[zones]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=230</guid>
		<description><![CDATA[One of the more frustrating things I deal with on OpenSolaris is that every time I reboot, I have to manually bring up each virtual network interface in order to start all of my zones. There is a bug report for this problem that says a fix will be integrated into b132, which is just [...]]]></description>
			<content:encoded><![CDATA[<p>One of the more frustrating things I deal with on OpenSolaris is that every time I reboot, I have to manually bring up each virtual network interface in order to start all of my zones.  There is a <a href="http://bugs.opensolaris.org/view_bug.do?bug_id=6776009">bug report</a> for this problem that says a fix will be integrated into b132, which is just a few weeks away, but in the mean time, I&#8217;ve whipped up an SMF service to handle this for me.  Create a file <tt>vnic.xml</tt>:</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;">'manifest'</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'vnic'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'network/vnic'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'service'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; <span style="color: #000066;">version</span>=<span style="color: #ff0000;">'1'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'network_service'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">grouping</span>=<span style="color: #ff0000;">'require_all'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">restart_on</span>=<span style="color: #ff0000;">'none'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &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; &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 />
&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; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependent</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'network_vnic'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">grouping</span>=<span style="color: #ff0000;">'optional_all'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">restart_on</span>=<span style="color: #ff0000;">'none'</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;service_fmri</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">'svc:/system/zones'</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;/dependent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec_method</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'method'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'start'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">exec</span>=<span style="color: #ff0000;">'/usr/sbin/dladm up-vnic ${SMF_FMRI/*:/}'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">timeout_seconds</span>=<span style="color: #ff0000;">'60'</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec_method</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'method'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'stop'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">exec</span>=<span style="color: #ff0000;">':true'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">timeout_seconds</span>=<span style="color: #ff0000;">'60'</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&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;">'startd'</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'framework'</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;propval</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">'duration'</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'astring'</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">'transient'</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;/property_group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
&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;">'Unstable'</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<br />
&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; <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;loctext</span> <span style="color: #000066;">xml:lang</span>=<span style="color: #ff0000;">'C'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Virtual Network Interface<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <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; <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; <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; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;manpage</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">'dladm'</span> <span style="color: #000066;">section</span>=<span style="color: #ff0000;">'1M'</span></span><br />
<span style="color: #009900;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">manpath</span>=<span style="color: #ff0000;">'/usr/share/man'</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;/documentation<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;/template<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<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<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>This service should run sometime after the network is started but before the zones are started.  Load it in with <tt>svccfg -v import vnic.xml</tt> and create an instance of the service for each of the VNICs that you want to start.  For example, if you want to start <tt>vnic0</tt> on boot:</p>
<pre class="terminal">
# <kbd>svccfg -s vnic add vnic0</kbd>
# <kbd>svcadm refresh vnic0</kbd>
# <kbd>svcadm enable vnic0</kbd>
</pre>
<p><strong>UPDATE:</strong> Build 132 is out an this functionality has been integrated as the <tt>svc:/network/datalink-management:default</tt> service.  The services that were added above can be removed by running <tt>svccfg delete vnic</tt>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2009/12/23/start-virtual-nics-on-opensolaris-boot/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>
		<item>
		<title>Replacing Apache with Yaws</title>
		<link>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/</link>
		<comments>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 02:35:25 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[yaws]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=139</guid>
		<description><![CDATA[After some time running with the Apache worker model, I noticed it was not much better on memory than prefork. It would spawn new threads as load increased, but didn&#8217;t give up the resources when load decreased. I know it does this for performance, but I am very tight on memory. And I know Apache [...]]]></description>
			<content:encoded><![CDATA[<p>After some time running with the Apache <a href="http://thestaticvoid.com/post/2009/07/27/reducing-memory-footprint-of-apache-services/">worker</a> model, I noticed it was not much better on memory than prefork.  It would spawn new threads as load increased, but didn&#8217;t give up the resources when load decreased.  I know it does this for performance, but I am very tight on memory.  And I know Apache is very tunable, so I could probably change that behavior, but tuning is boring.  Playing with new stuff is fun!  This was the perfect opportunity for me to look at lightweight web servers.</p>
<p>I toyed around with <a href="http://www.lighttpd.net/">lighttpd</a> and read the documentation for <a href="http://nginx.net/">nginx</a>.  Both seem to do what I need them to do, but I was more interested in the equally fast and light <a href="http://yaws.hyber.org/">Yaws</a>.  I&#8217;ve been really into <a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a> lately (more on that in another post), so this was a great opportunity to see how a real Erlang application works.</p>
<h3>Installation</h3>
<p>Naturally, Yaws isn&#8217;t included in OpenSolaris yet, but Erlang is!  So it was fairly easy to whip together a <a href="https://github.com/MrStaticVoid/specs/blob/master/yaws.spec">spec file</a> and <a href="https://github.com/MrStaticVoid/specs/blob/master/ext-sources/http-yaws.xml">SMF manifest</a> for the program.  Then it was as easy as:</p>
<pre class="terminal">
$ <kbd>pkgtool build-only --download --interactive yaws.spec</kbd>
$ <kbd>pfexec pkg install yaws</kbd>
</pre>
<p>I&#8217;ve set the configuration to go to <tt>/etc/yaws/yaws.conf</tt> and the service can be started with <tt>svcadm enable yaws</tt>.  When I&#8217;m completely satisfied with the package, I&#8217;ll upload it to <a href="http://jucr.opensolaris.org/">SourceJuicer</a>.</p>
<h3>Configuration</h3>
<p>I run two virtual hosts: thestaticvoid.com and iriverter.thestaticvoid.com.  Those two domains also have &#8220;.org&#8221; counterparts which I want to redirect to the &#8220;.com&#8221; domain.  The <tt>yaws.conf</tt> syntax to handle this case is very simple:</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">pick_first_virthost_on_nomatch = true<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> localhost<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / = thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/redirect<span style="color: #000000; font-weight: bold;">&gt;</span></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><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; docroot = /docs/thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; dir_listings = true<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><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> iriverter.thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; docroot = /docs/iriverter.thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; dir_listings = true<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><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> iriverter.thestaticvoid.org<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / = iriverter.thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/redirect<span style="color: #000000; font-weight: bold;">&gt;</span></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>Should be pretty self-explanatory, but the nice thing is the <tt>pick_first_virthost_on_nomatch</tt> directive combined with the localhost block so that if anyone gets to this site by any other address, they&#8217;ll be redirected to the canonical thestaticvoid.com.  I did actually run into a bug with the redirection putting extra slashes in the URL, but squashed that bug pretty quickly with a bit of help from the Yaws mailing list.  That whole problem is summarized in <a href="http://thread.gmane.org/gmane.comp.web.server.yaws.general/2188">this thread</a>.</p>
<h4>PHP</h4>
<p>Yaws handles PHP execution as a special case.  All you have to do is add a couple lines to the configuration above:</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">php_exe_path = /usr/php/bin/php-cgi<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; &nbsp; &nbsp; allowed_scripts = php<br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<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>Reload the server (<tt>svcadm refresh yaws</tt>) and PHP, well, won&#8217;t work just yet.  This actually took me an hour or two to figure out.  OpenSolaris&#8217; PHP is compiled with the <tt>--enable-force-cgi-redirect</tt> option which means PHP will refuse to execute unless it was invoked by an Apache <tt>Action</tt> directive.  Fortunately, you can disable this security measure by setting <tt>cgi.force_redirect = 0</tt> in your <tt>/etc/php/5.2/php.ini</tt>.</p>
<h4>Trac</h4>
<p>Trac needs a little work to get running in Yaws.  It&#8217;s requires an environmental variable, <tt>TRAC_ENV</tt>, set to tell it where to find the project database.  The easiest way to do that is to copy <tt>/usr/share/trac/cgi-bin/trac.cgi</tt> to the document root, modify it to set the environmental variable, and enable CGI scripts in Yaws by setting <tt>allowed_scripts = cgi</tt>.</p>
<p>But I decided to set up an appmod, so that <tt>trac.cgi</tt> could be left where it was, unmodified.  Appmods are Erlang modules which get run by Yaws whenever the configured URL is requested.  Here&#8217;s the one I wrote for Trac:</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>trac<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">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: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">APPMOD</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">TRAC_ENV</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac/iriverter&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/usr/share/trac/cgi-bin/trac.cgi&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</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; &nbsp; &nbsp; <span style="color: #45b3e6;">Pathinfo</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>pathinfo<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Env</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;SCRIPT_NAME&quot;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">APPMOD</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;TRAC_ENV&quot;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">TRAC_ENV</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; yaws_cg<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">call_cgi</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #6bb810;">,</span> undefined<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pathinfo</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Env</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>All appmods must define the out/1 function which takes an <tt>arg</tt> record which contains information about the current request.  At the end of the function, the Yaws API is used to execute the CGI script with the extra environmental variables.  This is compiled (<tt>erlc -o /var/yaws/ebin -I/usr/lib trac.erl</tt>) and enabled in the Yaws configuration by adding <tt>appmods = &lt;/trac, trac&gt;</tt> to a <tt>server</tt> section.  Then whenever someone requests <tt>/trac/foo/bar</tt>, Trac runs properly!</p>
<p><a name="trac-rewrite"></a></p>
<p>I also set up URL rewriting so that instead of requesting something like <tt>http://i.tsv.c/trac/wiki</tt>, all you see is <tt>http://i.tsv.c/wiki</tt>.  This involves another Erlang module, a rewrite module.  It looks like:</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: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>rewrite_trac<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>arg_rewrite<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: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">arg_rewrite</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; &nbsp; &nbsp; <span style="color: #45b3e6;">Req</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>req<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #6bb810;">.</span>path<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">try</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">url_decode_q_split</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">DecPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Query</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #45b3e6;">DecPath</span> <span style="color: #014ea4;">==</span> <span style="color: #ff7800;">&quot;/&quot;</span> <span style="color: #186895;">orelse</span> <span style="color: #014ea4;">not</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">is_file</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>docroot <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">DecPath</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">catch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #fa6fff;">exit</span>:_ <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></div></div>
<p>This module runs as soon as a request comes into the server and allows you to modify many variables before the request is handled.  This is a simple one which says: if the request is &#8220;/&#8221; or the requested file doesn&#8217;t exist, append the request to the Trac appmod, otherwise pass it through unaltered.  It&#8217;s enabled in the Yaws server by adding <tt>	arg_rewrite_mod = rewrite_trac</tt> to <tt>yaws.conf</tt>.  The Trac appmod must also be modified to make sure <tt>SCRIPT_NAME</tt> is now </tt>/</tt> so the application generates links without containing <tt>/trac</tt>.</p>
<h4>WordPress</h4>
<p>WordPress works perfectly once PHP is enabled in Yaws.  WordPress permalinks, however, do not.  A little background:  WordPress normally relies on Apache's mod_rewrite to execute <tt>index.php</tt> when it gets an request like <tt>/post/2009/07/27/suexec-on-opensolaris/</tt>.  mod_rewrite sets up the environmental variables such that WordPress is able to detect how it was called and can process the page accordingly.</p>
<p>Without mod_rewrite, the best it can do is rely on requests like <tt>/index.php/post/2009/07/27/suexec-on-opensolaris/</tt> and use the <tt>PATH_INFO</tt> variable, which is the text after <tt>index.php</tt>.  I think that looks ugly, having <tt>index.php</tt> in every URL.  You would think that simply rewriting the URL, just as was done with Trac, would solve the problem, but WordPress is too smart, and always sends you to a canonical URL which it thinks must include <tt>index.php</tt>.</p>
<p>After more experimentation than I care to explain, I discovered that if I set the <tt>REQUEST_URI</tt> variable to the original request (the one not including <tt>index.php</tt>), WordPress was happy.  This was a tricky exercise in trying to set an environmental variable from the rewrite module.  But, as we saw with the Trac example, environmental variables can be set from appmods.  And I found that data can be passed from the rewrite module to the appmod through the <tt>arg</tt> record!  Here's my solution:</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: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>rewrite_blog<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>arg_rewrite<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: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">arg_rewrite</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; &nbsp; &nbsp; <span style="color: #45b3e6;">Req</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>req<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #6bb810;">.</span>path<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">try</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">url_decode_q_split</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">DecPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Query</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #45b3e6;">DecPath</span> <span style="color: #014ea4;">==</span> <span style="color: #ff7800;">&quot;/&quot;</span> <span style="color: #186895;">orelse</span> <span style="color: #014ea4;">not</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">is_file</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>docroot <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">DecPath</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">str</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/wsvn&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #014ea4;">==</span> <span style="color: #ff9600;">1</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_RepCount</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">sub</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;^/wsvn(<span style="color: #000099; font-weight: bold;">\.</span>php)?&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/wsvn.php&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewPath</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>opaque <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;REQUEST_URI&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/blog&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">catch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #fa6fff;">exit</span>:_ <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></div></div>
<p>Nevermind the extra <a href="http://thestaticvoid.com/wsvn/">WebSVN</a> rewriting code.  Notice I set the <tt>opaque</tt> component of the <tt>arg</tt>.  Then in the appmod:</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>blog<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">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: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/docs/thestaticvoid.com/wordpress/index.php&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws.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_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</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; &nbsp; &nbsp; <span style="color: #45b3e6;">Pathinfo</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>pathinfo<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Env</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>opaque<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">GC</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Groups</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #fa6fff;">get</span><span style="color: #ff3c00;">conf</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; yaws_cg<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">call_cgi</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">GC</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">gconf</span><span style="color: #6bb810;">.</span>phpexe<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pathinfo</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Env</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>I pull the data from the <tt>arg</tt> record and pass it to the <tt>call_cgi/5</tt> function.  Also of note here is the special way to invoke the PHP CGI.  The location of the <tt>php-cgi</tt> executable is pulled from the Yaws configuration and passed as the second argument to <tt>call_cgi/5</tt> so Yaws knows what to do with the files.  You can surely imagine this as a way to execute things other than PHP which do not have a <tt>#!</tt> at the top.  Or emulating suEXEC with a custom wrapper <img src='http://thestaticvoid.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Overall, this probably seems like a lot of work to get things working that are trivial in other servers, but I'm finding that the appmods are really powerful, and the Yaws code itself is very easy to understand and modify.  Plus you get the legendary performance and fault-tolerance of Erlang.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

