fast-start-20001220
authorHartmut Reuter <reuter@rzg.mpg.de>
Sat, 23 Dec 2000 23:52:38 +0000 (23:52 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sat, 23 Dec 2000 23:52:38 +0000 (23:52 +0000)
FAST_RESTART ifdef'd code omits salvage at restart. -DontSalvage must be
added to salvager args in the bos configuration

BITMAPS_LATER ifdef'd code lets the fileserver create the bitmaps for
free vnodes only on demand, so the fileserver may start faster.

src/vol/vol-salvage.c
src/vol/volume.c

index 3b6d84e..1d8a25d 100644 (file)
@@ -547,6 +547,14 @@ static handleit(as)
          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
@@ -713,6 +721,9 @@ char **argv;
     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);
 }
index 9ffb550..2345e23 100644 (file)
@@ -746,6 +746,7 @@ private Volume *attach2(ec, path, header, partp, isbusy)
        return NULL;
     }
     if (programType == fileServer) {
+#ifndef FAST_RESTART
        if (V_inUse(vp) && VolumeWriteable(vp)) {
            if (!V_needsSalvaged(vp)) {
                V_needsSalvaged(vp) = 1;
@@ -756,6 +757,7 @@ private Volume *attach2(ec, path, header, partp, isbusy)
            *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);
@@ -767,6 +769,7 @@ private Volume *attach2(ec, path, header, partp, isbusy)
     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++) {
@@ -779,6 +782,7 @@ private Volume *attach2(ec, path, header, partp, isbusy)
            }
        }
     }
+#endif /* BITMAP_LATER */
 
     if (programType == fileServer) {
         if (vp->specialStatus) vp->specialStatus = 0;
@@ -1209,6 +1213,43 @@ int VAllocBitmapEntry_r(ec,vp,index)
        *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) {
@@ -1253,6 +1294,9 @@ void VFreeBitMapEntry_r(Error *ec, register struct vnodeIndex *index,
 {
     unsigned int offset;
      *ec = 0;
+#ifdef BITMAP_LATER
+     if (!index->bitmap) return;
+#endif /* BITMAP_LATER */
      offset = bitNumber>>3;
      if (offset >= index->bitmapSize) {
        *ec = VNOVNODE;
@@ -1339,6 +1383,9 @@ static void GetBitmap(Error *ec, Volume *vp, VnodeClass class)
     struct VnodeDiskObject *vnode;
     unsigned int unique = 0;
     FdHandle_t *fdP;
+#ifdef BITMAP_LATER
+    byte *BitMap = 0;
+#endif /* BITMAP_LATER */
 
     *ec = 0;
 
@@ -1357,9 +1404,14 @@ static void GetBitmap(Error *ec, Volume *vp, VnodeClass class)
                                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++) {
@@ -1372,7 +1424,11 @@ static void GetBitmap(Error *ec, Volume *vp, VnodeClass class)
            *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; 
        }
@@ -1394,6 +1450,17 @@ static void GetBitmap(Error *ec, Volume *vp, VnodeClass class)
     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,