From a862d2df93fd4e8c8c7a0b8eebe9e59b75f54072 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 2 Mar 2011 14:11:43 -0600 Subject: [PATCH] vol-salvage: VOL_DONE deleted volumes 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 Reviewed-by: Derrick Brashear --- src/vol/fssync-server.c | 3 +- src/vol/vol-salvage.c | 70 ++++++++++++++++++++++++++++++++++++++--- src/vol/vol-salvage.h | 2 ++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/vol/fssync-server.c b/src/vol/fssync-server.c index 05268a621..bec018dca 100644 --- a/src/vol/fssync-server.c +++ b/src/vol/fssync-server.c @@ -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. */ diff --git a/src/vol/vol-salvage.c b/src/vol/vol-salvage.c index d78a6ba95..932ef40a7 100644 --- a/src/vol/vol-salvage.c +++ b/src/vol/vol-salvage.c @@ -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) { diff --git a/src/vol/vol-salvage.h b/src/vol/vol-salvage.h index 9073a7688..da86c6c2d 100644 --- a/src/vol/vol-salvage.h +++ b/src/vol/vol-salvage.h @@ -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); -- 2.39.5