Building A Customized Bootable Solaris CD

By Kevin Maher

I spent a week at work researching on how to build a bootable CD for Solaris. My goal was to be able to automate system recovery in the case of a disaster (even a hard disk failure can be considered a disaster, not just major weather events or terrorism). We were ordered to be able to script a restoration for our critical systems. Since this would require restoring at least part of the OS, I felt that I could automate the entire system by simply dropping a CD into the drive.

Easier said than done, but mission accomplished!

I did manage to find several documents around the web detailing how to build a customized bootable CD. Turns out that it's more of a hack than a real boot CD, but for my purposes, it works, and I won't complain. First, as background materials, I do recommend that you read through my predecessors work before you start delving into what I've done to change it. The hack I referred to comes from the fact that we must pick apart a working CD, then work within the boundaries established by its VTOC, then piece a working image back together utilizing the original's VTOC and other UFS based slices.

From Lukas Karrar's personal page (the first reliable source I located)
      Burning a bootable CDRom for Solaris

From SunMANAGERS mailing list:
      SUMMARY: How to build a Solaris bootable CDROM

From the Sun Blueprints Collection
      Building a Bootable Jumpstart Installation CD-ROM

Since I would be repeating the processes already documented in these 3 papers, I'll skip most of the details of the prep work. Needless to say, you will need a few things on your system in order to build your new CD image. The CD recorder does not have to be on the Sun host, as you can copy the final image over to any PC with a recorder and burn the CD there. However, you will need the software mkisofs, which is freely available, but also comes pre-packaged with Solaris 8. You will also need a minimum of 2G free disk space to stage your new CD image. I actually built 2 2G partitions that I worked between, but do what you feel comfortable with.

I started by setting up my test system with my external 8mm tape drive attached and also added my old Yamaha CDR-400 drive. It's only 4x, but for testing, it's more than adequate. If you have read through the prior documents, perform all of the steps necessary to build your staging area and copy the data from your master CD (this will work for Solaris 2.5, 2.6, or 7).

Update! - I have determined that Solaris 8 can be done as well. The only trick is that you have to use CD #1, not the boot/install CD. The installation CD is just the webstart and miniroot, and doesn't have the same format as the 2.5 through 7 installation CDs. However, CD #1 does and is also bootable, so just use it and follow the same processes documented here and elsewhere.

Hacking up the boot process

Now the fun part begins. After I had copied all of the data to the hard drive, I began sifting through file after file trying to determine exactly how the system was starting things up, and where I could begin editing. I finally located what I needed. On the CD, in the directory /cdrom/<volume_name>/<Solaris_version>/Tools/Boot is located all of the files you need to change. These files on slice 0 are overlayed into the miniroot created from slice 1 on /usr.

After a few attempts, which all worked as boot CDs, but didn't do anything different than a normal CD, I finally managed to locate the script that starts the OpenWindows environment. This script, on the last line, opens the "Solaris Install Console" window in the upper left of the screen, and spawns the sysconfig script (which then spawns the suninstall script). The script is <..>/Tools/Boot/usr/sbin/install.d/openwin-init. I edited this file and edited the last line to start my custom script instead of sysconfig. I put my script in the <..>/Tools/Boot/usr/bin directory, but I could have been a bit more adventuresome and created <..>/Tools/Boot/usr/local/bin instead. I then burned my CD and made a test. As with the preparation steps, the steps in burning the CD are well documented in the 3 papers mentioned at the beginning. I was glad to see that I had finally hit the nail on the head. Aside from a few scripting errors and omissions, I had essentially accomplished what I was after. A few more iterations later, and I had my finished product.

Post Mortem Analysis

As with any process, an analysis after the fact can reveal its success or failure. While I had succeeded in my goals, I continued to scan through the CD's structure. There is always a better way of doing things. For example, since my script completely automates the process of the system restoration (partitioning/formatting disks, mounting partitions, restoring said partitions), I hardly need the openwin environment. My next revision will probably invoke my script in place of starting openwin entirely. Not only will this speed things up, I could even consider erasing all of the openwin files from my CD leaving me more room for other things.

Scripting Details

Since this is of potential use to somebody, I'll put some of the details of my script here. None of it is particularly complicated. What I needed to do was automatically partition a hard disk, format those partitions, temporarily mount them, and then restore from backup tape to the hard drive. Sounds simple enough, but some of the commands were not intended to be executed unattended. I did find a way to do it.

