]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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 05268a6216ee39310b3162ee2f2f56c29f4179bb..bec018dcae0b3aeaf1c9d9a2be45850cd7e1b894 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 d78a6ba956cada842eb77e25c8207bed71e4965d..932ef40a7f389ddf0f0c0afed7661d04a9ed1efd 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 9073a76885958aa5e2cd22b5bc2d5b7489769b94..da86c6c2db2fbafac1ee09b5e70130bb13f6c0a1 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);