accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ktur...@apache.org
Subject [2/3] ACCUMULO-1832 added volume replacement
Date Tue, 25 Feb 2014 16:13:59 GMT
http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
----------------------------------------------------------------------
diff --git a/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java b/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
index 03519ba..e6c8265 100644
--- a/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
+++ b/server/gc/src/main/java/org/apache/accumulo/gc/SimpleGarbageCollector.java
@@ -65,9 +65,10 @@ import org.apache.accumulo.core.security.Credentials;
 import org.apache.accumulo.core.security.SecurityUtil;
 import org.apache.accumulo.core.security.thrift.TCredentials;
 import org.apache.accumulo.core.util.NamingThreadFactory;
+import org.apache.accumulo.core.util.Pair;
 import org.apache.accumulo.core.util.ServerServices;
-import org.apache.accumulo.core.util.SslConnectionParams;
 import org.apache.accumulo.core.util.ServerServices.Service;
+import org.apache.accumulo.core.util.SslConnectionParams;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.core.zookeeper.ZooUtil;
 import org.apache.accumulo.fate.zookeeper.ZooLock.LockLossReason;
@@ -80,6 +81,7 @@ import org.apache.accumulo.server.conf.ServerConfiguration;
 import org.apache.accumulo.server.fs.VolumeManager;
 import org.apache.accumulo.server.fs.VolumeManager.FileType;
 import org.apache.accumulo.server.fs.VolumeManagerImpl;
+import org.apache.accumulo.server.fs.VolumeUtil;
 import org.apache.accumulo.server.security.SystemCredentials;
 import org.apache.accumulo.server.tables.TableManager;
 import org.apache.accumulo.server.util.Halt;
