void maybeRecoverBlobStores(int numStoreFailures, Map<PartitionId, Exception> startExceptions) {
    if (!storeConfig.storeRemoveDirectoryAndRestartBlobStore || numStoreFailures == stores.size()) {
      return;
    }
    for (Map.Entry<PartitionId, BlobStore> entry : stores.entrySet()) {
      PartitionId partitionId = entry.getKey();
      BlobStore store = entry.getValue();
      if (!shouldRemoveDirectory(partitionId, store, startExceptions.get(partitionId))) {
        continue;
      }
      logger.info("Remove directory for store {} and restart it", partitionId);

      // 1. Remove the blob store directory
      // 2. Create another blob store and restart it. since this time the blob store would be empty, we don't
      // have to use different threads for different blob stores.
      ReplicaId replica = partitionToReplicaMap.get(entry.getKey());
      String dataDir = store.getDataDir();
      try {
        Utils.deleteFileOrDirectory(new File(dataDir));
        BlobStore newStore =
            new BlobStore(replica, storeConfig, scheduler, longLivedTaskScheduler, this, diskIOScheduler,
                diskSpaceAllocator, storeMainMetrics, storeUnderCompactionMetrics, keyFactory, recovery, hardDelete,
                replicaStatusDelegates, time, accountService, diskMetrics, indexPersistScheduler);
        newStore.start();
        entry.setValue(newStore);
      } catch (Exception e) {
        logger.error("Failed to remove directory for store {} and restart it", dataDir, e);
      }
    }
  }
Maybe recover the blob stores that failed to start. The configuration has to be set to true and the number
of failed blob stores are not the same as the total number on the disk, then we would try to recover each
blob store. We only recover the blob store if the exception thrown in the start method is StoreException and
the store error code is one of the recoverable error codes.
@param numStoreFailures
@param startExceptions
ambry-store/src/main/java/com/github/ambry/store/DiskManager.java