mkCDrec logo Make CD-ROM Recovery

Home
News
FAQ List
Downloads
Documentation
Internals
SourceForge
Freshmeat
Mailing Lists
Support
Translations
Credits
Links

Internals Explained

Index



Introduction

Make CD-ROM Recovery (mkCDrec) consists out of 2 big pieces, namely "making the bootable CD image(s)", and the "restore/rescue/clone part" in case one needs it.


In this article we will try to explain both parts in more detail. Please be patient as this article will take a while before it is finished.
The question why mkCDrec is the best suitable tool for your backups is not on its place as mkCDrec never claimed to be a backup tool anyway! One has to see it as a "disaster recovery" tool which is not yet standard available in any linux distribution. Until this situation is corrected mkCDrec can be of assistance ;-)
A word of caution: do not trust blindly that mkCDrec will do its job without errors, therefore, please test it on a test-and-burn system which is more or less equivalent to your production system.
In case you stumble over a bug, submit a bug report (see support page)!


Configuring mkCDrec

After downloading the latest release of the main website ( http://mkcdrec.ota.be/download.html ) and installing it in some directory one can start customizing the behavior of mkCDrec by editing the Config.sh file.
For more details on all changeable items go and read the config.html web-page.

Make test

One of the first thing one can do to test his system if its ready to start a make process is to run make test first to check if all the prerequisites are met. Therefore, type the following commands:
 
# cd   mkcdrec
# make  test

This will result into (hopefully) as follows:

If a FAIL pops up then correct the problem by following the instructions. In case of missing executables please install them from your linux distribution CD-ROMs.


The make process

When you would like to make an ISO9660 image of your system you have to do it via a "make" command. A simple make command drives the whole process of gathering system information, making backups (if asked for), and creating ISO9660 images.
After typing make you will see the following menu:

Before we go in more detail in above menu lets discuss the makefile in more detail.

Design Goals

The reason why we choose to drive the complete process of making a bootable El Torito CD-ROM from a simple "make" command was for simplicity toward end-users.
In worst case the users have to edit the "Config.sh" file which contains directory paths where images will be stored and so on (see Config.sh page for more in-depth details).

The Makefile itself

The "Makefile" which is read by the make command can be found in the top directory of mkCDrec. The following table shows the Makefile of mkCDrec v0.4.7:

 
 
# Copyright (c) 2000-2001 Gratien D'haese 
# Please read LICENSE in the source directory 

VPATH=.:isofs:./bin 

DISKNAMES=rd-base 
SHFILES=$(addsuffix .sh,$(DISKNAMES)) 
BZ2FILES=$(addsuffix .img.bz2,$(DISKNAMES)) 

# local dirs 
MKCDREC_DIR := $(shell pwd) 
SCRIPTS=$(MKCDREC_DIR)/scripts 
BIN_DIR=$(MKCDREC_DIR)/bin 
UTILITIES=utilities 

# some packages used by mkCDrec (may be replaced by higher versions) 
SYSLINUX_DIR := $(shell ls -d syslinux*) 
BUSYBOX_DIR := $(shell ls -d busybox*) 
TINYLOGIN_DIR := $(shell ls -d tinylogin*) 
SFDISK_DIR := $(shell ls -d sfdisk*) 
CUTSTREAM_DIR := $(shell ls -d cutstream*) 
PASTESTREAM_DIR := $(shell ls -d pastestream*) 
CKSFV_DIR := $(shell ls -d cksfv*) 


SAFE_SYSLINUX=false 
DATE := $(shell date +%d.%m.%Y) 
ISOFS_DIR := $(shell grep ISOFS_DIR= Config.sh |grep -v ^\# | cut -d= -f 2) 
VERSION := $(shell cat VERSION) 
CDREC_ISO_DIR := $(shell grep CDREC_ISO_DIR= Config.sh |grep -v ^\#|cut -d= -f2) 

all: devs dirs mformat mkmakeISO9660 $(BZ2FILES) bootflop.img Backup_Finished 
    @echo Done. 

mkmakeISO9660: $(SCRIPTS)/makeISO9660.in 
    $(SCRIPTS)/mkmakeISO9660.sh 

CDrec.iso: $(BZ2FILES) bootflop.img Backup_Finished 
  mkisofs -J -r -P "$(VERSION)" -V "CDrec-$(DATE)" -o $(CDREC_ISO_DIR)/$@ -b bootflop.img isofs/ 

$(BZ2FILES): %.img.bz2: $(SCRIPTS)/%.sh 
      $< 

bootflop.img: $(SCRIPTS)/bootflop.sh initrd.img.gz syslinux 
 $(SCRIPTS)/bootflop.sh $(SAFE_SYSLINUX) 

initrd.img.gz: $(SCRIPTS)/initrd.sh linuxrc 
      $(SCRIPTS)/initrd.sh 

syslinux
      (cd $(SYSLINUX_DIR); make) 
      cp $(SYSLINUX_DIR)/syslinux ./bin/syslinux 

mformat
     ( objcopy -S /usr/local/bin/mformat $(BIN_DIR)/mformat 2> /dev/null || \ 
     objcopy -S /usr/bin/mformat $(BIN_DIR)/mformat 2> /dev/null || \ 
    @echo No mformat found on this system. Use ours instead. ) 

dirs
     mkdir -p $(ISOFS_DIR) stage tmp 

devs: /dev/initrd /dev/fd0u1722 
    @echo Device check OK 

/dev/initrd
     mknod /dev/initrd b 1 250 
     chmod 400 /dev/initrd 

/dev/fd0u1722
     mknod /dev/fd0u1722 b 2 60 
    chmod 666 /dev/fd0u1722 

Backup_Finished
     $(SCRIPTS)/tar-it.sh 

clean
    -umount stage 
    rm -f *.img 
    rm -f initrd.img.gz 
    rm -rf $(ISOFS_DIR) 
    rm -rf tmp 
    rm -f isofs 
    rm -rf bootflop 
    rm -f *.log 
    rm -f $(CDREC_ISO_DIR)/*.iso 

distclean: clean 
    (cd $(SYSLINUX_DIR); make clean) 
    (cd $(BUSYBOX_DIR); make clean) 
    (cd $(TINYLOGIN_DIR); make clean) 
    (cd $(SFDISK_DIR); make clean) 
    (cd $(CUTSTREAM_DIR); make clean) 
    (cd $(PASTESTREAM_DIR); make clean) 
    (cd $(CKSFV_DIR); make clean) 

dist: distclean 
    (cd ..; tar --file mk$(VERSION).tar.gz --create --gzip --verbose --exclude CDrec* --exclude stage --exclude tmp --exclude isofs --exclude OLD --exclude utilities mkcdrec ) 

utils
    (tar --create --gzip --verbose --file ../mk$(VERSION)_utils.tar.gz $(UTILITIES) ) 

test: $(SCRIPTS)/test.sh 
     $(SCRIPTS)/test.sh


All the bold items in the Makefile are headers which can be invoked separately. The most common make commands an user can use are:

    make: this will do it all for you! At the end you will have one or more iso9660 images on hard disk or CD-R dependent on the choice given by the user, but more on this later.

    make clean: cleans up all temporary files and directories. It is preferable to do this before running an new make command.

    make test: this will check if your system is able to do a successfully make command. If it fails here one has to correct what the script asks you to repair.

Running the make command

The make command on itself will use the "all" header to do its thing:
 
all: devs dirs mformat mkmakeISO9660 $(BZ2FILES) bootflop.img Backup_Finished

The "all" will execute in order the above items. The "devs" will check if the device /dev/initrd exists, and if not, it will make it automatically. Thereafter, "dirs" will create the necessary temporary directories, such as ISOFS_DIR, stage and tmp. With a "make clean" those directories are removed again (be careful with images residing in ISOFS_DIR!). Mformat checks if the executable mformat in installed on your system, if not, then mkCDrec will use its own mformat utility (in bin/ directory).
The "mkmakeISO9660" will create a shell script in scripts/ directory called "makeISO9660.sh" from the input file "makeISO9660.in" file and merging some variables from "Config.sh" file needed later on to create an ISO9660 images called by the cutstream program of tar-it.sh script depending on being a multi-volume CD-ROM backup or not.

The BZ2FILES does only contain one file, namely rd-base! Therefore, this line will execute the rd-base.sh script (all scripts are located in the scripts/ directory). rd-base.sh script is responsible for making the main root ram disk which will be loaded after the initial bootloader.

The "bootflop.img" is responsible for making the initial ram disk (initrd.sh), the syslinux boot loader, and finally the El-Torito bootfloppy (which contains the linux kernel, syslinux boot loader and the compressed initrd images).

Finally, Backup_Finished will execute the tar-it.sh script to make (or skip) the tar backups of your file systems. Tar-it.sh script will always call the makeISO9660.sh script to produce the ISO9660 image on hard disk (file called CDrec.iso) or burn it directory on a CD-R when chosen for it in the Config.sh file).
We will try to explain all the steps in more detail following the flowchart design:

mkmakeISO9660.sh

The sole purpose of this small script is to merge some variable settings from Config.sh into makeISO9660.sh. Therefore, it will merge the file makeISO9660.in and the correct variable settings of Config.sh. Correct settings have to be edited manually into Config.sh (sorry, no GUI yet) - see also config.html file in doc/ directory.
The reason we have to do this is that in some circumstances the makeISO9660.sh script will be called in an isolated environment where mkCDrec settings are unset, therefore, we have to hardcode some variables into this script - that's all.
 

rd-base.sh

The rd-base.sh script is responsible for building the main ram based root file system that will be active during the restore or cloning process.
The scripts starts up with asking the user what he wants to do (maybe it is not 100% similar to what you see):

mkCDrec will behave (do different things) on the selection you choose:

1. Here we will make only a rescue CD-ROM (no backups!). Always good to have around (and no real risk to keep on your desk as no sensitive data is kept on it).
Be aware that with this CD and physical access to any PC (with CD-ROM reader) one has access to all data on the hard disks!
2. This option will make backups on the rescue CD-ROM(s). It is smart enough to find out if multiple CDs are necessary (burn to CDR(W) directly or save separate ISO's).
3. This option will make a rescue CD-ROM and will put the backups on another path. That path can be a local disk or remote (NFS/SMB) disk.
Be aware that mkCDrec assumes that the destination path is on-line and mounted. It will not attempt to mount it for you.
4. This option will make a rescue CD-ROM and will be the backups on a (remote) tape.
5. Quit (do nothing)
Once the user selected an option the real work starts with making and mounting a RAM disk. It will compile and copy BusyBox, tinylogin, sfdisk, cut- and pastestream. It will populate the etc, dev, lib, bin directories according what was found in the Config.sh file.
An important part of rd-base.sh script will then investigate your current system and save all the needed information (system and disk related) into the directory etc/recovery/.
Once in a while a routine will keep an eye if you're not running out of disk space on the RAM disk. Once finished the RAM disk will be unmounted and compressed as rd-base.img.bz2 and copied to isofs/ directory. The isofs/ directory is the target directory for making, with mkisofs, the CDrec.iso image (or multiple images in case of large backups).
 

initrd.sh

The initrd.sh script is responsible for making the initial ram disk with minimal driver support, just enough to get the CD-ROM mounted and load the rd-base.img image into RAM.
The first step it takes is creating an empty ram disk, and make a file system on it, be it ext2, minix, msdos or romfs. Then it will populate the file system with the necessary directories and devices (when not using devfs). Thereafter we copy the bare minimum binaries and according libraries to get the system going from initrd stage to be able to mount a bigger ramdisk.
To finish we have a tricky part: check which loadable modules should be copied on the initrd so we can mount the IDE or SCSI CD-ROM. With this (new) approach we avoid to recompile the kernel (keep it modular).
Before unmounting the ram disk we copy some system files (such as linuxrc) and then gzip the image into initrd.img.gz.
 

Compile Syslinux

The next step in the process is to compile syslinux (once is enough) and copy the binary to our local bin/ directory. We need syslinux to make our bootfloppy which will be put on the CD-ROM too. In El-Torito mode the CD-ROM needs a bootable floppy disk image which we will make in the following step.
It will also compile isolinux and will use isolinux when it detect the following directory (done in bootfloppy.sh):
utilities/memtest.bin
Why? memtest.bin is the memtest86 executable which is an excellent ram checker. To let the end-user choose between mkcdrec or memtest we need another approach and we are unable to fit all executables (of mkcdrec and memtest) on one floppy, therefore, we decided to use isolinux instead of syslinux. Isolinux has another big advantage and that is, there is no size limit anymore for the bootable images, be it 1.44 or 2.88 Mb.
Be aware: this step is obsolete since mkCDrec v0.7.1. Now the syslinux package is a pre-requisite.
 

Bootflop.sh

The purpose of this script is to make a bootfloppy (emulation) image which will be put on the CD-ROM to make the El-Torito mode a reality.
In the first stage we will format an empty floppy in memory (not on a physical floppy!). The floppy image will be mounted as a MSDOS file system via a loopback device on a stage-directory. Then we will copy the linux kernel to it (as specified in Config.sh or we will use the current one), the initrd.img.gz image file (initial ramdisk), the syslinux.cfg file, the mkCDrec.msg file (the welcome message you see at boot time).
Now comes the magic - we unmount the bootflop.img and syslinux it to make it bootable.
Finally, the user may be prompted to create a physical bootfloppy when PROMPT_BOOT_FLOPPY= 1 and BOOT_FLOPPY_DENSITY=HD (both defined in Config.sh). Of course, this only works is bootflop.img is smaller than 1.44 Mb. Otherwise, the only alternative is a 2.88 Mb bootfloppy which is supported by El-Torito CD-ROMs.
The second approach available when mkCDrec Utilities are installed is the isolinux approach instead of the bootfloppy emulation of syslinux. If you see on the CD-ROM a directory called isolinux then be sure that isolinux is used. Under that directory you will find the linux kernel, initrd.gz image, some configuration files and the isolinux executable.
 

tar-it.sh

Tar-it.sh script will always be called (even when you selected the Rescue Only option) because at the very end of this script we will call another script, makeISO9660.sh to make (finally) the ISO9660 image(s).
Suppose we have a backup to make, either to tape, local mounted disk or NFS disk, or to CD-ROM (to an ISO9660 image that is). Depending on what we have chosen we will follow a different track.
If CD-ROM was chosen as destination for the backups then the script will examine if the complete backup will fit onto one CD-ROM or multiple CDs and it will warn us about is (press Enter to continue).
If  (local or remote) tape was chosen as destination then for the moment the script will assume that the maximum capacity is 2100000 Kb (approx. 2 Gb). This part could be improved a lot if we could ask or inquire the tape drive what the capacity is of the tape (if someone knows how please step forward and tell me).
Then the script will build up a exclude list of directories which may not be included in the backup (there is also an EXCLUDE_LIST variable in the Config.sh file to add yours). It is a rather complicated piece of code as RedHat, Debian and SuSe interpret the tar exclude list a bit different (bah, very ugly and there goes unified systems).
Once the script has struggled through the exclude list it can start with its thing, namely backup the damn thing. Therefore, it will build a loop over all the mounted ext2, ext3, jfs, xfs and reiserfs file systems (and excluding any loop devices, devps, etc.). For all Microsoft based file systems we use "dd" instead of the tar command!
Again for doing the backup itself there is a difference between tape or disk (local, NFS, CD-ROM) as destination. When using tape we will use the following statement:
 
(${DEBUG} tar --create --verbose --same-owner --blocking-factor=512 \
          --preserve-permissions --exclude-from=${TMP_DIR}/${_Fs}.exclude_list \
          --gzip --file - . | ${REMOTE_COMMAND} ${RHOST} dd of=${DESTINATION} obs=512 ) 1>>  ${ISOFS_DIR}/${_Dev}.${_Fs}.log 2>&1

Above statement contains lots of variables which are defined in Config.sh. What is important here is that we use the dd command to dump to tape which is the safest way so we are pretty sure we can restore with a different tape drive (later, much later in case of sh*t).

If the destination is a disk (local, NFS, SMB) then we use the following statement:
 
${DEBUG} tar --create --verbose --same-owner --${CMP_PROG} --blocking-factor=512 \
          --preserve-permissions --exclude-from=${TMP_DIR}/${_Fs}.exclude_list \
          --file ${DESTINATION} . 2>>${ISOFS_DIR}/${_Dev}.${_Fs}.log 1>&2 

The "DESTINATION" variable is build up as following:
 
DESTINATION=${DESTINATION_PATH}/${_Dev}.${_Fs}.tar.gz
The extension "tar.gz" is used in case gzip was selected for CMP_PROG, or "tar.bz2" if bzip is the preferred compression program.

If the destination directory is /CDROM/ then yet another approach is followed as it can happen we have to split up the backup across different CDs.
To make this magic happen we wrote a helper program "cutstream" to cut a data stream after an predefined amount of bytes which happens to be the size of the CD-R(W)!
We introduce some new variables to help us a bit. CAPACITY contains how much space is left for backups on a CD-R (remember the first CD contains also some images such as bootlop.img, rd-base.img and documentation). MAKE_ISO9660 variable just contains the absolute path to makeISO9660.sh, and VOLNO_FILE which contains the absolute path to tmp/volno file. the volno file contains the volume nummer of CD sets. It starts with 0 (single CD), and will be incremented if another CD is needed.
The command looks like:
 
CAPACITY=$((MAXCDSIZE-UsedByIsofs))
                                                                                        CUTSTREAM="cutstream"       # cut stream to fit on CDR
export CAPACITY
MAKE_ISO9660="${SCRIPTS}/makeISO9660.sh"
export MAKE_ISO9660
VOLNO_FILE="${TMP_DIR}/volno"       # volume nr (#Cds)
export VOLNO_FILE
(${DEBUG} tar --create --verbose --same-owner --blocking-factor=512 --preserve-permissions --exclude-from=${TMP_DIR}/${_Fs}.exclude_list --${CMP_PROG} --file - . | ${CUTSTREAM}) 2>>${TMP_DIR}/${_Dev}.${_Fs}.log

So to make the picture complete we'll explain also cutstream and makeISO9660.sh
 

cutstream

The cutstream program is based on a simple cat program, in fact it does not more than simple reading a data stream from a pipe and store it into a file. It gets the filename through the exported DESTINATION variable. It starts a counter which is incremented according the amount of data read, If the CAPACITY counter is reached then it will increment the volno counter (tmp/volno) and stops reading data and starts a system call to "makeISO9660.sh". If the shell scripts finishes (with making an ISO9660 image) it returns and happy as it is continue to dump in the file DESTINATION which was removed by the makeISO9660.sh script. Of course, the CAPACITY counter will be reset too to its maximum capacity (which is defined in Config.sh - you see how important that file is!).
It is maybe not the most elegant solution but it does work.
 

makeISO9660.sh

The makeISO9660.sh script does not exist initial, but is created through the make command as it contains absolute paths only to all kind of scripts we need. the reason is that this script will not run in our shell but in a subshell spawned by cutstream (maybe if multi-volume CDs are needed).
What does it do: it will run cksfv * > Checksums.sfv over all the files to have some kind of checksum.
Then it will start makeisofs command to create an ISO9660 image (only the first CD will be bootable).  In case BURN_CDR is Y (Config.sh again) then it will start to burn this image to a CD-R (will endless retry until it succeeds, so better insert a blank CD-R).
In case the images are stored on disk (CDREC_ISO_DIR definition in Config.sh) then it will check it we're dealing with a multi-volume CD-set and move CDrec.iso to something like CDrec-${DATE} followed by volume nummer. Please mark your Cds afterward with this label as a reference!
The most dangerous command happens at the end of makeISO9660.sh:

(cd ${ISOFS_DIR}; rm -vf *; rm -rvf doc; rm -rvf utilities)

This will clean up the old source for the ISO9660 images and remove old files and directories so we can continue with the new image.
If makeISO9660.sh was called from cutstream then now is the time to go back and continue with the data stream...otherwise, we're finished.


Restore your system


The purpose of mkCDrec is to restore your system to a situation when you ran for the last time 'make' within mkcdrec, and wrote the corresponding CDrec.iso image to a CDR (or are still able to make a CDR of the image when saved on another system - as I do sometimes).
When Murphy came along - and left a system unbootable or unusable (what's the difference?) - you will probably be under high pressure to restore the system as soon as possible!
Most of the times there is not much time to investigate in-depth what happened, if it is hardware related replace the broken item immediately and restore the system or file system (it depends) and you're back in business. In case it is software related (by accident or malicious) then it could be that the system is rather unstable or likely untrustable. In these situation it is better (or wise) to restore from scratch from the latest known stable backups.
In both cases mkCDrec can come to rescue!

However, some words of wishdom, do not blindly trust the tool without trying it out on a spare "crash-and-burn" system with data you can effort to loose!

What has mkCDrec to offer?

  • start-restore.sh: restore the "complete" system from scratch. Meaning all new disks have to be of the same type (IDE, SCSI) and may not be smaller in size (which is unlikely these days) as the original ones. The script will examine the system and halt if it detects an error. If an errors occurs you are thrown back into shell where you can repare or provide the requested item of the exit code. The script may be restarted afterward hopefully continues at the point it previously exited.
    Furthermore, it will reformat the disks and un-tar all file system backups. Finally, it will make your system bootable again with the help of lilo or grub.
  • clone-dsk.sh: this script allows you to restore one single disk to any kind of disk (IDE, SCSI) and it will recalculates the partition size layout for you as long the size of the original backup fits into the disk space of the newer disk. Excellent script made especially for cloning purposes (as the name of the script says). This script is more interactive as it allows you to skip parts of the restore scenario, e.g. re-format the partitions, make file system on it.
  • restore-fs.sh: this script will simply restore a single file system without much fuzz to a beforehand formatted disk (including partition layout). However, along the way you can choose the file system type you want to have, with other words, ideal for migrating from ext2 to ext3, ReiserFS, XFS or JFS. Another reason for this script is because it could happen that the backup is split across multiple CDRs, and therefore, you need to use "pastestream" to glue the different parts together while piping the input stream into tar.


How do we get there?
By simple inserting the mkCDrec CD-ROM into the CD-ROM drive and rebooting the system (make sure your system is able to boot from CD. Check your BIOS settings). The CD is bootable because it is compliant with the El-Torito definition which makes CDs bootable on Intel based PCs. This will emulates a bootfloppy! Therefore, the bootflop.img is loaded into memory and syslinux makes sure that initrd.gz is unzipped into /dev/ram0 and gets executed after the linux kernel is loaded into memory too.
This is called the "initial" ram disk phase: linuxrc gets executed and will try to find the CD-ROM as in fact the system booted from a kind of floppy stored on CD (can you follow?). If it can find the CD-ROM it will mount it and expands the bigger ram disk into /dev/ram1. When succeeded it will switch from /dev/ram0 to /dev/ram1.
At that point "init" is started (or linuxrc) which are links to busybox (to make as much space available in ram). The CD-ROM will get mounted again under /mnt/cdrom and /dev/ram1 will be the /, and /dev/ram0 became /dev/root.old and contains the former / which is now /initrd.
Then init will execute /etc/rc.d/rc.system which will take care of all the other steps necessary to give you a root prompt and a usable bash shell.

If you cd into /etc/recovery directory you will find the above mentioned scripts (and other scripts or files which helper scripts or input files for these scripts). If you delete these files by accident do not panic - just reboot the system with the same mkCDrec CD. No harm done ;-)

If the utilities were installed in the mkcdrec directory during the make process (before burning the CDR!) then you will have some handy tools available which gives plenty added value to your mkCDrec (see the utilities pages for additional information). I advise to add them always! 



$Id: internals.html,v 1.8 2004/03/28 18:28:18 gdha Exp $ 
Tux.Be

SourceForge