DAFS: Salvage VG on volume creation error
authorAndrew Deason <adeason@sinenomine.net>
Tue, 29 Jun 2010 18:19:11 +0000 (13:19 -0500)
committerDerrick Brashear <shadow@dementia.org>
Fri, 2 Jul 2010 17:34:53 +0000 (10:34 -0700)
When trying to create a volume (either an entirely new volume or a
clone), request a demand-salvage on that volume group if we hit an
unexpected error. This can allow some situations to automatically
rectify themselves if, for example, a volume is missing its .vol
header, but still otherwise exists and causes an error during a clone.

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

src/volser/volprocs.c

index b55af40..5e84bbf 100644 (file)
@@ -224,6 +224,28 @@ ConvertPartition(int apartno, char *aname, int asize)
     return 0;
 }
 
+#ifdef AFS_DEMAND_ATTACH_FS
+/* normally we should use the regular salvaging functions from the volume
+ * package, but this is a special case where we have a volume ID, but no
+ * volume structure to give the volume package */
+static void
+SalvageUnknownVolume(VolumeId volid, char *part)
+{
+    afs_int32 code;
+
+    Log("Scheduling salvage for allegedly nonexistent volume %lu part %s\n",
+        afs_printable_uint32_lu(volid), part);
+
+    code = FSYNC_VolOp(volid, part, FSYNC_VOL_FORCE_ERROR,
+                       FSYNC_SALVAGE, NULL);
+    if (code) {
+       Log("SalvageUnknownVolume: error %ld trying to salvage vol %lu part %s\n",
+           afs_printable_int32_ld(code), afs_printable_uint32_lu(volid),
+           part);
+    }
+}
+#endif /* AFS_DEMAND_ATTACH_FS */
+
 static struct Volume *
 VAttachVolumeByName_retry(Error *ec, char *partition, char *name, int mode)
 {
@@ -546,6 +568,11 @@ VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname,
     }
     vp = VCreateVolume(&error, ppath, volumeID, aparent);
     if (error) {
+#ifdef AFS_DEMAND_ATTACH_FS
+       if (error != VVOLEXISTS && error != EXDEV) {
+           SalvageUnknownVolume(volumeID, ppath);
+       }
+#endif
        Log("1 Volser: CreateVolume: Unable to create the volume; aborted, error code %u\n", error);
        LogError(error);
        DeleteTrans(tt, 1);
@@ -658,6 +685,9 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     Error error, code;
     register struct volser_trans *tt, *ttc;
     char caller[MAXKTCNAMELEN];
+#ifdef AFS_DEMAND_ATTACH_FS
+    struct Volume *salv_vp = NULL;
+#endif
 
     if (strlen(newName) > 31)
        return VOLSERBADNAME;
@@ -743,6 +773,9 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     }
 
     error = 0;
+#ifdef AFS_DEMAND_ATTACH_FS
+    salv_vp = originalvp;
+#endif
 
     newvp =
        VCreateVolume(&error, originalvp->partition->name, newId,
@@ -798,6 +831,9 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
        goto fail;
     }
     TClearRxCall(tt);
+#ifdef AFS_DEMAND_ATTACH_FS
+    salv_vp = NULL;
+#endif
     if (TRELE(tt)) {
        tt = (struct volser_trans *)0;
        error = VOLSERTRELE_ERROR;
@@ -817,6 +853,12 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_uint32 purgeId,
     }
     if (ttc)
        DeleteTrans(ttc, 1);
+#ifdef AFS_DEMAND_ATTACH_FS
+    if (salv_vp && error != VVOLEXISTS && error != EXDEV) {
+       Error salv_error;
+       VRequestSalvage_r(&salv_error, salv_vp, FSYNC_SALVAGE, 0);
+    }
+#endif /* AFS_DEMAND_ATTACH_FS */
     return error;
 }