From: basto@cactus.org (Luis Basto)
Newsgroups: comp.unix.aix,news.answers
Subject: AIX Frequently Asked Questions (Part 1 of 2) [REPOST]
Summary: This posting contains a list of Frequently Asked Questions 
         and their answers about AIX, IBM's version of Unix.
Keywords: AIX RS/6000 questions answers
Date: 16 Dec 92 06:26:56 GMT
Expires: 15 Jan 93 01:23:45 GMT
Reply-To: basto@cactus.org (Luis Basto)
Followup-To: comp.unix.aix

Archive-name: aix-faq/part1
Last-modified: Dec 12, 1992
Version: 2.0


Version: $Id: aix.faq,v 2.0 12/12/92 basto $

Frequently Asked Questions to AIX 3.x and IBM RS/6000
_____________________________________________________

This posting contains frequently asked questions (and answers) about the
IBM RS/6000 series workstations and AIX version 3.  All input is very
welcome, please mail it to basto@cactus.org.

The list is split into two articles so it can pass thru most mailers.
I cannot promise any precise periodic posting but I'll try to post an
updated FAQ roughly once a month to comp.unix.aix and to news.answers. 
Please let your input continue, I am most thankful for all of it.

If you see a From: line it means that whatever follows is either an
unabridged or slightly edited version of the input I have received, and
that I have not verified its contents.  If there is no From: line, I
probably know what I am talking about, and the entry is edited from
various sources.

All entries are numbered with major and minor subject number, e.g. 
3.05.  If the subject is preceded by an asterisk, that entry has been
changed or added since the last posting.

The comp.unix.aix group is really for AIX on the four platforms -- RT,
PS/2, 370 and RS/6000, but it has 90% or more of its traffic covering
AIX 3.x and the RS/6000.  The newsgroups comp.sys.ibm.pc.rt and
comp.sys.ibm.ps2.hardware discuss the PC/RT, mostly hardware and AOS 4.3,
and on PS/2 hardware respectively.  There is no group on AIX for the 370.

This article only covers AIX 3.x and the RS/6000, except when
specifically noted.

If you post questions to comp.unix.aix, please be sure to indicate:

- the machine type (not all questions are to the RS/6000) and brief 
  configuration, e.g. 64 MB RAM, 48 MB swap space (this is actually
  bad), 1.2 GB XYZ hard drive, etc.

- the exact AIX version number, i.e. AIX 3.1 is NOT sufficient, whereas
  AIX 3.1.5 or AIX 3.1 with the 3005 update is.
______________________________________________________________________________
Table of contents:

1.00  The AIX operating system - what is it?
1.01  I know neither Unix nor AIX - where do I find more information?
1.02  I am used to Unix systems programming, why should I learn SMIT?
1.03  What is the Object Database?
1.04  How do I get rid of the verbose error messages?
1.05  How do I make an informative prompt in the shell?
1.06  How do I import an /etc/passwd or /etc/group file from another box?
1.07  How do I put my own text into InfoExplorer?
1.08  Who has a termcap/terminfo source for aixterm or the HFT console?
1.09 *Which release of AIX do I have?
1.10  Some known problems, telnet, accounting, who
1.11  Other hints, fsck of /, X-windows and alt-cntl-backspace
1.12 *How do I shrink /usr?
1.13 *How do I shrink the default paging space on hd6?
1.14 *How do I make a filesystem larger than 2 Gig?
1.15  How do I see/change system parameters like number of processes per user?
1.16  My /dev/null seems to have disappeared or become a plain file, why?
1.17  The swapper seems to use extreme amount of paging space, why?
1.18  How much should I trust the ps memory reports?
1.19 *How do I mount a floppy disk as a filesystem?
1.20 *Some info about tape backups
1.21 *How do I do remote backup?
1.22  How do I backup a multi-disk volume group?
1.23  How do I put multiple backups on a single 8mm tape?
1.24 *How do I remove a committed lpp?
1.25 *My named dies frequently, why?
1.26 *How do I trace ethernet packets on an AIX system?

2.00  C/C++
2.01  I cannot make alloca work
2.02  How do I compile my BSD programs?
2.03  Isn't the linker different from what I am used to?
2.04  How do I link my program with a non-shared /lib/libc.a?
2.05  How do I make my own shared library?
2.06  Linking my program fails with strange error, why?
2.07 *What's with malloc()?
2.08  Why does xlc complain about 'extern char *strcpy()'
2.09  Why do I get 'Parameter list cannot contain fewer ....'
2.10  Why does xlc complain about '(sometype *)somepointer = something'
2.11  Some more common errors
2.12  Can the compiler generate assembler code?
2.13  Curses
2.14  How do I speed up linking?
2.15  What is deadbeef?

3.00  Fortran and other compilers
3.01  I have problems mixing fortran and C code, why?
3.02  How do I statically bind fortran libraries and dynamically bind
      C libraries?
3.03  How do I check if a number is NaN?

4.00  Public Domain software
4.01 *How do I find PD software?
4.02 *Are there any ftp sites?
4.03  General hints
4.04 *GNU Emacs
4.05 *gcc/gdb
4.06 *GNU Ghostscript 2.3
4.07 *TeX
4.08  Perl
4.09  X-Windows
4.10  bash
4.11  Elm
4.12 *Oberon 2.2
4.13 *Kermit
4.14  Gnu dbm
4.15  tcsh
4.16  Kyoto Common Lisp
4.17  TCL
4.18  Expect

5.00  Third party products
5.01  Disk/Tape/SCSI
5.02  Disks
5.03  Memory
5.04  Others
5.05  IBM List of third party products
5.06 *C++ compilers

6.00  Miscellaneous other stuff
6.01  Can I get support by email?
6.02  Some RS232 hints
6.03  VT100 key bindings for aixterm
6.04  What publications are available for AIX and RS/6000?
6.05  Some acronyms

7.00  How do I get this by mailserver or ftp?
7.01  Contributors
______________________________________________________________________________
1.00: The AIX operating system - what is it?

This is best answered by reading the text files in /usr/lpp/bos.  The
README file there contains general information and the bsdadm file
contains useful information if you know BSD and/or SystemV.

The last release for the RT PC is 2.2.1. The latest release for 
PS/2s and Intel architecture machines is AIX 1.3; for PS/2s only, 1.2.1.
For the RS/6000, there are two major levels, 3.1 and 3.2, and various
intermediate levels.


1.01: I know neither Unix nor AIX - where do I find more information?

Quite a number of questions posted to comp.unix.aix show that AIX is
people's first experience with Unix.  If this is the case with you, you
are advised to look at the other newsgroups in the comp.unix hierarchy,
in particular comp.unix.questions (for basic questions) or
comp.unix.wizards (for difficult questions).  These two groups have a
common FAQ posting as well.

If you need information about C programming, try comp.lang.c or comp.std.c,
the latter for Standard ANSI C issues.  comp.lang.c has a FAQ posting.