@@ -105,32 +107,32 @@ import com.google.common.net.HostAndPort;
 
 public class SimpleGarbageCollector implements Iface {
   private static final Text EMPTY_TEXT = new Text();
-  
+
   static class Opts extends ServerOpts {
     @Parameter(names = {"-v", "--verbose"}, description = "extra information will get printed to stdout also")
     boolean verbose = false;
     @Parameter(names = {"-s", "--safemode"}, description = "safe mode will not delete files")
     boolean safeMode = false;
   }
-  
+
   // how much of the JVM's available memory should it use gathering candidates
   private static final float CANDIDATE_MEMORY_PERCENTAGE = 0.75f;
 
   private static final Logger log = Logger.getLogger(SimpleGarbageCollector.class);
-  
+
   private Credentials credentials;
   private long gcStartDelay;
   private VolumeManager fs;
   private boolean useTrash = true;
   private Opts opts = new Opts();
   private ZooLock lock;
-  
+
   private GCStatus status = new GCStatus(new GcCycleStats(), new GcCycleStats(), new GcCycleStats(), new GcCycleStats());
-  
+
   private int numDeleteThreads;
-  
+
   private Instance instance;
-  
+
   public static void main(String[] args) throws UnknownHostException, IOException {
     SecurityUtil.serverLogin();
     Instance instance = HdfsZooInstance.getInstance();
@@ -140,21 +142,21 @@ public class SimpleGarbageCollector implements Iface {
     Opts opts = new Opts();
     opts.parseArgs("gc", args);
     SimpleGarbageCollector gc = new SimpleGarbageCollector(opts);
-    
+
     gc.init(fs, instance, SystemCredentials.get(), serverConf.getConfiguration().getBoolean(Property.GC_TRASH_IGNORE));
     Accumulo.enableTracing(opts.getAddress(), "gc");
     gc.run();
   }
-  
+
   public SimpleGarbageCollector(Opts opts) {
     this.opts = opts;
   }
-  
+
   public void init(VolumeManager fs, Instance instance, Credentials credentials, boolean noTrash) throws IOException {
     this.fs = fs;
     this.credentials = credentials;
     this.instance = instance;
-    
+
     gcStartDelay = ServerConfiguration.getSystemConfiguration(instance).getTimeInMillis(Property.GC_CYCLE_START);
     long gcDelay = ServerConfiguration.getSystemConfiguration(instance).getTimeInMillis(Property.GC_CYCLE_DELAY);
     numDeleteThreads = ServerConfiguration.getSystemConfiguration(instance).getCount(Property.GC_DELETE_THREADS);
@@ -166,7 +168,7 @@ public class SimpleGarbageCollector implements Iface {
     log.info("delete threads: " + numDeleteThreads);
     useTrash = !noTrash;
   }
-  
+
   private class GCEnv implements GarbageCollectionEnvironment {
 
     private String tableName;
@@ -288,6 +290,8 @@ public class SimpleGarbageCollector implements Iface {
 
       ExecutorService deleteThreadPool = Executors.newFixedThreadPool(numDeleteThreads, new NamingThreadFactory("deleting"));
 
+      final List<Pair<Path,Path>> replacements = ServerConstants.getVolumeReplacements();
+
       for (final String delete : confirmedDeletes.values()) {
 
         Runnable deleteTask = new Runnable() {
@@ -296,7 +300,18 @@ public class SimpleGarbageCollector implements Iface {
             boolean removeFlag;
 
             try {
-              Path fullPath = fs.getFullPath(FileType.TABLE, delete);
+              Path fullPath;
+              String switchedDelete = VolumeUtil.switchVolume(delete, FileType.TABLE, replacements);
+              if (switchedDelete != null) {
+                // actually replacing the volumes in the metadata table would be tricky because the entries would be different rows. So it could not be
+                // atomically in one mutation and extreme care would need to be taken that delete entry was not lost. Instead of doing that, just deal with
+                // volume switching when something needs to be deleted. Since the rest of the code uses suffixes to compare delete entries, there is no danger
+                // of deleting something that should not be deleted. Must not change value of delete variable because thats whats stored in metadata table.
+                log.debug("Volume replaced " + delete + " -> " + switchedDelete);
+                fullPath = fs.getFullPath(FileType.TABLE, switchedDelete);
+              } else {
+                fullPath = fs.getFullPath(FileType.TABLE, delete);
+              }
 
               log.debug("Deleting " + fullPath);
 
@@ -406,10 +421,10 @@ public class SimpleGarbageCollector implements Iface {
 
   private void run() {
     long tStart, tStop;
-    
+
     // Sleep for an initial period, giving the master time to start up and
     // old data files to be unused
-      
+
     try {
       getZooLock(startStatsService());
     } catch (Exception ex) {
@@ -424,13 +439,13 @@ public class SimpleGarbageCollector implements Iface {
       log.warn(e, e);
       return;
     }
-    
+
     Sampler sampler = new CountSampler(100);
-    
+
     while (true) {
       if (sampler.next())
         Trace.on("gc");
-      
+
       Span gcSpan = Trace.start("loop");
       tStart = System.currentTimeMillis();
       try {
@@ -449,14 +464,14 @@ public class SimpleGarbageCollector implements Iface {
         status.current.finished = System.currentTimeMillis();
         status.last = status.current;
         status.current = new GcCycleStats();
-        
+
       } catch (Exception e) {
         log.error(e, e);
       }
 
       tStop = System.currentTimeMillis();
       log.info(String.format("Collect cycle took %.2f seconds", ((tStop - tStart) / 1000.0)));
-      
+
       // Clean up any unused write-ahead logs
       Span waLogs = Trace.start("walogs");
       try {
@@ -469,7 +484,7 @@ public class SimpleGarbageCollector implements Iface {
         waLogs.stop();
       }
       gcSpan.stop();
-      
+
       // we just made a lot of metadata changes: flush them out
       try {
         Connector connector = instance.getConnector(credentials.getPrincipal(), credentials.getToken());
@@ -478,7 +493,7 @@ public class SimpleGarbageCollector implements Iface {
       } catch (Exception e) {
         log.warn(e, e);
       }
-      
+
       Trace.offNoFlush();
       try {
         long gcDelay = ServerConfiguration.getSystemConfiguration(instance).getTimeInMillis(Property.GC_CYCLE_DELAY);
@@ -490,7 +505,7 @@ public class SimpleGarbageCollector implements Iface {
       }
     }
   }
-  
+
   private boolean moveToTrash(Path path) throws IOException {
     if (!useTrash)
       return false;
@@ -500,29 +515,29 @@ public class SimpleGarbageCollector implements Iface {
       return false;
     }
   }
-  
+
   private void getZooLock(HostAndPort addr) throws KeeperException, InterruptedException {
     String path = ZooUtil.getRoot(HdfsZooInstance.getInstance()) + Constants.ZGC_LOCK;
-    
+
     LockWatcher lockWatcher = new LockWatcher() {
       @Override
       public void lostLock(LockLossReason reason) {
         Halt.halt("GC lock in zookeeper lost (reason = " + reason + "), exiting!");
       }
-      
+
       @Override
       public void unableToMonitorLockNode(final Throwable e) {
         Halt.halt(-1, new Runnable() {
-          
+
           @Override
           public void run() {
             log.fatal("No longer able to monitor lock node ", e);
           }
         });
-        
+
       }
     };
-    
+
     while (true) {
       lock = new ZooLock(path);
       if (lock.tryLock(lockWatcher, new ServerServices(addr.toString(), Service.GC_CLIENT).toString().getBytes())) {
@@ -531,7 +546,7 @@ public class SimpleGarbageCollector implements Iface {
       UtilWaitThread.sleep(1000);
     }
   }
-  
+
   private HostAndPort startStatsService() throws UnknownHostException {
     Processor<Iface> processor = new Processor<Iface>(TraceWrap.service(this));
     AccumuloConfiguration conf = ServerConfiguration.getSystemConfiguration(instance);
@@ -540,30 +555,27 @@ public class SimpleGarbageCollector implements Iface {
     HostAndPort result = HostAndPort.fromParts(opts.getAddress(), port);
     log.debug("Starting garbage collector listening on " + result);
     try {
-      return TServerUtils.startTServer(result, processor, this.getClass().getSimpleName(), "GC Monitor Service", 2, 1000, maxMessageSize, SslConnectionParams.forServer(conf), 0).address;
+      return TServerUtils.startTServer(result, processor, this.getClass().getSimpleName(), "GC Monitor Service", 2, 1000, maxMessageSize,
+          SslConnectionParams.forServer(conf), 0).address;
     } catch (Exception ex) {
       log.fatal(ex, ex);
       throw new RuntimeException(ex);
     }
   }
-  
 
   static public boolean almostOutOfMemory() {
     Runtime runtime = Runtime.getRuntime();
     return runtime.totalMemory() - runtime.freeMemory() > CANDIDATE_MEMORY_PERCENTAGE * runtime.maxMemory();
   }
-  
-  
+
   final static String METADATA_TABLE_DIR = "/" + MetadataTable.ID;
-  
-  private static void putMarkerDeleteMutation(final String delete, final BatchWriter writer)
-      throws MutationsRejectedException {
+
+  private static void putMarkerDeleteMutation(final String delete, final BatchWriter writer) throws MutationsRejectedException {
     Mutation m = new Mutation(MetadataSchema.DeletesSection.getRowPrefix() + delete);
     m.putDelete(EMPTY_TEXT, EMPTY_TEXT);
     writer.addMutation(m);
   }
-  
-  
+
   private boolean isDir(String delete) {
     int slashCount = 0;
     for (int i = 0; i < delete.length(); i++)
@@ -571,7 +583,7 @@ public class SimpleGarbageCollector implements Iface {
         slashCount++;
     return slashCount == 1;
   }
-  
+
   @Override
   public GCStatus getStatus(TInfo info, TCredentials credentials) {
     return status;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/master/src/main/java/org/apache/accumulo/master/recovery/RecoveryManager.java
----------------------------------------------------------------------
diff --git a/server/master/src/main/java/org/apache/accumulo/master/recovery/RecoveryManager.java b/server/master/src/main/java/org/apache/accumulo/master/recovery/RecoveryManager.java
index 2479d63..76d3520 100644
--- a/server/master/src/main/java/org/apache/accumulo/master/recovery/RecoveryManager.java
+++ b/server/master/src/main/java/org/apache/accumulo/master/recovery/RecoveryManager.java
@@ -35,7 +35,9 @@ import org.apache.accumulo.core.data.KeyExtent;
 import org.apache.accumulo.core.util.NamingThreadFactory;
 import org.apache.accumulo.core.zookeeper.ZooUtil;
 import org.apache.accumulo.master.Master;
+import org.apache.accumulo.server.ServerConstants;
 import org.apache.accumulo.server.fs.VolumeManager.FileType;
+import org.apache.accumulo.server.fs.VolumeUtil;
 import org.apache.accumulo.server.master.recovery.HadoopLogCloser;
 import org.apache.accumulo.server.master.recovery.LogCloser;
 import org.apache.accumulo.server.master.recovery.RecoveryPath;
@@ -127,6 +129,14 @@ public class RecoveryManager {
     for (Collection<String> logs : walogs) {
       for (String walog : logs) {
 
+        String switchedWalog = VolumeUtil.switchVolume(walog, FileType.WAL, ServerConstants.getVolumeReplacements());
+        if (switchedWalog != null) {
+          // replaces the volume used for sorting, but do not change entry in metadata table. When the tablet loads it will change the metadata table entry. If
+          // the tablet has the same replacement config, then it will find the sorted log.
+          log.info("Volume replaced " + walog + " -> " + switchedWalog);
+          walog = switchedWalog;
+        }
+
         String parts[] = walog.split("/");
         String sortId = parts[parts.length - 1];
         String filename = master.getFileSystem().getFullPath(FileType.WAL, walog).toString();

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/DefaultServlet.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/DefaultServlet.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/DefaultServlet.java
index 75aa400..4aa2869 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/DefaultServlet.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/DefaultServlet.java
@@ -268,7 +268,7 @@ public class DefaultServlet extends BasicServlet {
       long totalHdfsBytesUsed = 0l;
       
       try {
-        for (String baseDir : ServerConstants.getConfiguredBaseDirs()) {
+        for (String baseDir : ServerConstants.getConfiguredBaseDirs(ServerConfiguration.getSiteConfiguration())) {
           final Path basePath = new Path(baseDir);
           final FileSystem fs = vm.getFileSystemByPath(basePath);
           

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/tserver/src/main/java/org/apache/accumulo/tserver/DirectoryDecommissioner.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/DirectoryDecommissioner.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/DirectoryDecommissioner.java
deleted file mode 100644
index ea932ff..0000000
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/DirectoryDecommissioner.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.tserver;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.HashSet;
-
-import org.apache.accumulo.core.data.KeyExtent;
-import org.apache.accumulo.core.util.CachedConfiguration;
-import org.apache.accumulo.server.ServerConstants;
-import org.apache.accumulo.server.fs.VolumeManager;
-import org.apache.accumulo.server.security.SystemCredentials;
-import org.apache.accumulo.server.util.MetadataTableUtil;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.hadoop.fs.FSDataInputStream;
-import org.apache.hadoop.fs.FileStatus;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.FileUtil;
-import org.apache.hadoop.fs.Path;
-import org.apache.log4j.Logger;
-
-/**
- * This class contains utility code for switching a tablets default directory, if that default directory is no longer configured.
- */
-public class DirectoryDecommissioner {
-
-  private static final Logger log = Logger.getLogger(DirectoryDecommissioner.class);
-
-  public static boolean isActiveVolume(Path dir) {
-    for (String tableDir : ServerConstants.getTablesDirs()) {
-      // use Path to normalize tableDir
-      if (dir.toString().startsWith(new Path(tableDir).toString()))
-        return true;
-    }
-
-    return false;
-  }
-
-  public static Path checkTabletDirectory(TabletServer tserver, VolumeManager vm, KeyExtent extent, Path dir) throws IOException {
-    if (isActiveVolume(dir))
-      return dir;
-
-    if (!dir.getParent().getParent().getName().equals(ServerConstants.TABLE_DIR)) {
-      throw new IllegalArgumentException("Unexpected table dir " + dir);
-    }
-
-    Path newDir = new Path(vm.choose(ServerConstants.getTablesDirs()) + "/" + dir.getParent().getName() + "/" + dir.getName());
-
-    log.info("Updating directory for " + extent + " from " + dir + " to " + newDir);
-    if (extent.isRootTablet()) {
-      // the root tablet is special case, its files need to be copied if its dir is changed
-
-      // this code needs to be idempotent
-
-      FileSystem fs1 = vm.getFileSystemByPath(dir);
-      FileSystem fs2 = vm.getFileSystemByPath(newDir);
-
-      if (!same(fs1, dir, fs2, newDir)) {
-        if (fs2.exists(newDir)) {
-          Path newDirBackup = getBackupName(fs2, newDir);
-          // never delete anything because were dealing with the root tablet
-          // one reason this dir may exist is because this method failed previously
-          log.info("renaming " + newDir + " to " + newDirBackup);
-          if (!fs2.rename(newDir, newDirBackup)) {
-            throw new IOException("Failed to rename " + newDir + " to " + newDirBackup);
-          }
-        }
-
-        // do a lot of logging since this is the root tablet
-        log.info("copying " + dir + " to " + newDir);
-        if (!FileUtil.copy(fs1, dir, fs2, newDir, false, CachedConfiguration.getInstance())) {
-          throw new IOException("Failed to copy " + dir + " to " + newDir);
-        }
-
-        // only set the new location in zookeeper after a successful copy
-        log.info("setting root tablet location to " + newDir);
-        MetadataTableUtil.setRootTabletDir(newDir.toString());
-
-        // rename the old dir to avoid confusion when someone looks at filesystem... its ok if we fail here and this does not happen because the location in
-        // zookeeper is the authority
-        Path dirBackup = getBackupName(fs1, dir);
-        log.info("renaming " + dir + " to " + dirBackup);
-        fs1.rename(dir, dirBackup);
-      } else {
-        log.info("setting root tablet location to " + newDir);
-        MetadataTableUtil.setRootTabletDir(newDir.toString());
-      }
-
-      return dir;
-    } else {
-      MetadataTableUtil.updateTabletDir(extent, newDir.toString(), SystemCredentials.get(), tserver.getLock());
-      return newDir;
-    }
-  }
-
-  static boolean same(FileSystem fs1, Path dir, FileSystem fs2, Path newDir) throws FileNotFoundException, IOException {
-    // its possible that a user changes config in such a way that two uris point to the same thing. Like hdfs://foo/a/b and hdfs://1.2.3.4/a/b both reference
-    // the same thing because DNS resolves foo to 1.2.3.4. This method does not analyze uris to determine if equivalent, instead it inspects the contents of
-    // what the uris point to.
-
-    //this code is called infrequently and does not need to be optimized.  
-    
-    if (fs1.exists(dir) && fs2.exists(newDir)) {
-
-      if (!fs1.isDirectory(dir))
-        throw new IllegalArgumentException("expected " + dir + " to be a directory");
-
-
-      if (!fs2.isDirectory(newDir))
-        throw new IllegalArgumentException("expected " + newDir + " to be a directory");
-
-
-      HashSet<String> names1 = getFileNames(fs1.listStatus(dir));
-      HashSet<String> names2 = getFileNames(fs2.listStatus(newDir));
-
-      if (names1.equals(names2)) {
-        for (String name : names1)
-          if (!hash(fs1, dir, name).equals(hash(fs2, newDir, name)))
-            return false;
-        return true;
-      }
-
-    }
-    return false;
-  }
-
-  @SuppressWarnings("deprecation")
-  private static HashSet<String> getFileNames(FileStatus[] filesStatuses) {
-    HashSet<String> names = new HashSet<String>();
-    for (FileStatus fileStatus : filesStatuses)
-      if (fileStatus.isDir())
-        throw new IllegalArgumentException("expected " + fileStatus.getPath() + " to be a file");
-      else
-        names.add(fileStatus.getPath().getName());
-    return names;
-  }
-
-  private static String hash(FileSystem fs, Path dir, String name) throws IOException {
-    FSDataInputStream in = fs.open(new Path(dir, name));
-    try {
-      return DigestUtils.sha1Hex(in);
-    } finally {
-      in.close();
-    }
-
-  }
-
-  private static Path getBackupName(FileSystem fs, Path path) {
-    SecureRandom rand = new SecureRandom();
-    return new Path(path.getParent(), path.getName() + "_" + System.currentTimeMillis() + "_" + Math.abs(rand.nextInt()) + ".bak");
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/tserver/src/main/java/org/apache/accumulo/tserver/Tablet.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/Tablet.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/Tablet.java
index dd2afad..dac9528 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/Tablet.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/Tablet.java
@@ -104,6 +104,8 @@ import org.apache.accumulo.server.fs.FileRef;
 import org.apache.accumulo.server.fs.VolumeManager;
 import org.apache.accumulo.server.fs.VolumeManager.FileType;
 import org.apache.accumulo.server.fs.VolumeManagerImpl;
+import org.apache.accumulo.server.fs.VolumeUtil;
+import org.apache.accumulo.server.fs.VolumeUtil.TabletFiles;
 import org.apache.accumulo.server.master.state.TServerInstance;
 import org.apache.accumulo.server.master.tableOps.CompactionIterators;
 import org.apache.accumulo.server.problems.ProblemReport;
@@ -1126,6 +1128,7 @@ public class Tablet {
 
     if (extent.isRootTablet()) { // the meta0 tablet
       Path location = new Path(MetadataTableUtil.getRootTabletDir());
+
       // cleanUpFiles() has special handling for delete. files
       FileStatus[] files = fs.listStatus(location);
       Collection<String> goodPaths = cleanUpFiles(fs, files, true);
@@ -1248,20 +1251,26 @@ public class Tablet {
    * yet another constructor - this one allows us to avoid costly lookups into the Metadata table if we already know the files we need - as at split time
    */
   private Tablet(final TabletServer tabletServer, final Text location, final KeyExtent extent, final TabletResourceManager trm, final Configuration conf,
-      final VolumeManager fs, final List<LogEntry> logEntries, final SortedMap<FileRef,DataFileValue> datafiles, String time,
+      final VolumeManager fs, final List<LogEntry> rawLogEntries, final SortedMap<FileRef,DataFileValue> rawDatafiles, String time,
       final TServerInstance lastLocation, Set<FileRef> scanFiles, long initFlushID, long initCompactID) throws IOException {
+
+    TabletFiles tabletPaths = VolumeUtil.updateTabletVolumes(tabletServer.getLock(), fs, extent, new TabletFiles(location.toString(), rawLogEntries,
+        rawDatafiles));
+
     Path locationPath;
-    if (location.find(":") >= 0) {
-      locationPath = new Path(location.toString());
+
+    if (tabletPaths.dir.contains(":")) {
+      locationPath = new Path(tabletPaths.dir.toString());
     } else {
-      locationPath = fs.getFullPath(FileType.TABLE, extent.getTableId().toString() + location.toString());
+      locationPath = fs.getFullPath(FileType.TABLE, extent.getTableId().toString() + tabletPaths.dir.toString());
     }
 
-    locationPath = DirectoryDecommissioner.checkTabletDirectory(tabletServer, fs, extent, locationPath);
+    final List<LogEntry> logEntries = tabletPaths.logEntries;
+    final SortedMap<FileRef,DataFileValue> datafiles = tabletPaths.datafiles;
 
     this.location = locationPath;
     this.lastLocation = lastLocation;
-    this.tabletDirectory = location.toString();
+    this.tabletDirectory = tabletPaths.dir;
     this.conf = conf;
     this.acuTableConf = tabletServer.getTableConfiguration(extent);
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
index ac4962e..4efcab1 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
@@ -159,6 +159,7 @@ import org.apache.accumulo.server.fs.FileRef;
 import org.apache.accumulo.server.fs.VolumeManager;
 import org.apache.accumulo.server.fs.VolumeManager.FileType;
 import org.apache.accumulo.server.fs.VolumeManagerImpl;
+import org.apache.accumulo.server.fs.VolumeUtil;
 import org.apache.accumulo.server.master.recovery.RecoveryPath;
 import org.apache.accumulo.server.master.state.Assignment;
 import org.apache.accumulo.server.master.state.DistributedStoreException;
@@ -2905,6 +2906,7 @@ public class TabletServer extends AbstractMetricsImpl implements org.apache.accu
 
         // this opens the tablet file and fills in the endKey in the
         // extent
+        locationToOpen = VolumeUtil.switchRootTabletVolume(extent, locationToOpen);
         tablet = new Tablet(TabletServer.this, locationToOpen, extent, trm, tabletsKeyValues);
         /*
          * If a minor compaction starts after a tablet opens, this indicates a log recovery occurred. This recovered data must be minor compacted.

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/tserver/src/test/java/org/apache/accumulo/tserver/DirectoryDecommissionerTest.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/test/java/org/apache/accumulo/tserver/DirectoryDecommissionerTest.java b/server/tserver/src/test/java/org/apache/accumulo/tserver/DirectoryDecommissionerTest.java
deleted file mode 100644
index 47cdab9..0000000
--- a/server/tserver/src/test/java/org/apache/accumulo/tserver/DirectoryDecommissionerTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.tserver;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FSDataOutputStream;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-/**
- * 
- */
-public class DirectoryDecommissionerTest {
-
-  @Rule
-  public TemporaryFolder tempFolder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
-
-  @Test
-  public void testSame() throws Exception {
-    FileSystem fs = FileSystem.getLocal(new Configuration());
-
-    Path subdir1 = new Path(tempFolder.newFolder().toURI());
-    Path subdir2 = new Path(tempFolder.newFolder().toURI());
-    Path subdir3 = new Path(tempFolder.newFolder().toURI());
-
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir1, fs, new Path(tempFolder.getRoot().toURI().toString(), "8854339269459287524098238497")));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, new Path(tempFolder.getRoot().toURI().toString(), "8854339269459287524098238497"), fs, subdir1));
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir1, fs, subdir1));
-
-    writeFile(fs, subdir1, "abc", "foo");
-    writeFile(fs, subdir2, "abc", "bar");
-    writeFile(fs, subdir3, "abc", "foo");
-
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir1, fs, subdir1));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir1, fs, subdir2));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir2, fs, subdir1));
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir1, fs, subdir3));
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir3, fs, subdir1));
-
-    writeFile(fs, subdir1, "def", "123456");
-    writeFile(fs, subdir2, "def", "123456");
-    writeFile(fs, subdir3, "def", "123456");
-
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir1, fs, subdir1));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir1, fs, subdir2));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir2, fs, subdir1));
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir1, fs, subdir3));
-    Assert.assertTrue(DirectoryDecommissioner.same(fs, subdir3, fs, subdir1));
-
-    writeFile(fs, subdir3, "ghi", "09876");
-
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir1, fs, subdir3));
-    Assert.assertFalse(DirectoryDecommissioner.same(fs, subdir3, fs, subdir1));
-
-    fs.mkdirs(new Path(subdir2, "dir1"));
-
-    try {
-      DirectoryDecommissioner.same(fs, subdir1, fs, subdir2);
-      Assert.fail();
-    } catch (IllegalArgumentException e) {}
-
-    try {
-      DirectoryDecommissioner.same(fs, subdir2, fs, subdir1);
-      Assert.fail();
-    } catch (IllegalArgumentException e) {}
-
-    try {
-      DirectoryDecommissioner.same(fs, subdir1, fs, new Path(subdir2, "def"));
-      Assert.fail();
-    } catch (IllegalArgumentException e) {}
-
-    try {
-      DirectoryDecommissioner.same(fs, new Path(subdir2, "def"), fs, subdir3);
-      Assert.fail();
-    } catch (IllegalArgumentException e) {}
-
-  }
-
-  private void writeFile(FileSystem fs, Path dir, String filename, String data) throws IOException {
-    FSDataOutputStream out = fs.create(new Path(dir, filename));
-    try {
-      out.writeUTF(data);
-    } finally {
-      out.close();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/server/tserver/src/test/java/org/apache/accumulo/tserver/TabletServerSyncCheckTest.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/test/java/org/apache/accumulo/tserver/TabletServerSyncCheckTest.java b/server/tserver/src/test/java/org/apache/accumulo/tserver/TabletServerSyncCheckTest.java
index 590945a..50c8b31 100644
--- a/server/tserver/src/test/java/org/apache/accumulo/tserver/TabletServerSyncCheckTest.java
+++ b/server/tserver/src/test/java/org/apache/accumulo/tserver/TabletServerSyncCheckTest.java
@@ -88,11 +88,9 @@ public class TabletServerSyncCheckTest {
 
   private class TestVolumeManagerImpl extends VolumeManagerImpl {
 
-    protected final Map<String,? extends FileSystem> volumes;
-
+   
     public TestVolumeManagerImpl(Map<String,? extends FileSystem> volumes) {
       super(volumes, volumes.keySet().iterator().next(), new ConfigurationCopy(Collections.<String,String> emptyMap()));
-      this.volumes = volumes;
     }
 
     @Override
@@ -106,11 +104,6 @@ public class TabletServerSyncCheckTest {
     }
 
     @Override
-    public boolean closePossiblyOpenFile(Path path) throws IOException {
-      return false;
-    }
-
-    @Override
     public FSDataOutputStream create(Path dest) throws IOException {
       return null;
     }
@@ -161,11 +154,6 @@ public class TabletServerSyncCheckTest {
     }
 
     @Override
-    public Map<String,? extends FileSystem> getFileSystems() {
-      return volumes;
-    }
-
-    @Override
     public Path matchingFileSystem(Path source, String[] options) {
       return null;
     }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/CleanWalIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/CleanWalIT.java b/test/src/test/java/org/apache/accumulo/test/CleanWalIT.java
index ed04f7e..3c0f2ea 100644
--- a/test/src/test/java/org/apache/accumulo/test/CleanWalIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/CleanWalIT.java
@@ -38,12 +38,13 @@ import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.minicluster.impl.ProcessReference;
 import org.apache.accumulo.test.functional.ConfigurableMacIT;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class CleanWalIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setProperty(Property.INSTANCE_ZK_TIMEOUT, "3s");
     cfg.setNumTservers(1);
     cfg.useMiniDFS(true);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/ConfigurableMajorCompactionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/ConfigurableMajorCompactionIT.java b/test/src/test/java/org/apache/accumulo/test/ConfigurableMajorCompactionIT.java
index 28d183c..ef90c3b 100644
--- a/test/src/test/java/org/apache/accumulo/test/ConfigurableMajorCompactionIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/ConfigurableMajorCompactionIT.java
@@ -42,12 +42,13 @@ import org.apache.accumulo.tserver.compaction.CompactionPlan;
 import org.apache.accumulo.tserver.compaction.CompactionStrategy;
 import org.apache.accumulo.tserver.compaction.MajorCompactionRequest;
 import org.apache.accumulo.tserver.compaction.WriteParameters;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class ConfigurableMajorCompactionIT extends ConfigurableMacIT {
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "1s");
     cfg.setSiteConfig(siteConfig);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/DumpConfigIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/DumpConfigIT.java b/test/src/test/java/org/apache/accumulo/test/DumpConfigIT.java
index b98d452..717e500 100644
--- a/test/src/test/java/org/apache/accumulo/test/DumpConfigIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/DumpConfigIT.java
@@ -30,6 +30,7 @@ import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.server.util.Admin;
 import org.apache.accumulo.test.functional.ConfigurableMacIT;
 import org.apache.accumulo.test.functional.FunctionalTestUtils;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -40,7 +41,7 @@ public class DumpConfigIT extends ConfigurableMacIT {
   public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TABLE_FILE_BLOCK_SIZE.getKey(), "1234567"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/MasterRepairsDualAssignmentIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/MasterRepairsDualAssignmentIT.java b/test/src/test/java/org/apache/accumulo/test/MasterRepairsDualAssignmentIT.java
index afd1403..cc51d63 100644
--- a/test/src/test/java/org/apache/accumulo/test/MasterRepairsDualAssignmentIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/MasterRepairsDualAssignmentIT.java
@@ -44,6 +44,7 @@ import org.apache.accumulo.server.master.state.RootTabletStateStore;
 import org.apache.accumulo.server.master.state.TServerInstance;
 import org.apache.accumulo.server.master.state.TabletLocationState;
 import org.apache.accumulo.test.functional.ConfigurableMacIT;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
@@ -51,7 +52,7 @@ public class MasterRepairsDualAssignmentIT extends ConfigurableMacIT {
   
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setProperty(Property.INSTANCE_ZK_TIMEOUT, "5s");
     cfg.setProperty(Property.MASTER_RECOVERY_DELAY, "5s");
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java b/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java
index 4656d30..2d9aafb 100644
--- a/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java
@@ -16,7 +16,10 @@
  */
 package org.apache.accumulo.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.util.Map.Entry;
 
@@ -37,6 +40,7 @@ import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.minicluster.impl.ProcessReference;
 import org.apache.accumulo.test.functional.ConfigurableMacIT;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
@@ -46,7 +50,7 @@ public class NoMutationRecoveryIT extends ConfigurableMacIT {
   static final String TABLE = "table";
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.useMiniDFS(true);
     cfg.setNumTservers(1);
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
index ee38efd..a0efe45 100644
--- a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
@@ -26,6 +26,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.SortedSet;
@@ -67,6 +69,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.RawLocalFileSystem;
 import org.apache.hadoop.io.Text;
 import org.apache.zookeeper.ZooKeeper;
 import org.junit.After;
@@ -95,17 +98,20 @@ public class VolumeIT extends ConfigurableMacIT {
 
   @After
   public void clearDirs() throws IOException {
-    FileUtils.deleteDirectory(new File(v1.toUri()));
-    FileUtils.deleteDirectory(new File(v2.toUri()));
+    FileUtils.deleteQuietly(new File(v1.getParent().toUri()));
   }
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     // Run MAC on two locations in the local file system
     cfg.setProperty(Property.INSTANCE_DFS_URI, v1.toString());
     cfg.setProperty(Property.INSTANCE_DFS_DIR, "/accumulo");
     cfg.setProperty(Property.INSTANCE_VOLUMES, v1.toString() + "," + v2.toString());
-    super.configure(cfg);
+
+    // use raw local file system so walogs sync and flush will work
+    hadoopCoreSite.set("fs.file.impl", RawLocalFileSystem.class.getName());
+
+    super.configure(cfg, hadoopCoreSite);
   }
 
   @Test
@@ -255,7 +261,6 @@ public class VolumeIT extends ConfigurableMacIT {
 
   }
 
-
   @Test
   public void testAddVolumes() throws Exception {
 
@@ -264,23 +269,23 @@ public class VolumeIT extends ConfigurableMacIT {
     // grab this before shutting down cluster
     String uuid = new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers()).getInstanceID();
 
-    verifyVolumesUsed(tableNames[0], v1, v2);
+    verifyVolumesUsed(tableNames[0], false, v1, v2);
 
     Assert.assertEquals(0, cluster.exec(Admin.class, "stopAll").waitFor());
     cluster.stop();
-    
+
     Configuration conf = new Configuration(false);
     conf.addResource(new Path(cluster.getConfig().getConfDir().toURI().toString(), "accumulo-site.xml"));
-    
+
     File v3f = new File(volDirBase, "v3");
     v3f.mkdir();
     Path v3 = new Path("file://" + v3f.getAbsolutePath());
- 
-    conf.set(Property.INSTANCE_VOLUMES.getKey(), v1.toString() + "," + v2.toString()+","+v3.toString());
+
+    conf.set(Property.INSTANCE_VOLUMES.getKey(), v1.toString() + "," + v2.toString() + "," + v3.toString());
     BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(cluster.getConfig().getConfDir(), "accumulo-site.xml")));
     conf.writeXml(fos);
     fos.close();
-    
+
     // initialize volume
     Assert.assertEquals(0, cluster.exec(Initialize.class, "--add-volumes").waitFor());
 
@@ -297,12 +302,33 @@ public class VolumeIT extends ConfigurableMacIT {
     // start cluster and verify that new volume is used
     cluster.start();
 
-    verifyVolumesUsed(tableNames[1], v1, v2, v3);
+    verifyVolumesUsed(tableNames[1], false, v1, v2, v3);
 
   }
 
-  private void verifyVolumesUsed(String tableName, Path... paths) throws AccumuloException, AccumuloSecurityException, TableExistsException,
-      TableNotFoundException, MutationsRejectedException {
+  private void writeData(String tableName, Connector conn) throws AccumuloException, AccumuloSecurityException, TableExistsException, TableNotFoundException,
+      MutationsRejectedException {
+    TreeSet<Text> splits = new TreeSet<Text>();
+    for (int i = 1; i < 100; i++) {
+      splits.add(new Text(String.format("%06d", i * 100)));
+    }
+
+    conn.tableOperations().create(tableName);
+    conn.tableOperations().addSplits(tableName, splits);
+
+    BatchWriter bw = conn.createBatchWriter(tableName, new BatchWriterConfig());
+    for (int i = 0; i < 100; i++) {
+      String row = String.format("%06d", i * 100 + 3);
+      Mutation m = new Mutation(row);
+      m.put("cf1", "cq1", "1");
+      bw.addMutation(m);
+    }
+
+    bw.close();
+  }
+
+  private void verifyVolumesUsed(String tableName, boolean shouldExist, Path... paths) throws AccumuloException, AccumuloSecurityException,
+      TableExistsException, TableNotFoundException, MutationsRejectedException {
 
     Connector conn = cluster.getConnector("root", ROOT_PASSWORD);
 
@@ -313,24 +339,9 @@ public class VolumeIT extends ConfigurableMacIT {
     }
 
     if (!conn.tableOperations().exists(tableName)) {
+      Assert.assertFalse(shouldExist);
 
-      TreeSet<Text> splits = new TreeSet<Text>();
-      for (int i = 0; i < 100; i++) {
-        splits.add(new Text(String.format("%06d", i * 100)));
-      }
-
-      conn.tableOperations().create(tableName);
-      conn.tableOperations().addSplits(tableName, splits);
-
-      BatchWriter bw = conn.createBatchWriter(tableName, new BatchWriterConfig());
-      for (int i = 0; i < 100; i++) {
-        String row = String.format("%06d", i * 100 + 3);
-        Mutation m = new Mutation(row);
-        m.put("cf1", "cq1", "1");
-        bw.addMutation(m);
-      }
-
-      bw.close();
+      writeData(tableName, conn);
 
       verifyData(expected, conn.createScanner(tableName, Authorizations.EMPTY));
 
@@ -341,21 +352,30 @@ public class VolumeIT extends ConfigurableMacIT {
 
     String tableId = conn.tableOperations().tableIdMap().get(tableName);
     Scanner metaScanner = conn.createScanner(MetadataTable.NAME, Authorizations.EMPTY);
+    MetadataSchema.TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN.fetch(metaScanner);
     metaScanner.fetchColumnFamily(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME);
     metaScanner.setRange(new KeyExtent(new Text(tableId), null, null).toMetadataRange());
 
     int counts[] = new int[paths.length];
 
     outer: for (Entry<Key,Value> entry : metaScanner) {
+      String cf = entry.getKey().getColumnFamily().toString();
       String cq = entry.getKey().getColumnQualifier().toString();
+
+      String path;
+      if (cf.equals(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME.toString()))
+        path = cq;
+      else
+        path = entry.getValue().toString();
+
       for (int i = 0; i < paths.length; i++) {
-        if (cq.startsWith(paths[i].toString())) {
+        if (path.startsWith(paths[i].toString())) {
           counts[i]++;
           continue outer;
         }
       }
 
-      Assert.fail("Unexpected volume " + cq);
+      Assert.fail("Unexpected volume " + path);
     }
 
     // if a volume is chosen randomly for each tablet, then the probability that a volume will not be chosen for any tablet is ((num_volumes -
@@ -367,14 +387,14 @@ public class VolumeIT extends ConfigurableMacIT {
       sum += count;
     }
 
-    Assert.assertEquals(100, sum);
+    Assert.assertEquals(200, sum);
   }
 
   @Test
   public void testRemoveVolumes() throws Exception {
-    String[] tableNames = getTableNames(1);
+    String[] tableNames = getTableNames(2);
 
-    verifyVolumesUsed(tableNames[0], v1, v2);
+    verifyVolumesUsed(tableNames[0], false, v1, v2);
 
     Assert.assertEquals(0, cluster.exec(Admin.class, "stopAll").waitFor());
     cluster.stop();
@@ -393,7 +413,7 @@ public class VolumeIT extends ConfigurableMacIT {
     Connector conn = cluster.getConnector("root", ROOT_PASSWORD);
     conn.tableOperations().compact(tableNames[0], null, null, true, true);
 
-    verifyVolumesUsed(tableNames[0], v2);
+    verifyVolumesUsed(tableNames[0], true, v2);
 
     // check that root tablet is not on volume 1
     String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
@@ -402,5 +422,85 @@ public class VolumeIT extends ConfigurableMacIT {
     Assert.assertTrue(rootTabletDir.startsWith(v2.toString()));
     zookeeper.close();
 
+    conn.tableOperations().clone(tableNames[0], tableNames[1], true, new HashMap<String,String>(), new HashSet<String>());
+
+    conn.tableOperations().flush(MetadataTable.NAME, null, null, true);
+    conn.tableOperations().flush(RootTable.NAME, null, null, true);
+
+    verifyVolumesUsed(tableNames[0], true, v2);
+    verifyVolumesUsed(tableNames[1], true, v2);
+
+  }
+
+  private void testReplaceVolume(boolean cleanShutdown) throws Exception {
+    String[] tableNames = getTableNames(3);
+
+    verifyVolumesUsed(tableNames[0], false, v1, v2);
+
+    // write to 2nd table, but do not flush data to disk before shutdown
+    writeData(tableNames[1], cluster.getConnector("root", ROOT_PASSWORD));
+
+    if (cleanShutdown)
+      Assert.assertEquals(0, cluster.exec(Admin.class, "stopAll").waitFor());
+
+    cluster.stop();
+
+    File v1f = new File(v1.toUri());
+    File v8f = new File(new File(v1.getParent().toUri()), "v8");
+    v1f.renameTo(v8f);
+    Path v8 = new Path(v8f.toURI());
+
+    File v2f = new File(v2.toUri());
+    File v9f = new File(new File(v2.getParent().toUri()), "v9");
+    v2f.renameTo(v9f);
+    Path v9 = new Path(v9f.toURI());
+
+    Configuration conf = new Configuration(false);
+    conf.addResource(new Path(cluster.getConfig().getConfDir().toURI().toString(), "accumulo-site.xml"));
+
+    conf.set(Property.INSTANCE_VOLUMES.getKey(), v8 + "," + v9);
+    conf.set(Property.INSTANCE_VOLUMES_REPLACEMENTS.getKey(), v1 + " " + v8 + "," + v2 + " " + v9);
+    BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(cluster.getConfig().getConfDir(), "accumulo-site.xml")));
+    conf.writeXml(fos);
+    fos.close();
+
+    // start cluster and verify that volumes were replaced
+    cluster.start();
+
+    verifyVolumesUsed(tableNames[0], true, v8, v9);
+    verifyVolumesUsed(tableNames[1], true, v8, v9);
+
+    // verify writes to new dir
+    getConnector().tableOperations().compact(tableNames[0], null, null, true, true);
+    getConnector().tableOperations().compact(tableNames[1], null, null, true, true);
+
+    verifyVolumesUsed(tableNames[0], true, v8, v9);
+    verifyVolumesUsed(tableNames[1], true, v8, v9);
+
+    // check that root tablet is not on volume 1 or 2
+    String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
+    ZooKeeper zookeeper = new ZooKeeper(cluster.getZooKeepers(), 30000, null);
+    String rootTabletDir = new String(zookeeper.getData(zpath, false, null), Constants.UTF8);
+    Assert.assertTrue(rootTabletDir.startsWith(v8.toString()) || rootTabletDir.startsWith(v9.toString()));
+    zookeeper.close();
+
+    getConnector().tableOperations().clone(tableNames[1], tableNames[2], true, new HashMap<String,String>(), new HashSet<String>());
+
+    getConnector().tableOperations().flush(MetadataTable.NAME, null, null, true);
+    getConnector().tableOperations().flush(RootTable.NAME, null, null, true);
+
+    verifyVolumesUsed(tableNames[0], true, v8, v9);
+    verifyVolumesUsed(tableNames[1], true, v8, v9);
+    verifyVolumesUsed(tableNames[2], true, v8, v9);
+  }
+
+  @Test
+  public void testCleanReplaceVolumes() throws Exception {
+    testReplaceVolume(true);
+  }
+
+  @Test
+  public void testDirtyReplaceVolumes() throws Exception {
+    testReplaceVolume(false);
   }
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BalanceAfterCommsFailureIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BalanceAfterCommsFailureIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BalanceAfterCommsFailureIT.java
index 08242ff..a16ec2f 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BalanceAfterCommsFailureIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BalanceAfterCommsFailureIT.java
@@ -37,13 +37,14 @@ import org.apache.accumulo.core.security.Credentials;
 import org.apache.accumulo.fate.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.trace.instrument.Tracer;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class BalanceAfterCommsFailureIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.GENERAL_RPC_TIMEOUT.getKey(), "2s"));
   }
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BatchScanSplitIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BatchScanSplitIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BatchScanSplitIT.java
index faf8777..1530689 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BatchScanSplitIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BatchScanSplitIT.java
@@ -36,13 +36,14 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class BatchScanSplitIT extends ConfigurableMacIT {
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "0"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BigRootTabletIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BigRootTabletIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BigRootTabletIT.java
index 16130bf..599b0bf 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BigRootTabletIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BigRootTabletIT.java
@@ -30,13 +30,14 @@ import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.metadata.RootTable;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class BigRootTabletIT extends ConfigurableMacIT {
   // ACCUMULO-542: A large root tablet will fail to load if it does't fit in the tserver scan buffers
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.TABLE_SCAN_MAXMEM.getKey(), "1024");
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "60m");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BinaryStressIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BinaryStressIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BinaryStressIT.java
index 4a10a34..7338095 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BinaryStressIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BinaryStressIT.java
@@ -25,6 +25,7 @@ import org.apache.accumulo.core.client.Connector;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.util.CachedConfiguration;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -33,7 +34,7 @@ import org.junit.Test;
 public class BinaryStressIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.TSERV_MAXMEM.getKey(), "50K");
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "0");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BloomFilterIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BloomFilterIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BloomFilterIT.java
index e3914a1..27aab91 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BloomFilterIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BloomFilterIT.java
@@ -41,13 +41,14 @@ import org.apache.accumulo.core.file.keyfunctor.RowFunctor;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.minicluster.MemoryUnit;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class BloomFilterIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setDefaultMemory(1, MemoryUnit.GIGABYTE);
     cfg.setNumTservers(1);
     Map<String,String> siteConfig = new HashMap<String, String>();

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/BulkSplitOptimizationIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BulkSplitOptimizationIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BulkSplitOptimizationIT.java
index 337bd4f..f9abc0d 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BulkSplitOptimizationIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BulkSplitOptimizationIT.java
@@ -26,6 +26,7 @@ import org.apache.accumulo.core.util.CachedConfiguration;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.junit.Rule;
 import org.junit.Test;
@@ -46,7 +47,7 @@ public class BulkSplitOptimizationIT extends ConfigurableMacIT {
   public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "1s"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/ChaoticBalancerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/ChaoticBalancerIT.java b/test/src/test/java/org/apache/accumulo/test/functional/ChaoticBalancerIT.java
index 9a4a904..67a2d8c 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/ChaoticBalancerIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/ChaoticBalancerIT.java
@@ -27,13 +27,14 @@ import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.server.master.balancer.ChaoticLoadBalancer;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class ChaoticBalancerIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String, String>();
     siteConfig.put(Property.TSERV_MAXMEM.getKey(), "10K");
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "0");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/CleanTmpIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/CleanTmpIT.java b/test/src/test/java/org/apache/accumulo/test/functional/CleanTmpIT.java
index df1b51b..d02f041 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/CleanTmpIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/CleanTmpIT.java
@@ -34,6 +34,7 @@ import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.minicluster.impl.ProcessReference;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.junit.Test;
@@ -41,7 +42,7 @@ import org.junit.Test;
 public class CleanTmpIT extends ConfigurableMacIT {
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> props = new HashMap<String,String>();
     props.put(Property.INSTANCE_ZK_TIMEOUT.getKey(), "3s");
     cfg.setSiteConfig(props);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/CompactionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/CompactionIT.java b/test/src/test/java/org/apache/accumulo/test/functional/CompactionIT.java
index 3f8fcb3..2829533 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/CompactionIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/CompactionIT.java
@@ -41,6 +41,7 @@ import org.apache.accumulo.core.util.CachedConfiguration;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.server.util.Admin;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.junit.Rule;
 import org.junit.Test;
@@ -52,7 +53,7 @@ public class CompactionIT extends ConfigurableMacIT {
   public TemporaryFolder folder = new TemporaryFolder(new File(System.getProperty("user.dir") + "/target"));
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> map = new HashMap<String,String>();
     map.put(Property.TSERV_MAJC_THREAD_MAXOPEN.getKey(), "4");
     map.put(Property.TSERV_MAJC_DELAY.getKey(), "1");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/ConcurrencyIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/ConcurrencyIT.java b/test/src/test/java/org/apache/accumulo/test/functional/ConcurrencyIT.java
index c09216f..60c530b 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/ConcurrencyIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/ConcurrencyIT.java
@@ -39,6 +39,7 @@ import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
@@ -68,7 +69,7 @@ public class ConcurrencyIT extends ConfigurableMacIT {
   }
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "1"));
   }
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableCompactionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableCompactionIT.java b/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableCompactionIT.java
index cc43cc9..a208cc0 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableCompactionIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableCompactionIT.java
@@ -40,13 +40,14 @@ import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.tserver.compaction.CompactionPlan;
 import org.apache.accumulo.tserver.compaction.CompactionStrategy;
 import org.apache.accumulo.tserver.compaction.MajorCompactionRequest;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class ConfigurableCompactionIT extends ConfigurableMacIT {
 
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "1s"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableMacIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableMacIT.java b/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableMacIT.java
index 0de01c9..369bf69 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableMacIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/ConfigurableMacIT.java
@@ -16,7 +16,11 @@
  */
 package org.apache.accumulo.test.functional;
 
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
@@ -27,6 +31,7 @@ import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.util.MonitorUtil;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.log4j.Logger;
 import org.apache.zookeeper.KeeperException;
 import org.junit.After;
@@ -37,17 +42,27 @@ public class ConfigurableMacIT extends AbstractMacIT {
 
   public MiniAccumuloClusterImpl cluster;
 
-  public void configure(MiniAccumuloConfigImpl cfg) {}
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {}
 
   @Before
   public void setUp() throws Exception {
     MiniAccumuloConfigImpl cfg = new MiniAccumuloConfigImpl(
         createTestDir(this.getClass().getName() + "_" + this.testName.getMethodName()), ROOT_PASSWORD);
     cfg.setNativeLibPaths(NativeMapIT.nativeMapLocation().getAbsolutePath());
-    configure(cfg);
+    Configuration coreSite = new Configuration(false);
+    configure(cfg, coreSite);
     cfg.setProperty(Property.TSERV_NATIVEMAP_ENABLED, Boolean.TRUE.toString());
     configureForEnvironment(cfg, getClass());
     cluster = new MiniAccumuloClusterImpl(cfg);
+    if (coreSite.size() > 0) {
+      File csFile = new File(cluster.getConfig().getConfDir(), "core-site.xml");
+      if (csFile.exists())
+        throw new RuntimeException(csFile + " already exist");
+
+      OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(cluster.getConfig().getConfDir(), "core-site.xml")));
+      coreSite.writeXml(out);
+      out.close();
+    }
     cluster.start();
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/DeleteEverythingIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/DeleteEverythingIT.java b/test/src/test/java/org/apache/accumulo/test/functional/DeleteEverythingIT.java
index f00a445..a0bf118 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/DeleteEverythingIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/DeleteEverythingIT.java
@@ -32,13 +32,14 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class DeleteEverythingIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "1s"));
   }
   

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/DynamicThreadPoolsIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/DynamicThreadPoolsIT.java b/test/src/test/java/org/apache/accumulo/test/functional/DynamicThreadPoolsIT.java
index 5f7d38d..c89b8ce 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/DynamicThreadPoolsIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/DynamicThreadPoolsIT.java
@@ -33,12 +33,13 @@ import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.trace.instrument.Tracer;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class DynamicThreadPoolsIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setNumTservers(1);
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "100ms"));
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java b/test/src/test/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
index cc62cbb..6f9b926 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
@@ -56,6 +56,7 @@ import org.apache.accumulo.minicluster.impl.ProcessReference;
 import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -69,7 +70,7 @@ public class GarbageCollectorIT extends ConfigurableMacIT {
   private static final String OUR_SECRET = "itsreallysecret";
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> settings = new HashMap<String,String>();
     settings.put(Property.INSTANCE_SECRET.getKey(), OUR_SECRET);
     settings.put(Property.GC_CYCLE_START.getKey(), "1");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/HalfDeadTServerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/HalfDeadTServerIT.java b/test/src/test/java/org/apache/accumulo/test/functional/HalfDeadTServerIT.java
index d8f38c8..d08b822 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/HalfDeadTServerIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/HalfDeadTServerIT.java
@@ -39,12 +39,13 @@ import org.apache.accumulo.start.Main;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
 import org.apache.accumulo.tserver.TabletServer;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class HalfDeadTServerIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setNumTservers(1);
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.INSTANCE_ZK_TIMEOUT.getKey(), "15s");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/LargeRowIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/LargeRowIT.java b/test/src/test/java/org/apache/accumulo/test/functional/LargeRowIT.java
index c311413..2f3ce04 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/LargeRowIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/LargeRowIT.java
@@ -35,6 +35,7 @@ import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.TestIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.apache.log4j.Logger;
 import org.junit.Test;
@@ -42,7 +43,7 @@ import org.junit.Test;
 public class LargeRowIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "10ms"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/LateLastContactIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/LateLastContactIT.java b/test/src/test/java/org/apache/accumulo/test/functional/LateLastContactIT.java
index 7f1f29b..fc2ed52 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/LateLastContactIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/LateLastContactIT.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 /**
@@ -31,7 +32,7 @@ import org.junit.Test;
 public class LateLastContactIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.GENERAL_RPC_TIMEOUT.getKey(), "2s"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/MasterFailoverIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/MasterFailoverIT.java b/test/src/test/java/org/apache/accumulo/test/functional/MasterFailoverIT.java
index 1fbe2ff..8fd1499 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/MasterFailoverIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/MasterFailoverIT.java
@@ -26,12 +26,13 @@ import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.minicluster.impl.ProcessReference;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class MasterFailoverIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.INSTANCE_ZK_TIMEOUT.getKey(), "5s"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/MaxOpenIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/MaxOpenIT.java b/test/src/test/java/org/apache/accumulo/test/functional/MaxOpenIT.java
index 9483ab9..72ad0f7 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/MaxOpenIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/MaxOpenIT.java
@@ -33,6 +33,7 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 /**
@@ -42,7 +43,7 @@ import org.junit.Test;
 public class MaxOpenIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String, String> conf = new HashMap<String, String>();
     conf.put(Property.TSERV_SCAN_MAX_OPENFILES.getKey(), "4");
     conf.put(Property.TSERV_MAJC_MAXCONCURRENT.getKey(), "1");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/MetadataMaxFiles.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/MetadataMaxFiles.java b/test/src/test/java/org/apache/accumulo/test/functional/MetadataMaxFiles.java
index 789d84b..b83a7de 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/MetadataMaxFiles.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/MetadataMaxFiles.java
@@ -39,13 +39,14 @@ import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.server.util.Admin;
 import org.apache.accumulo.trace.instrument.Tracer;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class MetadataMaxFiles extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "1");
     siteConfig.put(Property.TSERV_SCAN_MAX_OPENFILES.getKey(), "10");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/MetadataSplitIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/MetadataSplitIT.java b/test/src/test/java/org/apache/accumulo/test/functional/MetadataSplitIT.java
index bb0dd15..3339698 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/MetadataSplitIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/MetadataSplitIT.java
@@ -26,12 +26,13 @@ import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class MetadataSplitIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "100ms"));
   }
  

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/RestartIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/RestartIT.java b/test/src/test/java/org/apache/accumulo/test/functional/RestartIT.java
index 709aa1d..cb7bddb 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/RestartIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/RestartIT.java
@@ -38,11 +38,12 @@ import org.apache.accumulo.minicluster.impl.ProcessReference;
 import org.apache.accumulo.server.util.Admin;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class RestartIT extends ConfigurableMacIT {
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> props = new HashMap<String,String>();
     props.put(Property.INSTANCE_ZK_TIMEOUT.getKey(), "5s");
     props.put(Property.GC_CYCLE_DELAY.getKey(), "1s");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/RestartStressIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/RestartStressIT.java b/test/src/test/java/org/apache/accumulo/test/functional/RestartStressIT.java
index da5a86f..06cdb8c 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/RestartStressIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/RestartStressIT.java
@@ -16,7 +16,7 @@
  */
 package org.apache.accumulo.test.functional;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -29,12 +29,13 @@ import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class RestartStressIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String, String> opts = new HashMap<String, String>();
     opts.put(Property.TSERV_MAXMEM.getKey(), "100K");
     opts.put(Property.TSERV_MAJC_DELAY.getKey(), "100ms");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/RowDeleteIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/RowDeleteIT.java b/test/src/test/java/org/apache/accumulo/test/functional/RowDeleteIT.java
index 0ee903b..c04be14 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/RowDeleteIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/RowDeleteIT.java
@@ -38,6 +38,7 @@ import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
 import org.apache.accumulo.core.iterators.user.RowDeletingIterator;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
@@ -45,7 +46,7 @@ public class RowDeleteIT extends ConfigurableMacIT {
 
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_MAJC_DELAY.getKey(), "50ms"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/ScanSessionTimeOutIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/ScanSessionTimeOutIT.java b/test/src/test/java/org/apache/accumulo/test/functional/ScanSessionTimeOutIT.java
index b223845..693a67d 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/ScanSessionTimeOutIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/ScanSessionTimeOutIT.java
@@ -32,13 +32,14 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.io.Text;
 import org.junit.Test;
 
 public class ScanSessionTimeOutIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     cfg.setSiteConfig(Collections.singletonMap(Property.TSERV_SESSION_MAXIDLE.getKey(), "3"));
   }
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/2ef2d885/test/src/test/java/org/apache/accumulo/test/functional/SimpleBalancerFairnessIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/SimpleBalancerFairnessIT.java b/test/src/test/java/org/apache/accumulo/test/functional/SimpleBalancerFairnessIT.java
index fcb19fd..13fea04 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/SimpleBalancerFairnessIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/SimpleBalancerFairnessIT.java
@@ -37,12 +37,13 @@ import org.apache.accumulo.core.util.UtilWaitThread;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.trace.instrument.Tracer;
+import org.apache.hadoop.conf.Configuration;
 import org.junit.Test;
 
 public class SimpleBalancerFairnessIT extends ConfigurableMacIT {
   
   @Override
-  public void configure(MiniAccumuloConfigImpl cfg) {
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
     Map<String,String> siteConfig = new HashMap<String,String>();
     siteConfig.put(Property.TSERV_MAXMEM.getKey(), "10K");
     siteConfig.put(Property.TSERV_MAJC_DELAY.getKey(), "0");


Mime
View raw message