예제 #1
0
        /// <summary>Delete a snapshot for a snapshottable directory</summary>
        /// <param name="snapshotName">Name of the snapshot to be deleted</param>
        /// <param name="collectedBlocks">Used to collect information to update blocksMap</param>
        /// <exception cref="System.IO.IOException"/>
        public virtual void DeleteSnapshot(INodesInPath iip, string snapshotName, INode.BlocksMapUpdateInfo
                                           collectedBlocks, IList <INode> removedINodes)
        {
            INodeDirectory srcRoot = GetSnapshottableRoot(iip);

            srcRoot.RemoveSnapshot(fsdir.GetBlockStoragePolicySuite(), snapshotName, collectedBlocks
                                   , removedINodes);
            numSnapshots.GetAndDecrement();
        }
예제 #2
0
        /// <summary>
        /// Find the source root directory where the snapshot will be taken
        /// for a given path.
        /// </summary>
        /// <returns>Snapshottable directory.</returns>
        /// <exception cref="System.IO.IOException">
        /// Throw IOException when the given path does not lead to an
        /// existing snapshottable directory.
        /// </exception>
        public virtual INodeDirectory GetSnapshottableRoot(INodesInPath iip)
        {
            string         path = iip.GetPath();
            INodeDirectory dir  = INodeDirectory.ValueOf(iip.GetLastINode(), path);

            if (!dir.IsSnapshottable())
            {
                throw new SnapshotException("Directory is not a snapshottable directory: " + path
                                            );
            }
            return(dir);
        }
예제 #3
0
        /// <summary>Test that the global limit on snapshots is honored.</summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestSnapshotLimits()
        {
            // Setup mock objects for SnapshotManager.createSnapshot.
            //
            INodeDirectory  ids   = Org.Mockito.Mockito.Mock <INodeDirectory>();
            FSDirectory     fsdir = Org.Mockito.Mockito.Mock <FSDirectory>();
            INodesInPath    iip   = Org.Mockito.Mockito.Mock <INodesInPath>();
            SnapshotManager sm    = Org.Mockito.Mockito.Spy(new SnapshotManager(fsdir));

            Org.Mockito.Mockito.DoReturn(ids).When(sm).GetSnapshottableRoot((INodesInPath)Matchers.AnyObject
                                                                                ());
            Org.Mockito.Mockito.DoReturn(testMaxSnapshotLimit).When(sm).GetMaxSnapshotID();
            // Create testMaxSnapshotLimit snapshots. These should all succeed.
            //
            for (int i = 0; i < testMaxSnapshotLimit; ++i)
            {
                sm.CreateSnapshot(iip, "dummy", i.ToString());
            }
            // Attempt to create one more snapshot. This should fail due to snapshot
            // ID rollover.
            //
            try
            {
                sm.CreateSnapshot(iip, "dummy", "shouldFailSnapshot");
                NUnit.Framework.Assert.Fail("Expected SnapshotException not thrown");
            }
            catch (SnapshotException se)
            {
                NUnit.Framework.Assert.IsTrue(StringUtils.ToLowerCase(se.Message).Contains("rollover"
                                                                                           ));
            }
            // Delete a snapshot to free up a slot.
            //
            sm.DeleteSnapshot(iip, string.Empty, Org.Mockito.Mockito.Mock <INode.BlocksMapUpdateInfo
                                                                           >(), new AList <INode>());
            // Attempt to create a snapshot again. It should still fail due
            // to snapshot ID rollover.
            //
            try
            {
                sm.CreateSnapshot(iip, "dummy", "shouldFailSnapshot2");
                NUnit.Framework.Assert.Fail("Expected SnapshotException not thrown");
            }
            catch (SnapshotException se)
            {
                NUnit.Framework.Assert.IsTrue(StringUtils.ToLowerCase(se.Message).Contains("rollover"
                                                                                           ));
            }
        }
예제 #4
0
        /// <summary>
        /// Compute the difference between two snapshots of a directory, or between a
        /// snapshot of the directory and its current tree.
        /// </summary>
        /// <exception cref="System.IO.IOException"/>
        public virtual SnapshotDiffReport Diff(INodesInPath iip, string snapshotRootPath,
                                               string from, string to)
        {
            // Find the source root directory path where the snapshots were taken.
            // All the check for path has been included in the valueOf method.
            INodeDirectory snapshotRoot = GetSnapshottableRoot(iip);

            if ((from == null || from.IsEmpty()) && (to == null || to.IsEmpty()))
            {
                // both fromSnapshot and toSnapshot indicate the current tree
                return(new SnapshotDiffReport(snapshotRootPath, from, to, Sharpen.Collections.EmptyList
                                              <SnapshotDiffReport.DiffReportEntry>()));
            }
            SnapshotDiffInfo diffs = snapshotRoot.GetDirectorySnapshottableFeature().ComputeDiff
                                         (snapshotRoot, from, to);

            return(diffs != null?diffs.GenerateReport() : new SnapshotDiffReport(snapshotRootPath
                                                                                 , from, to, Sharpen.Collections.EmptyList <SnapshotDiffReport.DiffReportEntry>()));
        }
