Article sep2006.tar

Questions and Answers

Amy Rich

Q We have around 500 Solaris servers running various different versions of Solaris (ranging from 8 to 10). To automate installs, we use a custom JumpStart process, which we're just now updating to use DHCP instead of RARP. I'm trying to set up ISC DHCP 3.0.4 on an existing Solaris 9 JumpStart server, and I have a couple of questions and at least one issue that I hope you can help with.

First, is there a way I can break out types of machines by the version of the OS that should be installed on them so that I don't need to set things like the install media location for every single client?

Second, is there a way I can consolidate all of this information into LDAP instead of using the dhcpd.conf file? We already keep so much of our configuration data in LDAP that this would make much more sense for us.

And third, on to the issue I'm having... I've set up one client that gets part way through the JumpStart then fails. It looks like some of the important Solaris-specific variables aren't being set. Here's my current dhcpd.conf file, set up for one Solaris 9 host:

 
pid-file-name "/var/run/dhcpd.pid"; 
lease-file-name "/usr/local/etc/dhcpd.leases"; 
default-lease-time 43200; 
max-lease-time 86400; 
ddns-update-style none; 

# JumpStart Support 
option space SUNW; 
option SUNW.root-mount-options code 1 = text; 
option SUNW.root-server-IP code 2 = ip-address; 
option SUNW.root-server-hostname code 3 = text; 
option SUNW.root-path code 4 = text; 
option SUNW.swap-server-IP code 5 = ip-address; 
option SUNW.swap-file-path code 6 = text; 
option SUNW.boot-file-path code 7 = text; 
option SUNW.timezone code 8 = text; 
option SUNW.boot-read-size code 9 = unsigned integer 16; 
option SUNW.install-server-IP code 10 = ip-address; 
option SUNW.install-server-hostname code 11 = text; 
option SUNW.install-path code 12 = text; 
option SUNW.sysidcfg-server code 13 = text; 
option SUNW.JumpStart-server code 14 = text; 
option SUNW.terminal-type code 15 = text; 
option SUNW.boot-URI code 16 = text; 
option SUNW.HTTP-proxy code 17 = text; 

subnet 192.168.100.0 netmask 255.255.255.0 { 
  option broadcast-address 192.168.100.255; 
  next-server 192.168.100.2; 
} 

host clienthost { 
  filename "inetboot.SUN4U.Solaris_9-1"; 
  hardware ethernet 0:3:ba:35:cd:23; 
  fixed-address 192.168.100.18; 
  option host-name "clienthost.my.domain";
 
  vendor-option-space SUNW; 
  option SUNW.root-mount-options "rsize=32768"; 
  option SUNW.install-server-hostname "jsserver.my.domain"; 
  option SUNW.install-server-IP 192.168.100.2; 
  option SUNW.root-server-hostname "jsserver.my.domain"; 
  option SUNW.root-server-IP 192.168.100.2; 
  option SUNW.JumpStart-server "192.168.100.2:/install/JumpStart"; 
  option SUNW.terminal-type "vt100"; 
  option SUNW.sysidcfg-server "192.168.100.2: /install/JumpStart/ \
    sysidcfg/SunOS-5.9"; 
  option SUNW.install-path "/install/media/SunOS-5.9-sparc"; 
  option SUNW.root-path \
"/install/media/SunOS-5.9-sparc/Solaris_9/Tools/Boot"; }
When the client boots, it reports the wrong location for the sysidcfg file and the install fails:
 
ok boot net:dhcp - install
 
Executing last command: boot net:dhcp - install  
Boot device: /pci@1f,0/ethernet@c:dhcp  File and args: - install 
Timeout waiting for BOOTP/DHCP reply. Retrying ... 
Timeout waiting for BOOTP/DHCP reply. Retrying ... 
Timeout waiting for BOOTP/DHCP reply. Retrying ... 
SunOS Release 5.9 Version Generic_118558-11 64-bit 
Copyright 1983-2003 Sun Microsystems, Inc.  All rights reserved. 
Use is subject to license terms. 
WARNING: pmap_kgetport: Portmapper not responding; still trying 
Configuring /dev and /devices 
Using DHCP for network configuration information. 
Searching for configuration file(s)... 
Using sysid configuration file /sysidcfg 
Search complete. 
The system is coming up. Please wait. 
Begin system identification... 
Starting remote procedure call (RPC) services: sysidns done. 
System identification complete. 

