Subject: dump bug?
To: None <netbsd-help@NetBSD.ORG, current-users@NetBSD.ORG>
From: Brook Milligan <brook@trillium.NMSU.Edu>
List: current-users
Date: 01/14/1997 13:46:27
I am having a problem with dump not distinguishing union mounts from
ffs mounts (both specified in fstab).  The problem is that when dump
reads /etc/fstab it contructs its data structure in reverse order
compared with the file itself.  As a result, when dump tries to match
a filesystem argument it matches the LAST one in /etc/fstab.
Normally, this is not a problem because a filesystem name (e.g., /usr)
only occurs once in /etc/fstab.  With union mounts, however, names may
occur twice, once for the actual device mount and once for the union
mount.  In that case the union mount typically (I think) comes second
in /etc/fstab, but is the entry that dump incorrectly matches first.

QUESTION:  Is there a reason for dump to construct its data structure
representing /etc/fstab in reverse order?  If not, the patch below is
one solution for reversing the orientation of the linked list that
solves this problem.

Have I missed something obvious here?

For more information, I've included below the relevant portion of the
dump source code, a portion of my /etc/fstab, and a portion of the df
output that illustrates the problem.  Dump is matching the union mount
for /usr/src-dist instead of the device mount (/dev/sd2e).

Thanks for your help.

Cheers,
Brook

===========================================================================
/*	$NetBSD: optr.c,v 1.4 1996/05/18 16:16:17 jtk Exp $	*/

void
getfstab()
{
	register struct fstab *fs;
	register struct pfstab *pf;

	if (setfsent() == 0) {
		msg("Can't open %s for dump table information: %s\n",
		    _PATH_FSTAB, strerror(errno));
		return;
	}
	while ((fs = getfsent()) != NULL) {
		if (strcmp(fs->fs_type, FSTAB_RW) &&
		    strcmp(fs->fs_type, FSTAB_RO) &&
		    strcmp(fs->fs_type, FSTAB_RQ))
			continue;
		fs = allocfsent(fs);
		if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
			quit("%s\n", strerror(errno));
		pf->pf_fstab = fs;
		pf->pf_next = table;
		table = pf;
	}
	(void) endfsent();
}
===========================================================================
/etc/fstab (in part):
/dev/sd0a / ffs rw 1 1
/dev/sd0f /usr ffs rw 1 2
/dev/sd0g /var ffs rw 1 2
/dev/sd2e /usr/src-dist ffs rw 1 2
/usr/src-dist /usr/local/NetBSD/src union rw,-b
===========================================================================
df output (in part):
Filesystem             1K-blocks     Used    Avail Capacity  Mounted on
/dev/sd0a                  32323    15304    15402    50%    /
/dev/sd0f                 508603    50537   432635    10%    /usr
/dev/sd0g                 508603     1617   481555     0%    /var
/dev/sd2e                 254887   136128   106014    56%    /usr/src-dist
<below>:/usr/src-dist    1900440   759234  1052990    42%    /usr/local/NetBSD/src
===========================================================================
*** optr.c.orig Sat May 18 10:16:17 1996
--- optr.c      Tue Jan 14 11:58:36 1997
***************
*** 433,444 ****
--- 433,446 ----
  {
        register struct fstab *fs;
        register struct pfstab *pf;
+       register struct pfstab *pf0;

        if (setfsent() == 0) {
                msg("Can't open %s for dump table information: %s\n",
                    _PATH_FSTAB, strerror(errno));
                return;
        }
+       pf0 = NULL;
        while ((fs = getfsent()) != NULL) {
                if (strcmp(fs->fs_type, FSTAB_RW) &&
                    strcmp(fs->fs_type, FSTAB_RO) &&
***************
*** 448,455 ****
                if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
                        quit("%s\n", strerror(errno));
                pf->pf_fstab = fs;
!               pf->pf_next = table;
!               table = pf;
        }
        (void) endfsent();
  }
--- 450,461 ----
                if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
                        quit("%s\n", strerror(errno));
                pf->pf_fstab = fs;
!               pf->pf_next = NULL;
!               if (!table)
!                 table = pf;
!               if (pf0)
!                 pf0->pf_next = pf;
!               pf0 = pf;
        }
        (void) endfsent();
  }