YARN-2071. Modified levelDB store permissions to be readable only by the server user. Contributed by Zhijie Shen.

svn merge --ignore-ancestry -c 1597231 ../../trunk/


git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1597232 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Vinod Kumar Vavilapalli 2014-05-24 01:25:04 +00:00
parent c605487979
commit 2994e2ac96
3 changed files with 51 additions and 17 deletions

View File

@ -93,6 +93,9 @@ Release 2.5.0 - UNRELEASED
YARN-2073. Fair Scheduler: Add a utilization threshold to prevent preempting YARN-2073. Fair Scheduler: Add a utilization threshold to prevent preempting
resources when cluster is free (Karthik Kambatla via Sandy Ryza) resources when cluster is free (Karthik Kambatla via Sandy Ryza)
YARN-2071. Modified levelDB store permissions to be readable only by the
server user. (Zhijie Shen via vinodkv)
OPTIMIZATIONS OPTIMIZATIONS
BUG FIXES BUG FIXES

View File

@ -18,6 +18,9 @@
package org.apache.hadoop.yarn.server.applicationhistoryservice.timeline; package org.apache.hadoop.yarn.server.applicationhistoryservice.timeline;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.readReverseOrderedLong;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.writeReverseOrderedLong;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -36,13 +39,16 @@ import java.util.TreeMap;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.collections.map.LRUMap; import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.WritableComparator; import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.service.AbstractService;
@ -50,8 +56,8 @@ import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity; import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent; import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvents; import org.apache.hadoop.yarn.api.records.timeline.TimelineEvents;
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvents.EventsOfOneEntity; import org.apache.hadoop.yarn.api.records.timeline.TimelineEvents.EventsOfOneEntity;
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse;
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse.TimelinePutError; import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse.TimelinePutError;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.fusesource.leveldbjni.JniDBFactory; import org.fusesource.leveldbjni.JniDBFactory;
@ -62,8 +68,7 @@ import org.iq80.leveldb.ReadOptions;
import org.iq80.leveldb.WriteBatch; import org.iq80.leveldb.WriteBatch;
import org.iq80.leveldb.WriteOptions; import org.iq80.leveldb.WriteOptions;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.readReverseOrderedLong; import com.google.common.annotations.VisibleForTesting;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.writeReverseOrderedLong;
/** /**
* <p>An implementation of an application timeline store backed by leveldb.</p> * <p>An implementation of an application timeline store backed by leveldb.</p>
@ -120,7 +125,9 @@ public class LeveldbTimelineStore extends AbstractService
private static final Log LOG = LogFactory private static final Log LOG = LogFactory
.getLog(LeveldbTimelineStore.class); .getLog(LeveldbTimelineStore.class);
private static final String FILENAME = "leveldb-timeline-store.ldb"; @Private
@VisibleForTesting
static final String FILENAME = "leveldb-timeline-store.ldb";
private static final byte[] START_TIME_LOOKUP_PREFIX = "k".getBytes(); private static final byte[] START_TIME_LOOKUP_PREFIX = "k".getBytes();
private static final byte[] ENTITY_ENTRY_PREFIX = "e".getBytes(); private static final byte[] ENTITY_ENTRY_PREFIX = "e".getBytes();
@ -135,6 +142,11 @@ public class LeveldbTimelineStore extends AbstractService
private static final byte[] EMPTY_BYTES = new byte[0]; private static final byte[] EMPTY_BYTES = new byte[0];
@Private
@VisibleForTesting
static final FsPermission LEVELDB_DIR_UMASK = FsPermission
.createImmutable((short) 0700);
private Map<EntityIdentifier, StartAndInsertTime> startTimeWriteCache; private Map<EntityIdentifier, StartAndInsertTime> startTimeWriteCache;
private Map<EntityIdentifier, Long> startTimeReadCache; private Map<EntityIdentifier, Long> startTimeReadCache;
@ -164,16 +176,23 @@ public class LeveldbTimelineStore extends AbstractService
YarnConfiguration.TIMELINE_SERVICE_LEVELDB_READ_CACHE_SIZE, YarnConfiguration.TIMELINE_SERVICE_LEVELDB_READ_CACHE_SIZE,
YarnConfiguration.DEFAULT_TIMELINE_SERVICE_LEVELDB_READ_CACHE_SIZE)); YarnConfiguration.DEFAULT_TIMELINE_SERVICE_LEVELDB_READ_CACHE_SIZE));
JniDBFactory factory = new JniDBFactory(); JniDBFactory factory = new JniDBFactory();
String path = conf.get(YarnConfiguration.TIMELINE_SERVICE_LEVELDB_PATH); Path dbPath = new Path(
File p = new File(path); conf.get(YarnConfiguration.TIMELINE_SERVICE_LEVELDB_PATH), FILENAME);
if (!p.exists()) { FileSystem localFS = null;
if (!p.mkdirs()) { try {
localFS = FileSystem.getLocal(conf);
if (!localFS.exists(dbPath)) {
if (!localFS.mkdirs(dbPath)) {
throw new IOException("Couldn't create directory for leveldb " + throw new IOException("Couldn't create directory for leveldb " +
"timeline store " + path); "timeline store " + dbPath);
} }
localFS.setPermission(dbPath, LEVELDB_DIR_UMASK);
} }
LOG.info("Using leveldb path " + path); } finally {
db = factory.open(new File(path, FILENAME), options); IOUtils.cleanup(LOG, localFS);
}
LOG.info("Using leveldb path " + dbPath);
db = factory.open(new File(dbPath.toString()), options);
startTimeWriteCache = startTimeWriteCache =
Collections.synchronizedMap(new LRUMap(getStartTimeWriteCacheSize( Collections.synchronizedMap(new LRUMap(getStartTimeWriteCacheSize(
conf))); conf)));

View File

@ -17,6 +17,10 @@
*/ */
package org.apache.hadoop.yarn.server.applicationhistoryservice.timeline; package org.apache.hadoop.yarn.server.applicationhistoryservice.timeline;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.writeReverseOrderedLong;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -28,6 +32,8 @@ import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileContext; import org.apache.hadoop.fs.FileContext;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities; import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities;
@ -39,9 +45,6 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.apache.hadoop.yarn.server.applicationhistoryservice.timeline.GenericObjectMapper.writeReverseOrderedLong;
import static org.junit.Assert.assertEquals;
@InterfaceAudience.Private @InterfaceAudience.Private
@InterfaceStability.Unstable @InterfaceStability.Unstable
public class TestLeveldbTimelineStore extends TimelineStoreTestUtils { public class TestLeveldbTimelineStore extends TimelineStoreTestUtils {
@ -51,7 +54,7 @@ public class TestLeveldbTimelineStore extends TimelineStoreTestUtils {
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
fsContext = FileContext.getLocalFSFileContext(); fsContext = FileContext.getLocalFSFileContext();
Configuration conf = new Configuration(); Configuration conf = new YarnConfiguration();
fsPath = new File("target", this.getClass().getSimpleName() + fsPath = new File("target", this.getClass().getSimpleName() +
"-tmpDir").getAbsoluteFile(); "-tmpDir").getAbsoluteFile();
fsContext.delete(new Path(fsPath.getAbsolutePath()), true); fsContext.delete(new Path(fsPath.getAbsolutePath()), true);
@ -71,6 +74,15 @@ public class TestLeveldbTimelineStore extends TimelineStoreTestUtils {
fsContext.delete(new Path(fsPath.getAbsolutePath()), true); fsContext.delete(new Path(fsPath.getAbsolutePath()), true);
} }
@Test
public void testRootDirPermission() throws IOException {
FileSystem fs = FileSystem.getLocal(new YarnConfiguration());
FileStatus file = fs.getFileStatus(
new Path(fsPath.getAbsolutePath(), LeveldbTimelineStore.FILENAME));
assertNotNull(file);
assertEquals(LeveldbTimelineStore.LEVELDB_DIR_UMASK, file.getPermission());
}
@Test @Test
public void testGetSingleEntity() throws IOException { public void testGetSingleEntity() throws IOException {
super.testGetSingleEntity(); super.testGetSingleEntity();