To format the drives (misnomer actually, since I'm creating partitions - like FDISK), I read through the man page and saw that several of the parameters allow me to pick a specific disk, specify a format table (ie: format.dat), and also a command file. That command file was actually the trick, since it allowed me to script the basic changes like I could using expect. I created my format table with data from each workstation. First, on each Sun host, I run the format command and give the partition table a unique name. I then save the data to the file /tmp/<hostname>.dat. I then combined all of this data from all of my systems into one single file.

disk_type = "SUN2.1G" \
	: ctlr = SCSI : fmt_time = 4 \
	: ncyl = 2733 : acyl = 2 : pcyl = 3500 : nhead = 19 : nsect = 80 \
	: rpm = 5400 : bpt = 44823

disk_type = "ST39140A" \
	: ctlr = ata : ncyl = 17660 : acyl = 2 : pcyl = 17662 \
	: nhead = 16 : nsect = 63 : rpm = 5400

disk_type = "SUN18G" \
	: ctlr = SCSI : ncyl = 7506 : acyl = 2 : pcyl = 7508 \
	: nhead = 19 : nsect = 248 : rpm = 7200

partition = "ultra1" \
	: disk = "SUN2.1G" : ctlr = SCSI \
	: 0 =  0, 1624880 : 1 =  1069, 787360 : 2 =  backup, \
	wm, 0, 4154160 : 7 =  var, wm, 1587, 1741920

partition = "dns1" \
	: disk = "ST39140A" : ctlr = ata \
	: 0 =  0, 11131344 : 1 =  11043, 525168 : 2 =  backup, \
	wm, 0, 17801280 : 7 =  var, wm, 11564, 6144768

partition = "dns2" \
	: disk = "ST39140A" : ctlr = ata \
	: 0 =  0, 17275104 : 1 =  17138, 526176 : 2 =  backup, \
	wm, 0, 17801280

partition = "orion1" \
	: disk = "SUN18G" : ctlr = SCSI \
	: 0 =  446, 2101522 : 1 =  0, 2101552 : 2 =  backup, \
	wm, 0, 35368272 : 3 =  usr, wm, 892, 14399872 : 7 =  \
	home, wm, 3948, 16765296

partition = "orion2" \
	: disk = "SUN18G" : ctlr = SCSI \
	: 1 =  unassigned, wm, 0, 8392072 : 2 =  backup, wm, \
	0, 35368272 : 3 =  1781, 16779432 : 4 =  usr, wm, \
	5342, 10182632

Sample Format.dat File

For the format command script I had to make a few assumptions. First, I assume that I'll be restoring to a like system. That is, the same drive size/type and quantity as the original system. This prevents me from having to build script menus that question the user as to the type of hardware installed (although, this will probably be done for a future revision).

When running the format program, you have the option of selecting pre-defined partition tables or defining your own. You use the select option to do this, and it will display a list of appropriate tables for the type of drive currently selected. If the drive is a "SUN2.1G", only those partition tables listed for a "SUN2.1G" will appear. For a particular system, I just need to figure out which partition to select in my command script. They are numbered 0 through n, and they are listed in the same order they appear in the format.dat file. As long as I know the sequence of that file, I can choose the proper table.

A sample format.cmd file looks like this:

partition
select 1
label
quit
Sample Format Command File

In this example, were I to have a SUN18G drive on my host computer, this command file would pick the partition named "orion2" from my format.dat file.

Finally, I can automate the format process with the command:

	Format -d c0t0d0 -x /format.dat -f /format.cmd

This will select the boot disk, and using the custom made format.dat file, execute the commands in the format.cmd file and then exit. When this is done, you will have the partitions created to your specs.

Next, I run the newfs program to actually format the new partitions. Newfs, however, does not have an unattended mode, and using the mkfs script directly is a pain in the ass (you need to know all of the parameters, and I'm trying to avoid knowing that). So, you need to pipe the response to format the partition into the program. The line in my script reads as such:

	echo "y^M" | newfs /dev/rdsk/c0t0d0

To create the carriage return (^M) within your file (and I'm assuming you use vi), use the sequence CTRL-V, then CTRL-M. The actual control sequence will show up rather than being interpreted as a carriage return. Caution: this eliminates any possibility of using a Windows based text editor to make future changes to this script, as they will interpret that ^M character as a return. Not only that, but you risk losing it if you FTP the script back and forth.

Once my partitions are formatted, I can install the boot block to the root partition. The location of the bootblk file on the CD is not quite the same as a regular OS, so here's the command I use:

     /usr/sbin/installboot /usr/platform/sun4u/lib/fs/ufs/bootblk /dev/rdsk/c0t0d0s0

Obviously, you would also change the platform type to your specific system. All I have are Ultra based hosts, so I can get away with just sun4u. Since I was lazy, I hard-pathed everything since I didn't add a PATH statement for the script. If you want to save some typing, make sure you setup a PATH within the environment for the script.

Finally, I can mount each partition at /mnt, and begin the restoration process using ufsrestore. Once that's done, I touch a reconfigure file on the new root partition, unmount them all, and get ready to reboot.

Final Notes

If all that you're trying to do is execute a few customized scripts at boot time, but otherwise leave the rest of the CD alone, you'll be fine, but if you need disk space, you may want to delete the <..>/<Solaris_version>/{Docs,Misc,Patches,Product} directories from your staging area. This will easily give you over 300M to play with. The Product directory contains all of the packages to install the OS, and the remaining directories should be fairly self-explanatory.

A possible future project for me is to clear out this space and install our network backup software onto the CD so we can do a restoration from our network backup server. It would no longer be fully automated, but I would have all of the tools I need (partition tables, formatting/partitioning tools, etc) to restore a system without a local tape drive. An advantage is that I can have 1 common CD for restoring any system rather than making 1 CD for each system as I am doing now.