orphans = ORPH_ATTACH;
}
+#ifdef FAST_RESTART
+ if (ti = as->parms[16].items) { /* -DontSalvage */
+ printf("Exiting immediately without salvage. Look into the FileLog");
+ printf(" to find volumes which really need to be salvaged!\n");
+ Exit(0);
+ }
+#endif /* FAST_RESTART */
+
/* Note: if seemvol we initialize this as a standard volume utility: this has the
implication that the file server may be running; negotations have to be made with
the file server in this case to take the read write volume and associated read-only
cmd_AddParm(ts, "-showsuid", CMD_FLAG,CMD_OPTIONAL, "Report on suid/sgid files");
cmd_AddParm(ts, "-showmounts", CMD_FLAG,CMD_OPTIONAL, "Report on mountpoints");
cmd_AddParm(ts, "-orphans", CMD_SINGLE, CMD_OPTIONAL, "ignore | remove | attach");
+#ifdef FAST_RESTART
+ cmd_AddParm(ts, "-DontSalvage", CMD_FLAG, CMD_OPTIONAL, "Don't salvage. This my be set in BosConfig to let the fileserver restart immediately after a crash. Bad volumes will be taken offline");
+#endif /* FAST_RESTART */
err = cmd_Dispatch(argc, argv);
Exit(err);
}
return NULL;
}
if (programType == fileServer) {
+#ifndef FAST_RESTART
if (V_inUse(vp) && VolumeWriteable(vp)) {
if (!V_needsSalvaged(vp)) {
V_needsSalvaged(vp) = 1;
*ec = VSALVAGE;
return NULL;
}
+#endif /* FAST_RESTART */
if (V_destroyMe(vp) == DESTROY_ME) {
FreeVolume(vp);
Log("VAttachVolume: volume %s is junk; it should be destroyed at next salvage\n", path);
AddVolumeToHashTable(vp, V_id(vp));
vp->nextVnodeUnique = V_uniquifier(vp);
vp->vnodeIndex[vSmall].bitmap = vp->vnodeIndex[vLarge].bitmap = NULL;
+#ifndef BITMAP_LATER
if (programType == fileServer && VolumeWriteable(vp)) {
int i;
for (i = 0; i<nVNODECLASSES; i++) {
}
}
}
+#endif /* BITMAP_LATER */
if (programType == fileServer) {
if (vp->specialStatus) vp->specialStatus = 0;
*ec = VREADONLY;
return 0;
}
+#ifdef BITMAP_LATER
+ if ((programType == fileServer) && !index->bitmap) {
+ int i;
+ int wasVBUSY = 0;
+ if (vp->specialStatus == VBUSY) {
+ if (vp->goingOffline) { /* vos dump waiting for the volume to
+ go offline. We probably come here
+ from AddNewReadableResidency */
+ wasVBUSY = 1;
+ } else {
+ VOL_UNLOCK
+ while (vp->specialStatus == VBUSY)
+#ifdef AFS_PTHREAD_ENV
+ sleep(2);
+#else /* AFS_PTHREAD_ENV */
+ IOMGR_Sleep(2);
+#endif /* AFS_PTHREAD_ENV */
+ VOL_LOCK
+ }
+ }
+ if (!index->bitmap) {
+ vp->specialStatus = VBUSY; /* Stop anyone else from using it.*/
+ for (i = 0; i<nVNODECLASSES; i++) {
+ VOL_UNLOCK
+ GetBitmap(ec,vp,i);
+ VOL_LOCK
+ if (*ec) {
+ vp->specialStatus = 0;
+ vp->shuttingDown = 1; /* Let who has it free it. */
+ return NULL;
+ }
+ }
+ if (!wasVBUSY)
+ vp->specialStatus = 0; /* Allow others to have access. */
+ }
+ }
+#endif /* BITMAP_LATER */
bp = index->bitmap + index->bitmapOffset;
ep = index->bitmap + index->bitmapSize;
while (bp < ep) {
{
unsigned int offset;
*ec = 0;
+#ifdef BITMAP_LATER
+ if (!index->bitmap) return;
+#endif /* BITMAP_LATER */
offset = bitNumber>>3;
if (offset >= index->bitmapSize) {
*ec = VNOVNODE;
struct VnodeDiskObject *vnode;
unsigned int unique = 0;
FdHandle_t *fdP;
+#ifdef BITMAP_LATER
+ byte *BitMap = 0;
+#endif /* BITMAP_LATER */
*ec = 0;
the whole thing is rounded up to nearest 4
bytes, because the bit map allocator likes
it that way */
+#ifdef BITMAP_LATER
+ BitMap = (byte *) calloc(1, vip->bitmapSize);
+ assert(BitMap != NULL);
+#else /* BITMAP_LATER */
vip->bitmap = (byte *) calloc(1, vip->bitmapSize);
assert(vip->bitmap != NULL);
vip->bitmapOffset = 0;
+#endif /* BITMAP_LATER */
if (STREAM_SEEK(file,vcp->diskSize,0) != -1) {
int bitNumber = 0;
for (bitNumber = 0; bitNumber < nVnodes+100; bitNumber++) {
*ec = VSALVAGE;
break;
}
+#ifdef BITMAP_LATER
+ *(BitMap + (bitNumber>>3)) |= (1 << (bitNumber & 0x7));
+#else /* BITMAP_LATER */
*(vip->bitmap + (bitNumber>>3)) |= (1 << (bitNumber & 0x7));
+#endif /* BITMAP_LATER */
if (unique <= vnode->uniquifier)
unique = vnode->uniquifier + 1;
}
STREAM_CLOSE(file);
FDH_CLOSE(fdP);
free(vnode);
+#ifdef BITMAP_LATER
+ /* There may have been a racing condition with some other thread, both
+ * creating the bitmaps for this volume. If the other thread was faster
+ * the pointer to bitmap should already be filled and we can free ours.
+ */
+ if (vip->bitmap == NULL) {
+ vip->bitmap = BitMap;
+ vip->bitmapOffset = 0;
+ } else
+ free((byte *)BitMap);
+#endif /* BITMAP_LATER */
}
static void GetVolumePath(Error *ec, VolId volumeId, char **partitionp,