« September 2008 | Main | December 2008 »

November 2008 Archives

November 9, 2008

Shadow Dawn - Adventure Template

Tell it Like it Is

One of the most difficult tasks for a DM when running a campaign is structuring adventures in a way that is both engaging for the players without becoming a tedious management task. After all, the enjoyment the DM gets as a participant in the gaming session is as the director of collective imagination.

More importantly, adventures need enough structure to move the storyline forward but enough flexibility to account for unexpected player actions. Achieving this balance is difficult, but luckily both Torg and Earthdawn provide excellent examples of how to structure an adventure just right. A more rigid storytelling structure results in too much Deus Ex Machina common in a lot of D&D style games.

The following template can be used to modify existing ShadowRun adventures (which, despite their exceptional back story are incredibly difficult to run) or create new scenarios to introduce elements of the world storyline into regular game play.

Common Adventure Themes

To prevent adventures from devolving from one dungeon trawl to another, it is crucial to craft a theme around adventures. This relieves the tedium most campaigns become, by providing a variety of encounters for the players some of which (believe it or not) do not require the use of swords. I find that most games which over-rely on physical confrontation quickly become "Gear" games. The only motivation for players is to acquire the next "Biggest, Baddest, Can of Whoop Ass". While there is something gratifying in having a powerful item, it quickly upsets game balance.

This is the main short-coming of ShadowRun. While advances in technology and magic make the game interesting, the system suffers from it's inability to scale with experienced players.

Before designing an adventure, decide the core theme. This will provide the foundation of the adventure experience. Here are some common themes (other than the basic Hack-N-Slash theme):

Themes

  1. Mystery

    I world without mystery quickly becomes predictable. Players crave discovery as part of the experience and making them work for it makes it all the more enjoyable. Metagaming is a part of a group dynamic that generally undermines mystery. The challenge is to engage the player regardless of this element by introducing the unpredictable to the campaign. Doing so provides opportunities for players to have a hand in determining the outcome of campaign wide events.

  2. Revenge

    Revenge can only work within a campaign setting if the DM invests the time to develop credible nemesi (probably a non-existent plural for nemesis) to continually challenge players. This means that death should not be the only outcome when encountering game master generated opposition. Like unrequited love, the longer the act is delayed, the sweeter it is (or the greater the disappointment).

  3. Comedy

    Like a good movie, the right mix of action, mystery, romance, and comedy contribute to the overall enjoyment experienced by players. Comedy provides colour and has multiplier effect on the other elements that make the game enjoyable for the players.

Don't overlook providing some character downtime as an opportunity to lighten the mood of the campaign. These moments allow players to become more vested in character by allowing them to pursue personal sub-themes. Sometimes, it is these sub-themes that become the motivating force for moving the plot forward.

Plots

Plots provide the primary motivation for the characters in terms of moving the story and action forward. Without motivation, campaigns quickly devolve into chaos. The GM's challenge is to allow characters to fulfill plots while allowing sub-plots to develop in parallel. These objectives should be achievable within 2-3 sessions. Larger story arcs should be broken up into chapters, each with its own plot. This prevents the primary motivation from becoming stale. Plots should have a definitive beginning and end. In the context of larger story arcs, each chapter should be able to stand on its own and allow the players to choose whether or not to continue the larger arc. There is nothing more frustrating from a players perspective then having to follow a story arc simply because the DM has an adventure for it. Using transitional elements to move the story forward allows the GM to introduce possible resolutions to a story without explicitly directing the players into a course of action. A campaign should be flexible enough to allow deviation while still accomplishing the necessary objectives.

Most plots are variations of the following types and usually vary only in scope within a campaign. These types should be fairly self explanatory.

  1. The Quest
  2. The Guantlet
  3. The Gathering

