Typo
[linux_from_scratch_hints.git] / OLD / boot_any_hd_sample_apps.txt
blobd7f1b0c213a3f1bdae37b08a3d68e35afcd357ef
1 TITLE:          Boot (not just root) any HD, sample application
2 LFS VERSION:    All.
3 AUTHOR:         Bill Maltby <lfsbill@wlmcs.com>
5 SYNOPSIS:
6         Examples of practical application of the boot_any_hd.txt hint.
8 HINT:
10 Version: 0.9 2003-06-14
12 Change Log:
13    1.0   2003-06-14 - Initial release
15 Unusual for me, I had no urge to explain much of anything in here. I pre-
16 sume that you have read the boot_any_hd.txt hint, if you need to, and any
17 of the other reading material it mentions. I also assume you have *some*
18 level of bash scripting skill above rank novice. If not, beware!
20 I present two processes here. The first is script that can be used as a
21 prototype for backing up your primary drive to a secondary boot drive. The
22 second is a semi-interactive script that will run lilo to install boot
23 blocks supporting the concepts discussed in the boot_any_hd.txt hint.
25 The backup script makes use of a file of sed commands and the lilo script
26 uses a configuration file that provides a little adaptation to your system.
27 A similar file should be done for the backup script, but I haven't done it.
29 CONTENTS
30    I. ROOT TO FALL-BACK ROOT BACKUP SCRIPT
31   II. A GENERALIZED LILO.CONF PROTOTYPE FOR USE BY LBI.SH
32  III. A BOOT-BLOCK INSTALL SCRIPT
33   IV. SUPPORT
35 I. ROOT TO FALL-BACK ROOT BACKUP SCRIPT
36     This script requires that you have bash, find and cpio installed on
37     your system.
38     
39     This script backs up a single root partition, normally /dev/hdb7 for
40     me, to a fall-back root partition on /dev/hdd7, for me. By adjusting
41     these to for your configuration, you should be able to use it. It ex-
42     amines the information from a mount command to generate a script that
43     will do the backup while suppressing copy of directories not contained
44     on your root partition. It also suppresses copy of some files often
45     found in a root FS. By default, the execution of the script made is
46     *not* executed. If you want it to execute automatically just uncom-
47     ment the line near the end of the script.
49     After making your adjustments, you can run it by typing
51          ./B7D7BU.sh
53     and giving a command line parameter of M, for master or I for incre-
54     mental backup.
56     If you give it the "M" parameter, it will generate a script to do a
57     full backup and leave a "timestamp" file on the target partition which
58     is used by an incremental backup to check for newer files to copy.
60     If you give it an "I" parameter, it backs up only files with a creation
61     or modification date later than the "time stamp" file.
63     The cpio copy is set to verbose mode and creates a log in /tmp named
64     B7D7{M|I}BU.out. This log can be checked to see if things look good.
65     You may want to remove the "v" parameter to cpio to reduce the amount of
66     output.
68     A couple of things to watch for: if you intend to be able to boot from
69     the "fall back" drive, remember to adjust various configuration files,
70     like /etc/fstab, that will be sensitive to a (possibly) changed root
71     when you are running from the fall back drive. If you update the orig-
72     inals and back up again, the new ones will overwrite the modified ones
73     unless those files are part of the list of exclusions the script makes.
75     You should change those exclusions to meet your needs.
77     If you do a full backup, it is better to start with an empty fall back
78     file system. Otherwise old stuff may be left in place. If you do a
79     master backup and then only do incrementals, the same problem will tend
80     to occur over time. Every once-in-awhile, empty the fall back partion
81     and do a master backup again.
83     If you are running on the fall back when things like mail happen, and
84     you forgot to put your mail spooling directory someplace *not* on your
85     root partition, you have the possibility that you'll miss some mail
86     when you go back to your normal root because some of the new mail will
87     be on the fall back root.
89     I've not tested with mount --bind stuff.
91     /boot is excluded from the copy. If you change this, there are times
92     you *may* need to run lilo boot blocks install again. Generally it is
93     better to manually copy /boot stuff and remember to run lilo
94     immediately after.
96     Make sure that permissions prevent running or modification by other
97     users. I keep these components in ~root/bin and have my $PATH set
98     accordingly.
100     If you use the cron facility to run this automatically in off-hours, it
101     can be very useful.
103     I intentionally use inconsistent script constructs. Sometimes "if, then,
104     else, fi" things and other times "test ... " things. Adapt to suit your-
105     self.
107     Here is the script.
109 ----------------- CUT ALONG DOTTED LINE ------------------------------------
110 #/bin/bash
111 SSD=~/bin   # Where sed scripts are.
113 # Exit if they don't give us a run type
114 if [ $# -ne 1 ] ; then
115     echo "Need an I or M parameter for Master or Incremental backup" \
116         >/dev/tty
117     echo "Exit 1" >/dev/tty ; exit 1
120 P1="$1"
122 #########################################################################
123 # Make sure I'm rooted on hdb7 or hdd7. CHANGE THIS FOR YOUR CONFIGURATION
124 #########################################################################
125 set `rdev`
126 if [ "x$1" = x/dev/hdb7 ] ; then
127    SP=hdb7;MP=hdd7
128 elif [ "x$1" = x/dev/hdd7 ] ; then
129    SP=hdd7;MP=hdb7
130 else
131    echo "*** Error: unexpected root mounted: '$1' on '$2'."
132    echo "*** Error: exiting code 1."
133    exit 1
136 ### Set run type ###
137 case "$P1" in
138     M | m ) unset NEWER # This is not really needed, but looks cleaner
139         BUT=M
140     ;;
141     I | i ) NEWER="-newer /mnt/$MP/BACKUPLAST_$SP"
142         BUT=I
143     ;;
144     * ) echo "Need I or M parameter: Master/Incremental backup" \
145             >/dev/tty
146         echo "Exit 2" >/dev/tty ; exit 2
147         ;;
148 esac
150 ### After the first time, the mkdir is a waste. ###
151 mkdir -p /mnt/$MP && mount /mnt/$MP
152 RC=$?
154 if [ $RC -eq 1 ] ; then                 # mkdir or mount failed
155    echo "*** Error: mkdir or mount /dev/$MP->/mnt/$MP fail: rc=$RC."
156    echo "*** Error: exiting code 2."; exit 2
157 elif [ $RC -ne 0 -a $RC -ne 32 ] ; then
158    echo "*** Error: mkdir or mount bad rc: $RC."
159    echo "*** Error: exiting code 3."; exit 3
162 #########################################################################
163 # The "meat" of the process. Create a script that finds only the root FS
164 # and does either a master backup or an incremental backup. Excludes some
165 # files that normally should *not* be copied.
166 # NOTE: you can use a inline ("here") document to replace the echos. Be sure
167 # you *don't* quote the EOF delimiter - it suppresses variable substitution.
168 #########################################################################
170    echo -e "#!/bin/bash\ncd /"
171    echo "find . \( -name 'mtab' -o -name 'fstab' -o -name '.*.swp' \\"
172    echo "-o -path './mnt/$MP/*' -o -path './boot/*' \\"
173    echo "-o -path './mnt/*' -o -path './tmp/*' \\"
174    echo "-o -path './var/log/*' -o -path './var/run/*' \\"
175    echo "-o -path './var/spool/*' -o -path './var/tmp/*' \\"
176    mount 2>&1 \
177       | sed -f $SSD/B7D7BU.se1
178    echo "\\) -prune -o \\( $NEWER -print \\) \\"
179    echo "| cpio -pdamv /mnt/$MP &> /tmp/B7D7${BUT}BU.out"
180    chmod u+x /tmp/B7D7${BUT}BU.sh
182     echo "touch /mnt/$MP/BACKUPLAST_$SP"
183 } &> /tmp/B7D7${BUT}BU.sh
185 #########################################################################
186 # /tmp/B7D7${BUT}BU.sh  # Uncomment to automatically run the script made.
187 #########################################################################
189 umount /mnt/$MP
190 ----------------- CUT ALONG DOTTED LINE ------------------------------------
192 Here are the sed commands contained in $SSD/B7D7BU.se1
194 ----------------- CUT ALONG DOTTED LINE ------------------------------------
195 / on \/mnt/d
196 / on \/ /d
197 s/^.* on \([^ ][^ ]*\) .*/-o -path '.\1\/*' \\/
198 ----------------- CUT ALONG DOTTED LINE ------------------------------------
200 II. A GENERALIZED LILO.CONF PROTOTYPE FOR USE BY LBI.SH
202     This is a "ptototype" file that can be used by the LBI.sh presented
203     later to automatically "do the right thing" when installing lilo boot
204     blocks for a multi-drive boot configuration. It is expected in to be in
205     /etc/LiloBootInst/lilo.conf-proto. Adjust everything to fit your
206     configuration.
208     The directory and this file should be inaccessible to all but the user
209     that will run the script - usually root.
211 ----------------- CUT ALONG DOTTED LINE ------------------------------------
212 disk=/dev/hda
213         sectors=63
214         heads=16
215         cylinders=6296
216         bios=$HDA
218 disk=/dev/hdb
219         sectors=63
220         heads=16
221         cylinders=39560
222         bios=$HDB
224 disk=/dev/hdd
225         sectors=63
226         heads=15
227         cylinders=82714
228         bios=$HDD
230 menu-title="/dev/hd$BOOTD Drive Boot Menu"
231 prompt
232 delay=100
233 timeout=100
234 lba32
235 default=B7-K6-20030530
237 ###### lfs20030504 BEG ######
238 other=/dev/hda1
239         label=W98
240         loader=$TBBOOT/chain.b
241         map-drive=$MD0
242             to=$TD0
243         map-drive=$MD1
244             to=$TD1
246 image=$TBBOOT/K6-20030530
247         label=B7-K6-20030530
248         root=/dev/hdb7
249         read-only
250         append="pci=biosirq idebus=66"
252 image=$TBBOOT/K6-20030530
253         label=D7-K6-20030530
254         root=/dev/hdd7
255         read-only
256         append="pci=biosirq idebus=66"
258 image=$TBBOOT/vmlinuz-2.2.5-15
259         label=RH-6.0-linux
260         root=/dev/hdb2
261         read-only
263 ###### lfs20030504 END ######
264 ----------------- CUT ALONG DOTTED LINE ------------------------------------
266 III. A BOOT-BLOCK INSTALL SCRIPT
268     This has been tested using lilo 22.2 on a "pure" (B)LFS system.
270     In /etc/LiloBootInst/LBI.conf create a file readably only by root with
271     the following contents, adjusted for your configuration.
273 ----------------- CUT ALONG DOTTED LINE ------------------------------------
274 #!/bin/bash
276 DISKS=(a b d)           # CHANGE THIS to show bootable drives
277 WD=$PWD                 # Where we'll be working
278 HDPFX=/dev/hd           # Change for scsi or devfs. Mixed? On your own!
279 BDIR=/boot              # Default loc of boot components (non Win*)
280 BOOTB=boot.b            # Default prototype boot block(s).
281 CProto=lilo.conf-proto  # lilo.conf prototype file
282 CONSOLE=/dev/tty        # For fd[0-2] I/O. Devfs? Change as needed.
283 ----------------- CUT ALONG DOTTED LINE ------------------------------------
285     The following shell script, /etc/LiloBootInst/LBI.sh helps get things
286     right during the grind of daily operations. It depends on being able to
287     find the prototype file, detailed above, and the configuration file just
288     displayed.
290     To run it, cd to /etc/LiloBootInst and run this command, with the
291     substitutions noted after.
293         ./LBI.sh {-t|-i} -d X -p N [ -D <default-image-label>
295     The "-t" means test only - don't actually install, but do everything
296     else. If you give it "-i", the boot blocks will be installed. The "X"
297     should be replaced with the drive this run is to affect: a for hda, b
298     for hdb, etc. The "N" is replaced by the partition number containing
299     the root file system.
301     If you provide the "-D" and the label of an image, it will be used as
302     the default boot image, overriding any "default=" within the file. If
303     there is no "default=" and no "-D ..." is provided, the system will
304     generate a "-D ..." for you and tell you that it is doing that. This
305     will be the same default as lilo would take.
307     For first runs, be sure to use the "-t" parameter, test. It will process
308     the prototype file and leave the results in a file named *-boot.conf.
309     This is the lilo.conf file that will be referenced by a shell script
310     that is also created, *-boot.sh. You can examine and adjust either of
311     these files as needed.
313     A file, *-boot.out will also be created, using a lilo debug level of v3,
314     showing the information lilo garnered and the decisions made. When this
315     looks good using the "-t" parameter, you can then remove the "-t" and
316     run the *-boot.sh script or rerun LBI.sh and give the "-i" parameter.
318     If you provide the "-i", install parameter, the shell will warn you
319     that you are going to install the boot blocks and ask if you want to do
320     it. Either way, both the "-t" and "-i" leave the *-boot.conf, *-boot.sh
321     and *-boot.out files there for you to examine.
323     The created shell has a "less" at the end that will page through the
324     corresponding *-boot.out file created when the *-boot.sh script is run.
326     The output log has a copy of the lilo command that runs.
328     Here is the shell script.
330 ----------------- CUT ALONG DOTTED LINE ------------------------------------
331 #!/bin/bash
333 source ./LBI.conf       # Load some config/customization vars.
335 #######################################################################
336 # stdusage: issue standard usage message
337 #######################################################################
338 stdusage() {            # Standard usage if an error found
339     echo "usage: lilo-boot-install.sh"
340     echo "  -{t|i}          --> runtype: Test or Install boot blocks"
341     echo "  -d [a|b|c|d]    --> Drive to *boot*"
342     echo "  [-D <def boot>] --> Default boot image lable (optional)"
343     echo "  -p partition    --> Partition containing ...$BDIR"
344 } &> $CONSOLE <$CONSOLE
346 #######################################################################
347 # stdchecks: see if mount point is involved. Is a boot block found.
348 #######################################################################
349 stdchecks()             # Cks common to several drive/part. validations
350 {   # $1=mount point preceding some *boot* directory name
351     # $2=some *boot* directory
352     # $3=the drive specified by the -d parameter
353     # $4=the drive partition specified by the -p parameter
354     # $5=a full path name of device that may have a *boot* directory
355     # $6=exit code if there is a failure
357     local BMP=$(mount | grep " on $1$2 " | sed -e 's/ on .*//')
358     if [ -n "$BMP" ] ; then                     # Found mount point
359         test $BMP != ${HDPFX}$3$4 && {
360             echo "-p $4 doesn't match $BMP on $2. Exit $6 a."
361             stdusage
362             exit $6
363         } 
364     fi
365     test ! -f $1$2/$BOOTB && {          # Assure boot blk exists
366         echo "$1$2/$BOOTB not found on $5. Exit $6 b."
367         stdusage
368         exit $6
369     }
372 #######################################################################
373 # getopts process: - validate options and set up parameters
374 #######################################################################
375 RUN=bad                 # To detect if they don't select test or install
377 # Process all the options passed in - all are required
378 while getopts "tid:p:D:" OPTLTR ; do
379     case $OPTLTR in
380         D ) test -n "$DBL" && {                 # Default Boot Label seen?
381                 echo "Multiple -D given. Default boot label already '$DBL'"
382                 stdusage
383                 echo "exit 13"
384                 exit 13
385             }
386             DBL="$OPTARG"
387             # We'll let lilo validate the default boot image and lable
388             # so just leave the case right here.
389             ;;
390         i | t )                                 # Do install or test?
391             if [ bad = "$RUN" ] ; then          # Not seen before?
392                 test $OPTLTR = i && unset RUN || RUN=-t
393             else
394                 echo "-t or -i duplicated or both were given"
395                 stdusage
396                 echo "exit 1"
397                 exit 1
398             fi;;
399         d ) test -n "$BOOTD" && {               # Seen boot dev before?
400                 echo "Multiple -d given. Boot drive already '$BOOTD'"
401                 stdusage
402                 echo "exit 2"
403                 exit 2
404             }
405             for N in ${DISKS[*]} ; do           # Drive given is valid?
406                test $N = $OPTARG && { BOOTD=$OPTARG ; break ; }
407             done
408             test -z "$BOOTD" && {               # Invalid drive given
409                 echo "Bad boot drive given '-$OPTLTR $OPTARG'"
410                 stdusage
411                 echo "exit 3"
412                 exit 3
413             }
414             ;;
415         p ) if BP=`expr "$OPTARG" : '.*[^0-9]'` # Part has non-numeric?
416             then
417                 echo "Bad partition char at char $BP in '$OPTARG'"
418                 stdusage
419                 echo "exit 4"
420                 exit 4
421             else
422                 BOOTP=$OPTARG
423             fi
424             ;;
425         * ) eval echo "Bad opt/param \$$((--OPTIND))/\'$OPTARG\' # $OPTIND"
426             stdusage
427             echo "exit 5"
428             exit 5
429             ;;
430     esac
431 done
433 #######################################################################
434 # Missing parameters process:, if all needed not found, error out
435 #######################################################################
436 test "$RUN" = bad -o -z "$BOOTD" -o -z "$BOOTP" && {
437     echo -e "Missing a needed parameter: you provided\n    \c"
438     echo "'$*'"
439     stdusage
440     echo "exit 6"
441     exit 6
444 #######################################################################
445 # check options vs. available components: set up variables and error
446 #     out if discrepancies are detected
447 #######################################################################
448 # See if toboot-boot, partition containing boot-time components, is
449 # available. Later we check to see if it has at least boot.b.
450 TBBOOT=$(mount | \
451     sed -n "/hd$BOOTD$BOOTP/s/^\(.*\) on \([^ ][^ ]*\).*$/\1 \2/p")
453 MPT='' ; MDV=''                                 # Mount point/device
454 if [ -n "$TBBOOT" ] ; then                      # Have something
455     set $TBBOOT ; test / != $2 && MPT=$2 ; MDV=$1
458 if [ "x$MDV" != "x${HDPFX}$BOOTD$BOOTP" ] ; then
459     echo "-p $BOOTP (${HDPFX}$BOOTD${BOOTP}) not mounted. Exit 7."
460     exit 7
463 # May have a wrong partition specified for boot-time components. This
464 # might yield an empty mount point when there *is* a mount point that is
465 # on another partition. This would give bad boot-time device. Check for
466 # this condition so we don't get burned.
468 if [ -z "$MPT" ] ; then                         # No special mount found
469     if [ -d $BDIR ] ; then                      # But we have a boot dir
470         stdchecks '' $BDIR $BOOTD $BOOTP $MDV 8
471         TBBOOT=${MPT}$BDIR                      # Set boot-time dir
472     else
473         echo "No boot directory found on ${HDPFX}$BOOTD$BOOTP. Exit 8."
474         exit 8
475     fi
476 elif [ "x/$(basename $MPT)" = "x$BDIR" ] ; then # A mounted boot-time pt
477     test -f $MPT/$BOOTB && TBBOOT=$MPT ||       # Assure boot blk exists
478         { echo "$MPT/$BOOTB not on $MDV. Exit 9." ; exit 9 ; }
479 elif [ -d $MPT$BDIR ] ; then                    # Boot dir in another FS
480     stdchecks $MPT $BDIR $BOOTD $BOOTP $MDV 10
481     TBBOOT=${MPT}$BDIR                          # Set boot-time dir
482 elif [ -d "$MPT/liloboot" ] ; then
483     stdchecks $MPT /liloboot $BOOTD $BOOTP $MDV 11
484     TBBOOT=${MPT}/liloboot                      # Set boot-time dir
485 else
486     echo "No boot directory found on ${HDPFX}$BOOTD$BOOTP. Exit 10."
487     exit 10
490 #######################################################################
491 # Set up the bios= variables to edit the CProto (lilo.conf-proto) file
492 #######################################################################
493 case $BOOTD in
494     a ) HDA=0x80;HDB=0x81;HDD=0x82
495         unset MD0 TD0 MD1 TD1
496         ;;
497     b ) HDA=0x81;HDB=0x80;HDD=0x82
498         MD0=0x80 TD0=0x81 MD1=0x81 TD1=0x80
499         ;;
500     d ) HDA=0x81;HDB=0x82;HDD=0x80
501         MD0=0x80 TD0=0x81 MD1=0x81 TD1=0x80
502         ;;
503     * ) echo "Frank Barrone: Holy Crap! How'd we get here Marie? Exit 12"
504         exit 12 ;;
505 esac
507 # Eliminate hijacking potential
508 rm -f hd$BOOTD${BOOTP}-boot.sh hd$BOOTD${BOOTP}-boot.out \
509     $WD/hd${BOOTD}$BOOTP-boot.conf
510 PUM=$(umask);umask 077
512 sed -e "s/=.HDA/=$HDA/" -e "s/=.HDB/=$HDB/" -e "s/=.HDD/=$HDD/" \
513     -e "s/\(.\).BOOTD/\1$BOOTD/" \
514     -e "s@=.TBBOOT@=$TBBOOT@" \
515     -e "/map-drive=/s/.MD0/$MD0/" -e "/to=/s/.TD0/$TD0/" \
516     -e "/map-drive=/s/.MD1/$MD1/" -e "/to=/s/.TD1/$TD1/" \
517     -e '/map-drive=$/d' -e '/to=$/d' \
518     $WD/$CProto \
519     > $WD/hd${BOOTD}$BOOTP-boot.conf
521 > hd$BOOTD${BOOTP}-boot.out                     # Empty log
523 #######################################################################
524 # default image process: -D overrides default= in prototype file. If
525 # no -D given, gets default from prototype file and makes a -D for lilo
526 # so it will be *visible* on $CONSOLE, in the script file and the log.
527 #######################################################################
528 test -z "$DBL" && {
529     DBL=$(grep default= $WD/hd${BOOTD}$BOOTP-boot.conf \
530         | head -1 | sed 's/.*default=//')
531     test -z "$DBL" && {
532         DBL=$(grep label= $WD/hd${BOOTD}$BOOTP-boot.conf \
533             | head -1 | sed 's/.*label=//')
534     }
535     echo "Note: default boot is $DBL"
536     echo "# default boot is $DBL" >> hd$BOOTD${BOOTP}-boot.out
539 #######################################################################
540 # make lilo script: combine variables and imperatives into shell file
541 # WATCH OUT! Those are *not* leading spaces on the lines between the
542 # "EOD" lines. Those lines use 1 leading tab and then enough spaces to
543 # maintain the visual indent. The "-EOD" removes *only* leading tabs, not
544 # leading spaces. In this case, it doesn't really matter though.
545 #######################################################################
546 cat > hd$BOOTD${BOOTP}-boot.sh <<-EOD
547         #!/bin/bash
548         lilo $RUN -v3 -b ${HDPFX}$BOOTD \\
549             -m $TBBOOT/hd$BOOTD${BOOTP}map \\
550             -C $WD/hd${BOOTD}$BOOTP-boot.conf \\
551             -D $DBL \\
552             >> hd$BOOTD${BOOTP}-boot.out 2>&1
553         less hd$BOOTD${BOOTP}-boot.out &> $CONSOLE
557     echo -e "\nInstall script to run is\n"
558     sed -e 's/^/    /'  hd$BOOTD${BOOTP}-boot.sh
559     echo
560     test -z "$RUN" && {
561         echo "=== INSTALLATION REQUESTED - WILL UPDATE BOOT BLOCKS ==="
562         echo -e "Run it? Y/[N] - \c" ; read A
563         test "x$A" != xY -a "x$A" != xy && {
564             echo "Script available in $WD/hd$BOOTD${BOOTP}-boot.sh"
565             exit 0
566         }
567     }
568 } &> $CONSOLE < $CONSOLE
570 cat hd$BOOTD${BOOTP}-boot.sh >> hd$BOOTD${BOOTP}-boot.out
571 echo "--- ABOVE COMMAND PRODUCED THIS LOG ---" >>hd$BOOTD${BOOTP}-boot.out
573 chmod u+x hd$BOOTD${BOOTP}-boot.sh
574 ./hd$BOOTD${BOOTP}-boot.sh
575 ----------------- CUT ALONG DOTTED LINE ------------------------------------
577 IV. SUPPORT
579     If you post to blfs-support with the subject "boot any hd", I'll keep an
580     eye open and try to help. But I expect you will have read and understood
581     the boot_any_hd.txt hint and the documents it references. I also expect
582     that any scripting problems have been investigated before you post. This
583     si hard enough to debug when its right on my own machines, no telling how
584     hard it would be to help a remote user.