Repository: zookeeper
Updated Branches:
  refs/heads/branch-3.4 5859e043c -> 17b93773c


ZOOKEEPER-2579: ZooKeeper server should verify that dataDir and snapDir are 
writeable before starting (Abraham Fine via phunt)

Change-Id: I2ee91f3cdce655a92c2c6c468a79b3c6059436c3


Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/17b93773
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/17b93773
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/17b93773

Branch: refs/heads/branch-3.4
Commit: 17b93773cdd9546e6a72604a0722eed05dbb9bbe
Parents: 5859e04
Author: Patrick Hunt <ph...@apache.org>
Authored: Sun Sep 18 14:26:47 2016 -0700
Committer: Patrick Hunt <ph...@apache.org>
Committed: Sun Sep 18 14:26:47 2016 -0700

----------------------------------------------------------------------
 CHANGES.txt                                     |   3 +
 .../server/persistence/FileTxnSnapLog.java      |   8 ++
 .../server/ZooKeeperServerMainTest.java         | 100 +++++++++++++++++--
 3 files changed, 100 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/17b93773/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 65de3fb..a4f8053 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,9 @@ BUGFIXES:
   ZOOKEEPER-2558: Potential memory leak in recordio.c
   (Michael Han via phunt)
 
+  ZOOKEEPER-2579: ZooKeeper server should verify that dataDir and
+  snapDir are writeable before starting (Abraham Fine via phunt)
+
 IMPROVEMENTS:
 
   ZOOKEEPER-2507: C unit test improvement: line break between

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/17b93773/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
----------------------------------------------------------------------
diff --git 
a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java 
b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
index 6f0df51..7841efa 100644
--- a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
+++ b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
@@ -86,12 +86,20 @@ public class FileTxnSnapLog {
                         + this.dataDir);
             }
         }
+        if (!this.dataDir.canWrite()) {
+            throw new IOException("Cannot write to data directory " + 
this.dataDir);
+        }
+
         if (!this.snapDir.exists()) {
             if (!this.snapDir.mkdirs()) {
                 throw new IOException("Unable to create snap directory "
                         + this.snapDir);
             }
         }
+        if (!this.snapDir.canWrite()) {
+            throw new IOException("Cannot write to snap directory " + 
this.snapDir);
+        }
+
         txnLog = new FileTxnLog(this.dataDir);
         snapLog = new FileSnap(this.snapDir);
     }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/17b93773/src/java/test/org/apache/zookeeper/server/ZooKeeperServerMainTest.java