Building an Adventure

  1. Basic Outline
    1. Adventure Idea
    2. Background
    3. Act One - setup. Near the conclusion of the act, a plot point in presented.
    4. Act Two - contains a confrontation leading to the major conflict.
    5. Act Three - contains a confrontation leading to the major conflict.
    6. Conclusion - climax and resolution of the major conflict.

    Beginnings - always try to start with some sort of action. This will set the tone of the adventure.

  2. Scenes - discrete units of action within each act to move the action forward. Within each scene you need to decide what the action will be and what events you want to occur.

    Settings - work along with tone and genre to place and adventure firmly in front of the players. Ideally, each Act should have its own unusual and distinct setting. One or two additional details will flesh out the scenario and make the setting real.

  3. The Action - what the player characters will be doing. Each scene should only involve one primary action. If there is another action, it should be split into two scenes.

  4. Events - an interactive situation which depends upon timing and setting. An incident of significance within a scene.

  5. Variables - plans for alternate directions in the storyline.

    Plot Twists - throw in a surprise or two. Keep some information secret until later.

  6. Flags - conditional events that are activated by the player characters' action, not necessarily connected to a specific setting. Design flags that add new twists, new menaces, or new information to the adventure.

    Bits - events not part of the central storyline. Used to insert running gags, comic relief, red herrings, to add spice to the story line.

    Stacks - scenes that exist separate and apart from the individual acts designed to move the storyline forward.

  7. Awards

    Rewards should scale based on player experience. The challenge is to ensure that players feel like they are advancing without unbalancing the game. ED is great for this as power is acquired incrementally and requires a proportional investment of experience to gain the benefits of a new power or item. Power is rooted in knowledge not simple possession.

  8. Cut To ... - The lead-in to the next act.

    This is an opportunity for the DM to provide context for the Action and exercise his/her storytelling abilities. Introduction of new game themes or characters allows the story to flow into the general narrative.

  9. Gamemaster Characters

    These elements of GM characters give depth which allow players to treat them with more that disposable game elements. The more you allow players to interact with characters with these elements, the more they are likely to be recurring elements in your campaign. This is useful for being able to subtly direct action through interaction as imposing them situationally.

    1. Distinctive Appearance
    2. Distinctive Speech
    3. Definite Objective
    4. Skills
    5. Motivation
  10. GM Character Roles

    GMing is a balancing act that requires practice. It requires intuition of the players themselves in order to determine the right amount of these elements to introduce and when to introduce them. Ultimately, although your job is to play all the obstacles the players are likely to encounter, you must also give them the opportunity to succeed. The challenges should be difficult, but not impossible. This is what builds the feeling of being invested in the development of a player character. Death, while being a real possibility in the game, should be used sparingly. Players should feel their mortality, but should not always be put in mortal danger.

    1. Information Source
    2. Obstacle
    3. Major Villain
    4. Comic Relief
    5. Mood-Setting Device

As with all this material, please feel free to comment.

Ruby Deja Vu

Having recently upgraded my laptop to a new spanky Hitatchi 7K320, I've had the opportunity to build my Ruby development platform from scratch (and hopefully jettison some unwanted cruft) as well as relearn the in's and out's of Ruby on OS X. A clean install provides you with ruby 1.8.4 as well as an older rails 1.1.2. The challenge is to get the latest and greatest. With that in mind, I've outline the steps that I need to follow to get there:

# sudo gem update --system
# sudo gem update

Instead of the cumbersome update of individual components, a simple update will catch all the necessary updates and bring your system up to speed (rails 2.2.0).

Now on to see if installing PostgreSQL is any easier ....

OSX Install Redux

Having staved off the inevitable lack of storage with the installation of a new drive in my laptop, I've endeavored to bring my machine back into working order and avoid the newb mistakes I've made over the course of 2 years on OS X. Unfortunately, my memory is not what it used to be and I've had to jog the cobwebs to relearn certain gotchas. I'm writing about them here in the hope that I will at least remember to look up the answers next time and save time and frustration.
  • X11

    Let me say it. The X.org 7.2 packaged with Leopard is simply half-baked. There are a number of obvious shortcomings in this release and unfortunately, Apple has declined to make amends. Fortunately, there is the XQuartz project which provides updated X11.app binaries which are a direct replacement. This upgrade is a must if you are planning to use X11 apps in Fink. There are still no native ports of wireshark, pan, and other great open source apps found under Linux. Fink is a quick and elegant way to get these on your system, though it is not without it's own difficulties.

    I used to require an updated X11.app to use with OpenOffice, but as there is a native aqua version as of version 3.0, there is no longer a need for this. I wonder how much longer it will take before there are native packages that can be built and deployed in the native OS X environment?

  • Fink

    As or writing this, Fink is at version 0.9.0. This package manager is by far the simplest way to get open source apps working under OS X. When I reinstalled this on my system, I was perplexed by the incompleteness of the packages displayed. I finally clued in and realized that the update method was set to point. This only allows packages added to the 10.5 tree to be accessible. To change this, Fink needs to be reconfigured using the following command:

    # fink configure
    

    The trick is to change the self update method to rsync or cvs. This will ensure that all supported packages from 10.4 to 10.5 will be available to Fink.

    Just a word of warning: if you decide to update/install an application which requires gcc 4.3.2 as a dependency, prepare for a long install.

  • OpenVPN

    One of the things that seemed to require herculean effort the first time around was the installation of an OpenVPN client on OS X. When I first attempted to use TunnelBlick, it did not seem to support automatic installation of the kernel extensions required to create the tap virtual network interfaces. Thankfully, as an official project under the auspices of Google, this is no longer the case. Installation was pretty straight-forward and all that was required was to drop in my existing configuration files into the User/Library/openvpn directory.

    One caveat is to ensure that the contents of the configuration files use file and path names that are relative to their location within that directory. TunnelBlick will fail otherwise.

I'm sure other things will crop up, but this has been good exercise thus far. One last thing for my future self : remember to remove ALL THE SCREWS when attempting to replace the hard drive.

Ymmm .... ProductivityPR0N

Raw Thought: HOWTO: Be more productive

I created this category to catch all of the productivity stuff that I seem to find myself reading. I'm not sure however, whether or not the time invested in reading these articles actually contributes to my procrastination or not .... a question best left for another posting.

Anyway, this article is a great motivator. I have a lot of ideas that simply stay as ideas and I need a way to move from ideas to action. I'm sure I'm not alone in this respect, but that fact that I am self-aware is frankly depressing enough that I'm doing something about it.

As per the article, I have a handy-dandy Moleskin with blank note cards that I carry with me to capture my eureka moments. At the very least, I've begun investigating the possibility of actually carrying out these projects and in some cases prototyping. Not to say that everything is achievable given certain externalities (damn you iPhone and your paltry 2 megapixel non-autofocusing camera !!!!). But the fact of the matter is that the idea has a least been given an opportunity. I'm sure that most of these ideas will never see fruition, but at the very least, I can always point out my rather brilliant precognitive outlook when other people build them.

Ahhhh, basking in the reflected light of another's success!!! The validation of a true procrastinator. It's only taken a year to actually post something to this category though. Guess what? I put it off.

November 10, 2008

It was a dark and stormy night ....

In an effort to actually finish some of the books on my reading list, I'm going to document my efforts here. My tastes are pretty eclectic, but I'm trying to find out if there is an underlying thread in the books that I enjoy, versus those which are simply dead trees to me. I'll separate out the technical from the fiction/non-fiction, just in case anyone is actually reading this and needs to make the distinction (which apparently, I don't).

I'll begin this category with an entry titled with the immortal words of Edward George Bulwer-Lytton, in his book Paul Clifford (1830). Seems appropriate.

Reboot !!!

I usually avoid rebooting as a matter of principle. It always seemed like using a hammer to swat a fly, and the inferiority of an OS is directly related to the number of reboots required to get it to function civilly. That being said, I've run into a number of situations during my OS X re-installation where a reboot was quite necessary.

The first involved an application called TextExpander - a great little app that performs macro expansion at the OS level for all applications and meshes well with QuickSilver and Ubiquity for Firefox. The beauty of these applications is that almost everything is accessible via the keyboard as opposed to having to switch input methods (the old keyboard, mouse conundrum). This allow you preserve flow when you are working without being distracted by the cognitive changes required to switch input methods.

Anyway, the problem I experienced was with the way TextExpander choose to install itself. Although the instructions are pretty straight forward, nothing in the installation docs mentioned the application's requirement of a custom daemon - textexpanderd. Unfortunately, the installer, while correctly copying the daemon onto the System, failed to enable the associated Login item. The system logs provided the very unhelpful messages consisting of the following lines :


