/// <exception cref="System.IO.IOException"/> public override void FinalizeLogSegment(long firstTxId, long lastTxId) { lock (this) { FilePath inprogressFile = NNStorage.GetInProgressEditsFile(sd, firstTxId); FilePath dstFile = NNStorage.GetFinalizedEditsFile(sd, firstTxId, lastTxId); Log.Info("Finalizing edits file " + inprogressFile + " -> " + dstFile); Preconditions.CheckState(!dstFile.Exists(), "Can't finalize edits file " + inprogressFile + " since finalized file " + "already exists"); try { NativeIO.RenameTo(inprogressFile, dstFile); } catch (IOException e) { errorReporter.ReportErrorOnFile(dstFile); throw new InvalidOperationException("Unable to finalize edits file " + inprogressFile , e); } if (inprogressFile.Equals(currentInProgress)) { currentInProgress = null; } } }
/// <exception cref="System.IO.IOException"/> public override void Close() { bool triedToClose = false; bool success = false; try { Flush(); ((FileOutputStream)@out).GetChannel().Force(true); triedToClose = true; base.Close(); success = true; } finally { if (success) { bool renamed = tmpFile.RenameTo(origFile); if (!renamed) { // On windows, renameTo does not replace. if (origFile.Exists() && !origFile.Delete()) { throw new IOException("Could not delete original file " + origFile); } try { NativeIO.RenameTo(tmpFile, origFile); } catch (NativeIOException e) { throw new IOException("Could not rename temporary file " + tmpFile + " to " + origFile + " due to failure in native rename. " + e.ToString()); } } } else { if (!triedToClose) { // If we failed when flushing, try to close it to not leak an FD IOUtils.CloseStream(@out); } // close wasn't successful, try to delete the tmp file if (!tmpFile.Delete()) { Log.Warn("Unable to delete tmp file " + tmpFile); } } } }
/// <exception cref="System.IO.IOException"/> private void RenameSelf(string newSuffix) { FilePath src = file; FilePath dst = new FilePath(src.GetParent(), src.GetName() + newSuffix); // renameTo fails on Windows if the destination file already exists. try { if (dst.Exists()) { if (!dst.Delete()) { throw new IOException("Couldn't delete " + dst); } } NativeIO.RenameTo(src, dst); } catch (IOException e) { throw new IOException("Couldn't rename log " + src + " to " + dst, e); } file = dst; }
/// <summary> /// Move replicas in the lazy persist directory to their corresponding locations /// in the finalized directory. /// </summary> /// <returns>number of replicas recovered.</returns> /// <exception cref="System.IO.IOException"/> private int MoveLazyPersistReplicasToFinalized(FilePath source) { FilePath[] files = FileUtil.ListFiles(source); int numRecovered = 0; foreach (FilePath file in files) { if (file.IsDirectory()) { numRecovered += MoveLazyPersistReplicasToFinalized(file); } if (Block.IsMetaFilename(file.GetName())) { FilePath metaFile = file; FilePath blockFile = Block.MetaToBlockFile(metaFile); long blockId = Block.Filename2id(blockFile.GetName()); FilePath targetDir = DatanodeUtil.IdToBlockDir(finalizedDir, blockId); if (blockFile.Exists()) { if (!targetDir.Exists() && !targetDir.Mkdirs()) { Log.Warn("Failed to mkdirs " + targetDir); continue; } FilePath targetMetaFile = new FilePath(targetDir, metaFile.GetName()); try { NativeIO.RenameTo(metaFile, targetMetaFile); } catch (IOException e) { Log.Warn("Failed to move meta file from " + metaFile + " to " + targetMetaFile, e ); continue; } FilePath targetBlockFile = new FilePath(targetDir, blockFile.GetName()); try { NativeIO.RenameTo(blockFile, targetBlockFile); } catch (IOException e) { Log.Warn("Failed to move block file from " + blockFile + " to " + targetBlockFile , e); continue; } if (targetBlockFile.Exists() && targetMetaFile.Exists()) { ++numRecovered; } else { // Failure should be rare. Log.Warn("Failed to move " + blockFile + " to " + targetDir); } } } } FileUtil.FullyDelete(source); return(numRecovered); }