1.02: I am used to Unix systems programming, why should I learn SMIT?

Using SMIT is probably very different from your normal way of doing
system administration, but could prove very useful in the long run.  In
some areas, in particular TCP/IP, NFS, etc., you also have the
possibility of doing things the "normal" way, but it is unfortunately
difficult to know exactly when the "normal" way works.  Again, always
using SMIT, is probably your best way to go, even when you have to learn
a new tool.

What SMIT actually does is to call a large number of specific tools for
each part of the system administration.  The commands called and the
output they produce are stored in the files smit.script and smit.log in
your home directory.  Looking in smit.script may teach you more about
system administration.


1.03: What is the Object Database?

The Object Database Manager, ODM, stored in /etc/objrepos, is AIX's way
of storing all the system management information.  Under most
circumstances, only SMIT or the commands SMIT call (see above) should be
used to change the ODM.

A harmless way to look at the ODM is to use odmget <Class> where <Class>
is one of the files in /etc/objrepos.

The very interested user can use the ODM editor, odme, to navigate the
ODM in detail.  Modifying the ODM should only be attempted if you know
exactly what you are doing.
 

1.04: How do I get rid of the verbose error messages?

Many of the messages from the Unix commands are available in different
languages.  This is controlled by the LANG environment variable, the
default being En_US meaning English in the US.  All the default messages
have a message number associated with them, e.g.:

$ cat no-such-file
cat: 0652-050 Cannot open no-such-file.

If you prefer the terser Unix-looking error message, set your
environment LANG to C, and you will get:

$ cat no-such-file
cat: Cannot open no-such-file.


1.05: How do I make an informative prompt in the shell?

In the Korn Shell (ksh), the PS1 variable is expanded each time it is
printed, so you can use:

$ myhost=`hostname`
$ PS1='$LOGNAME@$myhost $PWD \$ '

to get, e.g. 

bengsig@ieibm1 /u/bengsig $

In the C-shell, use:

% set myhost=`hostname`
% alias cd 'chdir \!*' > /dev/null; set prompt="$LOGNAME@$myhost $cwd % "'
% cd

to get, e.g.

bengsig@dkunix9 /u/bengsig/aixfaq %

There is no easy solution in the Bourne Shell.  Use the Korn Shell instead.


1.06: How do I import an /etc/passwd or /etc/group file from another box?

Make sure that you run usrck and pwdck (/etc/passwd) and grpck
(/etc/group) to let AIX work its password/group magic.


1.07: How do I put my own text into InfoExplorer?

With AIX 3.1, you cannot do it.  AIX 3.2 has a product called
InfoCrafter that allows you to do that.


1.08: Who has a termcap/terminfo source for the HFT console?

