Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 84E1D200B86 for ; Sun, 18 Sep 2016 23:31:55 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 83834160AC3; Sun, 18 Sep 2016 21:31:55 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 9F9F1160A8C for ; Sun, 18 Sep 2016 23:31:54 +0200 (CEST) Received: (qmail 85609 invoked by uid 500); 18 Sep 2016 21:31:53 -0000 Mailing-List: contact commits-help@zookeeper.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ Delivered-To: mailing list commits@zookeeper.apache.org Received: (qmail 85598 invoked by uid 99); 18 Sep 2016 21:31:53 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Sep 2016 21:31:53 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 994CFE03C0; Sun, 18 Sep 2016 21:31:53 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: phunt@apache.org To: commits@zookeeper.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: zookeeper git commit: ZOOKEEPER-2579: ZooKeeper server should verify that dataDir and snapDir are writeable before starting (Abraham Fine via phunt) Date: Sun, 18 Sep 2016 21:31:53 +0000 (UTC) archived-at: Sun, 18 Sep 2016 21:31:55 -0000 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 Authored: Sun Sep 18 14:26:47 2016 -0700 Committer: Patrick Hunt 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. */