HDFS-14777. RBF: Set ReadOnly is failing for mount Table but actually readonly succeed to set. Contributed by Ranith Sardar.

This commit is contained in:
Surendra Singh Lilhore 2019-09-04 15:09:09 +05:30
parent cfa41a49af
commit 05704754a0
2 changed files with 83 additions and 4 deletions

View File

@ -30,6 +30,7 @@
import java.util.Set; import java.util.Set;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.hdfs.DFSUtil;
@ -42,6 +43,7 @@
import org.apache.hadoop.hdfs.protocolPB.RouterPolicyProvider; import org.apache.hadoop.hdfs.protocolPB.RouterPolicyProvider;
import org.apache.hadoop.hdfs.server.federation.resolver.ActiveNamenodeResolver; import org.apache.hadoop.hdfs.server.federation.resolver.ActiveNamenodeResolver;
import org.apache.hadoop.hdfs.server.federation.resolver.FederationNamespaceInfo; import org.apache.hadoop.hdfs.server.federation.resolver.FederationNamespaceInfo;
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableResolver;
import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation; import org.apache.hadoop.hdfs.server.federation.resolver.RemoteLocation;
import org.apache.hadoop.hdfs.server.federation.store.DisabledNameserviceStore; import org.apache.hadoop.hdfs.server.federation.store.DisabledNameserviceStore;
import org.apache.hadoop.hdfs.server.federation.store.MountTableStore; import org.apache.hadoop.hdfs.server.federation.store.MountTableStore;
@ -267,11 +269,13 @@ public AddMountTableEntryResponse addMountTableEntry(
@Override @Override
public UpdateMountTableEntryResponse updateMountTableEntry( public UpdateMountTableEntryResponse updateMountTableEntry(
UpdateMountTableEntryRequest request) throws IOException { UpdateMountTableEntryRequest request) throws IOException {
UpdateMountTableEntryResponse response =
getMountTableStore().updateMountTableEntry(request); UpdateMountTableEntryResponse response = getMountTableStore()
.updateMountTableEntry(request);
try { try {
MountTable mountTable = request.getEntry(); MountTable mountTable = request.getEntry();
if (mountTable != null && router.isQuotaEnabled()) { if (mountTable != null && router.isQuotaEnabled()
&& isQuotaUpdated(request, mountTable)) {
synchronizeQuota(mountTable.getSourcePath(), synchronizeQuota(mountTable.getSourcePath(),
mountTable.getQuota().getQuota(), mountTable.getQuota().getQuota(),
mountTable.getQuota().getSpaceQuota()); mountTable.getQuota().getSpaceQuota());
@ -280,11 +284,36 @@ public UpdateMountTableEntryResponse updateMountTableEntry(
// Ignore exception, if any while reseting quota. Specifically to handle // Ignore exception, if any while reseting quota. Specifically to handle
// if the actual destination doesn't exist. // if the actual destination doesn't exist.
LOG.warn("Unable to reset quota at the destinations for {}: {}", LOG.warn("Unable to reset quota at the destinations for {}: {}",
request.getEntry().toString(), e.getMessage()); request.getEntry(), e.getMessage());
} }
return response; return response;
} }
private boolean isQuotaUpdated(UpdateMountTableEntryRequest request,
MountTable mountTable) throws IOException {
long nsQuota = -1;
long ssQuota = -1;
String path = request.getEntry().getSourcePath();
if (this.router.getSubclusterResolver() instanceof MountTableResolver) {
MountTableResolver mResolver = (MountTableResolver) this.router
.getSubclusterResolver();
MountTable entry = mResolver.getMountPoint(path);
if (entry != null) {
RouterQuotaUsage preQuota = entry.getQuota();
nsQuota = preQuota.getQuota();
ssQuota = preQuota.getSpaceQuota();
}
}
RouterQuotaUsage mountQuota = mountTable.getQuota();
if (nsQuota != mountQuota.getQuota()
|| ssQuota != mountQuota.getSpaceQuota()) {
return true;
}
return false;
}
/** /**
* Synchronize the quota value across mount table and subclusters. * Synchronize the quota value across mount table and subclusters.
* @param path Source path in given mount table. * @param path Source path in given mount table.

View File

@ -93,6 +93,7 @@ public static void globalSetUp() throws Exception {
.metrics() .metrics()
.admin() .admin()
.rpc() .rpc()
.quota()
.safemode() .safemode()
.build(); .build();
cluster.addRouterOverrides(conf); cluster.addRouterOverrides(conf);
@ -1209,6 +1210,55 @@ public void testUpdateReadonlyUserGroupPermissionMountable()
assertEquals((short)0455, mountTable.getMode().toShort()); assertEquals((short)0455, mountTable.getMode().toShort());
} }
@Test
public void testUpdateReadonlyWithQuota() throws Exception {
// Add a mount table
String nsId = "ns0";
String src = "/test-updateReadonlywithQuota";
String dest = "/UpdateReadonlywithQuota";
String[] argv = new String[] {"-add", src, nsId, dest };
assertEquals(0, ToolRunner.run(admin, argv));
stateStore.loadCache(MountTableStoreImpl.class, true);
GetMountTableEntriesRequest getRequest = GetMountTableEntriesRequest
.newInstance(src);
GetMountTableEntriesResponse getResponse = client.getMountTableManager()
.getMountTableEntries(getRequest);
// Ensure mount table added successfully
MountTable mountTable = getResponse.getEntries().get(0);
assertEquals(src, mountTable.getSourcePath());
RemoteLocation localDest = mountTable.getDestinations().get(0);
assertEquals(nsId, localDest.getNameserviceId());
assertEquals(dest, localDest.getDest());
assertFalse(mountTable.isReadOnly());
argv = new String[] {"-update", src, nsId, dest, "-readonly", "true" };
assertEquals(0, ToolRunner.run(admin, argv));
stateStore.loadCache(MountTableStoreImpl.class, true);
getResponse = client.getMountTableManager()
.getMountTableEntries(getRequest);
mountTable = getResponse.getEntries().get(0);
assertTrue(mountTable.isReadOnly());
// Update Quota
long nsQuota = 50;
long ssQuota = 100;
argv = new String[] {"-setQuota", src, "-nsQuota", String.valueOf(nsQuota),
"-ssQuota", String.valueOf(ssQuota) };
assertEquals(0, ToolRunner.run(admin, argv));
stateStore.loadCache(MountTableStoreImpl.class, true);
getResponse = client.getMountTableManager()
.getMountTableEntries(getRequest);
mountTable = getResponse.getEntries().get(0);
RouterQuotaUsage quota = mountTable.getQuota();
assertEquals(nsQuota, quota.getQuota());
assertEquals(ssQuota, quota.getSpaceQuota());
assertTrue(mountTable.isReadOnly());
}
@Test @Test
public void testUpdateOrderMountTable() throws Exception { public void testUpdateOrderMountTable() throws Exception {
testUpdateOrderMountTable(DestinationOrder.HASH); testUpdateOrderMountTable(DestinationOrder.HASH);