commit ad89f12f701f598023136672a5563a4c996edf17 Author: tedyu Date: Fri Oct 16 09:11:20 2015 -0700 HBASE-14605 Split fails due to 'No valid credentials' error when SecureBulkLoadEndpoint#start tries to access hdfs diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java index 9ec5f60..3a4d5c0 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitRequest.java @@ -19,7 +19,6 @@ package org.apache.hadoop.hbase.regionserver; import java.io.IOException; -import java.security.PrivilegedExceptionAction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -60,7 +59,7 @@ class SplitRequest implements Runnable { return "regionName=" + parent + ", midKey=" + Bytes.toStringBinary(midKey); } - private void doSplitting() { + private void doSplitting(User user) { boolean success = false; server.getMetrics().incrSplitRequest(); long startTime = EnvironmentEdgeManager.currentTimeMillis(); @@ -81,7 +80,7 @@ class SplitRequest implements Runnable { // the prepare call -- we are not ready to split just now. Just return. if (!st.prepare()) return; try { - st.execute(this.server, this.server); + st.execute(this.server, this.server, user); success = true; } catch (Exception e) { if (this.server.isStopping() || this.server.isStopped()) { @@ -153,22 +152,7 @@ class SplitRequest implements Runnable { this.server.isStopping() + " or stopped=" + this.server.isStopped()); return; } - if (this.user == null) doSplitting(); - else { - try { - user.getUGI().doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - doSplitting(); - return null; - } - }); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } catch (IOException ioe) { - LOG.error("Encountered exception while splitting", ioe); - } - } + doSplitting(user); } protected void releaseTableLock() { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java index 9be7385..0840c2c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java @@ -24,6 +24,7 @@ import static org.apache.hadoop.hbase.executor.EventType.RS_ZK_REGION_SPLITTING; import java.io.IOException; import java.io.InterruptedIOException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; @@ -51,6 +52,7 @@ import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.executor.EventType; import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CancelableProgressable; import org.apache.hadoop.hbase.util.ConfigUtil; @@ -272,12 +274,13 @@ public class SplitTransaction { * @param server Hosting server instance. Can be null when testing (won't try * and update in zk if a null server) * @param services Used to online/offline regions. + * @param user * @throws IOException If thrown, transaction failed. * Call {@link #rollback(Server, RegionServerServices)} * @return Regions created */ /* package */PairOfSameType createDaughters(final Server server, - final RegionServerServices services) throws IOException { + final RegionServerServices services, User user) throws IOException { LOG.info("Starting split of region " + this.parent); if ((server != null && server.isStopped()) || (services != null && services.isStopping())) { @@ -290,9 +293,26 @@ public class SplitTransaction { // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - // TODO: Remove one of these - this.parent.getCoprocessorHost().preSplit(); - this.parent.getCoprocessorHost().preSplit(this.splitrow); + if (user == null) { + // TODO: Remove one of these + parent.getCoprocessorHost().preSplit(); + parent.getCoprocessorHost().preSplit(splitrow); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preSplit(); + parent.getCoprocessorHost().preSplit(splitrow); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } journal.add(new JournalEntry(JournalEntryType.AFTER_PRE_SPLIT_HOOK)); @@ -306,10 +326,26 @@ public class SplitTransaction { PairOfSameType daughterRegions = stepsBeforePONR(server, services, testing); - List metaEntries = new ArrayList(); + final List metaEntries = new ArrayList(); + boolean ret = false; if (this.parent.getCoprocessorHost() != null) { - if (this.parent.getCoprocessorHost(). - preSplitBeforePONR(this.splitrow, metaEntries)) { + if (user == null) { + ret = parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries); + } else { + try { + ret = user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Boolean run() throws Exception { + return parent.getCoprocessorHost().preSplitBeforePONR(splitrow, metaEntries); + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } + if (ret) { throw new IOException("Coprocessor bypassing region " + this.parent.getRegionNameAsString() + " split."); } @@ -657,6 +693,15 @@ public class SplitTransaction { } } + public PairOfSameType execute(final Server server, + final RegionServerServices services) + throws IOException { + if (User.isHBaseSecurityEnabled(parent.getBaseConf())) { + LOG.warn("Should use execute(Server, RegionServerServices, User)"); + } + return execute(server, services, null); + } + /** * Run the transaction. * @param server Hosting server instance. Can be null when testing (won't try @@ -669,19 +714,35 @@ public class SplitTransaction { * @see #rollback(Server, RegionServerServices) */ public PairOfSameType execute(final Server server, - final RegionServerServices services) + final RegionServerServices services, User user) throws IOException { useZKForAssignment = server == null ? true : ConfigUtil.useZKForAssignment(server.getConfiguration()); - PairOfSameType regions = createDaughters(server, services); + PairOfSameType regions = createDaughters(server, services, user); if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().preSplitAfterPONR(); + if (user == null) { + parent.getCoprocessorHost().preSplitAfterPONR(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preSplitAfterPONR(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } - return stepsAfterPONR(server, services, regions); + return stepsAfterPONR(server, services, regions, user); } public PairOfSameType stepsAfterPONR(final Server server, - final RegionServerServices services, PairOfSameType regions) + final RegionServerServices services, final PairOfSameType regions, User user) throws IOException { openDaughters(server, services, regions.getFirst(), regions.getSecond()); if (server != null && server.getZooKeeper() != null && useZKForAssignment) { @@ -690,7 +751,23 @@ public class SplitTransaction { journal.add(new JournalEntry(JournalEntryType.BEFORE_POST_SPLIT_HOOK)); // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + if (user == null) { + this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond()); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } journal.add(new JournalEntry(JournalEntryType.AFTER_POST_SPLIT_HOOK)); return regions; @@ -936,6 +1013,14 @@ public class SplitTransaction { return splitStoreFile(family, sf); } } + + public boolean rollback(final Server server, final RegionServerServices services) + throws IOException { + if (User.isHBaseSecurityEnabled(parent.getBaseConf())) { + LOG.warn("Should use rollback(Server, RegionServerServices, User)"); + } + return rollback(server, services, null); + } /** * @param server Hosting server instance (May be null when testing). @@ -945,11 +1030,27 @@ public class SplitTransaction { * of no return and so now need to abort the server to minimize damage. */ @SuppressWarnings("deprecation") - public boolean rollback(final Server server, final RegionServerServices services) + public boolean rollback(final Server server, final RegionServerServices services, User user) throws IOException { // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().preRollBackSplit(); + if (user == null) { + this.parent.getCoprocessorHost().preRollBackSplit(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().preRollBackSplit(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } boolean result = true; @@ -1027,7 +1128,23 @@ public class SplitTransaction { } // Coprocessor callback if (this.parent.getCoprocessorHost() != null) { - this.parent.getCoprocessorHost().postRollBackSplit(); + if (user == null) { + this.parent.getCoprocessorHost().postRollBackSplit(); + } else { + try { + user.getUGI().doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + parent.getCoprocessorHost().postRollBackSplit(); + return null; + } + }); + } catch (InterruptedException ie) { + InterruptedIOException iioe = new InterruptedIOException(); + iioe.initCause(ie); + throw iioe; + } + } } return result; } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java index d401cc9..611e7c5 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java @@ -110,7 +110,7 @@ public class TestEndToEndSplitTransaction { split.prepare(); // 1. phase I - PairOfSameType regions = split.createDaughters(server, server); + PairOfSameType regions = split.createDaughters(server, server, null); assertFalse(test(con, tableName, firstRow, server)); assertFalse(test(con, tableName, lastRow, server)); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java index 999f188..af3e541 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java @@ -76,6 +76,7 @@ import org.apache.hadoop.hbase.master.RegionState; import org.apache.hadoop.hbase.master.RegionState.State; import org.apache.hadoop.hbase.master.RegionStates; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; +import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; @@ -865,7 +866,7 @@ public class TestSplitTransactionOnCluster { SplitTransaction st = new SplitTransaction(region, Bytes.toBytes("row2")); try { st.prepare(); - st.createDaughters(regionServer, regionServer); + st.createDaughters(regionServer, regionServer, null); } catch (IOException e) { } @@ -1512,7 +1513,7 @@ public class TestSplitTransactionOnCluster { throws IOException { RegionCoprocessorEnvironment environment = ctx.getEnvironment(); HRegionServer rs = (HRegionServer) environment.getRegionServerServices(); - st.stepsAfterPONR(rs, rs, daughterRegions); + st.stepsAfterPONR(rs, rs, daughterRegions, null); } }