/// <summary>Create a new encryption zone.</summary> /// <remarks> /// Create a new encryption zone. /// <p/> /// Called while holding the FSDirectory lock. /// </remarks> /// <exception cref="System.IO.IOException"/> internal virtual XAttr CreateEncryptionZone(string src, CipherSuite suite, CryptoProtocolVersion version, string keyName) { System.Diagnostics.Debug.Assert(dir.HasWriteLock()); INodesInPath srcIIP = dir.GetINodesInPath4Write(src, false); if (dir.IsNonEmptyDirectory(srcIIP)) { throw new IOException("Attempt to create an encryption zone for a non-empty directory." ); } if (srcIIP != null && srcIIP.GetLastINode() != null && !srcIIP.GetLastINode().IsDirectory ()) { throw new IOException("Attempt to create an encryption zone for a file."); } EncryptionZoneManager.EncryptionZoneInt ezi = GetEncryptionZoneForPath(srcIIP); if (ezi != null) { throw new IOException("Directory " + src + " is already in an " + "encryption zone. (" + GetFullPathName(ezi) + ")"); } HdfsProtos.ZoneEncryptionInfoProto proto = PBHelper.Convert(suite, version, keyName ); XAttr ezXAttr = XAttrHelper.BuildXAttr(HdfsServerConstants.CryptoXattrEncryptionZone , proto.ToByteArray()); IList <XAttr> xattrs = Lists.NewArrayListWithCapacity(1); xattrs.AddItem(ezXAttr); // updating the xattr will call addEncryptionZone, // done this way to handle edit log loading FSDirXAttrOp.UnprotectedSetXAttrs(dir, src, xattrs, EnumSet.Of(XAttrSetFlag.Create )); return(ezXAttr); }
/// <summary>Test setting and removing multiple xattrs via single operations</summary> /// <exception cref="System.Exception"/> public virtual void TestXAttrMultiSetRemove() { IList <XAttr> existingXAttrs = Lists.NewArrayListWithCapacity(0); // Keep adding a random number of xattrs and verifying until exhausted Random rand = new Random(unchecked ((int)(0xFEEDA))); int numExpectedXAttrs = 0; while (numExpectedXAttrs < numGeneratedXAttrs) { Log.Info("Currently have " + numExpectedXAttrs + " xattrs"); int numToAdd = rand.Next(5) + 1; IList <XAttr> toAdd = Lists.NewArrayListWithCapacity(numToAdd); for (int i = 0; i < numToAdd; i++) { if (numExpectedXAttrs >= numGeneratedXAttrs) { break; } toAdd.AddItem(generatedXAttrs[numExpectedXAttrs]); numExpectedXAttrs++; } Log.Info("Attempting to add " + toAdd.Count + " XAttrs"); for (int i_1 = 0; i_1 < toAdd.Count; i_1++) { Log.Info("Will add XAttr " + toAdd[i_1]); } IList <XAttr> newXAttrs = FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd , EnumSet.Of(XAttrSetFlag.Create)); VerifyXAttrsPresent(newXAttrs, numExpectedXAttrs); existingXAttrs = newXAttrs; } // Keep removing a random number of xattrs and verifying until all gone while (numExpectedXAttrs > 0) { Log.Info("Currently have " + numExpectedXAttrs + " xattrs"); int numToRemove = rand.Next(5) + 1; IList <XAttr> toRemove = Lists.NewArrayListWithCapacity(numToRemove); for (int i = 0; i < numToRemove; i++) { if (numExpectedXAttrs == 0) { break; } toRemove.AddItem(generatedXAttrs[numExpectedXAttrs - 1]); numExpectedXAttrs--; } int expectedNumToRemove = toRemove.Count; Log.Info("Attempting to remove " + expectedNumToRemove + " XAttrs"); IList <XAttr> removedXAttrs = Lists.NewArrayList(); IList <XAttr> newXAttrs = FSDirXAttrOp.FilterINodeXAttrs(existingXAttrs, toRemove, removedXAttrs); NUnit.Framework.Assert.AreEqual("Unexpected number of removed XAttrs", expectedNumToRemove , removedXAttrs.Count); VerifyXAttrsPresent(newXAttrs, numExpectedXAttrs); existingXAttrs = newXAttrs; } }
/// <exception cref="System.IO.IOException"/> internal static IList <XAttr> GetXAttrs(FSDirectory fsd, string srcArg, IList <XAttr > xAttrs) { string src = srcArg; CheckXAttrsConfigFlag(fsd); FSPermissionChecker pc = fsd.GetPermissionChecker(); bool isRawPath = FSDirectory.IsReservedRawName(src); bool getAll = xAttrs == null || xAttrs.IsEmpty(); if (!getAll) { XAttrPermissionFilter.CheckPermissionForApi(pc, xAttrs, isRawPath); } byte[][] pathComponents = FSDirectory.GetPathComponentsForReservedPath(src); src = fsd.ResolvePath(pc, src, pathComponents); INodesInPath iip = fsd.GetINodesInPath(src, true); if (fsd.IsPermissionEnabled()) { fsd.CheckPathAccess(pc, iip, FsAction.Read); } IList <XAttr> all = FSDirXAttrOp.GetXAttrs(fsd, src); IList <XAttr> filteredAll = XAttrPermissionFilter.FilterXAttrsForApi(pc, all, isRawPath ); if (getAll) { return(filteredAll); } if (filteredAll == null || filteredAll.IsEmpty()) { return(null); } IList <XAttr> toGet = Lists.NewArrayListWithCapacity(xAttrs.Count); foreach (XAttr xAttr in xAttrs) { bool foundIt = false; foreach (XAttr a in filteredAll) { if (xAttr.GetNameSpace() == a.GetNameSpace() && xAttr.GetName().Equals(a.GetName( ))) { toGet.AddItem(a); foundIt = true; break; } } if (!foundIt) { throw new IOException("At least one of the attributes provided was not found."); } } return(toGet); }
/// <exception cref="System.IO.IOException"/> private static void SetDirStoragePolicy(FSDirectory fsd, INodeDirectory inode, byte policyId, int latestSnapshotId) { IList <XAttr> existingXAttrs = XAttrStorage.ReadINodeXAttrs(inode); XAttr xAttr = BlockStoragePolicySuite.BuildXAttr(policyId); IList <XAttr> newXAttrs = FSDirXAttrOp.SetINodeXAttrs(fsd, existingXAttrs, Arrays. AsList(xAttr), EnumSet.Of(XAttrSetFlag.Create, XAttrSetFlag.Replace)); XAttrStorage.UpdateINodeXAttrs(inode, newXAttrs, latestSnapshotId); }
public virtual void TestINodeXAttrsLimit() { IList <XAttr> existingXAttrs = Lists.NewArrayListWithCapacity(2); XAttr xAttr1 = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.User).SetName("a1" ).SetValue(new byte[] { unchecked ((int)(0x31)), unchecked ((int)(0x32)), unchecked ( (int)(0x33)) }).Build(); XAttr xAttr2 = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.User).SetName("a2" ).SetValue(new byte[] { unchecked ((int)(0x31)), unchecked ((int)(0x31)), unchecked ( (int)(0x31)) }).Build(); existingXAttrs.AddItem(xAttr1); existingXAttrs.AddItem(xAttr2); // Adding system and raw namespace xAttrs aren't affected by inode // xAttrs limit. XAttr newSystemXAttr = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.System) .SetName("a3").SetValue(new byte[] { unchecked ((int)(0x33)), unchecked ((int)(0x33 )), unchecked ((int)(0x33)) }).Build(); XAttr newRawXAttr = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.Raw).SetName ("a3").SetValue(new byte[] { unchecked ((int)(0x33)), unchecked ((int)(0x33)), unchecked ( (int)(0x33)) }).Build(); IList <XAttr> newXAttrs = Lists.NewArrayListWithCapacity(2); newXAttrs.AddItem(newSystemXAttr); newXAttrs.AddItem(newRawXAttr); IList <XAttr> xAttrs = FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, newXAttrs , EnumSet.Of(XAttrSetFlag.Create, XAttrSetFlag.Replace)); NUnit.Framework.Assert.AreEqual(xAttrs.Count, 4); // Adding a trusted namespace xAttr, is affected by inode xAttrs limit. XAttr newXAttr1 = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.Trusted).SetName ("a4").SetValue(new byte[] { unchecked ((int)(0x34)), unchecked ((int)(0x34)), unchecked ( (int)(0x34)) }).Build(); newXAttrs.Set(0, newXAttr1); try { FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, newXAttrs, EnumSet.Of(XAttrSetFlag .Create, XAttrSetFlag.Replace)); NUnit.Framework.Assert.Fail("Setting user visible xattr on inode should fail if " + "reaching limit."); } catch (IOException e) { GenericTestUtils.AssertExceptionContains("Cannot add additional XAttr " + "to inode, would exceed limit" , e); } }
/// <exception cref="System.IO.IOException"/> internal static IList <XAttr> ListXAttrs(FSDirectory fsd, string src) { FSDirXAttrOp.CheckXAttrsConfigFlag(fsd); FSPermissionChecker pc = fsd.GetPermissionChecker(); bool isRawPath = FSDirectory.IsReservedRawName(src); byte[][] pathComponents = FSDirectory.GetPathComponentsForReservedPath(src); src = fsd.ResolvePath(pc, src, pathComponents); INodesInPath iip = fsd.GetINodesInPath(src, true); if (fsd.IsPermissionEnabled()) { /* To access xattr names, you need EXECUTE in the owning directory. */ fsd.CheckParentAccess(pc, iip, FsAction.Execute); } IList <XAttr> all = FSDirXAttrOp.GetXAttrs(fsd, src); return(XAttrPermissionFilter.FilterXAttrsForApi(pc, all, isRawPath)); }
/// <summary>Remove an xattr for a file or directory.</summary> /// <param name="src">- path to remove the xattr from</param> /// <param name="xAttr">- xAttr to remove</param> /// <exception cref="System.IO.IOException"/> internal static HdfsFileStatus RemoveXAttr(FSDirectory fsd, string src, XAttr xAttr , bool logRetryCache) { FSDirXAttrOp.CheckXAttrsConfigFlag(fsd); FSPermissionChecker pc = fsd.GetPermissionChecker(); XAttrPermissionFilter.CheckPermissionForApi(pc, xAttr, FSDirectory.IsReservedRawName (src)); byte[][] pathComponents = FSDirectory.GetPathComponentsForReservedPath(src); IList <XAttr> xAttrs = Lists.NewArrayListWithCapacity(1); xAttrs.AddItem(xAttr); INodesInPath iip; fsd.WriteLock(); try { src = fsd.ResolvePath(pc, src, pathComponents); iip = fsd.GetINodesInPath4Write(src); CheckXAttrChangeAccess(fsd, iip, xAttr, pc); IList <XAttr> removedXAttrs = UnprotectedRemoveXAttrs(fsd, src, xAttrs); if (removedXAttrs != null && !removedXAttrs.IsEmpty()) { fsd.GetEditLog().LogRemoveXAttrs(src, removedXAttrs, logRetryCache); } else { throw new IOException("No matching attributes found for remove operation"); } } finally { fsd.WriteUnlock(); } return(fsd.GetAuditFileInfo(iip)); }
/// <exception cref="System.Exception"/> public virtual void TestXAttrMultiAddRemoveErrors() { // Test that the same XAttr can not be multiset twice IList <XAttr> existingXAttrs = Lists.NewArrayList(); IList <XAttr> toAdd = Lists.NewArrayList(); toAdd.AddItem(generatedXAttrs[0]); toAdd.AddItem(generatedXAttrs[1]); toAdd.AddItem(generatedXAttrs[2]); toAdd.AddItem(generatedXAttrs[0]); try { FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd, EnumSet.Of(XAttrSetFlag .Create)); NUnit.Framework.Assert.Fail("Specified the same xattr to be set twice"); } catch (IOException e) { GenericTestUtils.AssertExceptionContains("Cannot specify the same " + "XAttr to be set" , e); } // Test that CREATE and REPLACE flags are obeyed toAdd.Remove(generatedXAttrs[0]); existingXAttrs.AddItem(generatedXAttrs[0]); try { FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd, EnumSet.Of(XAttrSetFlag .Create)); NUnit.Framework.Assert.Fail("Set XAttr that is already set without REPLACE flag"); } catch (IOException e) { GenericTestUtils.AssertExceptionContains("already exists", e); } try { FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd, EnumSet.Of(XAttrSetFlag .Replace)); NUnit.Framework.Assert.Fail("Set XAttr that does not exist without the CREATE flag" ); } catch (IOException e) { GenericTestUtils.AssertExceptionContains("does not exist", e); } // Sanity test for CREATE toAdd.Remove(generatedXAttrs[0]); IList <XAttr> newXAttrs = FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd , EnumSet.Of(XAttrSetFlag.Create)); NUnit.Framework.Assert.AreEqual("Unexpected toAdd size", 2, toAdd.Count); foreach (XAttr x in toAdd) { NUnit.Framework.Assert.IsTrue("Did not find added XAttr " + x, newXAttrs.Contains (x)); } existingXAttrs = newXAttrs; // Sanity test for REPLACE toAdd = Lists.NewArrayList(); for (int i = 0; i < 3; i++) { XAttr xAttr = (new XAttr.Builder()).SetNameSpace(XAttr.NameSpace.System).SetName( "a" + i).SetValue(new byte[] { unchecked ((byte)(i * 2)) }).Build(); toAdd.AddItem(xAttr); } newXAttrs = FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd, EnumSet.Of( XAttrSetFlag.Replace)); NUnit.Framework.Assert.AreEqual("Unexpected number of new XAttrs", 3, newXAttrs.Count ); for (int i_1 = 0; i_1 < 3; i_1++) { Assert.AssertArrayEquals("Unexpected XAttr value", new byte[] { unchecked ((byte)( i_1 * 2)) }, newXAttrs[i_1].GetValue()); } existingXAttrs = newXAttrs; // Sanity test for CREATE+REPLACE toAdd = Lists.NewArrayList(); for (int i_2 = 0; i_2 < 4; i_2++) { toAdd.AddItem(generatedXAttrs[i_2]); } newXAttrs = FSDirXAttrOp.SetINodeXAttrs(fsdir, existingXAttrs, toAdd, EnumSet.Of( XAttrSetFlag.Create, XAttrSetFlag.Replace)); VerifyXAttrsPresent(newXAttrs, 4); }