예제 #5
0
        /// <summary>Set the given directory as a snapshottable directory.</summary>
        /// <remarks>
        /// Set the given directory as a snapshottable directory.
        /// If the path is already a snapshottable directory, update the quota.
        /// </remarks>
        /// <exception cref="System.IO.IOException"/>
        public virtual void SetSnapshottable(string path, bool checkNestedSnapshottable)
        {
            INodesInPath   iip = fsdir.GetINodesInPath4Write(path);
            INodeDirectory d   = INodeDirectory.ValueOf(iip.GetLastINode(), path);

            if (checkNestedSnapshottable)
            {
                CheckNestedSnapshottable(d, path);
            }
            if (d.IsSnapshottable())
            {
                //The directory is already a snapshottable directory.
                d.SetSnapshotQuota(DirectorySnapshottableFeature.SnapshotLimit);
            }
            else
            {
                d.AddSnapshottableFeature();
            }
            AddSnapshottable(d);
        }
예제 #6
0
        /// <summary>Check the replication for both the current file and all its prior snapshots
        ///     </summary>
        /// <param name="currentFile">the Path of the current file</param>
        /// <param name="snapshotRepMap">
        /// A map maintaining all the snapshots of the current file, as well
        /// as their expected replication number stored in their corresponding
        /// INodes
        /// </param>
        /// <param name="expectedBlockRep">The expected replication number</param>
        /// <exception cref="System.Exception"/>
        private void CheckSnapshotFileReplication(Path currentFile, IDictionary <Path, short
                                                                                 > snapshotRepMap, short expectedBlockRep)
        {
            // First check the getBlockReplication for the INode of the currentFile
            INodeFile inodeOfCurrentFile = GetINodeFile(currentFile);

            NUnit.Framework.Assert.AreEqual(expectedBlockRep, inodeOfCurrentFile.GetBlockReplication
                                                ());
            // Then check replication for every snapshot
            foreach (Path ss in snapshotRepMap.Keys)
            {
                INodesInPath iip     = fsdir.GetINodesInPath(ss.ToString(), true);
                INodeFile    ssInode = iip.GetLastINode().AsFile();
                // The replication number derived from the
                // INodeFileWithLink#getBlockReplication should always == expectedBlockRep
                NUnit.Framework.Assert.AreEqual(expectedBlockRep, ssInode.GetBlockReplication());
                // Also check the number derived from INodeFile#getFileReplication
                NUnit.Framework.Assert.AreEqual(snapshotRepMap[ss], ssInode.GetFileReplication(iip
                                                                                               .GetPathSnapshotId()));
            }
        }
예제 #7
0
        /// <summary>Create a snapshot of the given path.</summary>
        /// <remarks>
        /// Create a snapshot of the given path.
        /// It is assumed that the caller will perform synchronization.
        /// </remarks>
        /// <param name="iip">the INodes resolved from the snapshottable directory's path</param>
        /// <param name="snapshotName">The name of the snapshot.</param>
        /// <exception cref="System.IO.IOException">
        /// Throw IOException when 1) the given path does not lead to an
        /// existing snapshottable directory, and/or 2) there exists a
        /// snapshot with the given name for the directory, and/or 3)
        /// snapshot number exceeds quota
        /// </exception>
        public virtual string CreateSnapshot(INodesInPath iip, string snapshotRoot, string
                                             snapshotName)
        {
            INodeDirectory srcRoot = GetSnapshottableRoot(iip);

            if (snapshotCounter == GetMaxSnapshotID())
            {
                // We have reached the maximum allowable snapshot ID and since we don't
                // handle rollover we will fail all subsequent snapshot creation
                // requests.
                //
                throw new SnapshotException("Failed to create the snapshot. The FileSystem has run out of "
                                            + "snapshot IDs and ID rollover is not supported.");
            }
            srcRoot.AddSnapshot(snapshotCounter, snapshotName);
            //create success, update id
            snapshotCounter++;
            numSnapshots.GetAndIncrement();
            return(Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.GetSnapshotPath(snapshotRoot
                                                                                            , snapshotName));
        }