Generating software table of contents [this may take a few minutes...] 
Table of contents complete. 
Starting Solaris installation program... 
Searching for JumpStart directory... 
not found 
Warning: Could not find matching rule in rules.ok 
Press the return key for an interactive Solaris install program... 
If I boot into single-user mode and run dhcpinfo for each of the values I've set, only some of them appear:
 
ok boot net:dhcp -s 
... 
 
# for i in SrootOpt SrootIP4 SrootNM SrootPTH SswapIP4 SswapPTH 
  SbootFIL Stz SbootRS SinstIP4 SinstNM SinstPTH SsysidCF SjumpsCF 
  Sterm SbootURI SHTTPproxy; do 
> echo "$i:"; /sbin/dhcpinfo -c $i 
> done 

SrootOpt: 
rsize=32768 
SrootIP4: 
192.168.100.2 
SrootNM: 
jsserver.my.domain 
SrootPTH: 
/install/media/SunOS-5.9-sparc/Solaris_9/Tools/Boot 
SswapIP4: 
SswapPTH: 
SbootFIL: 
Stz: 
SbootRS: 
SinstIP4: 
192.168.100.2 
SinstNM: 
jsserver.my.domain 
SinstPTH: 
/install/media/SunOS-5.9-sparc 
SsysidCF: 
192.168.100.2:/install/JumpStart/sysidcfg/SunOS-5.9 
SjumpsCF: 
Sterm: 
SbootURI: 
SHTTPproxy: 
As you can see, it's neglecting to set some important vendor macros like SjumpsCF. The installation obviously won't work without the correct setting there. It does, however, set the sysidcfg-server macro correctly. I'm at a loss to explain why some things are getting set and others aren't, and why the ones that are getting set correctly don't appear to be read correctly at boot time.

I do know that this JumpStart server can install hosts fine via RARP, and I'm using the exact same settings for DHCP, so I'm guessing this is something to do with DHCP itself, not a problem with the parameters I've set for the sysidcfg, media location, etc.

Any help you can offer with any of these things is greatly appreciated.

A Starting with your first question about splitting things out into logical groups by operating system -- yes, you can define groups within the dhcpd.conf file and place hosts within those groups. The hosts will inherit the settings from the group block.

It looks like you're designating all of 192.168.100.0/24 as your JumpStart network, so I'd put a number of the definitions within the subnet definition. Guessing which bits are tied to OS-specific or JumpStart server-specific settings based on your naming convention, here's what I'd suggest for your dhcpd.conf file to support Solaris 8, 9, and 10:

 
pid-file-name "/var/run/dhcpd.pid"; 
lease-file-name "/usr/local/etc/dhcpd.leases"; 
default-lease-time 43200; 
max-lease-time 86400; 
ddns-update-style none; 

# JumpStart Support 
option space SUNW; 
option SUNW.root-mount-options code 1 = text; 
option SUNW.root-server-IP code 2 = ip-address; 
option SUNW.root-server-hostname code 3 = text; 
option SUNW.root-path code 4 = text; 
option SUNW.swap-server-IP code 5 = ip-address; 
option SUNW.swap-file-path code 6 = text; 
option SUNW.boot-file-path code 7 = text; 
option SUNW.timezone code 8 = text; 
option SUNW.boot-read-size code 9 = unsigned integer 16; 
option SUNW.install-server-IP code 10 = ip-address; 
option SUNW.install-server-hostname code 11 = text; 
option SUNW.install-path code 12 = text; 
option SUNW.sysidcfg-server code 13 = text; 
option SUNW.JumpStart-server code 14 = text; 
option SUNW.terminal-type code 15 = text; 
option SUNW.boot-URI code 16 = text; 
option SUNW.HTTP-proxy code 17 = text; 

subnet 192.168.100.0 netmask 255.255.255.0 { 
  vendor-option-space SUNW; 
  option broadcast-address 192.168.100.255; 
  option SUNW.root-mount-options "rsize=32768"; 
  option SUNW.install-server-hostname "jsserver.my.domain"; 
  option SUNW.install-server-IP 192.168.100.2; 
  option SUNW.root-server-hostname "jsserver.my.domain"; 
  option SUNW.root-server-IP 192.168.100.2; 
  option SUNW.JumpStart-server "192.168.100.2:/install/JumpStart"; 
  option SUNW.terminal-type "vt100"; 
  next-server 192.168.100.2; 
} 

