vol-salvage: VOL_DONE deleted volumes
authorAndrew Deason <adeason@sinenomine.net>
Wed, 2 Mar 2011 20:11:43 +0000 (14:11 -0600)
committerDerrick Brashear <shadow@dementia.org>
Fri, 4 Mar 2011 15:36:58 +0000 (07:36 -0800)
When the salvager deletes a volume (because it is an invalid RO clone,
or because there is no data associated with the volume), we should
inform the fileserver that the volume is gone. Otherwise, the volume
in the fileserver can get put into an error state (in DAFS) when it
tries to attach the volume, preventing anything from creating or using
that volume.

Change-Id: Iae7763b752a2bab7a529dd327d034fdb9e18664a
Reviewed-on: http://gerrit.openafs.org/4118
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/vol/fssync-server.c
src/vol/vol-salvage.c
src/vol/vol-salvage.h

index 05268a6..bec018d 100644 (file)
@@ -1219,7 +1219,8 @@ FSYNC_com_VolDone(FSSYNC_VolOp_command * vcom, SYNC_response * res)
        if (FSYNC_partMatch(vcom, vp, 1)) {
 #ifdef AFS_DEMAND_ATTACH_FS
            if ((V_attachState(vp) == VOL_STATE_UNATTACHED) ||
-               (V_attachState(vp) == VOL_STATE_PREATTACHED)) {
+               (V_attachState(vp) == VOL_STATE_PREATTACHED) ||
+               VIsErrorState(V_attachState(vp))) {
 
                /* Change state to DELETED, not UNATTACHED, so clients get
                 * a VNOVOL error when they try to access from now on. */
index d78a6ba..932ef40 100644 (file)
@@ -934,18 +934,41 @@ SalvageFileSys1(struct DiskPartition64 *partP, VolumeId singleVolumeNumber)
        RemoveTheForce(salvinfo->fileSysPath);
 
     if (!Testing && singleVolumeNumber) {
+       int foundSVN = 0;
 #ifdef AFS_DEMAND_ATTACH_FS
        /* unlock vol headers so the fs can attach them when we AskOnline */
        VLockFileReinit(&salvinfo->fileSysPartition->volLockFile);
 #endif /* AFS_DEMAND_ATTACH_FS */
 
-       AskOnline(salvinfo, singleVolumeNumber);
-
        /* Step through the volumeSummary list and set all volumes on-line.
-        * The volumes were taken off-line in GetVolumeSummary.
+        * Most volumes were taken off-line in GetVolumeSummary.
+        * If a volume was deleted, don't tell the fileserver anything, since
+        * we already told the fileserver the volume was deleted back when we
+        * we destroyed the volume header.
+        * Also, make sure we bring the singleVolumeNumber back online first.
         */
+
+       for (j = 0; j < salvinfo->nVolumes; j++) {
+           if (salvinfo->volumeSummaryp[j].header.id == singleVolumeNumber) {
+               foundSVN = 1;
+               if (!salvinfo->volumeSummaryp[j].deleted) {
+                   AskOnline(salvinfo, singleVolumeNumber);
+               }
+           }
+       }
+
+       if (!foundSVN) {
+           /* singleVolumeNumber generally should always be in the constructed
+            * volumeSummary, but just in case it's not... */
+           AskOnline(salvinfo, singleVolumeNumber);
+       }
+
        for (j = 0; j < salvinfo->nVolumes; j++) {
-           AskOnline(salvinfo, salvinfo->volumeSummaryp[j].header.id);
+           if (salvinfo->volumeSummaryp[j].header.id != singleVolumeNumber) {
+               if (!salvinfo->volumeSummaryp[j].deleted) {
+                   AskOnline(salvinfo, salvinfo->volumeSummaryp[j].header.id);
+               }
+           }
        }
     } else {
        if (!Showmode)
@@ -979,6 +1002,10 @@ DeleteExtraVolumeHeaderFile(struct SalvInfo *salvinfo, struct VolumeSummary *vsp
        if (unlink(path) && errno != ENOENT) {
            Log("Unable to unlink %s (errno = %d)\n", path, errno);
        }
+       if (salvinfo->useFSYNC) {
+           AskDelete(salvinfo, vsp->header.id);
+       }
+       vsp->deleted = 1;
     }
     vsp->fileName = 0;
 }
@@ -4201,6 +4228,10 @@ MaybeZapVolume(struct SalvInfo *salvinfo, struct InodeSummary *isp,
                if (unlink(path) && errno != ENOENT) {
                    Log("Unable to unlink %s (errno = %d)\n", path, errno);
                }
+               if (salvinfo->useFSYNC) {
+                   AskDelete(salvinfo, isp->volumeId);
+               }
+               isp->volSummary->deleted = 1;
            }
        }
     } else if (!check) {
@@ -4372,6 +4403,37 @@ AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId)
     }
 }
 
+void
+AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId)
+{
+    afs_int32 code, i;
+
+    for (i = 0; i < 3; i++) {
+       code = FSYNC_VolOp(volumeId, salvinfo->fileSysPartition->name,
+                          FSYNC_VOL_DONE, FSYNC_SALVAGE, NULL);
+
+       if (code == SYNC_OK) {
+           break;
+       } else if (code == SYNC_DENIED) {
+           Log("AskOnline:  file server denied DONE request to volume %u partition %s; trying again...\n", volumeId, salvinfo->fileSysPartition->name);
+       } else if (code == SYNC_BAD_COMMAND) {
+           Log("AskOnline:  fssync protocol mismatch (bad command word '%d')\n",
+               FSYNC_VOL_DONE);
+#ifdef DEMAND_ATTACH_ENABLE
+           Log("AskOnline:  please make sure fileserver, volserver, salvageserver and salvager binaries are same version.\n");
+#else
+           Log("AskOnline:  please make sure fileserver, volserver and salvager binaries are same version.\n");
+#endif
+           break;
+       } else if (i < 2) {
+           /* try it again */
+           Log("AskOnline:  request for fileserver to delete volume failed; trying again...\n");
+           FSYNC_clientFinis();
+           FSYNC_clientInit();
+       }
+    }
+}
+
 int
 CopyInode(Device device, Inode inode1, Inode inode2, int rwvolume)
 {
index 9073a76..da86c6c 100644 (file)
@@ -59,6 +59,7 @@ struct VolumeSummary {                /* Volume summary an entry for each
      * numbers of each major component of
      * the volume */
     IHandle_t *volumeInfoHandle;
+    char deleted;               /* did we delete this volume? */
     byte wouldNeedCallback;    /* set if the file server should issue
                                 * call backs for all the files in this volume when
                                 * the volume goes back on line */
@@ -194,6 +195,7 @@ extern int Wait(char *prog);
 extern char *ToString(const char *s);
 extern void AskOffline(struct SalvInfo *salvinfo, VolumeId volumeId);
 extern void AskOnline(struct SalvInfo *salvinfo, VolumeId volumeId);
+extern void AskDelete(struct SalvInfo *salvinfo, VolumeId volumeId);
 extern void CheckLogFile(char * log_path);
 #ifndef AFS_NT40_ENV
 extern void TimeStampLogFile(char * log_path);