----------------------------------------------------------------------
diff --git 
a/src/java/test/org/apache/zookeeper/server/ZooKeeperServerMainTest.java 
b/src/java/test/org/apache/zookeeper/server/ZooKeeperServerMainTest.java
index fcb7889..aa94fb6 100644
--- a/src/java/test/org/apache/zookeeper/server/ZooKeeperServerMainTest.java
+++ b/src/java/test/org/apache/zookeeper/server/ZooKeeperServerMainTest.java
@@ -62,35 +62,45 @@ public class ZooKeeperServerMainTest extends ZKTestCase 
implements Watcher {
         final File confFile;
         final TestZKSMain main;
         final File tmpDir;
+        final File dataDir;
+        final File logDir;
 
         public MainThread(int clientPort, boolean preCreateDirs) throws 
IOException {
+            this(clientPort, preCreateDirs, ClientBase.createTmpDir());
+        }
+
+        public MainThread(int clientPort, boolean preCreateDirs, File tmpDir) 
throws IOException {
             super("Standalone server with clientPort:" + clientPort);
-            tmpDir = ClientBase.createTmpDir();
-            confFile = new File(tmpDir, "zoo.cfg");
+            this.tmpDir = tmpDir;
+            confFile = new File(this.tmpDir, "zoo.cfg");
 
             FileWriter fwriter = new FileWriter(confFile);
             fwriter.write("tickTime=2000\n");
             fwriter.write("initLimit=10\n");
             fwriter.write("syncLimit=5\n");
 
-            File dataDir = new File(tmpDir, "data");
-            String dir = dataDir.toString();
-            String dirLog = dataDir.toString() + "_txnlog";
+            dataDir = new File(this.tmpDir, "data");
+            logDir = new File(dataDir.toString() + "_txnlog");
             if (preCreateDirs) {
                 if (!dataDir.mkdir()) {
                     throw new IOException("unable to mkdir " + dataDir);
                 }
-                dirLog = dataDir.toString();
+                if (!logDir.mkdir()) {
+                    throw new IOException("unable to mkdir " + logDir);
+                }
             }
-            
+
+            String dataDirPath = dataDir.toString();
+            String logDirPath = logDir.toString();
+
             // Convert windows path to UNIX to avoid problems with "\"
             String osname = java.lang.System.getProperty("os.name");
             if (osname.toLowerCase().contains("windows")) {
-                dir = dir.replace('\\', '/');
-                dirLog = dirLog.replace('\\', '/');
+                dataDirPath = dataDirPath.replace('\\', '/');
+                logDirPath = logDirPath.replace('\\', '/');
             }
-            fwriter.write("dataDir=" + dir + "\n");
-            fwriter.write("dataLogDir=" + dirLog + "\n");
+            fwriter.write("dataDir=" + dataDirPath + "\n");
+            fwriter.write("dataLogDir=" + logDirPath + "\n");
             fwriter.write("clientPort=" + clientPort + "\n");
             fwriter.flush();
             fwriter.close();
@@ -197,6 +207,74 @@ public class ZooKeeperServerMainTest extends ZKTestCase 
implements Watcher {
         main.deleteDirs();
     }
 
+    @Test(timeout = 30000)
+    public void testReadOnlySnapshotDir() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT = PortAssignment.unique();
+
+        // Start up the ZK server to automatically create the necessary 
directories
+        // and capture the directory where data is stored
+        MainThread main = new MainThread(CLIENT_PORT, true);
+        File tmpDir = main.tmpDir;
+        main.start();
+        Assert.assertTrue("waiting for server being up", ClientBase
+                .waitForServerUp("127.0.0.1:" + CLIENT_PORT,
+                        CONNECTION_TIMEOUT / 2));
+        main.shutdown();
+
+        // Make the snapshot directory read only
+        File snapDir = new File(main.dataDir, FileTxnSnapLog.version + 
FileTxnSnapLog.VERSION);
+        snapDir.setWritable(false);
+
+        // Restart ZK and observe a failure
+        main = new MainThread(CLIENT_PORT, false, tmpDir);
+        main.start();
+
+        Assert.assertFalse("waiting for server being up", ClientBase
+                .waitForServerUp("127.0.0.1:" + CLIENT_PORT,
+                        CONNECTION_TIMEOUT / 2));
+
+        main.shutdown();
+
+        snapDir.setWritable(true);
+
+        main.deleteDirs();
+    }
+
+    @Test(timeout = 30000)
+    public void testReadOnlyTxnLogDir() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT = PortAssignment.unique();
+
+        // Start up the ZK server to automatically create the necessary 
directories
+        // and capture the directory where data is stored
+        MainThread main = new MainThread(CLIENT_PORT, true);
+        File tmpDir = main.tmpDir;
+        main.start();
+        Assert.assertTrue("waiting for server being up", ClientBase
+                .waitForServerUp("127.0.0.1:" + CLIENT_PORT,
+                        CONNECTION_TIMEOUT / 2));
+        main.shutdown();
+
+        // Make the transaction log directory read only
+        File logDir = new File(main.logDir, FileTxnSnapLog.version + 
FileTxnSnapLog.VERSION);
+        logDir.setWritable(false);
+
+        // Restart ZK and observe a failure
+        main = new MainThread(CLIENT_PORT, false, tmpDir);
+        main.start();
+
+        Assert.assertFalse("waiting for server being up", ClientBase
+                .waitForServerUp("127.0.0.1:" + CLIENT_PORT,
+                        CONNECTION_TIMEOUT / 2));
+
+        main.shutdown();
+
+        logDir.setWritable(true);
+
+        main.deleteDirs();
+    }
+
     /**
      * Verify the ability to start a standalone server instance.
      */

Reply via email to