I am building a network appliance based on linux. I
want this appliance to have three bootable partitions, a recovery partition and
two runtime partitions (designated 0 and 1). To simply manufacturing as well as to facilitate
functional testing in virtual hardware, I want to build a bootable ISO that I
can use to either initialize new hardware or to initialize virtual hardware
with all three partitions. I have decided to use kickstart/anaconda to automate
the install process. I have succeeded so far in constructing a
netstg2.img that uses a “shim” anaconda to invoke the
“real” anaconda twice in succession, but with different ks.cfg
files, and then invoke partimage to duplicate image0 to create image1. My new netstg2.img works perfectly, but success with
stage2.img and ISO/CD installs (as opposed to network-installs) is eluding me. My shim anaconda is included below (the original
10.2.1.5-2 anaconda has been copied to /usr/bin/anaconda.orig). My problem is the following… When running under netstg2.img the
‘reset_mounts’ function correctly umounts the ks.cfg defined
partitions, and removes all of the anaconda-created device nodes allowing
anaconda to be run a second time with a different ks.cfg. However when running under stage2.img, the
‘reset_mounts’ functions fails to umount the
“/mnt/sysimage” partition with a “Device Busy” error.
Furthermore switching to the alternative tty and issuing ‘umount
/mnt/sysimage’ also results in a Device Busy error. I am sure the problem is a subtle different in the
way stage2 operates from netstg2, but I at a loss as to what it could be. -- James -------------------------------------------- #!/usr/bin/python import os import sys # If this is a syslogd request, handle it if sys.argv[1] == '--syslogd': os.execv('/usr/bin/anaconda.orig',
('syslogd',sys.argv[1],sys.argv[2],sys.argv[3])) method = ‘cdrom’ def _invoke(cmdpath, args): pid = os.fork() if not pid:
os.execv(cmdpath, args) os.waitpid(pid, 0) def do_anaconda(imageName, args): nargs = args[:] # .. other stuff to change arg list to
load a dynamically generated ks.cfg
_invoke(‘/usr/bin/anaconda.orig’,[‘anaconda’,]+list(nargs)) def reset_mounts(zapdevices=True): # if CD install create CDROM mount
point if method == “cdrom”:
os.mkdir(“/mnt/cdrom”) # Unmount sysimage mounts
(‘maint’,’data’,’image0’,’image1’
are all partitions created in ks.cfg) sysMounts =
(‘dev’,’selinux’,’sys’,’proc’,’boot’,’maint’,’data’,’image0’,’image1’) for m in sysMounts:
_invoke(‘/usr/bin/umount’,(‘umount’,’/mnt/sysimage/%s’%m))
_invoke(‘/usr/bin/umount’,(‘umount’,’/mnt/sysimage’)) # /dev/hdc7 is provisioned as the swap
partition in ks.cfg
_invoke(‘/usr/bin/swapoff’,(‘swapoff’,’/dev/hdc7’)) # Drop device nodes deviceGlobs =
(‘/dev/hdc*’,’/dev/md*’,’dev/sda*’,’dev/initctl’,’/dev/mapper’,’/dev/log’,’/dev/hdc*’) if zapdevices: map(lambda x:
_invoke(‘/usr/bin/rm’,(‘rm’,’-rf’,x)),
deviceGlobs) if method == ‘cdrom’:
_invoke(‘/usr/bin/mount’,(‘mount’,’/tmp/cdrom’,’/mnt/source’))
os.unlink(‘/tmp/cdrom’) try: args =
sys.argv[1:] # Run anaconda on maint do_anaconda('maint',args) # Run anaconda on image0 reset_mounts() do_anaconda('image0',args) # .. other stuff to canonicalize
maint and image0, update grub # Capture image0 and duplicate to
image1 reset_mounts(zapdevices=False) # .. other stuff to use
partimage to copy image0 to image1 and canonicalize image1 except: print "%s %s\n%s" %
(sys.exc_info()[0],sys.exc_info()[1],repr(sys.exc_info()[2])) # Done print "Press any key to reboot" sys.stdin.readline() sys.exit(0) ---------------------------------------------- |