/// <summary>Upgrade to any release after 0.22 (0.22 included) release e.g.</summary> /// <remarks> /// Upgrade to any release after 0.22 (0.22 included) release e.g. 0.22 => 0.23 /// Upgrade procedure is as follows: /// <ol> /// <li>If <SD>/current/<bpid>/previous exists then delete it</li> /// <li>Rename <SD>/current/<bpid>/current to /// <SD>/current/bpid/current/previous.tmp</li> /// <li>Create new <SD>current/<bpid>/current directory</li> /// <ol> /// <li>Hard links for block files are created from previous.tmp to current</li> /// <li>Save new version file in current directory</li> /// </ol> /// <li>Rename previous.tmp to previous</li> </ol> /// </remarks> /// <param name="bpSd">storage directory <SD>/current/<bpid></param> /// <param name="nsInfo">Namespace Info from the namenode</param> /// <exception cref="System.IO.IOException">on error</exception> internal virtual void DoUpgrade(DataNode datanode, Storage.StorageDirectory bpSd, NamespaceInfo nsInfo) { // Upgrading is applicable only to release with federation or after if (!DataNodeLayoutVersion.Supports(LayoutVersion.Feature.Federation, layoutVersion )) { return; } Log.Info("Upgrading block pool storage directory " + bpSd.GetRoot() + ".\n old LV = " + this.GetLayoutVersion() + "; old CTime = " + this.GetCTime() + ".\n new LV = " + HdfsConstants.DatanodeLayoutVersion + "; new CTime = " + nsInfo.GetCTime()); // get <SD>/previous directory string dnRoot = GetDataNodeStorageRoot(bpSd.GetRoot().GetCanonicalPath()); Storage.StorageDirectory dnSdStorage = new Storage.StorageDirectory(new FilePath( dnRoot)); FilePath dnPrevDir = dnSdStorage.GetPreviousDir(); // If <SD>/previous directory exists delete it if (dnPrevDir.Exists()) { DeleteDir(dnPrevDir); } FilePath bpCurDir = bpSd.GetCurrentDir(); FilePath bpPrevDir = bpSd.GetPreviousDir(); System.Diagnostics.Debug.Assert(bpCurDir.Exists(), "BP level current directory must exist." ); CleanupDetachDir(new FilePath(bpCurDir, DataStorage.StorageDirDetached)); // 1. Delete <SD>/current/<bpid>/previous dir before upgrading if (bpPrevDir.Exists()) { DeleteDir(bpPrevDir); } FilePath bpTmpDir = bpSd.GetPreviousTmp(); System.Diagnostics.Debug.Assert(!bpTmpDir.Exists(), "previous.tmp directory must not exist." ); // 2. Rename <SD>/current/<bpid>/current to // <SD>/current/<bpid>/previous.tmp Rename(bpCurDir, bpTmpDir); // 3. Create new <SD>/current with block files hardlinks and VERSION LinkAllBlocks(datanode, bpTmpDir, bpCurDir); this.layoutVersion = HdfsConstants.DatanodeLayoutVersion; System.Diagnostics.Debug.Assert(this.namespaceID == nsInfo.GetNamespaceID(), "Data-node and name-node layout versions must be the same." ); this.cTime = nsInfo.GetCTime(); WriteProperties(bpSd); // 4.rename <SD>/current/<bpid>/previous.tmp to // <SD>/current/<bpid>/previous Rename(bpTmpDir, bpPrevDir); Log.Info("Upgrade of block pool " + blockpoolID + " at " + bpSd.GetRoot() + " is complete" ); }
/// <summary>Cleanup the detachDir.</summary> /// <remarks> /// Cleanup the detachDir. /// If the directory is not empty report an error; Otherwise remove the /// directory. /// </remarks> /// <param name="detachDir">detach directory</param> /// <exception cref="System.IO.IOException">if the directory is not empty or it can not be removed /// </exception> private void CleanupDetachDir(FilePath detachDir) { if (!DataNodeLayoutVersion.Supports(LayoutVersion.Feature.AppendRbwDir, layoutVersion ) && detachDir.Exists() && detachDir.IsDirectory()) { if (FileUtil.List(detachDir).Length != 0) { throw new IOException("Detached directory " + detachDir + " is not empty. Please manually move each file under this " + "directory to the finalized directory if the finalized " + "directory tree does not have the file." ); } else { if (!detachDir.Delete()) { throw new IOException("Cannot remove directory " + detachDir); } } } }