public virtual void PrintStats(StringBuilder p) { p.Append("Block scanner information for volume " + volume.GetStorageID() + " with base path " + volume.GetBasePath() + "%n"); lock (stats) { p.Append(string.Format("Bytes verified in last hour : %57d%n", stats.bytesScannedInPastHour )); p.Append(string.Format("Blocks scanned in current period : %57d%n", stats.blocksScannedInCurrentPeriod )); p.Append(string.Format("Blocks scanned since restart : %57d%n", stats.blocksScannedSinceRestart )); p.Append(string.Format("Block pool scans since restart : %57d%n", stats.scansSinceRestart )); p.Append(string.Format("Block scan errors since restart : %57d%n", stats.scanErrorsSinceRestart )); if (stats.nextBlockPoolScanStartMs > 0) { p.Append(string.Format("Hours until next block pool scan : %57.3f%n", PositiveMsToHours (stats.nextBlockPoolScanStartMs - Time.MonotonicNow()))); } if (stats.blockPoolPeriodEndsMs > 0) { p.Append(string.Format("Hours until possible pool rescan : %57.3f%n", PositiveMsToHours (stats.blockPoolPeriodEndsMs - Time.Now()))); } p.Append(string.Format("Last block scanned : %57s%n", ((stats.lastBlockScanned == null) ? "none" : stats.lastBlockScanned.ToString()))); p.Append(string.Format("More blocks to scan in period : %57s%n", !stats.eof)); p.Append("%n"); } }
internal ScanInfo(long blockId, FilePath blockFile, FilePath metaFile, FsVolumeSpi vol) { this.blockId = blockId; string condensedVolPath = vol == null ? null : GetCondensedPath(vol.GetBasePath() ); this.blockSuffix = blockFile == null ? null : GetSuffix(blockFile, condensedVolPath ); this.blockFileLength = (blockFile != null) ? blockFile.Length() : 0; if (metaFile == null) { this.metaSuffix = null; } else { if (blockFile == null) { this.metaSuffix = GetSuffix(metaFile, condensedVolPath); } else { this.metaSuffix = GetSuffix(metaFile, condensedVolPath + blockSuffix); } } this.volume = vol; }
public virtual void Handle(ExtendedBlock block, IOException e) { FsVolumeSpi volume = scanner.volume; if (e == null) { Log.Trace("Successfully scanned {} on {}", block, volume.GetBasePath()); return; } // If the block does not exist anymore, then it's not an error. if (!volume.GetDataset().Contains(block)) { Log.Debug("Volume {}: block {} is no longer in the dataset.", volume.GetBasePath( ), block); return; } // If the block exists, the exception may due to a race with write: // The BlockSender got an old block path in rbw. BlockReceiver removed // the rbw block from rbw to finalized but BlockSender tried to open the // file before BlockReceiver updated the VolumeMap. The state of the // block can be changed again now, so ignore this error here. If there // is a block really deleted by mistake, DirectoryScan should catch it. if (e is FileNotFoundException) { Log.Info("Volume {}: verification failed for {} because of " + "FileNotFoundException. This may be due to a race with write." , volume.GetBasePath(), block); return; } Log.Warn("Reporting bad {} on {}", block, volume.GetBasePath()); try { scanner.datanode.ReportBadBlocks(block); } catch (IOException) { // This is bad, but not bad enough to shut down the scanner. Log.Warn("Cannot report bad " + block.GetBlockId(), e); } }
/// <summary>Set up a scanner for the given block pool and volume.</summary> /// <param name="ref">A reference to the volume.</param> public virtual void AddVolumeScanner(FsVolumeReference @ref) { lock (this) { bool success = false; try { FsVolumeSpi volume = @ref.GetVolume(); if (!IsEnabled()) { Log.Debug("Not adding volume scanner for {}, because the block " + "scanner is disabled." , volume.GetBasePath()); return; } VolumeScanner scanner = scanners[volume.GetStorageID()]; if (scanner != null) { Log.Error("Already have a scanner for volume {}.", volume.GetBasePath()); return; } Log.Debug("Adding scanner for volume {} (StorageID {})", volume.GetBasePath(), volume .GetStorageID()); scanner = new VolumeScanner(conf, datanode, @ref); scanner.Start(); scanners[volume.GetStorageID()] = scanner; success = true; } finally { if (!success) { // If we didn't create a new VolumeScanner object, we don't // need this reference to the volume. IOUtils.Cleanup(null, @ref); } } } }
internal VolumeScanner(BlockScanner.Conf conf, DataNode datanode, FsVolumeReference @ref) { this.conf = conf; this.datanode = datanode; this.@ref = @ref; this.volume = @ref.GetVolume(); VolumeScanner.ScanResultHandler handler; try { handler = System.Activator.CreateInstance(conf.resultHandler); } catch (Exception e) { Log.Error("unable to instantiate {}", conf.resultHandler, e); handler = new VolumeScanner.ScanResultHandler(); } this.resultHandler = handler; SetName("VolumeScannerThread(" + volume.GetBasePath() + ")"); SetDaemon(true); }
/// <summary> /// Stops and removes a volume scanner.<p/> /// This function will block until the volume scanner has stopped. /// </summary> /// <param name="volume">The volume to remove.</param> public virtual void RemoveVolumeScanner(FsVolumeSpi volume) { lock (this) { if (!IsEnabled()) { Log.Debug("Not removing volume scanner for {}, because the block " + "scanner is disabled." , volume.GetStorageID()); return; } VolumeScanner scanner = scanners[volume.GetStorageID()]; if (scanner == null) { Log.Warn("No scanner found to remove for volumeId {}", volume.GetStorageID()); return; } Log.Info("Removing scanner for volume {} (StorageID {})", volume.GetBasePath(), volume .GetStorageID()); scanner.Shutdown(); Sharpen.Collections.Remove(scanners, volume.GetStorageID()); Uninterruptibles.JoinUninterruptibly(scanner, 5, TimeUnit.Minutes); } }
internal virtual FilePath GetBlockFile() { return((blockSuffix == null) ? null : new FilePath(volume.GetBasePath(), blockSuffix )); }