volser: Ignore duplicate file tags when restoring
authorAndrew Deason <adeason@sinenomine.net>
Fri, 6 Aug 2010 19:32:16 +0000 (14:32 -0500)
committerDerrick Brashear <shadow@dementia.org>
Thu, 12 Aug 2010 03:36:54 +0000 (20:36 -0700)
Currently, if the volserver encounters multiple file tags for a vnode
when restoring a volume dump, it will create extra vnodes which are
not recorded anywhere, and are leaked when the volume is removed.
Instead of doing that, ignore any duplicate file tags that are
encountered (which is what happens with other tags), and log a
warning.

Change-Id: I1ac76b0217096d013db355b899f1a53174d20eb5
Reviewed-on: http://gerrit.openafs.org/2531
Tested-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/volser/dumpstuff.c

index 701a07c..f1d1b64 100644 (file)
@@ -1330,6 +1330,7 @@ ReadVnodes(register struct iod *iodp, Volume * vp, int incremental,
     V_pref(vp, nearInode);
     while (tag == D_VNODE) {
        int haveStuff = 0;
+       int saw_f = 0;
        memset(buf, 0, sizeof(buf));
        if (!ReadInt32(iodp, (afs_uint32 *) & vnodeNumber))
            break;
@@ -1402,6 +1403,15 @@ ReadVnodes(register struct iod *iodp, Volume * vp, int incremental,
                    Error error;
                    afs_fsize_t vnodeLength;
 
+                   if (saw_f) {
+                       Log("Volser: ReadVnodes: warning: ignoring duplicate "
+                           "file entries for vnode %lu in dump\n",
+                           (unsigned long)vnodeNumber);
+                       volser_WriteFile(vnodeNumber, iodp, NULL, tag, &error);
+                       break;
+                   }
+                   saw_f = 1;
+
                    ino =
                        IH_CREATE(V_linkHandle(vp), V_device(vp),
                                  VPartitionPath(V_partition(vp)), nearInode,
@@ -1506,6 +1516,9 @@ ReadVnodes(register struct iod *iodp, Volume * vp, int incremental,
 /* called with disk file only.  Note that we don't have to worry about rx_Read
  * needing to read an ungetc'd character, since the ReadInt32 will have read
  * it instead.
+ *
+ * if handleP == NULL, don't write the file anywhere; just read and discard
+ * the file contents
  */
 static afs_fsize_t
 volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
@@ -1556,13 +1569,15 @@ volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
            *status = 3;
            break;
        }
-       nBytes = FDH_WRITE(handleP, p, size);
-       if (nBytes > 0)
-           written += nBytes;
-       if (nBytes != size) {
-           Log("1 Volser: WriteFile: Error writing (%u) bytes to vnode %d: %s; restore aborted\n", (int)(nBytes & 0xffffffff), vn, afs_error_message(errno));
-           *status = 4;
-           break;
+       if (handleP) {
+           nBytes = FDH_WRITE(handleP, p, size);
+           if (nBytes > 0)
+               written += nBytes;
+           if (nBytes != size) {
+               Log("1 Volser: WriteFile: Error writing (%u) bytes to vnode %d; %s; restore aborted\n", (int)(nBytes & 0xffffffff), vn, afs_error_message(errno));
+               *status = 4;
+               break;
+           }
        }
     }
     free(p);