Nov 10 18:57:31 aleph kernel[0]: Finder[109] Unable to clear quarantine 
`TextExpander.prefPane': 30
Nov 10 18:57:37 aleph [0x0-0x1a01a].com.apple.systempreferences[188]: 
No matching processes belonging to you were found
Nov 10 18:57:38 aleph textexpanderd[191]: textexpanderd 2.5 
at your service

Luckily, I managed to decipher this gobbledegook, and a handy reboot allowed the daemon to start without issue. It is documented here for others who might one day run into the same problem.

The other situation I found I need to bounce the machine was with the installation of PostgreSQL. In my orginal instructions, I outlined the steps to create a user account using the dscl command line utility. I unfortunately forgot to include the caveat that a reboot is required to make the user account visible to the system. Yet again, a less than insightful error message was displayed when attempting to initialize the database. I've lost the message, but the gist of it was the inability for postgres to proceed with the initialization because of inadequate shared memory configured on the system. This, needless to say, is not one of the limitations of my machine. Note to self: if the user is not visible from the User dialog, but available from the terminal, this is the issue.

Oh well, such is life.

November 11, 2008

PostgreSQL Addendum

As I installed PostgreSQL using Fink, the user account that I originally create using my previous instructions is not aware of these binaries. The simplest way for pgsql account to be aware of these new binaries is to create a custom .bash_profile file which appends the /sw/bin directory to the PATH environment variable. Create a .bash_profile file in the home directory of the pgsql account with the following contents:

PATH=$PATH:/sw/bin

This should allow you to refer to the PostgreSQL binaries within the Fink installation directory without have to use full qualified path names.

In addtiion, the original startup script required modification of the PGSQL_HOME variable to reflect the new installation's location(/usr/local/pgsql) as well as ensuring that the correct file permissions were enabled on both the service directory and script (which happen to have the same name):

# chmod 555 PostgreSQL

The only other thing that bit me in the ass was the fact that my copy and paste operation didn't work out quite as well as I expected and I was missing the shebang at the top of the script as well as having an orphaned comment. Always check the validity of the script contents.

November 20, 2008

Rubyisms

Most rubyisms are convention based, meaning that they are not strictly enforced by the language/interpreter. Hear is my cheat sheet to help orient those new to ruby with some of these conventions without having to dig through the documentation.

Variables & Class Naming Conventions

  • Local Variables, Methods, and Parameters - always start with a lower case character or an underscore
  • Globals - prefixed with a $
  • Instance Variables - prefixed with a @
  • Class Variables - prefixed with a @@. These type of variables imply that there is only a single instance for the entire class. This does not however, imply public visibility.
  • Class Methods - prefix with class name class.method

Access Control

  • public - no access control; the default visibility applied. The only exception is the initialized method which is always private.
  • protected - limited visibility to an instance of the class and subclasses.
  • private - cannot be called with an explicit receiver. Visible only within the class.

Iterators

Code blocks can be dynamically associated with method invocations. The can be used to implement call backs, pass around chunks of code, and to implement iterators.

Code blocks are delimited by {} or the following key words :

do
   ...
   ...
end

The block is invoked in the receiver with a call to yield.

A callblock has the following form :

{|parameter1, .... parametern| argument1, .... argumentn}

The parameters are the values that will be used by the arguments.

Quirks

  • gets stores the input into a global variable $_
  • $_ is the default input for most cases.
  • don't create your own Observer class .... fucks things up.

Troubleshooting

  • Attribute setter not being called. Within an object, Ruby will parse setter= as an assignment to a local variable, not as a method call. Use self.setter= to indicate the method call.
  • A parse error at the last line of the source often indicates a missing end keyword.
  • Make sure that the type of the object you are using is what you think it is. If in doubt, use Object#type to check the type of an object.
  • Make sure that your methods start with a lowercase letter and that classes and constants start with an uppercase letter.
  • If you happen to forget a ``,'' in an argument list---especially to print---you can produce some very odd error messages.
  • Block parameters are actually local variables. If an existing local of the same name exists when the block executes, that variable will be modified by the call to the block. This may or may not be a good thing.
  • Watch out for precedence, especially when using {} instead of do/end.
  • Make sure that the open parenthesis of a method's parameter list butts up against the end of the method name with no intervening spaces.
  • Output written to a terminal may be buffered. This means that you may not see a message you write immediately. In addition, if you write messages to both $stdout and $stderr, the output may not appear in the order you were expecting. Always use nonbuffered I/O (set sync=true) for debug messages.
  • If numbers don't come out right, perhaps they're strings. Text read from a file will be a String, and will not be automatically converted to a number by Ruby. A call to to_i will work wonders. A common mistake Perl programmers make is:

    while gets
      num1, num2 = split /,/
      # ...
    end
    
  • Unintended aliasing---if you are using an object as the key of a hash, make sure it doesn't change its hash value (or arrange to call Hash#rehash if it does).
  • Use trace_var to watch when a variable changes value.
  • Use the debugger.
  • Use Object#freeze. If you suspect that some unknown portion of code is setting a variable to a bogus value, try freezing the variable. The culprit will then be caught during the attempt to modify the variable.

Performance

These idioms will help close the distance in performance between native code versus interpreted code generated by ruby:
  • Create locals outside of code blocks to prevent reinstantiation of iterator variables.
  • Use the included profiler. This feature can be invoked by either including the -r profile argument to the interpreter or adding the require 'profile' directive to your code.
Got your own Rubyisms? Just add them below.

One Language to Rule them All

Will machines think like human beings, or will human beings begin thinking like machines?

This is an interesting question with rather practical implications to a programmer. Although there are certain advantages understanding the low level mechanics of how computers work, I don't think the relationship between that kind of technical knowledge and being able to write a program are necessarily related. No doubt a relationship exists, but I don't think it follows that knowing one automatically leads to the other.

Perhaps an analogy would better explain what I'm getting at. Technical details are like the study of linguistics compared to programs which are like prose/poetry. Knowing linguistics allows you to describe languages and their components such as verbs, nouns, adverbs, the rules of grammatical correctness, etc. This knowledge however doesn't mean that familiarity with these structural elements will automatically allow you to write meaningfully or expressively. These elements provide the constraints of expression when attempting to articulate an idea, but the articulation of the idea lies outside the bounds of this domain of knowledge. This is the same in programming. Although understanding how a computer functions or a compiler works is useful, it does not follow that you can write useful or meaningful programs just as knowing linguistics won't necessarily let you write literature. So what exactly is the nature of the relationship?

At its core, I think that the relationship can be summed up as follows:

Programming, as an endeavor, is still an exercise in expression.

How you choose to express an idea is as important as the idea itself. Like great literature which is firmly rooted in the language chosen by the author, a program acquires this quality of expressiveness based on the language which forms the foundation of a program. Although great writers sometime "break the rules" when writing literature, it is no different than the clever hacks exploited by programmers to express the difference between constraint and convention.

This idea of language as a source the expression implies that certain languages are better suited to expressing different ideas. No one single language is capable of the full range of expression because, at the point of its creation, the range of future expression is completely unknown. It also follows that languages evolve to fill that gap in expression.

So what is it that programmers seek in languages that they choose to solve problems? Quite simply, languages with real longevity possess an expressive quality that is both aesthetic and technical. Although semantics may vary widely between languages, this "expressiveness" is what programmers implicitly recognize and use to build their conceptual framework on which to hang those semantics. For lack of a better word (and borrowing shamelessly from Neal Stephanson and his novel Snowcrash), this is the Ur quality that is the root of all programming languages.

This brings us back to the question at the beginning of this article. Implicitly, expression is still a very human endeavour. Until this changes, I'm inclined to believe that machines will evolve to express very human ideas which will be reflected in the language we choose to express our intentions to them.

I think in this regard, Ruby is a step in the right direction.

Addendum

Beauty Is Truth In Mathematical Intuition: First Empirical Evidence

I found this article a day after writing this tidbit. Interesting how much the aesthetic guides intuition to the truth.

November 25, 2008

Installing OpenBSD 4.4 on a Soekris 4801

Not a very sexy title, but entirely to the point. It's been a while since I installed on my trusty Soekris 4801 and time has been both kind and capricious by dulling my memory regarding the arcana required to make this combo work. To save myself future frustration, I've decided to document the steps and commit them to the collective unconscious.

Just a little background; I began this project when I retired my rather thirsty and ancient Pentium Pro that served as my personal firewall/gateway for my home LAN a couple of years ago. I wanted a device that would not compromise on security and flexibility (hence the requirement to support OpenBSD) but also consume a reasonable amount of power. Enter the Soekris 4801 - an AMD Geode based embedded system. Base power consumption is 5W - 12W at peek. Not a powerful machine by modern standards, but certainly more powerful than my old system and more than sufficient for my needs. This system was cutting edge in the embedded systems space when I got it, but has been superceded by the newer 5501-60. For the record, the 4801-60 has the following specifications:

  • 233 Mhz i386 compatible AMD Geode CPU
  • 128 Mbyte SDRAM (embedded)
  • 3 SIS 10/100BaseT Ethernet ports (embeded)
  • 2 RS232 Serial extensions with a single 9 pin port
  • 1 32-bit Compact Flash socket
  • 1 44 pin IDE 66 connector
  • 1 Mini-PCI socket
  • 1 3.3V PCI connector
  • 1 1621 dual port SIS 10/100BaseT Ethernet card attached to the PCI connector

Soekris Engineering also manufactures an add-in mini-PCI VPN accelerator (vpn1411), but I haven't gotten around to installing one of these yet. Although, the Soekris is ideally suited for flash based firewall distros, I opted to have a full version of OpenBSD. Storage for the OS is provided through a CF adapter which houses a 6GB Hitachi Microdrive.

Like most embedded systems, there is no built-in support for external peripherals, such as keyboards, mice, and video. All communications happens through one of the two serial ports. Thankfully, the engineers at Soekris were kind enough to wire up a port, otherwise you'd be left to your own devices to rig one up for yourself. The 4801 supports comBIOS, meaning you can use a null serial cable and a communications program (such as minicom) to manage the device through its entire boot cycle. This brings us to my first tidbit; communication parameters. The 4801 supports the following :

19200 8N1
hardware and software flowcontrol off 

Be sure that your communication software is configured with these parameters - their importance will become apparent when we attempt to update the 4801 with the latest BIOS firmware. It is good practice to use the latest vendor supplied firmware to reduce the possibility of potential hardware conflicts. However, without the correct parameters, attempting to update the firmware using the built-in BIOS monitor is impossible and will result in spurious cryptic errors being thrown. There were sites which suggested that the following xmodem parameters be changed to enable communications compatibility with the 4801:

/usr/sbin/sx -vv -b -X

but from my experience, disabling hardware flow control was sufficient to ensure seemless serial communications.

The process for updating the firmware is as follows and assumes that you are already connected to the 4801 through a serial cable :

  1. Download the latest firmware from Soekris.
  2. Reboot the 4801. At the boot prompt, interrupt the boot process using CTRL-P. This will bring up the boot monitor.
  3. The official documentation refers to the download command to initiate file transfer. There is an undocumented option to this command however which will correctly initialize the file transfer session.

    download -

    Failing to provide the additional - argument will result in NAK errors when attempting to establish the communications channel.

  4. Once the file has been uploaded, issue the following command:

    flashupdate
  5. Reboot.

For more detailed instructions, please see the Updating the Soekris BIOS.

As there is no direct way to supply install media directly to the 4801, updating the 4801 requires configuration for PXE booting. At this point, I'd like to point out my second major caveat regarding the upgrade process:

The Soekris 4801 does not support PXE booting on any other interface other than the first ethernet port (ETH1).

I wasted a precious amount of time learning this lesson. Heed it well. This limitation also implies that to upgrade the 4801 requires it being in a network environment where the primary network interface can be configured. If this is not the case (such as when the 4801 resides on the network boundary), you will have to move it. Kiss goodbye to an in-place upgrade.

There are two services that are required to facilitate PXE booting - tftp and dhcp. The DHCP server has to be configured to supply an optional filename to a lease request made from the 4801's primary network interface. This implies that you know the MAC address of this interface. If you do not already have it, you can get it by forcing the 4801 into booting off the network using the BIOS monitor. See below.

The following is an example of a dhcpd.conf file that supports PXE booting

# dhcpd.conf
#
# Configuration file for ISC dhcpd (see 'man dhcpd.conf')
#

## GLOBAL OPTIONS
ddns-update-style ad-hoc;
default-lease-time 1200;
max-lease-time 9600;

subnet 10.0.1.0 netmask 255.255.255.0 
	{
		range 10.0.1.101 10.0.1.200;
		option broadcast-address 10.0.1.255;
		option routers 10.0.1.1;
		option domain-name "domain.com";
	}

host soekris
	{
		hardware ethernet 00:00:24:c3:90:f8;
		fixed-address 10.0.1.100;
		filename "pxeboot";
		option host-name "soekris";
		next-server 10.0.1.10;
	}

Please note the following :

  • The argument to filename is not an absolute path. It is simply the name of the pxeboot file.
  • The next-server option is required.
  • The ddns-update-style global option is required for newer versions of dhcpd.

Following these guidelines when configuring dhcpd will save you from needless troubleshooting.

TFTP is usually managed through inetd/xinetd. Unfortunately, this results in arp network issues. It is recommended that tftpd run in standalone mode to avoid these issues.

The last part of the tftpd configuration requires creating a directory to serve out the pxeboot and bsd.rd files. Keep in mind that by default, tftpd runs as an unprivileged user (such as nobody). Ensure that wherever you place these PXE files, they have appropriate permissions for the daemon to access. Because we are using the console to manage the boot process, this PXE installation also requires an etc directory with a boot.conf file to configure the installer to use the console. The contents of the file are as follows:

stty com0 19200
set tty com0
boot bsd.rd

The order of these configuration parameters is important. The stty must come before the set command.

Believe it or not, at this point, you are ready to install OpenBSD. To get the 4801 to boot over the network requires the following steps:

  1. Reboot. Interrupt the boot process using CTRL-P to enter the BIOS monitor.
  2. Issue the following boot command:

    boot f0
    

I won't belabor the install details; you can get these directly from the main OpenBSD site. There is however one last caveat in this upgrade process: when the installer has completed unpacking the file sets, you are asked whether you want to set the current serial console as the default terminal. Say Yes! If you don't, when the 4801 reboots, it will hang attempting to load the kernel. This unfortunately leads to the boot process simply hanging at the following message:

entry point at 0x200120

Took me a while to figure this out. Hopefully others will not have to suffer quite as much as I did. Thankfully, OpenBSD has finally "modernized" and supplied a cleaner upgrade path than in previous releases. Hurray!!! About fucking time.

November 26, 2008

OpenBSD Cheat Sheet

I always find myself having to dig out the following commands after I've upgraded my systems. Here's my contribution to working smarter, not harder.

Ports

  • Unpack ports.tgz in the /usr directory.
  • The following command will update the ports tree using anonymous cvs:

    # cvs -q -d anoncvs@anoncvs3.usa.openbsd.org:/cvs up -r \
    OPENBSD_4_4 -Pd
    

    For a list of anoncvs servers look here.

  • To find where a package lives in the ports tree, use the following command:

    # make search key=programName
    

    Beats visual grepping all the port directories.

  • To show available package flavors:

    # make show=FLAVORS
    

    To build a flavor:

    # env FLAVOR="flavorName" make install
    

Base System Source Code

  • Unpack src.tgz and sys.tgz in the /usr/src. Do NOT unpack these archives in the /usr directory unless you want trouble.
  • Apply patches from the top of the source tree - /usr/src using the following command:

    # patch -p0 < pathToPatch/001_patchname
    

    The instructions are fairly clear with regards what needs to happen after application of the patch. Don't skip any steps or bad shit will happen.

  • Rebuild the kernel using the following commands:

    # cd /usr/src/sys/arch/i386/conf && config GENERIC && \
    cd ../compile/GENERIC && make depend bsd && mv /bsd /bsd.old && \
    cp bsd /
    

    I usually put this into an executable script in the /usr/src directory so that I can easily rebuild the kernel. You might want to install screen from ports before attempting to run this command on a Soekris 4801 or have the patience of a saint. If you've applied of patches in succession, you can issue a single rebuild instead of rebuilding per patch. That's just masochistic.

About November 2008

This page contains all entries posted to Z1R0 in November 2008. They are listed from oldest to newest.

September 2008 is the previous archive.

December 2008 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.