The console used on the RISC System/6000, the PS/2 and the RT can be
used as a terminal on another system with the termcap below.  You can find
this and other termcaps in /lib/libtermcap/termcap.src, including IBM
specific ones.  The terminfo sources are stored in /usr/lib/terminfo/*.ti.
This termcap can also be used from an aixterm window.

hf|hft|hft-c|ibm8512|ibm8513|IBM_High_Function_Terminal:\
	:co#80:li#25:am:ht:\
	:cm=\E[%i%d;%dH:ti=\E[25;1H:te=\E[20h:\
	:nd=\E[C:up=\E[A:do=^J:ho=\E[H:\
	:bs:sf=\E[S:ec=\E[%dX:\
	:cl=\E[H\E[J:cd=\E[J:ce=\E[K:\
	:AL=\E[%dL:DL=\E[%dM:al=\E[L:dl=\E[M:\
	:im=\E[4h:ei=\E[4l:mi:\
	:dm=\E[4h:ed=\E[4l:\
	:so=\E[7m:se=\E[m:ul=\E[4m:ue=\E[m:\
	:md=\E[1m:mr=\E[7m:mb=\E[5m:me=\E[m:\
	:as=^N:ae=^O:sc=\E[s:rc=\E[u:\
	:kl=\E[D:kb=^H:kr=\E[C:ku=\E[A:kd=\E[B:kh=\E[H:\
	:kn#10:k1=\E[001q:k2=\E[002q:k3=\E[003q:k4=\E[004q:k5=\E[005q:\
	:k6=\E[006q:k7=\E[007q:k8=\E[008q:k9=\E[009q:k0=\E[010q:\
	:is=\Eb\E[m^O\E[?7h:rs=\Eb\E[m^O\E[?7h\E[H\E[J:


1.09: Which release of AIX or other products do I have?

The command 'lslpp -h bos.obj' will show all lines referring to the BOS, 
Basic Operating System.  E.g.:

Option Name          State      Event      Date      Release         User Name

-------------------- ---------- ---------- --------- --------------- ----------
bos.obj              INACTIVE   COMMIT     02/03/90  03.01.0000.0000 root
                     INACTIVE   APPLY      06/25/90  03.01.0000.0001 root
                     INACTIVE   COMMIT     06/25/90  03.01.0000.0001 root
                     INACTIVE   APPLY      11/16/90  03.01.0002.0015 root
                     INACTIVE   COMMIT     11/16/90  03.01.0002.0015 root
		     ACTIVE     COMMIT     05/07/91  03.01.0005.0012 root

gives the history for the BOS lpp.  The last line, column four, tells
that this is release 3.1.5.  (Note that '3' in 3005 has nothing to do
with '3' in 3.1.5 - we should stop calling the versions 3005, etc.  and
call it by its real version number 3.1.5).

To see a listing of everything installed use lslpp -l '*', then use
lslpp with the -h option as above to get a history of a particular lpp. 

Here is a description on IBM's release numbering scheme:

From: jswillia@nycvmic2.vnet.ibm.com

The output of lslpp -h bos.obj shows a release number similar to
03.01.0002.0003.

Contrary to your description and some other news items, this should be
referred to as 3.1.2 not 3002. The 3002 numbering is used to indicate
a PTF update tape. There are two types of PTF tapes 300x and 200x.
The 300x tapes are full PTF's to update all previous levels to 3.1.x level
The 200x tapes are incremental tapes and only apply to level 3.1.(x-1),
ie 2004 updates 3.1.3 to 3.1.4 and will not work with 3.1.2 at all,
whereas 3004 would update 3.1.0, 3.1.1, 3.1.2, and 3.1.3 upto level 3.1.4.
The release number is defined as follows, 03.01 is the major release number
shortened to 3.1 and the 0002 in the example is the minor release number.
Major releases are provided with full installable tapes, whereas minor
releases are obtained by applying a PTF update tape to a previous level
as indicated above. The fourth number is used by development and has no
validity(?) outside of development ( note it may be of interest during
defect resolution ).

For AIX 3.2, it's a completely different scheme.  You may come across
discussions on releases 3.2.0, 3.2.1, 3.2.2, or 3.2.3.  There is no
absolute way to tell which of these you are running since the newer
releases are simply 3.2.0 with some sets of PTFs added.  And since one
can apply selective fixes it is possible that there could be many
slightly different variations of 3.2 in use.  IBM is currently working
on resolving this situation.


1.10: Some known problems, telnet, accounting, who

There are known problems in telnetd in 3.1.2 and 3.1.3 (the RS/6000 may
lock when telnet'ing to it, use the 3001 telnetd or update to 3.1.5),
accounting has a number of problems, and 'who' often displays entries
that do not correspond to active sessions.

Following refers to 3.1.2 and 3.1.3.

The problem with telnetd seems to be solved in 3.1.5, I do not know about
accounting, but the problem with who is known not to be solved.  The
program below by jfh@rpp386.cactus.org (John F. Haugh) can be used to fix
up your /etc/utmp file:

#include <sys/types.h>
#include <utmp.h>
#include <fcntl.h>

main ()
{
	int	fd;
	struct	utmp	utmp;

	while (1) {
		if ((fd = open ("/etc/utmp", O_RDWR)) < 0)
			exit (1);

		while (read (fd, &utmp, sizeof utmp) == sizeof utmp) {
			if (utmp.ut_type == USER_PROCESS &&
					kill (utmp.ut_pid, 0) != 0) {
				lseek (fd, - (long) sizeof utmp, 1);
				utmp.ut_type = DEAD_PROCESS;
				write (fd, &utmp, sizeof utmp);
			}
		}
		close (fd);
		sleep (60);
	}
}

Another utmp program was posted to comp.sources.unix, volume 25, issue
96 by David W. Sanderson (dws@cs.wisc.edu) that also works on AIX 3.1.


1.11: Other hints, fsck of /, X-windows and cntl-alt-backspace

- Normally cntl-alt-backspace will kill the X session.  If you add the
  -T option when initializing X, this will not happen.

- You should never run fsck on mounted filesystems; you need to be in
  maintenance mode to run fsck on the root filesystem:

  1. boot from diskette
  2. select maintenance mode
  3. type /etc/continue hdisk0 exit (replace hdisk0 with boot disk if not
     hdisk0)
  4. fsck /dev/hd4


1.12: How do I shrink /usr?
From: mike@bria.UUCP (Michael Stefanik) and Richard Hasting

FOR AIX 3.1
-----------

 1) Make a backup of /usr

        find /usr -print | backup -ivf /dev/rmt0

    Use the appropriate tape device if it is not rmt0.

 2) shutdown to maintenance mode

        shutdown -Fm
 
 3) export LANG=C
 
 4) remove the filesystem and the logical volume
    ignore an error about the "dspmsg" command not found

        umount /usr
        rmfs /usr

 5) make a new logical volume hd2 and place it on rootvg with desired size

        mklv -yhd2 -a'e' rootvg NNN 

   where NNN is the number of 4 meg partitions

 6) create a filesystem on /dev/hd2

        crfs -vjfs -dhd2 -m'/usr' -Ayes -p'rw'

 7) mount the new /usr filesystem and check it

        /etc/mount /usr
        df -v

 8) restore from the tape; system won't reboot otherwise

        restore -xvf/dev/rmt0

 9) Sync and reboot the system; you now have a smaller /usr filesystem

FOR AIX 3.2
-----------

 1) Remove any unneeded files from /usr.

 2) Make sure all filesystems in the root volume group are mounted. If
    not, they will not be included in the re-installed system.

 3) Type "mkszfile". This will create "/.fs.size" that contains a list
    of the active filesystems in the root volume group that will be
    included in the installation procedure.

 4) Edit .fs.size. Change the size of /usr to what you want.

    Example: This .fs.size file shows /usr to be 40MB.

                   rootvg 4 hd2 /usr 10 40 jfs

    The number 10 is the number of physical partitions for the filesystem
    and the 40 is 40 MB. Most systems have a physical partition
    size of 4 MB. Therefore, the second number (40) will always be
    4 times the previous number (10). Note, however, that a model 320
    with a 120 MB drive will have a physical partition size of only 2 MB,
    and the total MB is therefore twice the number of physical partitions.
    The first number (4) in the .fs.size file represents the PP size.

    If you want to reduce the size of /usr from 40 MB to 32 MB, 
    edit the /usr entry to:

        rootvg 4 hd2 /usr 8 32 jfs

    IMPORTANT: Make sure that you DO NOT enter a value which is less
    than the size of the filesystem required to contain the current
    data. Doing so will cause the re-installation procedure to fail.

 5) chdev -l rmt0 -a block=512 -T

 6) Unmount all filesystems that are NOT in the root volume group.
 
 7) Varyoff all user-defined volume groups, if any

        varyoffvg VGname

 8) Export the user-defined volume groups, if any

        exportvg VGname

 9) With a tape in the tape drive, type

        mksysb /dev/rmt0

     This will do a complete system backup, which will include
     information (in the .fs.size file) for the installation procedure
     on how large the filesystems are to be created.

 10) Follow the instructions in the Installation Kit under "How to
     Install and perform maintenance from Diskettes" using the
     diskettes and tape that you created in the previous steps.
     DO NOT select the option "Reinstall AIX with Current System
     Settings" during the install procedure. The new system must be
     installed using the option "Install AIX with Current System
     Settings" for the logical volume size changes to take affect.

 11) When the operating system installation is complete, you may then
     import the information into your newly installed operating system
     for any user-defined volume groups.

         importvg -y VGname PVname

     where "VGname" is the name of the volume group, and "PVname" is
     the name of any one of the physical volumes in the volume group.

 12) Varyon your user-defined volume groups

         varyonvg VGname

 The reduction of the filesystems is now complete.


1.13: How do I shrink the default paging space on hd6?

1) create a paging space to use temporarily
   mkps -s 20 -a rootvg

2) change default paging space hd6 so it is not used at next reboot
   chps -a n hd6

3) For AIX 3.1, edit /etc/rc.boot4 and change swapon /dev/hd6;
   for AIX 3.2, edit /sbin/rc.boot and change swapon /dev/hd6
   swapon /dev/paging00

4) Update information in boot logical volume
   bosboot -a             (3.1)
   bosboot -a -d hdisk0   (3.2)

5) shutdown and reboot

6) remove current hd6 and create a new one of smaller size
   rmps hd6
   mklv -y hd6 -t paging rootvg <size of PS in 4 Meg blocks>

7) Re-edit /etc/rc.boot4 (3.1), /sbin/rc.boot (3.2) to swap to /dev/hd6
   swapon /dev/hd6

8) Update information in boot logical volume
   bosboot -a             (3.1)
   bosboot -a -d hdisk0   (3.2)

9) change current paging device (paging00) so it is inactive at next boot
   chps -a n /dev/paging00

10) shutdown, reboot, remove paging00 using the command:
    rmps paging00


1.14 *How do I make a filesystem larger than 2 Gig?

The largest filesystem under AIX is 2 Gigabytes because the largest
signed integer is 2**32 - 1.


1.15: How do I see/change system parameters like number of processes per user?

You can use SMIT as described below or simply use the lsattr/chdev pair. 
The former will list the current setting as in:

  # lsattr -E -l sys0 -a maxuproc
  maxuproc 40 Maximum # of processes allowed per user True

and you can then increase the maxuproc parameter:

  # chdev -l sys0 -a maxuproc=200
  sys0 changed

If you just type 'lsattr -E -l sys0' you will get a list of all parameters,
some of which can be changed - others not.

If you want to use smit, this procedure can be followed:

smit
  System Environments and Processes
    Change / Show Operating System Parameters
      - on this screen you can change by overtyping the following fields:
        - Maximum number of PROCESSES allowed per user
        - Maximum number of pages in block I/O BUFFER CACHE
        - Maximum Kbytes of real memory allowed for MBUFS
      - toggle fields exist for:
        - Automatically REBOOT system after a crash  (false/true)
        - Continuously maintain DISK I/O history (true/false)


1.16: My /dev/null seems to have disappeared or become a plain file, why?

The script /usr/etc/lsnfsexp has a bug in 3.1.3. Change line 100 from
  rm -rf ${TMP_FILE} >/dev/null 2>&1 /dev/null
to
  rm -rf ${TMP_FILE} >/dev/null 2>&1

and recreate /dev/null by:

  # mknod /dev/null c 2 2
  # chmod 666 /dev/null

This is fixed in release 3.1.5.


1.17: The swapper seems to use extreme amount of paging space, why?

When you run ps, you may see a line like:

USER   PID %CPU %MEM    SZ   RSS     TT STAT  TIME CMD
root     0 0.0%  14% 386528  8688      -    S 17:06 swapper

This is normal behavior, the swapper looks to ps like it has the entire
paging space plus real memory allocated.


1.18: How much should I trust the ps memory reports?
From: chukran@austin.VNET.IBM.COM

Using "ps vg" gives a per process tally of memory usage for each running
process.  Several fields give memory usage in different units, but these
numbers do not tell the whole story on where all the memory goes.

First of all, the man page for ps does not give an accurate description
of the memory related fields.  Here is a better description:

RSS - This tells how much RAM resident memory is currently being used
for the text and data segments for a particular process in units of
kilobytes.  (this value will always be a multiple of 4 since memory is
allocated in 4 KB pages).

%MEM - This is the fraction of RSS divided by the total size of RAM for
a particular process.  Since RSS is some subset of the total resident
memory usage for a process, the %MEM value will also be lower than actual.

TRS - This tells how much RAM resident memory is currently being used
for the text segment for a particular process in units of kilobytes. 
This will always be less than or equal to RSS.

SIZE - This tells how much paging space is allocated for this process
for the text and data segments in units of kilobytes.  If the executable
file is on a local filesystem, the page space usage for text is zero. 
If the executable is on an NFS filesystem, the page space usage will be
nonzero.  This number may be greater than RSS, or it may not, depending
on how much of the process is paged in.  The reason RSS can be larger is
that RSS counts text whereas SIZE does not.

TSIZ - This field is absolutely bogus because it is not a multiple of 4
and does not correlate to any of the other fields.

These fields only report on a process text and data segments.  Segment
size which cannot be interrogated at this time are:

       Text portion of shared libraries (segment 13)

       Files that are in use. Open files are cached in memory as
       individual segments.  The traditional kernel cache buffer
       scheme is not used in AIX 3.

       Shared data segments created with shmat.

       Kernel segments such as kernel segment 0, kernel extension
       segments, and virtual memory management segments.

Speaking of kernel segments, the %MEM and RSS report for process zero
are totally bogus for AIX 3.1.  The reason why RSS is so big is that the
kernel segment zero is counted twice.  For AIX 3.2, this has been
changed, but the whole story is still not known.  The RSS value for
process 0 will report a very small number of the swapper private data
segment.  It does not report the size of the kernel segment 0, where the
swapper code lives.

In summary, ps is not a very good tool to measure system memory usage. 
It can give you some idea where some of the memory goes, but it leaves
too many questions unanswered about the total usage.


1.19 *How do I mount a floppy disk as a filesystem?

From: op@holmes.acc.Virginia.EDU (Olaf Pors)

You can build a filesystem on a floppy and mount it, however the
filesystem will be read only.  The reason that the filesystem will be
read only is because AIX Version 3.1.5 cannot create a journal log on a
diskette.  The intended use is for temporary access to the read only
data.  The diskette file system must be unmounted after use and during
system backup procedures or errors could occur.

To make the read only filesystem on a floppy:

1. Make a subdirectory on an existing filesystem on the hardfile, and
   place all of the files that the diskette will contain into this
   subdirectory.

2. Enter the following command to create a prototype file containing
   information about the new filesystem, in the example /dir_struct
   is the pathname of the subdirectory created in step 1, and
   proto_filename is the name of the prototype file to be created.

         proto /dir_struct > proto_filename

3. Place your floppy disk into the drive and format it.

4. Edit the prototype file and replace the first line with the following:

         <noboot> 0 0

5. Enter the following command to make the filesystem on your floppy:

          mkfs -p proto_filename -V jfs /dev/fd0

6. Create the directory upon which you will mount the floppy based
   filesystem, or you can use the /mnt directory.  Enter the following
   command to mount the filesystem:

          mount -r -V jfs /dev/fd0 /your_mount_point

7. To unmount the filesystem, use the command:

          umount /dev/fd0

Since the filesystem is read-only it may be of limited use but if you
are going to use it for utility programs and other data that does not
change much, it still may be useful.  If you need to change the data,
you can copy the directory from the floppy into another directory, make
your modifications, and remake the filesystem using this procedure.


1.20  Some info about tape backups
From: Craig Anderson

The following supplements the information on rmt devices in
InfoExplorer.  It is based on my own personal experience with IBM tape
drives running on AIX 3.1.  No warranty is expressed or implied.

CONFIGURING THROUGH SMIT:
    BLOCK size (0=variable length)		(ALL)
	Sets the tape block size.  When reading, the block size must be
	set to the block size set when the tape was written.  When
	using some commands, tapes written with ANY block size can be
	read if the block size is set to 0 (variable length) (see
	"BLOCK SIZES" below).

    Use DEVICE BUFFERS during writes		(ALL)
	Set to yes, the device will buffer data internally on writes.
	This greatly improves performance, but under certain cases may
	be undesirable since the data is not written to tape before
	returning a good indication.

    Use EXTENDED file marks			(8mm only)
	Extended file marks take up much more space than short (or
	non-extended) file marks.  But extended file marks can be
	overwritten, allowing data not at the beginning of tape to be
	overwritten (see "FILE MARKS" below).

    RETENSION on tape change or reset		(1/4" only)
	If set to "no" then the tape will not be retentioned
	automatically when the tape is inserted.  Note that this will
	take effect only after the device is used.


FILE MARKS:
     Tape devices support multiple tape files.  Tape files are the
     result of a backup/cpio/tar/dd type command, where the device is
     opened, written to, and closed.  Because tapes allow large
     quantities of data to be written on a single tape, several backups
     (that is, tape files), may be combined on one physical tape.
     Between each tape file is a "tape file mark" or simply "file
     mark".  These file marks are used by the device driver to indicate
     where one tape file ends and another begins.

                              B       E
                   <-------   O       O   ------->
                              T       T
              __ ____________________________ _______________
     physical | \            |       |      \             |physical
     beginning|  \           | tape  |       \            | end
       of     |   \          | file  |        \           |  of
      tape    |    \         | mark  |         \          | tape
              |_____\________|_______|__________\_________|
 
     Note that there is a distinction between the beginning of tape
     (BOT) side of a file mark and the end of tape (EOT) side of a file
     mark.  If the head is on the BOT side of a file- mark, "tctl fsf
     1" command will move only to the EOT side of the same file mark.

     With the 1/4" tape drive, writing can only take place
     sequentially, or after blank tape has been detected.  You cannot
     write over data on the tape (except at BOT).  If you wish to add
     data to a tape which has been written and then rewound you should
     space forward file mark until an error occurs.  Only then can
     you start writing again.

     With an 8mm tape drive, writing can only take place before blank
     tape, an EXTENDED file mark, or at BOT.  Thus if several backups
     have been made on one tape and you wish to overwrite one of the
     backups, position the tape to the place you wish to start writing
     and issue the following commands:
	tctl bsf 1
	tctl eof 1
     The first command skips back to the BOT side of the same file
     mark.  The second command rewrites the file mark (writing is
     allowed before extended file marks).  The erase head will erase
     data ahead of the write head, so that after writing the file mark
     the head will be positioned before blank tape.  Only after this
     may you start writing over data in the middle of the tape.  (All
     data beyond where you are currently writing will be lost).  Note
     that you cannot write over short file marks.  In order for this to
     work, the tape must have been written with extended file marks
     (use smit to change this).

     With the 9-track drive writing can take place anywhere on the
     tape although overwriting single blocks of data is not supported.

     On the 8mm drive extended filemarks use 2.2 megabytes of tape and
     can take up to 8.5 seconds to write.  Short filemarks use 184K
     and take up to 1.5 seconds to write.

BLOCK SIZES:
     When data is written to tape it is written in blocks.  The blocks
     on a tape are separated by inter-record gaps.  It is important to
     understand the structure of the written tape in order to
     understand the problems which can occur with changing block
     sizes.

     In fixed block size mode all blocks on the tape are the same
     size.  They are the size of the block size set in the device
     configuration.  All read()s and write()s to the tape drive must be
     a multiple of the fixed block size.

     In fixed block mode a read() will return as many blocks as needed
     to satisfy the read() request.  If a file mark is encountered
     while reading the tape only the data up until the file mark will
     be returned.

     It is not possible for the tape drive to read a tape whose block
     size is not the same as the block size in the device
     configuration.  (Unless the device configuration is in variable
     size blocks.)

     In variable block size (0) mode, the blocks written on the tape
     are the size of the read() and write() requests to the device
     driver.  In this case, the actual block sizes on the tape can be
     changed using the options to the backup commands (tar -C, cpio -C,
     backup -C).

     In variable mode, read() requests greater than size of the block
     on the tape will return only the data from the next block on the
     tape.  It is this feature that allows tapes written in any block
     size (fixed or variable) to read with the dd command (the output
     from the dd command may be piped to restore, tar, or cpio for
     example.)  Note that backup, tar, and cpio cannot read all tapes
     by using a large block size because they assume there is an error
     if they get a short read().
		dd ibs=128k obs=16k if=/dev/rmt0 | ...

     The tape head is always positioned at an inter-record gap, file
     mark, or blank tape after reading or writing.

     With the 8mm tape drive, using a fixed block size which is not a
     multiple of 1K is inefficient.  The 8mm tape drive always writes
     internally in 1K blocks.  It simulates the effect of variable
     block sizes, but, for example, using a fixed block size of 512
     bytes (or using variable block size and write()ing 512 bytes at a
     time) wastes one half of the tape capacity and gives only one half
     the maximum transfer rate.


EXCHANGING DATA WITH NON-UNIX AND OTHER VENDORS MACHINES:
     Many tape drives support both variable and fixed block sizes.

     Variable block mode writes block sizes the size of the write
     command issued (tar and backup specify this with the -b option). 
     In fixed mode, block sizes are fixed and all writes must be a
     multiple of the fixed block size.

     Unix often internally chops larger reads and writes up into
     manageable pieces (often 65535, 65534, or 65532 bytes) before
     doing the actual reads and writes.  This means reads and writes of
     64K bytes are often broken up into a 65535 byte record and a 1
     byte record (In fixed mode the write will fail).  Block sizes >=
     64K (-C128 and greater) should be avoided for this reason.  AIX
     does not break up read and write requests, but be aware of the
     situation on other machines.

     If the tape is written in an unknown block size then set the
     device configuration in smit to use variable size blocks, use the
     "dd" command with a large input block size, and pipe it to the
     restore command.  For example:
	  chdev -l rmt0 -a block_size=0
	  dd if=/dev/rmt0 ibs=128k obs=16k | tar -tvf-


1.21: *How do I do remote backup?
From: oquinn@elder.austin.ibm.com

You can back up files on a remote tape drive with:

  tar -cBf - . | rsh REMOTEHOST "tar -xBf /dev/TAPEDEVICE"


From: kraemerf@franvm3.VNET.IBM.COM (Frank Kraemer)

mksysb will not back up to remote tape devices. Frank provided the
following script to do remote backups.

#!/bin/ksh
# @(#) Create a backup tape of the private user data.
#=================================================================#
#   Script :  usave.sh                                            #
#   Author :  F. Kraemer                                          #
#   Date   :  92/02/19                                            #
#   Update :  92/10/29                                            #
#   Info   :  the ultimative backup script                        #
#   Example:  usave.sh /dev/rmt0      -  save to local tape       #
#             usave.sh /save/save.me  -  save to local file       #
#             usave.sh /tmp/pipe      -  save to remote tape      #
#-----------------------------------------------------------------#
PS4="(+) "
#set -x
PROG=$(basename $0)
HOST=$(hostname)
TODAY=$(date +%H:%M:%S)
#-----------------------------------------------------------------#
# cleanup                                                         #
#-----------------------------------------------------------------#
cleanup ()
{
ec=$1
error=$2
case "$ec"
in
   "$USAGE_EC")    # usage error
     error="Usage:\t$PROG DeviceName\n" 1>&2
    ;;
   "$NOTAP_EC")    # Tape error
     error="error:\t$PROG: $DEVICE is not available on the system.\n" 1>&2
    ;;
   "$LISTE_EC")    # list error
     error="error:\t$PROG: could not create tar list for $LOGNAME.\n" 1>&2
    ;;
   "$NOTAR_EC")    # tar command error
     error="error:\t$PROG: tar command failed.\n" 1>&2
    ;;
   "$PIPEP_EC")    # pipe error
     error="error:\t$PROG: mknod command failed.\n" 1>&2
    ;;
   "$NORSH_EC")    # rsh error
     error="error:\t$PROG: rsh - Remote Shell command failed.\n" 1>&2
    ;;
   "$RHOST_EC")    # remote host error
     error="error:\t$PROG: Remote Host unknown.\n" 1>&2
    ;;
   *)
   ;;
esac
case "$DEVICE"
in
    #
    # Fix the block size if $DEVICE is a tape device
    #
    /dev/rmt[0-9]*)
        echo "\n\t$PROG: Rewinding tape to begin.........(please wait)\n"
        tctl -f $DEVICE rewind 2>/dev/null
        ;;
    *) ;;
esac
rm -f ${LIST} ${PIPE} 2>/dev/null
[ -n "$error" ] && echo "\n${error}\n"
trap '' 0 1 2 15
exit "$ec"
}
#-----------------------------------------------------------------#
# Variables.                                                      #
#-----------------------------------------------------------------#
USAGE_EC=1                         # exit code for usage error
NOMNT_EC=2                         # exit code wrong device name
NOTAP_EC=3                         # exit code no tape available
LISTE_EC=4                         # exit code backup list error
NOTAR_EC=5                         # exit code for wrong tar
TRAPP_EC=6                         # exit code for trap
PIPEP_EC=7                         # exit code for pipe
RHOST_EC=8                         # exit code for bad ping
NORSH_EC=9                         # exit code for bad rsh
DEVICE="$1"                        # device to tar into
LIST="/tmp/.tar.$LOGNAME.$$"       #
REMOTEH=""                         # Remote host for backup
REMOTET=""                         # Remote tape for backup
tapedev=                           #
PIPE="/tmp/pipe"                   # Pipe for remote backup
#-----------------------------------------------------------------#
# main()                                                          #
#-----------------------------------------------------------------#
tput clear
echo "\n\t$PROG started from $LOGNAME@$HOST on $TERM at $TODAY.\n"
rm -f $LIST 2>/dev/null
#-----------------------------------------------------------------#
# Trap on exit/interrupt/break to clean up                        #
#-----------------------------------------------------------------#
trap "cleanup $TRAPP_EC \"Abnormal program termination. $PROG"\"  0 1 2 15
#-----------------------------------------------------------------#
# Check command options                                           #
#-----------------------------------------------------------------#
[ "$#" -ne 1 ]  &&  cleanup "$USAGE_EC" ""
#-----------------------------------------------------------------#
# Check device name                                               #
#-----------------------------------------------------------------#
[ `expr "$DEVICE" : "[/]"` -eq 0 ] && cleanup "$NOMNT_EC" \
        "$PROG: Backup device or file name must start with a '/'."
#-----------------------------------------------------------------#
# Check tape device.                                              #
#-----------------------------------------------------------------#
case "$DEVICE"
in
    #
    # Fix the block size if $DEVICE is a tape device
    #
    /dev/rmt[0-9]*)
        #
        echo "\n\t$PROG: Verify backup media ($DEVICE)............\n"
        #
        # see if a low or high density tape device was specified
        # (eg rmt0.1)
        density="`expr $DEVICE : \
                "/dev/rmt[0-9]*\.\([0-9]*\)"`"
        #
        # strip /dev/ from device name and
        # get the base name (eg translate:
        # /dev/rmt0.2 to rmt0)
        #
        tapedev="`expr $DEVICE : \
                "/dev/\(rmt[0-9]*\)[\.]*[0-9]*"`"
        #
        # Check if the tape is defined in the system.
        lsdev -C -c tape -S Available -F "name" | grep $tapedev >/dev/null 2>&1
        rc=$?
        [ "$rc" -ne 0 ] && cleanup "$NOTAP_EC" ""
        #
        # Restore old tape name.
        #
        [ "${density:-1}" -lt 4 ] && density=1 || density=5
        DEVICE="/dev/${tapedev}.${density}"
        echo "\n\t$PROG: Insert a tape in ($DEVICE)........(press enter)\n"
        read TEMP
        echo "\n\t$PROG: Rewinding tape to begin...........(please wait)\n"
        tctl -f $DEVICE rewind 2>/dev/null
        ;;
    #
    # Backup is done on remote host. The remote shell facility
    # must be set up and running.
    #
    ${PIPE}*)
        #
        echo "\n\t$PROG: Assuming remote backup via network.\n"
        echo "\t$PROG: Enter name of Remote Host   ===> \c"
        read REMOTEH
        echo "\n\t$PROG: Pinging Remote Host to test connection.\n"
        ping ${REMOTEH} 1 1 >/dev/null 2>&1
        rc=$?                                    # give up unknown host
        [ "$rc" -ne 0 ] && cleanup "$RHOST_EC" ""
        JUNK=$(rsh ${REMOTEH} "/usr/sbin/lsdev -C -c tape -S Available")
        rc=$?                                    # give up rsh failed
        [ "$rc" -ne 0 ] && cleanup "$NORSH_EC" ""
        echo "\t$PROG: Available Tapes on ${REMOTEH} are :\n\n\t\t${JUNK}\n"
        echo "\t$PROG: Enter name of Remote Tape (e.g. /dev/rmt0) ===> \c"
        read REMOTET
        echo "\n\t$PROG: Insert tape on ${REMOTEH} in ${REMOTET}..(press enter)"
        read TEMP
        echo "\t$PROG: Rewinding Remote Tape ${REMOTET} on ${REMOTEH}.\n"
        rsh ${REMOTEH} "tctl -f ${REMOTET} rewind"
        rc=$?                                    # give up rsh failed
        [ "$rc" -ne 0 ] && cleanup "$NOTAP_EC" ""
        rm -f ${PIPE} 2>/dev/null
        mknod ${PIPE} p
        rc=$?                                    # give up mknod failed
        [ "$rc" -ne 0 ] && cleanup "$PIPEP_EC" ""
        cat ${DEVICE} | rsh ${REMOTEH} "dd of=${REMOTET} obs=100b 2>/dev/null" &
        ;;
    *)  ;;
esac
#-----------------------------------------------------------------#
# Prepare the list.                                               #
#-----------------------------------------------------------------#
echo "\n\t$PROG: Create list of files to be saved...."
find $HOME -print > $LIST
rc=$?
[ "$rc" -ne 0 ] &&  cleanup "$LISTE_EC" ""
#-----------------------------------------------------------------#
# tar the files.                                                  #
#-----------------------------------------------------------------#
echo "\n\t$PROG: Changing current directory to (/)...."
cd / > /dev/null 2>&1
echo "\n\t$PROG: Running tar format backup from user ($LOGNAME)...."
tar -cvf "$DEVICE" -L "$LIST"
rc="$?"
[ "$rc" -ne 0 ]  && cleanup "$NOTAR_EC" ""
#-----------------------------------------------------------------#
# Backup completed                                                #
#-----------------------------------------------------------------#
TODAY=$(date +%H:%M:%S)
echo "\n\t$PROG ended at $TODAY............................\n\n"
cleanup 0
#-----------------------------------------------------------------#
# EOF                                                             #
#-----------------------------------------------------------------#


1.22: How do I backup a multi-disk volume group?
From: pack@acd.ucar.edu (Daniel Packman)

[ Editor's note: I have not verified this procedure.  I would actually
  recommend NOT to have one volume group span multiple disks unless you
  really need such big logical volumes. ]

  1. If you have a set of three or more disks in a volume group.
     (typically 3 for 5xx machines with three internal drives;
     with only two, the procedures outlined here have to be modified
     to ignore the fact that you don't have a quorum in the volume group)

  2. If one drive has failed (usually only one fails at a time :-) )

It is possible to go through a service boot and (if we say the volume
group is called rootvg and one of the 2 good disks on it is called hdisk0):

  importvg -y rootvg hdisk0
  varyonvg -f -n -m1 rootvg

These commands will work, but give error messages.  If you wish to mount
a user filesystem, say /u on logical volume /dev/lv00, then

  mount -f /dev/lv00 /v

will work only if the jfslog, the journaled file system log device, is not
on the damaged disk.  If it is, you must (and can in any case) mount the
filesystem read-only:

  mount -f -r /dev/lv00 /v

This crucial and rather obvious point baffled several level 3 support
personnel at Austin as well as myself for almost a week.  Once the file
system(s) of interest are available, then they can be saved to tape for
restoration later.  Of course, one can expect only about two thirds of a
filesystem to be recoverable if it spans all 3 physical disks.  One
other point to remember is that the standard boot procedure from floppy
includes the restore command but does not include the backup command. 

******************************************************************************
* If you do not have other RS6000 machines at your site is is imperative     * 
* that you either build a bootable tape which includes either restore or     * 
* tar or cpio (a bootable floppy set will not have enough space) or at the   *
* very least copy onto a spare floppy backup, cpio, or tar.  The floppy      *
* should be created with backup -ivq so that its contents can be read into   *
* the memory resident system after booting.                                  *
******************************************************************************

All is not lost if tar, cpio or backup are available on an undamaged
disk that can be mounted.  Since tar and cpio are in /bin, they may both
very well be unavailable.

It is a very good idea for those who have tape devices to build a
bootable tape with their desired extra commands in it.  Follow the
instructions from IBM but add your desired commands to the following
three files:

    /usr/lpp/bosinst/tape2
    /usr/lpp/bosinst/diskette/boot2
    /usr/lpp/bosinst/diskette/inslist

If you have anything other than a minimum memory configuration, you
should be able to add many commands.


1.23: How do I put multiple backups on a single 8mm tape?
From: kerm@mcnc.org (Cary E. Burnette)

There are two possible solutions to this, which both use the /dev/rmt0.1
device which is non-rewinding.

SOLUTION #1
-----------

To put multiple backups on a single tape, use /dev/rmt0.1, which is a
no-rewind device, using either rdump or backup (both by name & inode
work).  Using rdump or backup "byinode" both generate the message that
the tape is rewinding but actually do not.  This is an example that
would work on my system:

# rsh remote1 -l root /etc/rdump host:/dev/rmt0.1 -Level -u /u
# rsh remote2 -l root /etc/rdump host:/dev/rmt0.1 -Level -u /u
# tctl -f /dev/rmt0.1 rewind       # rewinds the tape

where I am implementing the command from host.
To restore a table of contents of the first I would use 

# restore -f /dev/rmt0.1 -s1 -tv

where the -s1 flag tells restore to go to the first record it comes
across on the tape.  To get the second type in exactly the same once
again.  Basically -s(Number) stands for - go to Number record from this
spot.  It works pretty well.


SOLUTION #2
-----------

Steve Knodle
Educational Resources Center
Clarkson University

I use:
------------------- Dump.sh --------------------
CONTENTSFILE=`date |dd conv=lcase |sed -e 's/19//' |awk '{print $6 $2 $3}'`
set -x
LEVEL=$1
shift

backup -c -b 56 -$LEVEL -uf /dev/rmt0.1 /
backup -c -b 56 -$LEVEL -uf /dev/rmt0.1 /usr
backup -c -b 56 -$LEVEL -uf /dev/rmt0.1 /u
tctl -f /dev/rmt0 rewind

touch /usr/local/dumps/Contents.$CONTENTSFILE
echo "Dumping /" >>/usr/local/dumps/Contents.$CONTENTSFILE
restore -t -s 1 -f /dev/rmt0.1 >>/usr/local/dumps/Contents.$CONTENTSFILE
echo "Dumping /usr" >>/usr/local/dumps/Contents.$CONTENTSFILE
restore -t -q -s 1 -f /dev/rmt0.1 >>/usr/local/dumps/Contents.$CONTENTSFILE
echo "Dumping /u" >>/usr/local/dumps/Contents.$CONTENTSFILE
restore -t -q -s 1 -f /dev/rmt0.1 >>/usr/local/dumps/Contents.$CONTENTSFILE
tctl -f /dev/rmt0 rewind

I process the table-of-contents first by a little program that does
common prefix encoding, and then compress.

This gives a table of contents file I can keep on-line until the tape
is reused.


1.24 *How do I remove a committed lpp?
From: drb@chmeds.ac.nz (Ross Boswell)

This seems to be a common problem.  I got the following script from IBM
NZ AIX software support.  As far as I know, it works -- I used it to
remove unwanted fonts.  I have no official permission to post it -- use
it at your own risk!

#!/bin/ksh
#
# Permanently remove a product from disk and AIX databases
#

if [ `whoami` != "root" ] ; then
  echo You must be root to run this script.
  exit 1
fi

if [ `uname -a | awk '{print $1$4$3}'` != "AIX32" ] ; then
  echo This script only works on AIX 3.2.
  exit 1
fi

TMP_FREE=`df /tmp | awk '$3 ~ /[0-9]/{print $3}'`
if [ "$TMP_FREE" -lt 1000 ] ; then
   echo There is not enough room in your /tmp directory.
   echo You need 1000 KB free, and you have only $TMP_FREE KB free.
   echo Either remove some stuff from /tmp, or use chfs to make it bigger.
   exit 1
fi

ODMDIRS="/etc/objrepos /usr/lib/objrepos /usr/share/lib/objrepos"
ODMDIR=/usr/lib/objrepos
export ODMDIR

if [ $# -lt 1 ]
then
  echo usage: $0 lppname [lppname ...]
  echo lppname is a string compatible with grep, ie "X11" or "PHIGS"
  echo typing   $0 PHIGS   will remove all LPPs with PHIGS in their name.
  exit 1
fi

NAMES=$1
shift
while [ $# -gt 0 ] ; do
  NAMES="$NAMES|$1"
  shift
done
echo "Searching for lpps with egrep \"$NAMES\"...\c"

for ODMDIR in $ODMDIRS ; do
  if [ ! -d $ODMDIR -o ! -w $ODMDIR ] ; then
     echo $ODMDIR is not writeable or is not a directory.
     echo I hope this is because you are a /usr client or diskless.
     echo If you are not a diskless or a /usr client, you should stop.
     echo "Enter y to continue ->\c"
     read answer
     if [ "$answer" != "y" ] ; then
       exit 0
     fi 
  fi
  TMP=`odmget lpp | awk -F\" '/name/ {print $2}' | egrep "$NAMES"`
  LPPS=`echo $LPPS $TMP`
done

if [ "$LPPS" = "" ]
then
  echo "failed.\nNo LPP with the name $NAMES detected."
  exit 1
fi
echo ok.

for ODMDIR in $ODMDIRS ; do
  mkdir -p /tmp/rmlpp/$ODMDIR > /dev/null 2>&1
done

> /tmp/listOfFilesToRM$$    # truncate temporary file, just in case.
echo
echo This script is about to attempt to remove an LPP from your system.
echo I say attempt, because it could fail.  If it fails, you may have
echo to at least reload the LPP.  Use the \"lppchk\" command to make sure
echo all is well with your system.
echo
# Loop through all the LPP names found.
for LPP in $LPPS
do
  DESCR=none
  answer=""

  # find the LPP ids.  They will be different in the three SWVPD databases.
  for ODMDIR in $ODMDIRS ; do
    # get the lpp id for this ODMDIR (yes, they are different)
    LPPID=`odmget -q name=$LPP lpp | grep lpp_id | sed 's/.* = //'`

    # did we find the LPP?
    if [ "$DESCR" = "none" -a "$LPPID" != ""  ] ; then
      # all the descriptions should be the same
      DESCR=`odmget -q name=$LPP lpp | grep description | sed 's/.* = //'`
      echo "Delete $LPP, $DESCR?"
      echo "y or (n) ->\c"
      read answer
      if [ "$answer" != "y" ] ; then # jump back up to the next LPP name
        continue 2
      fi
    fi
    # if there is no DESCR, then we didn't find the LPP.  Weird.
    if [ "$DESCR" = "none" -o "$LPPID" = "" ] ; then
      continue
    fi
	SOMETHING_DONE_FLAG=true
    # Optionally, save the ODM stuff we are about to remove,
    # in case something goes wrong.  The problem is it is difficult
    # to determine if something really did fail, since these commands
    # don't return any decent error return codes.
    odmget -q lpp_id=$LPPID history   > /tmp/rmlpp/$ODMDIR/$LPP.history
    odmget -q name=$LPP lpp           > /tmp/rmlpp/$ODMDIR/$LPP.lpp
    odmget -q lpp_name=$LPP product   > /tmp/rmlpp/$ODMDIR/$LPP.product
    # Get the list of files and links to remove later....
    odmget -q lpp_id=$LPPID inventory > /tmp/rmlpp/$ODMDIR/$LPP.inventory
    awk -F\" '/loc/ {print $2}' /tmp/rmlpp/$ODMDIR/$LPP.inventory | \
      sed 's/,/ /g' >> /tmp/listOfFilesToRM$$
    odmdelete -o history -q lpp_id=$LPPID   > /dev/null 2>&1
    odmdelete -o lpp -q name=$LPP           > /dev/null 2>&1
    odmdelete -o product -q lpp_name=$LPP   > /dev/null 2>&1
    odmdelete -o inventory -q lpp_id=$LPPID > /dev/null 2>&1
  done
done

if [ "$SOMETHING_DONE_FLAG" = "true" ] ; then

  echo ODM work is done.  Now, time to delete files....

  # This could be catastrophic if there is a problem.  For example,
  # if the ODM database for an application had / as one of its files.
  # You be the judge.  Here's your rope....
  cat /tmp/listOfFilesToRM$$ | sort -r | uniq | xargs rm -rf

  rm -rf /tmp/listOfFilesToRM$$
  echo done.
fi

# take this line out if you want to save your ODM saved files.
rm -rf /tmp/rmlpp

exit 0


1.25 *My named dies frequently, why?

Running on 3.2, named dies frequently on network's primary name server.

From: jpe@ee.egr.duke.edu (John P. Eisenmenger)

Try the following:

     stopsrc -s named	# stop running named
     setenv MALLOCTYPE 3.1	# use 3.1 memory allocation algorithm
     /etc/named ...		# don't use smit to start named

You might be able to use startsrc/smit after setting MALLOCTYPE and get
the same effect, but I'm not sure.

[According to John, the problem is malloc() in the named code. He
 also suggests using Berkeley's bind, which he has ported and can be
 ftp'ed from ftp.egr.duke.edu, /archives/network/bind-4.8.3.tar.Z. -ed]


1.26: How do I trace ethernet packets on an AIX system?
From: afx@muc.ibm.de (Andreas Siegert)

Do the following:

     iptrace -i en0 /tmp/ipt

The iptrace backgrounds.  Find its process id and kill it when you are
ready.  Then run

     ipreport -rns /tmp/ipt >/tmp/ipr

and look at the output.  The current version of Info does not document
the r, n and s options but they are quite useful for layering the output.

______________________________________________________________________________
2.00: C/C++

Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users' Guide and a Reference Manual.

The compiler can be invoked with either xlc to invoke it in ANSI mode
and cc to invoke it in RT (i.e. IBM 6150 with AIX 2) compatible mode. 
The default options for each mode are set in the /etc/xlc.cfg file, and
you can actually add another stanza and create a link to the /bin/xlc
executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport contains useful information,
in particular for users used to BSD.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.


2.01: I cannot make alloca work

A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

In earlier releases of the C compiler, alloca did not work well with the
optimizer turned on (-O flag), but this problem is solved now.  The fix
was probably in release 1.1.3 of xlc.obj, it is for sure in 1.1.5.


2.02: How do I compile my BSD programs?

The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.1.  The contents of this file can
actually be very useful for others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.


2.03: Isn't the linker different from what I am used to?

Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.


2.04: How do I link my program with a non-shared /lib/libc.a?

  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.


2.05: How do I make my own shared library?

To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Likewise, you cannot split your code
into more than one shared object if externals in one object refer to
another one. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----------------------------------------------------------
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----------------------------------------------------------
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----------------------------------------------------------
    #!
    addint
---- sub2.exp ----------------------------------------------------------
    #!
    printint
---- usesub.c ----------------------------------------------------------
    main()
    {
      printint( addint(5,8) );
    }
---------------------------------------------------------------

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $


2.06: Linking my program fails with strange errors.  Why?

Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e.  you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

-- 
Luis Basto
Computer Sciences Corporation
Internet: basto@cactus.org
Usenet:   cs.utexas.edu!mavrick!luis