The task was to create a system installer that would boot a sun, load up
the appropriate system images and tools required for a server in our
environment. Yes, this is a perfect job for jumpstart, but the systems
would be distributed across the state and not connected via a fast enough
pipe to use jumpstart effectivly. The other option was to build external
disks with the proper images on them and boot from there. The cost of
producing a few hundrad of these was prohibitive, thus the CDROM approach
was taken.
Of the few responses I received from Sun Managers readers, all of them
basicly said 'Its easy to clone the install disc!' or 'it just cant be
done!'
Well. It is possible.
First, a breakdown of the process. When the command > boot cdrom < is
givin to openboot the system actually looks at slice 2 to 5 for its
bootblks depending on the machine type. A sun4c is slice 2 to an sun4u at
slice 5. These bootblks redirect the system to slice 1 to load its
kernel. The root partition is also stored in slice 1 and slice 0 is usr
as well as packages. All slices save 0 are ufs, and 0 is hsfs.
This brings us to a small problem point. First we must boot from a UFS
partition, as the bootblks all require that. Second, a CDROM has no label
by default, thus its kinda hard to make partitions. And third, even if we
do flush a UFS filesystem image off to the cdrom, the geometries will be
all wrong, unless your staging disk just happens to have the same
geometries as the CDROM.
My solution is probally not the best. What would be required is an
application that simply converts the UFS geometries from the staging disk
uses to those used by the cdrom. I didnt really have time to create this
so I did it as follows. Im sure I will get lots of flak for this
solution, but it does work.
1) Use dd to grab the first cylinder offthe solaris boot cdrom. This
contains a valid disk label and VTOC for the cdrom. Oce this is created
our limitation is that we must work within the defines of this VTOC. You
should be able to use prtvtoc on the cdrom to get a look at this VTOC, but
this dosnt work if volmgr is running.
dd if=/dev/dsk/c0t6d0s0 of=cdrom.vtoc bs=512 count=1
2) Now use dd to grab the UFS slices from 1 to 5
for slice in 1 2 3 4 5
do
dd if=/dev/dsk/c0t6d0${slice} of=cdrom.s${slice}
done
3) Create a staging area and copy the parts of the usr filesystem (slice
0) off the cdrom into it. I started by copying cdrom:/export to it and
then trimmed out the parts I didnt need like X and openwindows.
4) Add in all the things you need for your disc. For me, this ment a
shell script that automated the build process, and images of all the data
I wanted to move out. Make sure you donot go beyond te size of the slice
0 on the cdrom you started with. prtvtoc will should you this, if you
cant get prtvtoc to work on the cdrom (sometimes it does, sometimes it
dosnt) then use > dd if=/dev/dsk/c0t6d0s0 of=/dev/null bs=512 < Record
the exact size of the partition in blocks as you will need it later.
5) Patch the slice 1 image (cdrom.s1) to start your custom application
rather then the suninstall. This can be done by finding the break point
you wish to use in the file cdrom:/sbin/sysconfig, selecting a unique set
of chars in this file ( I used the string #***** S30sysid.net ) and then
searching via a hexeditor or emacs in bin mode for that string. Then find
a comment line, change the first # and chars after to point to your
script, then add a # line after. Example, I patched my image so the line
#***** S30sysid.net
became
exec build #ysid.net
I then put a script in my staging area into the /usr/bin dir. (the staging
area will be made into slice 0 which is hsfs)
6) Using mkisofs or the tools that came with your cdrom burning package
(HyCD worked well, as well as Gear) turn your staging area into a hsfs
filesystem image, making sure that symbloic links are unmodified. HyCD
required changing a default option that would have modified all the links.
7) Using dd, throw away the first block of this image.
dd if=image of=image.data bs=512 skip=1
8) Subtract the block count of slice 0 from the solaris cdrom from the
image size above, add one to the answer. Say dd reported for the above
step that your image was 500000 blocks, and your solaris cdrom has a size
of 787840 for slice 0
787840 - ( 500000 + 1 ) = 287839
9) Feed this number into dd reading from /dev/zero to build a pad file.
dd if=/dev/zero of=image.pad bs=512 count=287839
10) Cat all of the image files together with the VTOC and the UFS slices.
cat cdrom.vtoc > image
cat image.data >> image
cat image.pad >> image
cat cdrom.s1 >> image
..
cat cdrom.s5 >> image
11) Burn this image to the cdrom drive using cdrecord, HyCD, Gear, etc
12) put it in a machine and test boot it and make sure it does what you
need.
Thats about it. We have to go through the gyrations because UFS is
geometry sensitive. We cannot take a image of a hard disk built UFS as
all the cylinder groups will be off. The RIGHT way of doing this would be
to build a tool that did the conversion for you and built an image up for
burning. But that requires a bit more work, this gets the job done with a
minimal amount of strain. I am working on the above mentioned tool, but
so far my progress has been to create lots of coasters. Sun has a tool
called MakeDisc that does this job, or something similar, but I do not
have a copy of it, so had to develop a method, while under a big gun, to
do it in a very compressed amount of time. The only real limitation this
has is you can only store about 400 megs of information, of which around
70 or so are needed by usr in the hsfs partition. Plus you do not have to
go through the pain of figuring out which parts of the system need to be
moved to the memfs filesystem (cdrom is readonly, so dev, devices, etc
need to be linked to /tmp)
If you wish to flame the procedure and tell me that I did it really
stupid, please correct me! I would willing stop development of my tools
to do same and do it the right way :) But my original question on how to
do this went unanswered.
Have Fun
James