The information presented here is based on MacOS 10.3.9 and the 10/01 release of Solaris 8. It works for me, but your mileage may vary. If you find this information helpful, or have suggestions to improve the procedure, please drop me a line: osXjumpstart@marget.com
In this walkthrough I'm installing the jumstart tree on /Volumes/Jumpstart. My Solaris distribution media (well, images of same) are mounted on /Volumes/SOL_8_1001_SPARC and /Volumes/SOL_8_1001_SPARC_2. I'm installing a host named jumpclient. Substitute paths and hostnames as appropriate for your environment
1.) Create a Jumpstart Network Location
Your Mac needs to be on a network with a consistent configuration in order for jumpstart to work. I'm using a PowerBook, and will be doing most of my jumpstarting Solarix boxen with just my PowerBook and a network cable, so I need to define a "location" to be used when I'm jumpstarting. If you're working with a servers that don't move around much, then you can probably skip this step.
Click Apple Menu -> Location -> Network Preferences Click Location -> New Location Name of your new location: Jumpstart (OK) Show: Built-in Ethernet Click the TCP/IP tab Configure IPv4: Manually IP Address: 192.168.100.1 SubnetMask: 255.255.255.0 Router: 192.168.100.254 (Apply Now) Quit System Preferences
Now, I know it doesn't seem like it should matter, but the router entry is important. It must be present. With no default route, OSX bootparamd will put 255.255.255.255 in the router field in the responses to WHOAMI requests. The jumpstart will fail. The router doesn't need to exist, but the configuration must be present, and the router must be in the same network as the jumpstart client.
Finally, enter the IP address you've just selected into the hosts file, because add_install_client will look for it there.
$ cat /etc/hosts > /tmp/hosts $ echo 192.168.100.1 osx_jumpstart_server >> /tmp/hosts $ sudo mv /tmp/hosts /etc/hosts $ sudo chown root:admin /etc/hosts
The gotcha with the Solaris jumpstart tree is that it cannot be installed on an HFS filesystem. Unless you've rebuilt your Mac using UFS, you've probably got an HFS filesystem. Not sure which you've got? Try this in the filesystem where you'd like your jumpstart files to live:
$ touch foo $ touch FOO $ ls | grep -i foo
If ls finds both the uppercase and lowercase files, you're okay, and can skip section 2. If ls only returns foo, then you're probably using HFS, and need to jump through the rest of these hoops.
Update: I had previously advised creating the filesystem with a combination of mkfile and the Disk Utility application. Thankfully, Alex Koralewski swooped in to offer this much more elegant solution:
$ hdiutil create -size 1.2g /jump.dmg -type UDIF -fs UFS -volname "Jumpstart" -attach
The size is arbitrary, but the file needs to be at least about this size. There's an incompatibility in the setup_install_server script. It checks for adequate space by comparing the disk blocks reported by /usr/bin/du -s with the KB reported by df, but doesn't realize it's comparing apples and oranges. Rather than fix the script, I just made the file bigger, because I'm sure to dump lots of crap in my jumpstart export later on. This broken space check only happens once.
Update: It turns out that the du vs. df incompatibility was unique to my environment. setup_install_server was finding /sw/bin/du rather than /usr/bin/du. If your du and df -s report the same units, then you should be able to make the image around 650-700MB.
3.) Install the Jumpstart Tree
The Jumpstart tree is installed by the setup_install_server script from the first Solaris CD, and the add_to_install_server script from the second Solaris CD. But it's not quite so simple.
3.1) setup_install_server
3.1.1) The script uses bar for some reason. /usr/bin/tar works fine. Simulate bar with a link from tar.
$ sudo ln -s /usr/bin/tar /usr/bin/bar
$ echo -e "#\0041/bin/sh\nuname -p" > /tmp/mach $ chmod 755 /tmp/mach $ sudo mv /tmp/mach /usr/bin
The setup_install_server script checks the target directory to be sure it's empty. Mac OS tends to leave directories named .Trashes everywhere. The script is not expecting this, and doesn't like it. I'm not sure what makes the .Trashes directories reappear, but they do from time to time.
$ sudo rm -rf /Volumes/Jumpstart/.Trashes
The output of setup_install_server isn't going to be pretty. The spinner doesn't print correctly, and there will be some errors along the lines of adb: command not found. Ignore them. Now would be a good time to get some coffee...
$ cd /Volumes/SOL_8_1001_SPARC/Solaris_8/Tools $ sudo ./setup_install_server /Volumes/Jumpstart
Now we fix the adb errors. The script was trying to figure out the netmask and stuff it in a file. We'll just do that by hand:
$ echo 255.255.255.0 | sudo dd of=/Volumes/Jumpstart/Solaris_8/Tools/Boot/netmask
The next step is to run the add_to_install_server script from the second Solaris CD. This script is a bigger problem than the previous one. For one thing, it uses ksh, which isn't available on 10.3.9, so more likely than not, you won't have it. Incidentally, according to http://www.apple.com/macosx/newfeatures/over200.html ksh does ship with 10.4. Alas, 10.4 was still 2 days away when I was solving this problem. There are undoubtedly other incompatibilities with add_to_install_server, but I can't remember what they were. Instead, I gutted the script and did minimal patching to get it to work. I suggest you download my hacked up version and diff it carefully against the one on your Solaris media -- I might have done something stupid. Some of the functionality was lost in the butchering, but it should install the second disk correctly. Be sure to run it from the root of the second Solaris CD, because one of the things I gutted was the bit that determines from where it's being run.
$ cd /tmp $ wget http://logsoft.com/chris/osx_jumpstart/add_to_install_server $ chmod 755 ./add_to_install_server $ cd /Volumes/SOL_8_1001_SPARC_2 $ sudo /tmp/add_to_install_server /Volumes/Jumpstart
/usr/sbin/portmap is needed by several of the other system daemons, namely bootparamd, mountd and nfsd. Start it before starting the others, like this:
$ sudo /usr/sbin/portmap
bootparamd provides diskless clients with location information for files they need on bootup. It works like this:
Now, Sun stretches this protocol a little bit. Jumpstart clients use bootparamd to get other kinds of information, Like NFS mount options. A Solaris Jumpstart boot server has this additional directive for each client:
rootopts=:rsize=32768
Note that the fileserver portion, which should be between the '=' and ':' is missing, and 'rsize=32768' certainly isn't a path to a file.
The MacOS bootparamd will choke on this syntax, but we can make it work. The first step is to define a host with address 0.0.0.0:
$ sudo nicl / create /machines/blackhole ip_address 0.0.0.0
The second step is to change any bootparams with no host portion. So rootopts=:rsize=32768 becomes rootopts=blackhole:rsize=32768. The modified add_install_client will take care of this.
Now, the bootparam exchange looks like:
That's pretty close to what Solaris bootparamd does. The key differences are that Solaris doesn't return the hostname. That portion of the reply packet is blanked out. Jumpstart clients don't seem to mind seeing a server name here.
One final thing about bootparamd. It doesn't read /etc/bootparams. It pulls parameters from NetInfo. ...But niload, which claims to know how to parse bootparams data, loads the parameters wrong. According to the man page, you should be able to populate /etc/bootparams, and then do this:
niload bootparams < /etc/bootparams
That pretty much works, with one fatal flaw. It loads the string of bootparams as a single value to the property bootparams in the NetInfo directory /machines/clientname. The correct behavior would be to have many values associated with the property bootparams. For example, if your /etc/bootparams contains:
client_name root=servername:/path/to/root install=servername:/path/to/install
The way niload reads these values, bootparamd would return an answer to a 'root' query from 'client_name' with: "Hello, client_name, your file 'root' can be found on server 'servername' at location '/path/to/root install=servername:/path/to/install'"
Obviously not what we're looking for. The modified add_install_client will take care of this as well, but I thought it worth mentioning, because it cost me the most time, and because I think it's really broken.
bootparamd caches the route information that it learns from running netstat -r -n. Make sure your location stuff in step 1 is correct before starting bootparamd. Use the -d flag for debugging output.
Start bootparamd:
$ /usr/sbin/bootparamd
Check for bootparamd in the output of:
$ rpcinfo -p localhost
The jumpstart boot server needs to run tftp. I've been running the Mac OS built-in tftpd for a while, so I don't remember exactly what it took to get it going. At a minimum, you'll need to create /tftpboot, and enable the tftp service within xinetd. I think this should do it:
$ mkdir /tftpboot $ sudo /sbin/service tftp start
rarpd processes rarp (what is my ip address?) requests from jumpstart clients. It requires:
If all those tests pass, rarpd will send a response to the client, and the client will tftp to the server who answered the rarp query. The setup_install_client script should be taking care of those first 3 requirements. The fourth depends on your MacOS "Jumpstart" network location in step 1.
I run rarpd on interface en0 only. rarpd has seemed unhappy about finding my Airport interface (en1) switched off, and if I switch the Airport on, it will join a network and screw up the default route that's so critical from step 1. If you want to run rarpd on all interfaces, run rarpd -a. For debugging output, use the -d flag.
Start rarpd:
$ sudo /usr/sbin/rarpd en0
Partway through the installation, a Jumpstart client runs the /sbin/get_netmask program while it's setting up its interfaces. This program sends an ICMP type 17 message to the server. By default, your Mac won't answer, and the install will hang with a spinning dial thing forever. The solution is to enable replies:
$ sudo sysctl -w net.inet.icmp.maskrepl=1
We need to export the Jumpstart directory to the client. Here's how:
$ sudo nicl / create /exports/\\/Volumes\\/Jumpstart opts maproot=root:wheel,ro,alldirs
The options here are important:
$ sudo nicl / append /exports/\\/Volumes\\/Jumpstart clients nfs_client_name
$ nicl / cat /exports/\\/Volumes\\/Jumpstart name: /Volumes/Jumpstart opts: maproot=root:wheel,ro,alldirs clients: clientA clientB clientC jumpclient clientD
Make sure the name field points exactly to the top of your Jumpstart tree, and that the options look good. You may or may not see the clients: line, depending on what you've done so far.
9.5) nfsd and mountd
Now that the export is fully defined, we can (re)start nfsd and mountd. Having the declarations in NetInfo may cause the daemons to come up automagically on boot. I haven't bothered to reboot to test.
If mountd and nfsd are already running:
$ sudo kill -1 `cat /var/run/mountd.pid `if nfsd and mountd are not running:
$ sudo /sbin/nfsd -t -u -n 6 $ sudo /usr/sbin/mountdCheck for nfsd and mountd in the output of:
$ rpcinfo -p localhost
From here on out, it's regular jumpstart stuff: sysid stuff, rules stuff, etc... I haven't yet ported the check script to MacOS. I usually just create that by hand.
You'll need my modified add_install_client script. Understand that I provide no warranty or support, then get it here: add_install_client
$ cd /Volumes/Jumpstart/Solaris_8/Tools $ mv add_install_client add_install_client.orig $ wget http://logsoft.com/chris/osx_jumpstart/add_install_client
Finally, we're ready to set things up a new jumpstart client. I will call him jumpclient
$ sudo nicl / create /machines/jumpclient ip_address 192.168.100.15 $ sudo ./add_install_client -c 192.168.100.1:/Volumes/Jumpstart \ -p 192.168.100.1:/Volumes/Jumpstart/sysidcfg.d/core\ -e 8:0:20:fa:72:4c jumpclient sun4u
I use a USB->Serial port adapter made by iConcepts. It's got the pl2303 chipset from Prolific. It works great, with one exception: the rs-232 BREAK signal doesn't seem to be implemented by the driver. This is a real bummer if you're trying to use it to install Sun boxes. Well, it turns out there's a way around this problem. A BREAK signal involves setting voltage on the serial TX line, and holding it there way too long. We can accomplish the same thing by sending ASCII '0x00' (NUL) at a way too-low baudrate.
Dave Alverson's wonderful ZTerm application for OSX includes this functionality built right in. To enable it, simply:
$ defaults write com.mac.dalverson.ZTerm breakSim '300'
Thanks to Duane Grant for turning me on to ZTerm and the BREAK via baudrate-switcheroo.
11.2) Firewall
All of this can certainly be made to run with the firewall enabled. I have not bothered to try it because my jumpstarting usually involves my PowerBook, a crossover cable, and a blank Sparc. Not much risk of being attacked. Disable the firewall.