## Solaris 8 SPARC global 
group { 
  filename "inetboot.SUN4U.Solaris_8-1"; 
  vendor-option-space SUNW; option SUNW.sysidcfg-server \ 
     "192.168.100.2:/install/JumpStart/sysidcfg/SunOS-5.8"; 
  option SUNW.install-path "/install/media/SunOS-5.8-sparc"; 
  option SUNW.root-path \
     "/install/media/SunOS-5.8-sparc/Solaris_9/Tools/Boot"; 

  # Solaris 8 SPARC hosts 
  host client8 { 
    hardware ethernet xx:xx:xx:xx:xx:xx; 
    fixed-address 192.168.100.xxx; 
    option host-name "client8.my.domain"; 
  } 
} 

## Solaris 9 SPARC global 
group { 
  filename "inetboot.SUN4U.Solaris_9-1"; 
  vendor-option-space SUNW; 
  option SUNW.sysidcfg-server \
     "192.168.100.2:/install/JumpStart/sysidcfg/SunOS-5.9"; 
  option SUNW.install-path "/install/media/SunOS-5.9-sparc"; 
  option SUNW.root-path \ 
     "/install/media/SunOS-5.9-sparc/Solaris_9/Tools/Boot"; 

  # Solaris 9 SPARC hosts 
  host client9 { 
    hardware ethernet xx:xx:xx:xx:xx:xx; 
    fixed-address 192.168.100.xxx; 
    option host-name "client9.my.domain"; 
  } 
} 

## Solaris 10 SPARC global 
group { 
  filename "inetboot.SUN4U.Solaris_10-1"; 
  vendor-option-space SUNW; 
  option SUNW.sysidcfg-server \
     "192.168.100.2:/install/JumpStart/sysidcfg/SunOS-5.10"; 
  option SUNW.install-path "/install/media/SunOS-5.10-sparc"; 
  option SUNW.root-path \ 
     "/install/media/SunOS-5.10-sparc/Solaris_10/Tools/Boot"; 

  # Solaris 10 SPARC hosts 
  host client10 { 
    hardware ethernet xx:xx:xx:xx:xx:xx; 
    fixed-address 192.168.100.xxx; 
    option host-name 
    "client10.my.domain"; 
  } 
} 
    
To store all of this information in LDAP instead of using a flat dhcpd.conf file, you can recompile ISC DHCP with Brian Masney's ISC DHCP LDAP patch, found at:
 
http://personal.cfw.com/~masneyb/dhcp-3.0.4-ldap-patch 
    
If you go this route, each configuration is stored based on the DHCP server host name. If you want to write your own implementation/patch from scratch, you might want to think about using LDAP groups and storing information in a tree based on the client hostname instead (which makes more sense if you approach this as an LDAP organizational problem and not a direct translation of the dhcpd.conf into LDAP).

The aforementioned patch includes a schema for OpenLDAP (you may need to tweak things if your LDAP server is not running OpenLDAP) and a script called dhcpd-conf-to-ldap.pl, which will take your flat file dhcpd.conf and translate it into an LDIF-formatted file. Once you patch the ISC DHCP source, take a look at the Changelog-LDAP and README.ldap files for more information on how to set up the DHCP tree within LDAP and what should go in the dhcpd.conf file on each of your DHCP servers.

Lastly, we come to the issue you're having jumpstarting your Solaris 9 client. Based on the information you provide, you're probably exceeding the Solaris DHCP client vendor options definitions limit of 256 bytes. If you reduce the length of your path names and/or use unqualified host names for the JumpStart server, your problem will likely disappear. I'd suggest rearranging your directory structure layout or just using symlinks. You might also investigate not setting parameters that you don't really need (like rsize).

Q As part of creating a Solaris package file, we need to remove some files from another package which conflict with this one. I can install over the files or remove the old files first, but they're still listed as dependencies in the software database. I'm not keen on editing /var/sadm/install/contents directly (and I'm not even sure that will work), so I was wondering about the best way to handle this sort of situation.

A If you're no longer going to be using any files from the conflicting package, have your preinstall script check for the old package and remove it if it exists. If you're only overlapping on a select few files from the already-installed package, you can write a preinstall script that uses the removef command to clear dependencies in the software database and then use rm to actually delete the files (or install over them).

The example from the removef man page should work pretty well for your purposes (substitute your already-installed package name for $PKGINST and your list of files for /dev/xt[0-9][0-9][0-9] below):

 
removef $PKGINST /dev/xt[0-9][0-9][0-9] | 
while read pathname 
do 
  echo "$pathname"
  rm -f $pathname 
done 
removef -f $PKGINST || exit 2 
    
Amy Rich has more than a decade of Unix systems administration experience in various types of environments. Her current roles include that of Senior Systems Administrator for the University Systems Group at Tufts University, Unix systems administration consultant, author, and charter member of LOPSA. She can be reached at: qna@oceanwave.com.