HDFS-9470. Encryption zone on root not loaded from fsimage after NN restart. Xiao Chen via wang.

(cherry picked from commit 9b8e50b424)
This commit is contained in:
Andrew Wang 2015-11-30 14:32:19 -08:00
parent 854ef2be5b
commit ce1111ceea
4 changed files with 74 additions and 17 deletions

View File

@ -2715,6 +2715,9 @@ Release 2.6.3 - UNRELEASED
HDFS-9434. Recommission a datanode with 500k blocks may pause NN for 30 HDFS-9434. Recommission a datanode with 500k blocks may pause NN for 30
seconds for printing info log messags. (szetszwo) seconds for printing info log messags. (szetszwo)
HDFS-9470. Encryption zone on root not loaded from fsimage after NN
restart. (Xiao Chen via wang)
Release 2.6.2 - 2015-10-28 Release 2.6.2 - 2015-10-28
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -1163,27 +1163,42 @@ public class FSDirectory implements Closeable {
inodeMap.put(inode); inodeMap.put(inode);
if (!inode.isSymlink()) { if (!inode.isSymlink()) {
final XAttrFeature xaf = inode.getXAttrFeature(); final XAttrFeature xaf = inode.getXAttrFeature();
if (xaf != null) { addEncryptionZone((INodeWithAdditionalFields) inode, xaf);
XAttr xattr = xaf.getXAttr(CRYPTO_XATTR_ENCRYPTION_ZONE);
if (xattr != null) {
try {
final HdfsProtos.ZoneEncryptionInfoProto ezProto =
HdfsProtos.ZoneEncryptionInfoProto.parseFrom(
xattr.getValue());
ezManager.unprotectedAddEncryptionZone(inode.getId(),
PBHelperClient.convert(ezProto.getSuite()),
PBHelperClient.convert(ezProto.getCryptoProtocolVersion()),
ezProto.getKeyName());
} catch (InvalidProtocolBufferException e) {
NameNode.LOG.warn("Error parsing protocol buffer of " +
"EZ XAttr " + xattr.getName());
}
}
}
} }
} }
} }
private void addEncryptionZone(INodeWithAdditionalFields inode,
XAttrFeature xaf) {
if (xaf == null) {
return;
}
XAttr xattr = xaf.getXAttr(CRYPTO_XATTR_ENCRYPTION_ZONE);
if (xattr == null) {
return;
}
try {
final HdfsProtos.ZoneEncryptionInfoProto ezProto =
HdfsProtos.ZoneEncryptionInfoProto.parseFrom(
xattr.getValue());
ezManager.unprotectedAddEncryptionZone(inode.getId(),
PBHelperClient.convert(ezProto.getSuite()),
PBHelperClient.convert(ezProto.getCryptoProtocolVersion()),
ezProto.getKeyName());
} catch (InvalidProtocolBufferException e) {
NameNode.LOG.warn("Error parsing protocol buffer of " +
"EZ XAttr " + xattr.getName() + " dir:" + inode.getFullPathName());
}
}
/**
* This is to handle encryption zone for rootDir when loading from
* fsimage, and should only be called during NN restart.
*/
public final void addRootDirToEncryptionZone(XAttrFeature xaf) {
addEncryptionZone(rootDir, xaf);
}
/** /**
* This method is always called with writeLock of FSDirectory held. * This method is always called with writeLock of FSDirectory held.
*/ */

View File

@ -404,6 +404,7 @@ public final class FSImageFormatPBINode {
if (f != null) { if (f != null) {
dir.rootDir.addXAttrFeature(f); dir.rootDir.addXAttrFeature(f);
} }
dir.addRootDirToEncryptionZone(f);
} }
} }

View File

@ -378,6 +378,44 @@ public class TestEncryptionZones {
assertZonePresent(null, nonpersistZone.toString()); assertZonePresent(null, nonpersistZone.toString());
} }
@Test(timeout = 60000)
public void testBasicOperationsRootDir() throws Exception {
int numZones = 0;
final Path rootDir = new Path("/");
final Path zone1 = new Path(rootDir, "zone1");
/* Normal creation of an EZ on rootDir */
dfsAdmin.createEncryptionZone(rootDir, TEST_KEY);
assertNumZones(++numZones);
assertZonePresent(null, rootDir.toString());
/* create EZ on child of rootDir which is already an EZ should fail */
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
try {
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
fail("EZ over an EZ");
} catch (IOException e) {
assertExceptionContains("already in an encryption zone", e);
}
// Verify rootDir ez is present after restarting the NameNode
// and saving/loading from fsimage.
fs.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
fs.saveNamespace();
fs.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
cluster.restartNameNode(true);
assertNumZones(numZones);
assertZonePresent(null, rootDir.toString());
/* create EZ on child of rootDir which is already an EZ should fail */
try {
dfsAdmin.createEncryptionZone(zone1, TEST_KEY);
fail("EZ over an EZ");
} catch (IOException e) {
assertExceptionContains("already in an encryption zone", e);
}
}
/** /**
* Test listing encryption zones as a non super user. * Test listing encryption zones as a non super user.
*/ */