From: Tom Keiser Date: Mon, 17 Mar 2008 17:06:30 +0000 (+0000) Subject: dafs-accurately-track-inuse-20080317 X-Git-Tag: BP-openafs-windows-kdfs-ifs~10 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=c7bce5882a685fcc6ecac53fb54ec7047f21ec6c dafs-accurately-track-inuse-20080317 LICENSE IPL10 keep accurate tabs on whether a volume is "in use" so we don't end up with volume state that's nonsensical. ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== LICENSE IPL10 keep accurate tabs on whether a volume is "in use" so we don't end up with volum e state that's nonsensical. ==================== LICENSE IPL10 keep accurate tabs on whether a volume is "in use" so we don't end up with volum e state that's nonsensical. --- diff --git a/src/vol/fssync-debug.c b/src/vol/fssync-debug.c index 1084e6d..47d2ce1 100644 --- a/src/vol/fssync-debug.c +++ b/src/vol/fssync-debug.c @@ -759,7 +759,11 @@ VolHdrQuery(struct cmd_syndesc * as, void * rock) printf("\tid = %u\n", v.id); printf("\tname = '%s'\n", v.name); - printf("\tinUse = %d\n", v.inUse); + if (v.inUse != 0) { + printf("\tinUse = %d (%s)\n", v.inUse, program_type_to_string(v.inUse)); + } else { + printf("\tinUse = %d (no)\n", v.inUse); + } printf("\tinService = %d\n", v.inService); printf("\tblessed = %d\n", v.blessed); printf("\tneedsSalvaged = %d\n", v.needsSalvaged); diff --git a/src/vol/vol-salvage.c b/src/vol/vol-salvage.c index 86445ea..7161272 100644 --- a/src/vol/vol-salvage.c +++ b/src/vol/vol-salvage.c @@ -1633,7 +1633,7 @@ QuickCheck(register struct InodeSummary *isp, int nVols) && volHeader.stamp.magic == VOLUMEINFOMAGIC && volHeader.dontSalvage == DONT_SALVAGE && volHeader.needsSalvaged == 0 && volHeader.destroyMe == 0) { - if (volHeader.inUse == 1) { + if (volHeader.inUse != 0) { volHeader.inUse = 0; volHeader.inService = 1; if (!Testing) { diff --git a/src/vol/volume.c b/src/vol/volume.c index e97f7c8..33c7ddd 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -1806,7 +1806,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) /* if it's already attached, see if we can return it */ if (V_attachState(vp) == VOL_STATE_ATTACHED) { VGetVolumeByVp_r(ec, vp); - if (V_inUse(vp)) { + if (V_inUse(vp) == fileServer) { VCancelReservation_r(vp); return vp; } @@ -1876,7 +1876,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) #else /* AFS_DEMAND_ATTACH_FS */ vp = VGetVolume_r(ec, volumeId); if (vp) { - if (V_inUse(vp)) + if (V_inUse(vp) == fileServer) return vp; if (vp->specialStatus == VBUSY) isbusy = 1; @@ -1950,6 +1950,11 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode) vp = attach2(ec, volumeId, path, &iheader, partp, vp, isbusy, mode); if (programType == volumeUtility && vp) { + if ((mode == V_VOLUPD) || (VolumeWriteable(vp) && (mode == V_CLONE))) { + /* mark volume header as in use so that volser crashes lead to a + * salvage attempt */ + VUpdateVolume_r(ec, vp, 0); + } #ifdef AFS_DEMAND_ATTACH_FS /* for dafs, we should tell the fileserver, except for V_PEEK * where we know it is not necessary */ @@ -2093,7 +2098,7 @@ VAttachVolumeByVp_r(Error * ec, Volume * vp, int mode) /* if it's already attached, see if we can return it */ if (V_attachState(vp) == VOL_STATE_ATTACHED) { VGetVolumeByVp_r(ec, vp); - if (V_inUse(vp)) { + if (V_inUse(vp) == fileServer) { return vp; } else { if (vp->specialStatus == VBUSY) @@ -2487,9 +2492,12 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h if (vp->specialStatus) vp->specialStatus = 0; if (V_blessed(vp) && V_inService(vp) && !V_needsSalvaged(vp)) { - V_inUse(vp) = 1; + V_inUse(vp) = fileServer; V_offlineMessage(vp)[0] = '\0'; } + } else { + V_inUse(vp) = programType; + V_checkoutMode(vp) = mode; } AddVolumeToHashTable(vp, V_id(vp)); @@ -2497,7 +2505,7 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h AddVolumeToVByPList_r(vp); VLRU_Add_r(vp); if ((programType != fileServer) || - V_inUse(vp)) { + (V_inUse(vp) == fileServer)) { VChangeState_r(vp, VOL_STATE_ATTACHED); } else { VChangeState_r(vp, VOL_STATE_UNATTACHED); @@ -3429,12 +3437,25 @@ static int VCheckDetach(register Volume * vp) { int ret = 0; + Error ec = 0; if (vp->nUsers || vp->nWaiters) return ret; if (vp->shuttingDown) { ret = 1; + if ((programType != fileServer) && + (V_inUse(vp) == programType) && + ((V_checkoutMode(vp) == V_VOLUPD) || + ((V_checkoutMode(vp) == V_CLONE) && + (VolumeWriteable(vp))))) { + V_inUse(vp) = 0; + VUpdateVolume_r(&ec, vp, VOL_UPDATE_NOFORCEOFF); + if (ec) { + Log("VCheckDetach: failed to clear inUse failed during detachment of volid %u\n", + vp->hashid); + } + } VReleaseVolumeHandles_r(vp); VCheckSalvage(vp); ReallyFreeVolume(vp); @@ -3449,12 +3470,25 @@ static int VCheckDetach(register Volume * vp) { int ret = 0; + Error ec = 0; if (vp->nUsers) return ret; if (vp->shuttingDown) { ret = 1; + if ((programType != fileServer) && + (V_inUse(vp) == programType) && + ((V_checkoutMode(vp) == V_VOLUPD) || + ((V_checkoutMode(vp) == V_CLONE) && + (VolumeWriteable(vp))))) { + V_inUse(vp) = 0; + VUpdateVolume_r(&ec, vp, VOL_UPDATE_NOFORCEOFF); + if (ec) { + Log("VCheckDetach: failed to clear inUse failed during detachment of volid %u\n", + vp->hashid); + } + } VReleaseVolumeHandles_r(vp); ReallyFreeVolume(vp); if (programType == fileServer) { diff --git a/src/vol/volume.h b/src/vol/volume.h index 48c8774..cbf0881 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -113,11 +113,16 @@ extern pthread_t vol_glock_holder; #define VTRANS_UNLOCK #endif /* AFS_PTHREAD_ENV */ -typedef enum { fileServer, /* the fileserver process */ - volumeUtility, /* volserver, or a single volume salvager (non-dafs) */ - salvager, /* standalone whole-partition salvager */ - salvageServer, /* dafs online salvager */ - debugUtility /* fssync-debug or similar utility */ +/** + * volume package program type enumeration. + */ +typedef enum { + fileServer = 1, /**< the fileserver process */ + volumeUtility = 2, /**< volserver, or a + * single volume salvager (non-dafs) */ + salvager = 3, /**< standalone whole-partition salvager */ + salvageServer = 4, /**< dafs online salvager */ + debugUtility = 5 /**< fssync-debug or similar utility */ } ProgramType; extern ProgramType programType; /* The type of program using the package */ @@ -615,6 +620,7 @@ typedef struct Volume { byte specialStatus; /* An error code to return on VGetVolume: the * volume is unavailable for the reason quoted, * currently VBUSY or VMOVED */ + afs_uint32 checkoutMode; /* for volume utilities, mode number for current checkout */ afs_uint32 updateTime; /* Time that this volume was put on the updated * volume list--the list of volumes that will be * salvaged should the file server crash */ @@ -649,6 +655,7 @@ struct volHeader { #define V_vnodeIndex(vp) ((vp)->vnodeIndex) #define V_nextVnodeUnique(vp) ((vp)->nextVnodeUnique) #define V_linkHandle(vp) ((vp)->linkHandle) +#define V_checkoutMode(vp) ((vp)->checkoutMode) #ifdef AFS_DEMAND_ATTACH_FS #define V_attachState(vp) ((vp)->attach_state) #define V_attachFlags(vp) ((vp)->attach_flags)