dmmartindale (12/08/82)
When specifying the device to be dumped, you can give either the device name or the name that the filesystem is normally mounted on. Unfortunately, the code which does the string matching is wrong, and so "/u" will match "/usr". Basically, strncmp is passed the wrong length and ends up checking to see if one name is a prefix of the other. The following diff shows the needed changes from the 4.1BSD distribution (don't expect line numbers to match though). Dave Martindale *** /usr/distr/4.1/usr/src/cmd/dump/dumpoptr.c Thu Dec 18 03:52:59 1980 --- dumpoptr.c Tue Dec 7 17:00:46 1982 *************** *** 230,236 (((1.0*(tnow - tstart_writing))/blockswritten) * esize); msg("%3.2f%% done, finished in %d:%02d\n", (blockswritten*100.0)/esize, ! deltat/3600, (deltat%3600)/60); } } --- 230,236 ----- (((1.0*(tnow - tstart_writing))/blockswritten) * esize); msg("%3.2f%% done, finished in %d:%02d\n", (blockswritten*100.0)/esize, ! (int)deltat/3600, ((int)deltat%3600)/60); } } *************** *** 315,321 { register struct fstab *dt; int i; - int keylength; char *rawname(); keylength = min(strlen(key), sizeof (dt->fs_file)); --- 315,320 ----- { register struct fstab *dt; int i; char *rawname(); for (i = 0, dt = fstab; i < nfstab; i++, dt++){ *************** *** 318,324 int keylength; char *rawname(); - keylength = min(strlen(key), sizeof (dt->fs_file)); for (i = 0, dt = fstab; i < nfstab; i++, dt++){ if (strncmp(dt->fs_file, key, keylength) == 0) return(dt); --- 317,322 ----- int i; char *rawname(); for (i = 0, dt = fstab; i < nfstab; i++, dt++){ if (strncmp(dt->fs_file, key, sizeof(dt->fs_file)) == 0) return(dt); *************** *** 320,326 keylength = min(strlen(key), sizeof (dt->fs_file)); for (i = 0, dt = fstab; i < nfstab; i++, dt++){ ! if (strncmp(dt->fs_file, key, keylength) == 0) return(dt); if (strncmp(dt->fs_spec, key, keylength) == 0) return(dt); --- 318,324 ----- char *rawname(); for (i = 0, dt = fstab; i < nfstab; i++, dt++){ ! if (strncmp(dt->fs_file, key, sizeof(dt->fs_file)) == 0) return(dt); if (strncmp(dt->fs_spec, key, sizeof(dt->fs_spec)) == 0) return(dt); *************** *** 322,328 for (i = 0, dt = fstab; i < nfstab; i++, dt++){ if (strncmp(dt->fs_file, key, keylength) == 0) return(dt); ! if (strncmp(dt->fs_spec, key, keylength) == 0) return(dt); if (strncmp(rawname(dt->fs_spec), key, keylength) == 0) return(dt); --- 320,326 ----- for (i = 0, dt = fstab; i < nfstab; i++, dt++){ if (strncmp(dt->fs_file, key, sizeof(dt->fs_file)) == 0) return(dt); ! if (strncmp(dt->fs_spec, key, sizeof(dt->fs_spec)) == 0) return(dt); if (strcmp(rawname(dt->fs_spec), key) == 0) return(dt); *************** *** 324,330 return(dt); if (strncmp(dt->fs_spec, key, keylength) == 0) return(dt); ! if (strncmp(rawname(dt->fs_spec), key, keylength) == 0) return(dt); if (key[0] != '/'){ --- 322,328 ----- return(dt); if (strncmp(dt->fs_spec, key, sizeof(dt->fs_spec)) == 0) return(dt); ! if (strcmp(rawname(dt->fs_spec), key) == 0) return(dt); if (key[0] != '/'){ *************** *** 329,335 if (key[0] != '/'){ if ( (dt->fs_spec[0] == '/') ! && (strncmp(dt->fs_spec+1, key, keylength) == 0)) return(dt); if ( (dt->fs_file[0] == '/') && (strncmp(dt->fs_file+1, key, keylength) == 0)) --- 327,333 ----- if (key[0] != '/'){ if ( (dt->fs_spec[0] == '/') ! && (strncmp(dt->fs_spec+1, key, sizeof(dt->fs_spec)-1) == 0)) return(dt); if ( (dt->fs_file[0] == '/') && (strncmp(dt->fs_file+1, key, sizeof(dt->fs_file)-1) == 0)) *************** *** 332,338 && (strncmp(dt->fs_spec+1, key, keylength) == 0)) return(dt); if ( (dt->fs_file[0] == '/') ! && (strncmp(dt->fs_file+1, key, keylength) == 0)) return(dt); } } --- 330,336 ----- && (strncmp(dt->fs_spec+1, key, sizeof(dt->fs_spec)-1) == 0)) return(dt); if ( (dt->fs_file[0] == '/') ! && (strncmp(dt->fs_file+1, key, sizeof(dt->fs_file)-1) == 0)) return(dt); } }
mckusick@ucbvax.UUCP (Kirk Mckusick) (03/25/84)
From: dlw@berkeley (David L Wasley)
Subject: bug in dump
Index: /usr/src/etc/dump 4.2 Fix
Description:
The problem is that restore needs the full inode bitmap
for the filesystem. Dump, as distributed, truncates the
map to the smallest size possible (the highest inode of
interest). This causes restore to FAIL in some cases.
Repeat-by:
newfs /dev/rra0h ra81
dump 0 /dev/rra0h
...(add stuff to the filesystem)...
dump 3 /dev/rra0h
Now try to restore it.
Fix:
Below is a diff of dumptraverse.c that will fix the bug.
The line numbers may not match yours. The routine is
``bitmap()''.
------
diff dumptraverse.c.old dumptraverse.c
------
210,218c211
< n = -1;
< for (i = 0; i < msiz; i++)
< if(map[i])
< n = i;
< if (n < 0)
< return;
< n++;
<
< spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
---
> spcl.c_count = howmany(msiz * sizeof(map[0]), TP_BSIZE);
srradia@watmath.UUCP (sanjay Radia) (06/25/84)
Index: dump 4.2 Fix Description: A serious bug exists in dump. Dump makes a pass through all the inodes and marks the inodes to be dumped in dirmap & nodmap. However, if the system is busy the inodes can be deleted and possibly reallocated for other files. In the next pass, when dumping inodes, dump does not bother to check to see if the inodes are still allocated and in the case of directories does not check to see the inode is still a directory. Now, the dump tape has a bunch of directories (directory-zone) followed by non-directories and as soon as restore sees a non-directory it thinks it has scanned the directory-zone. Thus if a directory inode is delelted (and maybe realloced to a file) between the 1st & 2nd passes of dump, the dump tape will not be correctly read by restore (you will loose some (a lot) of the directory information). Repeated-By: Create about 3 directories and start a dump on the file system. When dump asks you to mount the tape delete one of the three directories (the one with the lowest inode #). Now continue with the dump. Do a "/etc/restore ivd". You will see that restore will not know of any directories with inodes greater than the the one you deleted (ie they will be marked as regular files and not as directories). You can check this out by doing a "lc" in restore's interactive mode. Fix: The following is a fix to dump. Since our dump has changed, the line numbers might not match. Note that restore can be fixed to ignore free inodes (in function dirextract() in dirs.c) but there is no nice way to by-pass file-inodes in the directory-zone. There should have been a special record between the directory-zone and the file-zone (if you put this in, your old & new tapes will not be compatible). ****** dumpmain.c >change the line marked with ! (the context and old/new versions given OLD *** 265,271 bitmap(clrmap, TS_CLRI); msg("dumping (Pass III) [directories]\n"); ! pass(dump, dirmap); msg("dumping (Pass IV) [regular files]\n"); pass(dump, nodmap); NEW --- 288,295 ----- bitmap(clrmap, TS_CLRI); msg("dumping (Pass III) [directories]\n"); ! pass(dirdump, dirmap); msg("dumping (Pass IV) [regular files]\n"); pass(dump, nodmap); --- dumptraverse.c > add the function dirdump() (marked with +) (add an extern in dump.h) > and add the lines marked with '+' in dump() (the context is given) + dirdump(ip) + struct dinode *ip; + { + /* watchout for dir inodes deleted and maybe reallocated */ + if ((ip->di_mode & IFMT) != IFDIR) + return; + dump(ip); + } + + dump(ip) struct dinode *ip; { ........ ...... ..... i = ip->di_mode & IFMT; + + if (i == 0) /* free inode */ + return; + if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) { spclrec(); return; -- sanjay {allegra,decvax}!watmath!srradia
henry@utzoo.UUCP (Henry Spencer) (06/26/84)
You've just discovered a reason (one of several) why people who really want to trust their dumps run them single-user so the filesystems are guaranteed to be static. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry