SambaX

Links and Downloads

samba.sh (download)
kicker-samba.xml (download)

Problem:
When my IP address changes, Samba stops responding.
Solution:
Restart Samba every time my IP address changes.
Better Solution:
Use configd to restart Samba automatically when my IP address changes.

Note

This worked at one point. I haven't verified this on Panther. Also, since Jaguar, Mac OS X has had support for Samba built in which kind of makes this discussion obsolete. I mostly keep this around for the kicker and configd banter./p>

Background

I started noticing this problem when I began moving my laptop between networks at home and work. Initially, I would just use the Samba Sharing control panel to stop and then start the smbd and nmbd daemons. Unfortunately this is somewhat cumbersome and really isn't necessary. After a few weeks of poking around on and off, I have found a better solution.

Disclaimer

This only works with version SambaX v2.2.2. The newest release from the Xamba project does not work with the method that I am about to describe. However, you can always roll back to the previous version. I assume at this point that you have installed SambaX and SSCT, and that you have at least one working configuration.

configd

configd is a daemon that I believe is unique to Darwin-based systems. Its purpose is to provide configuration information dynamically to applications and other daemons. Essentially it is a local server that exports information stored using the SystemConfiguration framework. Here is a brief list of exported data:

There are several ways to access this information:
  1. The SystemConfiguration.framework itself, which is part of CoreFoundation. This allows an application to interact directly with configd, but requires code modifications. This is a good choice if you've got time on your hands and want to make your application very robust. However, it is Darwin-specific, and thus not readily available on other systems like Linux, or other BSD distrobutions.
  2. scutil is command line interface to configd. It seems mostly for debugging purposes, but it can be used to extract basic information from configd in a rudimentary fashion.
  3. /var/db/SystemConfiguration/preferences.xml is the persistant store for SystemConfiguration data. I wouldn't interact directly with (as in, make changes to) this file, but it can be handy to peruse if you are looking for a specific piece of data.
configd has a farily simple plugin architecture which uses bundles to provide additional functionality. There are a number of bundles installed with Mac OS X - the most useful, for my purposes, is the Kicker.bundle.

Kicker

The Kicker is essentially a narrow bridge between the information available from the SystemConfiguration and the wonderful world of command line tools. The interesting files reside in /System/Library/SystemConfiguration/Kicker.bundle/Resources. The most important file is Kicker.xml, which essentially ties SystemConfiguration events to executing a particular shell script.

Kicker.xml is basically an array of dictionaries. 1 Each dictionary supports a number of keys, each of which are required, as far as I can tell:

samba.sh

This is a small script to control the Samba daemons via the command line. It has been written to accept arguments from either the Kicker or the command line directly. The two keys we are interested in are:

A notification on the key State:/Network/Global/IPv4 indicates that the primary IP address for the machine has changed. The shell script reacts by terminating all running instances of smbd and nmbd, and then restarting them as root.

The second one informs us that someone, most likely the user, has altered the system location, most likely via the Location option in the System menu or the Network System Preferences. In this case, the shell script extracts the name of the selected location and attempts to find a Samba configuration with a matching name. If a match is found, it switches the active configuration and restarts the daemons.

Installing the Files

The only file you need to modify, Kicker.xml, is stored within /System/Library/SystemConfiguration/Kicker.bundle/Resources/

Simply edit the Kicker.xml file, (sudo vi Kicker.xml) and place your control script in a well defined location.

The shell variable $BUNDLE resolves to /System/Library/SystemConfiguration/Kicker.bundle and can be used to simplify the path to your shell script, if you store it within the Kicker bundle.

Once you have made the changes, you can issue the following command to reset configd and reload the kicker.

Footnotes

  1. While I am glad that Apple has decided to use xml for some of its configuration files, I have to say that at the same time, they seemed to have missed the point a bit. Their xml files, or plist, are highly suited to mapping back into CoreFoundation objects, like arrays, dictionaries and strings. However, one of the goals of xml is to make files more human readable. Apple has made steps in the right direction - at least we are beyond binary preferences in resource forks, however, I personally would have been inclined to use an even more human readable format, supplying a DTD and an XSL to convert from human-readable to more machine friendly. Obviously, this is just an opinion, and it has limitations as well.