YARN-6354. LeveldbRMStateStore can parse invalid keys when recovering reservations. Contributed by Jason Lowe

(cherry picked from commit 318bfb01bc)
This commit is contained in:
Eric Payne 2017-03-31 12:30:35 -05:00
parent 3ae529ba54
commit 4396c8e938
2 changed files with 23 additions and 4 deletions

View File

@ -214,6 +214,11 @@ public class LeveldbRMStateStore extends RMStateStore {
return db == null;
}
@VisibleForTesting
DB getDatabase() {
return db;
}
@Override
protected Version loadVersion() throws Exception {
Version version = null;
@ -284,6 +289,9 @@ public class LeveldbRMStateStore extends RMStateStore {
while (iter.hasNext()) {
Entry<byte[],byte[]> entry = iter.next();
String key = asString(entry.getKey());
if (!key.startsWith(RM_RESERVATION_KEY_PREFIX)) {
break;
}
String planReservationString =
key.substring(RM_RESERVATION_KEY_PREFIX.length());

View File

@ -31,6 +31,7 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.records.Version;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
import org.fusesource.leveldbjni.JniDBFactory;
import org.iq80.leveldb.DB;
import org.junit.After;
import org.junit.Before;
@ -125,17 +126,27 @@ public class TestLeveldbRMStateStore extends RMStateStoreTestBase {
public void testCompactionCycle() throws Exception {
final DB mockdb = mock(DB.class);
conf.setLong(YarnConfiguration.RM_LEVELDB_COMPACTION_INTERVAL_SECS, 1);
LeveldbRMStateStore store = new LeveldbRMStateStore() {
stateStore = new LeveldbRMStateStore() {
@Override
protected DB openDatabase() throws Exception {
return mockdb;
}
};
store.init(conf);
store.start();
stateStore.init(conf);
stateStore.start();
verify(mockdb, timeout(10000)).compactRange(
(byte[]) isNull(), (byte[]) isNull());
store.close();
}
@Test
public void testBadKeyIteration() throws Exception {
stateStore = new LeveldbRMStateStore();
stateStore.init(conf);
stateStore.start();
DB db = stateStore.getDatabase();
// add an entry that appears at the end of the database when iterating
db.put(JniDBFactory.bytes("zzz"), JniDBFactory.bytes("z"));
stateStore.loadState();
}
class LeveldbStateStoreTester implements RMStateStoreHelper {