Altering the Boot Process
This section demonstrates how to augment the client's boot image to make it suitable for use as a platform for system recovery operations:
Modify the option and argument processing during boot
Provide services and daemons
Provide an interactive shell
It is important to note that the following modifications to the client's boot image offer additional functionality. The default functionality of the client's boot image remains unchanged, and you can still use the client's boot image to install the Solaris OE.
The first challenge in transforming the install boot image into a boot image suitable for recovery operations is to change the boot process, or startup process, of the miniroot. The client should come up to multiuser mode, yet not enter the default action of beginning the installation process. To take control away from the default boot process, you must modify the scripts that run at startup time on the client.
Processing Options and Arguments During Boot
The first task in converting the install boot image into a recovery boot image is to augment the boot process with a "recover" mode. You do that by altering the boot parameter processing logic in the startup scripts. For example, the OBP boot command, boot net - install, is normally used to perform a JumpStart (network) boot and installation. The install argument is passed through the kernel and to init as the system startup scripts are executed. We want to find where that argument is parsed and add logic to allow other keywords (such as recover).
The OBP passes options to the kernel, such as the -s (boot to single-user mode) and -r (initiate a device tree rebuild and kernel reconfiguration) options. In this instance the kernel is genunix, the miniroot. The OBP passes arguments along to the kernel as well. Since the kernel does not process command-line arguments (it only processes the options it recognizes), the arguments are ignored by the kernel and passed along to init. To prevent confusion, kernel switches and arguments are separated by a lone dash, which is why the space following the minus character (-) is crucial in the command boot net - install.
In turn, init passes all arguments on to the scripts that it calls. FIGURE 0-1 shows an overview of the startup process.
FIGURE 0-1 Overview of the Startup Process
By using the processing control table used by init, $ROOTDIR/etc/inittab, as a road map to the startup processing, you can determine that $ROOTDIR/sbin/rcS is where the argument processing takes place. The portion of $ROOTDIR/sbin/rcS relevant to the argument processing is as follows:
set -- "" set -- '/sbin/getbootargs 2>/dev/null' if [ $# -gt 0 ] ; then while [ $# -gt 0 ] ; do case $1 in FD=*) # at end of script, save root dev in /tmp/.preinstall # this is an unambiguous indication of stub boot FJS_BOOT="yes" From='(IFS="="; set -- $1; echo "$2 $3 $4 $5" )' break ;; browser) cat < /dev/null > /tmp/.install_boot cat < /dev/null > /tmp/.smi_boot shift ;; install) INSTALL_BOOT="yes" cat < /dev/null > /tmp/.install_boot shift dhcp) TRY_DHCP="yes" shift ;; tape*) echo "$1" >/tmp/.cjfiles_method shift ;; mansysid) cat < /dev/null > /tmp/.manual-sysid shift ;; w) cat < /dev/null > /tmp/.nowin shift ;; *) shift ;; esac done fi
It is now relatively straightforward to add recognition and processing for the recover argument by adding another "word" to the case statement. The modified section of $ROOTDIR/sbin/rcS is as follows:
set -- "" set -- '/sbin/getbootargs 2>/dev/null' if [ $# -gt 0 ] ; then while [ $# -gt 0 ] ; do case $1 in FD=*) # at end of script, save root dev in /tmp/.preinstall # this is an unambiguous indication of stub boot FJS_BOOT="yes" From='(IFS="="; set -- $1; echo "$2 $3 $4 $5" )' break ;; browser) cat < /dev/null > /tmp/.install_boot cat < /dev/null > /tmp/.smi_boot shift ;; recover) cat < /dev/null > /tmp/._recover_startup shift ;; install) INSTALL_BOOT="yes" cat < /dev/null > /tmp/.install_boot shift dhcp) TRY_DHCP="yes" shift ;; tape*) echo "$1" >/tmp/.cjfiles_method shift ;; mansysid) cat < /dev/null > /tmp/.manual-sysid shift ;; w) cat < /dev/null > /tmp/.nowin shift ;; *) shift ;; esac done fi
It is important to note that almost no action is performed within the case statement or $ROOTDIR/sbin/rcS. As in the case of the install argument, the processing of the recover argument consists only of creating a state file (or flag file). Using this mechanism eases the decision process in scripts executed later, without the need to parse the arguments directly. If recovery scripts or tools must start automatically on a recovery boot or if scripts must determine the state of the system and take appropriate action, these scripts only need to check for the existence of the file /tmp/._recover_startup to determine the system's state. Because this method of modifying $ROOTDIR/sbin/rcS reduces complexity and minimizes the opportunity for human error in modifying the crucial $ROOTDIR/sbin/rcS script, it is strongly recommended that you use the same or a similar approach whenever adding additional startup processing.
Providing Services for Recovery
The default boot process does not start any service daemons that are not required by the Solaris OE installation process. However, some of these daemons may facilitate or are needed during a system recovery operation. For example, the Internet service daemon, inetd, is not needed for installation. However, a recovery operation is greatly facilitated by having inetd start automatically on a recovery boot.
Unfortunately, daemons can be started from many scripts and there is no reference or mapping of where a particular daemon may be started. However, most of the standard or common Solaris OE daemons are present, but commented out (referred to as stubbed), in the startup scripts executed by init. The only recourse is to follow the execution flow of the scripts launched by init to locate what services are started from which scripts, uncommenting the required daemons. For example, inetd is present but commented out in $ROOTDIR/sbin/sysconfig. To start inetd during a recovery boot, modify $ROOTDIR/sbin/sysconfig (at the point where inetd startup is commented out), as follows:
if [ -f /tmp/._recover_startup ] ; then /usr/sbin/inetd -s fi
Starting inetd is sufficient for the most common network services. "Adding a Recovery Tool" on page 26 gives an example of adding additional services. If a service or daemon is required at startup but is not stubbed in one of the startup scripts, you must add the invocation to the startup processing. If it is necessary to add a call to a script or the execution of a command, it is recommended that the addition be done as late as possible in the startup sequence to avoid impacting dependencies or setup work that services may have on other services or daemons. For example, many network services require that sysidnet has been run, which implies the presence of a name service or sysidcfg file.
Providing an Interactive Shell
The default installation boot image enters the installation utility (suninstall) at the end of its startup processing. To have the default installation boot image act as a recovery platform, you will find it advantageous to provide an interactive shell rather than to execute suninstall. To provide the interactive shell, add the following lines to the end of $ROOTDIR/sbin/sysconfig.
if [ -f /tmp/._recover_startup ] ; then echo "Starting interactive Korn shell..." exec /bin/ksh -o vi fi