/*
         * Roll back to old snapshot at the block pool level
         * If previous directory exists:
         * <ol>
         * <li>Rename <SD>/current/<bpid>/current to removed.tmp</li>
         * <li>Rename * <SD>/current/<bpid>/previous to current</li>
         * <li>Remove removed.tmp</li>
         * </ol>
         *
         * Do nothing if previous directory does not exist.
         * @param bpSd Block pool storage directory at <SD>/current/<bpid>
         */
        /// <exception cref="System.IO.IOException"/>
        internal virtual void DoRollback(Storage.StorageDirectory bpSd, NamespaceInfo nsInfo
                                         )
        {
            FilePath prevDir = bpSd.GetPreviousDir();

            // regular startup if previous dir does not exist
            if (!prevDir.Exists())
            {
                return;
            }
            // read attributes out of the VERSION file of previous directory
            Org.Apache.Hadoop.Hdfs.Server.Datanode.BlockPoolSliceStorage prevInfo = new Org.Apache.Hadoop.Hdfs.Server.Datanode.BlockPoolSliceStorage
                                                                                        ();
            prevInfo.ReadPreviousVersionProperties(bpSd);
            // We allow rollback to a state, which is either consistent with
            // the namespace state or can be further upgraded to it.
            // In another word, we can only roll back when ( storedLV >= software LV)
            // && ( DN.previousCTime <= NN.ctime)
            if (!(prevInfo.GetLayoutVersion() >= HdfsConstants.DatanodeLayoutVersion && prevInfo
                  .GetCTime() <= nsInfo.GetCTime()))
            {
                // cannot rollback
                throw new InconsistentFSStateException(bpSd.GetRoot(), "Cannot rollback to a newer state.\nDatanode previous state: LV = "
                                                       + prevInfo.GetLayoutVersion() + " CTime = " + prevInfo.GetCTime() + " is newer than the namespace state: LV = "
                                                       + HdfsConstants.DatanodeLayoutVersion + " CTime = " + nsInfo.GetCTime());
            }
            Log.Info("Rolling back storage directory " + bpSd.GetRoot() + ".\n   target LV = "
                     + nsInfo.GetLayoutVersion() + "; target CTime = " + nsInfo.GetCTime());
            FilePath tmpDir = bpSd.GetRemovedTmp();

            System.Diagnostics.Debug.Assert(!tmpDir.Exists(), "removed.tmp directory must not exist."
                                            );
            // 1. rename current to tmp
            FilePath curDir = bpSd.GetCurrentDir();

            System.Diagnostics.Debug.Assert(curDir.Exists(), "Current directory must exist.");
            Rename(curDir, tmpDir);
            // 2. rename previous to current
            Rename(prevDir, curDir);
            // 3. delete removed.tmp dir
            DeleteDir(tmpDir);
            Log.Info("Rollback of " + bpSd.GetRoot() + " is complete");
        }
Esempio n. 2
0
        /// <summary>Perform rollback of the storage dir to the previous state.</summary>
        /// <remarks>
        /// Perform rollback of the storage dir to the previous state. The existing
        /// current dir is removed, and the previous dir is renamed to current.
        /// </remarks>
        /// <param name="sd">the storage directory to roll back.</param>
        /// <exception cref="System.IO.IOException">in the event of error</exception>
        internal static void DoRollBack(Storage.StorageDirectory sd)
        {
            FilePath prevDir = sd.GetPreviousDir();

            if (!prevDir.Exists())
            {
                return;
            }
            FilePath tmpDir = sd.GetRemovedTmp();

            Preconditions.CheckState(!tmpDir.Exists(), "removed.tmp directory must not exist for rollback."
                                     + "Consider restarting for recovery.");
            // rename current to tmp
            FilePath curDir = sd.GetCurrentDir();

            Preconditions.CheckState(curDir.Exists(), "Current directory must exist for rollback."
                                     );
            NNStorage.Rename(curDir, tmpDir);
            // rename previous to current
            NNStorage.Rename(prevDir, curDir);
            // delete tmp dir
            NNStorage.DeleteDir(tmpDir);
            Log.Info("Rollback of " + sd.GetRoot() + " is complete.");
        }