From zookeeper-commits-returnsamanthajackson@example.org Sat Aug 02 00:07:58 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 27924 invoked from network); 2 Aug 2008 00:07:58 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 2 Aug 2008 00:07:58 -0000 Received: (qmail 60119 invoked by uid 500); 2 Aug 2008 00:07:58 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 60101 invoked by uid 500); 2 Aug 2008 00:07:57 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 60090 invoked by uid 99); 2 Aug 2008 00:07:57 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Aug 2008 17:07:57 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 02 Aug 2008 00:07:04 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 92E3E2388987; Fri, 1 Aug 2008 17:07:31 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r681910 - in /hadoop/zookeeper/trunk/src/java: main/org/apache/zookeeper/ZooKeeper.java main/org/apache/zookeeper/server/DataTree.java main/org/apache/zookeeper/server/PrepRequestProcessor.java test/org/apache/zookeeper/test/ClientTest.java Date: Sat, 02 Aug 2008 00:07:31 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mahadev Date: Fri Aug 1 17:07:30 2008 New Revision: 681910 URL: http://svn.apache.org/viewvc?rev=681910&view=rev Log: ZOOKEEPER-44. Create sequence flag children with prefixes of 0's so that they can be lexicographically sorted. (Jakob Homan via mahadev) Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java?rev=681910&r1=681909&r2=681910&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java Fri Aug 1 17:07:30 2008 @@ -828,12 +828,15 @@ * triggered by a successful operation that deletes the node of the given * path or creates/delete a child under the node. * <p> + * The list of children returned is not sorted and no guarantee is provided + * as to its natural or lexical order. + * <p> * A KeeperException with error code KeeperException.NoNode will be thrown * if no node with the given path exists. * * @param path * @param watcher explicit watcher - * @return an array of children of the node with the given path + * @return an unordered array of children of the node with the given path * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. */ @@ -864,12 +867,15 @@ * triggered by a successful operation that deletes the node of the given * path or creates/delete a child under the node. * <p> + * The list of children returned is not sorted and no guarantee is provided + * as to its natural or lexical order. + * <p> * A KeeperException with error code KeeperException.NoNode will be thrown * if no node with the given path exists. * * @param path * @param watch - * @return an array of children of the node with the given path + * @return an unordered array of children of the node with the given path * @throws InterruptedException If the server transaction is interrupted. * @throws KeeperException If the server signals an error with a non-zero error code. */ Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java?rev=681910&r1=681909&r2=681910&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java Fri Aug 1 17:07:30 2008 @@ -292,7 +292,6 @@ synchronized (n) { ArrayList<String> children = new ArrayList<String>(); children.addAll(n.children); - Collections.sort(children); if (watcher != null) { childWatches.addWatch(path, watcher); } Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java?rev=681910&r1=681909&r2=681910&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java Fri Aug 1 17:07:30 2008 @@ -204,7 +204,7 @@ request.authInfo); int parentCVersion = parentRecord.stat.getCversion(); if ((createRequest.getFlags() & CreateFlags.SEQUENCE) != 0) { - path = path + parentCVersion; + path = path + String.format("%010d", parentCVersion); } try { if (getRecordForPath(path) != null) { Modified: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java?rev=681910&r1=681909&r2=681910&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java (original) +++ hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java Fri Aug 1 17:07:30 2008 @@ -278,6 +278,47 @@ } } + // Test that sequential filenames are being created correctly, + // with 0-padding in the filename + public void testSequentialNodeNames() throws IOException, InterruptedException, KeeperException { + String path = "/SEQUENCE"; + String file = "TEST"; + String filepath = path + "/" + file; + + ZooKeeper zk = null; + try { + zk =createClient(this); + zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, 0); + zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateFlags.SEQUENCE); + List<String> children = zk.getChildren(path, false); + assertEquals(1, children.size()); + assertEquals(file + "0000000000", children.get(0)); + + zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateFlags.SEQUENCE); + children = zk.getChildren(path, false); + assertEquals(2, children.size()); + assertTrue(children.contains(file + "0000000001")); + + zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateFlags.SEQUENCE); + children = zk.getChildren(path, false); + assertEquals(3, children.size()); + assertTrue(children.contains(file + "0000000002")); + + // The pattern is holding so far. Let's run the counter a bit + // to be sure it continues to spit out the correct answer + for(int i = children.size(); i < 105; i++) + zk.create(filepath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateFlags.SEQUENCE); + + children = zk.getChildren(path, false); + assertTrue(children.contains(file + "0000000104")); + + } + finally { + if(zk != null) + zk.close(); + } + } + private void notestConnections() throws IOException, InterruptedException, KeeperException { ZooKeeper zk; for(int i = 0; i < 2000; i++) { From zookeeper-commits-returnsamanthajackson@example.org Thu Aug 07 20:35:32 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 30423 invoked from network); 7 Aug 2008 20:35:32 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 7 Aug 2008 20:35:32 -0000 Received: (qmail 97981 invoked by uid 500); 7 Aug 2008 20:35:32 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 97961 invoked by uid 500); 7 Aug 2008 20:35:31 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 97950 invoked by uid 99); 7 Aug 2008 20:35:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Aug 2008 13:35:31 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Aug 2008 20:34:44 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D9BD1238899E; Thu, 7 Aug 2008 13:34:41 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r683707 - in /hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server: ./ quorum/ Date: Thu, 07 Aug 2008 20:34:41 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mahadev Date: Thu Aug 7 13:34:41 2008 New Revision: 683707 URL: http://svn.apache.org/viewvc?rev=683707&view=rev Log: ZOOKEEPER-108. Fix sync operation reordering on a Quorum. (Flavio Paiva Junqueira via mahadev) Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ProposalRequestProcessor.java Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java Thu Aug 7 13:34:41 2008 @@ -158,6 +158,7 @@ err = rc.err; break; case OpCode.sync: + LOG.debug("OpCode.sync " + request); SyncRequest syncRequest = new SyncRequest(); ZooKeeperServer.byteBuffer2Record(request.request, syncRequest); Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java Thu Aug 7 13:34:41 2008 @@ -47,11 +47,6 @@ */ LinkedList<Request> committedRequests = new LinkedList<Request>(); - /* - * Pending sync requests - */ - LinkedList<Request> pendingSyncs = new LinkedList<Request>(); - RequestProcessor nextProcessor; public CommitProcessor(RequestProcessor nextProcessor) { @@ -127,7 +122,7 @@ break; case OpCode.sync: nextPending = request; - pendingSyncs.add(request); + //pendingSyncs.add(request); break; default: toProcess.add(request); @@ -149,6 +144,7 @@ new Exception("committing a null! ")); return; } + LOG.debug("Committing" + request.cxid); committedRequests.add(request); notifyAll(); } Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java Thu Aug 7 13:34:41 2008 @@ -64,10 +64,11 @@ // the response nextProcessor.processRequest(request); switch (request.type) { + case OpCode.sync: + zks.pendingSyncs.add(request); case OpCode.create: case OpCode.delete: case OpCode.setData: - case OpCode.sync: case OpCode.setACL: case OpCode.createSession: case OpCode.closeSession: Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java Thu Aug 7 13:34:41 2008 @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.log4j.Logger; @@ -50,6 +51,11 @@ SyncRequestProcessor syncProcessor; + /* + * Pending sync requests + */ + ConcurrentLinkedQueue<Request> pendingSyncs; + /** * @param port * @param dataDir @@ -59,6 +65,7 @@ QuorumPeer self,DataTreeBuilder treeBuilder) throws IOException { super(dataDir, dataLogDir, self.tickTime,treeBuilder); this.self = self; + this.pendingSyncs = new ConcurrentLinkedQueue<Request>(); } public Follower getFollower(){ @@ -131,12 +138,12 @@ } public void sync(){ - if(commitProcessor.pendingSyncs.size() ==0){ + if(pendingSyncs.size() ==0){ LOG.warn("Not expecting a sync."); return; } - commitProcessor.commit(commitProcessor.pendingSyncs.remove()); + commitProcessor.commit(pendingSyncs.remove()); } Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java Thu Aug 7 13:34:41 2008 @@ -373,6 +373,11 @@ } commit(zxid); zk.commitProcessor.commit(p.request); + if(pendingSyncs.containsKey(zxid)){ + sendSync(syncHandler.get(pendingSyncs.get(zxid).sessionId), pendingSyncs.get(zxid)); + syncHandler.remove(pendingSyncs.get(zxid)); + pendingSyncs.remove(zxid); + } } } return; @@ -462,12 +467,6 @@ lastCommitted = zxid; QuorumPacket qp = new QuorumPacket(Leader.COMMIT, zxid, null, null); sendPacket(qp); - - if(pendingSyncs.containsKey(zxid)){ - sendSync(syncHandler.get(pendingSyncs.get(zxid).sessionId), pendingSyncs.get(zxid)); - syncHandler.remove(pendingSyncs.get(zxid)); - pendingSyncs.remove(zxid); - } } long lastProposed; @@ -544,8 +543,14 @@ */ public void sendSync(FollowerHandler f, Request r){ - QuorumPacket qp = new QuorumPacket(Leader.SYNC, 0, null, null); - f.queuePacket(qp); + if(f != null){ + QuorumPacket qp = new QuorumPacket(Leader.SYNC, 0, null, null); + f.queuePacket(qp); + } + else{ + LOG.warn("Committing sync: " + r.cxid ); + zk.commitProcessor.commit(r); + } } /** Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ProposalRequestProcessor.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ProposalRequestProcessor.java?rev=683707&r1=683706&r2=683707&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ProposalRequestProcessor.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ProposalRequestProcessor.java Thu Aug 7 13:34:41 2008 @@ -48,14 +48,22 @@ // request.addRQRec(">prop"); + /* In the following IF-THEN-ELSE block, we process syncs on the leader. + * If the sync is coming from a follower, then the follower + * handler adds it to syncHandler. Otherwise, if it is a client of + * the leader that issued the sync command, then syncHandler won't + * contain the handler. In this case, we add it to syncHandler, and + * call processRequest on the next processor. + */ + if(request.type == ZooDefs.OpCode.sync){ - if(zks.getLeader().syncHandler.containsKey(request.sessionId)){ - zks.getLeader().processSync(request); - } - else{ + zks.getLeader().processSync(request); + + if(!zks.getLeader().syncHandler.containsKey(request.sessionId)){ + zks.getLeader().syncHandler.put(request.sessionId, null); nextProcessor.processRequest(request); - zks.commitProcessor.commit(request); } + } else{ nextProcessor.processRequest(request); From zookeeper-commits-returnsamanthajackson@example.org Thu Aug 07 20:35:58 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 30567 invoked from network); 7 Aug 2008 20:35:58 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 7 Aug 2008 20:35:58 -0000 Received: (qmail 98060 invoked by uid 500); 7 Aug 2008 20:35:57 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 98039 invoked by uid 500); 7 Aug 2008 20:35:57 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 98028 invoked by uid 99); 7 Aug 2008 20:35:57 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Aug 2008 13:35:57 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Aug 2008 20:35:10 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id AA1C723889BB; Thu, 7 Aug 2008 13:35:37 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r683708 - /hadoop/zookeeper/trunk/src/java/Changes.txt Date: Thu, 07 Aug 2008 20:35:37 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mahadev Date: Thu Aug 7 13:35:37 2008 New Revision: 683708 URL: http://svn.apache.org/viewvc?rev=683708&view=rev Log: Adding changes.txt in src/java Added: hadoop/zookeeper/trunk/src/java/Changes.txt Added: hadoop/zookeeper/trunk/src/java/Changes.txt URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/Changes.txt?rev=683708&view=auto ============================================================================== --- hadoop/zookeeper/trunk/src/java/Changes.txt (added) +++ hadoop/zookeeper/trunk/src/java/Changes.txt Thu Aug 7 13:35:37 2008 @@ -0,0 +1,6 @@ +Trunk: + BUGFIXES: + + ZOOKEEPER-105. Catch Zookeeper exceptions and print on the stderr. (Anthony Urso via Mahadev) + + ZOOKEEPER-108. Fix sync operation reordering on a Quorum. (Flavio Paiva Junqueira via Mahadev) From zookeeper-commits-returnsamanthajackson@example.org Fri Aug 08 17:58:19 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 60857 invoked from network); 8 Aug 2008 17:58:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 8 Aug 2008 17:58:19 -0000 Received: (qmail 4515 invoked by uid 500); 8 Aug 2008 17:58:19 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 4499 invoked by uid 500); 8 Aug 2008 17:58:19 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 4488 invoked by uid 99); 8 Aug 2008 17:58:18 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Aug 2008 10:58:18 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Aug 2008 17:57:31 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E4144238896D; Fri, 8 Aug 2008 10:57:58 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r684030 - in /hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper: ServerAdminClient.java server/ZooKeeperServer.java server/quorum/FollowerHandler.java server/quorum/QuorumPeer.java Date: Fri, 08 Aug 2008 17:57:58 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fpj Date: Fri Aug 8 10:57:58 2008 New Revision: 684030 URL: http://svn.apache.org/viewvc?rev=684030&view=rev Log: JIRA 109. Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ServerAdminClient.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ServerAdminClient.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ServerAdminClient.java?rev=684030&r1=684029&r2=684030&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ServerAdminClient.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ServerAdminClient.java Fri Aug 8 10:57:58 2008 @@ -66,11 +66,11 @@ } public static void ruok(String host, int port) { + Socket s = null; try { byte[] reqBytes = new byte[4]; ByteBuffer req = ByteBuffer.wrap(reqBytes); req.putInt(ByteBuffer.wrap("ruok".getBytes()).getInt()); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -86,17 +86,25 @@ int rc = is.read(resBytes); String retv = new String(resBytes); System.out.println("rc=" + rc + " retv=" + retv); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } public static void dump(String host, int port) { + Socket s = null; try { byte[] reqBytes = new byte[4]; ByteBuffer req = ByteBuffer.wrap(reqBytes); req.putInt(ByteBuffer.wrap("dump".getBytes()).getInt()); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -112,17 +120,25 @@ int rc = is.read(resBytes); String retv = new String(resBytes); System.out.println("rc=" + rc + " retv=" + retv); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } public static void stat(String host, int port) { + Socket s = null; try { byte[] reqBytes = new byte[4]; ByteBuffer req = ByteBuffer.wrap(reqBytes); req.putInt(ByteBuffer.wrap("stat".getBytes()).getInt()); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -138,17 +154,25 @@ int rc = is.read(resBytes); String retv = new String(resBytes); System.out.println("rc=" + rc + " retv=" + retv); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } public static void kill(String host, int port) { + Socket s = null; try { byte[] reqBytes = new byte[4]; ByteBuffer req = ByteBuffer.wrap(reqBytes); req.putInt(ByteBuffer.wrap("kill".getBytes()).getInt()); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -163,12 +187,21 @@ int rc = is.read(resBytes); String retv = new String(resBytes); System.out.println("rc=" + rc + " retv=" + retv); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } public static void setTraceMask(String host, int port, String traceMaskStr) { + Socket s = null; try { byte[] reqBytes = new byte[12]; ByteBuffer req = ByteBuffer.wrap(reqBytes); @@ -176,7 +209,6 @@ req.putInt(ByteBuffer.wrap("stmk".getBytes()).getInt()); req.putLong(traceMask); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -196,18 +228,26 @@ + Long.toOctalString(retv) + " masks=0" + Long.toOctalString(traceMask)); assert (retv == traceMask); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } public static void getTraceMask(String host, int port) { + Socket s = null; try { byte[] reqBytes = new byte[12]; ByteBuffer req = ByteBuffer.wrap(reqBytes); req.putInt(ByteBuffer.wrap("gtmk".getBytes()).getInt()); - Socket s = null; s = new Socket(); s.setSoLinger(false, 10); s.setSoTimeout(20000); @@ -225,8 +265,16 @@ long retv = res.getLong(); System.out.println("rc=" + rc + " retv=0" + Long.toOctalString(retv)); - } catch (IOException ioe) { - LOG.warn("Unexpected exception", ioe); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + LOG.warn("Unexpected exception", e); + } + } } } Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java?rev=684030&r1=684029&r2=684030&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java Fri Aug 8 10:57:58 2008 @@ -426,7 +426,7 @@ TxnHeader hdr = new TxnHeader(); Record txn = deserializeTxn(ia, hdr); if (logStream.readByte("EOR") != 'B') { - LOG.error("Last transaction was partial."); + LOG.warn("Last transaction was partial."); throw new EOFException(); } if (hdr.getZxid() <= highestZxid && highestZxid != 0) { @@ -468,6 +468,7 @@ addCommittedProposal(r); } } catch (EOFException e) { + // expected in some cases - see comments in try block } return highestZxid; } @@ -569,6 +570,8 @@ while (true) { byte[] bytes = ia.readBuffer("txtEntry"); if (bytes.length == 0) { + // Since we preallocate, we define EOF to be an + // empty transaction throw new EOFException(); } InputArchive iab = BinaryInputArchive @@ -576,6 +579,7 @@ TxnHeader hdr = new TxnHeader(); deserializeTxn(iab, hdr); if (ia.readByte("EOF") != 'B') { + LOG.warn("Last transaction was partial."); throw new EOFException(); } if (hdr.getZxid() == finalZxid) { @@ -586,11 +590,17 @@ FileOutputStream fout = new FileOutputStream(f); FileChannel fchanOut = fout.getChannel(); fchanOut.truncate(pos); + fchanOut.close(); + fout.close(); truncated = true; break; } } } catch (EOFException eof) { + // expected in some cases - see comments in try block + } finally { + fchan.close(); + fin.close(); } if (truncated == true) { break; Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java?rev=684030&r1=684029&r2=684030&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerHandler.java Fri Aug 8 10:57:58 2008 @@ -48,7 +48,7 @@ public class FollowerHandler extends Thread { private static final Logger LOG = Logger.getLogger(FollowerHandler.class); - public Socket s; + public Socket sock; Leader leader; @@ -65,9 +65,9 @@ private BufferedOutputStream bufferedOutput; - FollowerHandler(Socket s, Leader leader) throws IOException { - super("FollowerHandler-" + s.getRemoteSocketAddress()); - this.s = s; + FollowerHandler(Socket sock, Leader leader) throws IOException { + super("FollowerHandler-" + sock.getRemoteSocketAddress()); + this.sock = sock; this.leader = leader; leader.addFollowerHandler(this); start(); @@ -102,7 +102,7 @@ oa.writeRecord(p, "packet"); bufferedOutput.flush(); } catch (IOException e) { - if (!s.isClosed()) { + if (!sock.isClosed()) { LOG.warn("Unexpected exception",e); } break; @@ -179,9 +179,9 @@ public void run() { try { - ia = BinaryInputArchive.getArchive(new BufferedInputStream(s + ia = BinaryInputArchive.getArchive(new BufferedInputStream(sock .getInputStream())); - bufferedOutput = new BufferedOutputStream(s.getOutputStream()); + bufferedOutput = new BufferedOutputStream(sock.getOutputStream()); oa = BinaryOutputArchive.getArchive(bufferedOutput); QuorumPacket qp = new QuorumPacket(); @@ -264,7 +264,7 @@ new Thread() { public void run() { Thread.currentThread().setName( - "Sender-" + s.getRemoteSocketAddress()); + "Sender-" + sock.getRemoteSocketAddress()); try { sendPackets(); } catch (InterruptedException e) { @@ -292,7 +292,7 @@ switch (qp.getType()) { case Leader.ACK: - leader.processAck(qp.getZxid(), s.getLocalSocketAddress()); + leader.processAck(qp.getZxid(), sock.getLocalSocketAddress()); break; case Leader.PING: // Process the touches @@ -338,13 +338,14 @@ } } } catch (IOException e) { - if (s != null && !s.isClosed()) { + if (sock != null && !sock.isClosed()) { LOG.error("FIXMSG",e); } } catch (InterruptedException e) { LOG.error("FIXMSG",e); } finally { - LOG.warn("******* GOODBYE " + s.getRemoteSocketAddress() + LOG.warn("******* GOODBYE " + + (sock != null ? sock.getRemoteSocketAddress() : "<null>") + " ********"); // Send the packet of death try { @@ -358,8 +359,8 @@ public void shutdown() { try { - if (s != null && !s.isClosed()) { - s.close(); + if (sock != null && !sock.isClosed()) { + sock.close(); } } catch (IOException e) { LOG.error("FIXMSG",e); Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java?rev=684030&r1=684029&r2=684030&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java (original) +++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java Fri Aug 8 10:57:58 2008 @@ -520,9 +520,9 @@ if (leader != null) { synchronized (leader.followers) { for (FollowerHandler fh : leader.followers) { - if (fh.s == null) + if (fh.sock == null) continue; - String s = fh.s.getRemoteSocketAddress().toString(); + String s = fh.sock.getRemoteSocketAddress().toString(); if (leader.isFollowerSynced(fh)) s += "*"; l.add(s); From zookeeper-commits-returnsamanthajackson@example.org Sat Aug 09 05:03:12 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 71296 invoked from network); 9 Aug 2008 05:03:12 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 9 Aug 2008 05:03:12 -0000 Received: (qmail 97776 invoked by uid 500); 9 Aug 2008 05:03:11 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 97754 invoked by uid 500); 9 Aug 2008 05:03:11 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 97743 invoked by uid 99); 9 Aug 2008 05:03:11 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Aug 2008 22:03:11 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 09 Aug 2008 05:02:15 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 19FFA2388882; Fri, 8 Aug 2008 22:02:13 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r684175 - /hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java Date: Sat, 09 Aug 2008 05:02:12 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: phunt Date: Fri Aug 8 22:02:12 2008 New Revision: 684175 URL: http://svn.apache.org/viewvc?rev=684175&view=rev Log: Committing ZOOKEEPER-108-TEST.patch Added: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java (with props) Added: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java?rev=684175&view=auto ============================================================================== --- hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java (added) +++ hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java Fri Aug 8 22:02:12 2008 @@ -0,0 +1,114 @@ +/** + * 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.zookeeper.test; + +import java.io.IOException; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.zookeeper.Watcher; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.AsyncCallback.ChildrenCallback; +import org.apache.zookeeper.AsyncCallback.StringCallback; +import org.apache.zookeeper.AsyncCallback.VoidCallback; +import org.apache.zookeeper.ZooDefs.Ids; +import org.apache.zookeeper.proto.WatcherEvent; +import org.junit.Test; + + +public class SyncCallTest extends ClientBase + implements Watcher, ChildrenCallback, StringCallback, VoidCallback +{ + private CountDownLatch clientConnected; + private CountDownLatch opsCount; + + List<Integer> results = new LinkedList<Integer>(); + Integer limit = 100 + 1 + 100 + 100; + + @Test + public void testSync() throws Exception { + try { + LOG.info("Starting ZK:" + (new Date()).toString()); + opsCount = new CountDownLatch(limit); + ZooKeeper zk = createClient(); + + LOG.info("Beginning test:" + (new Date()).toString()); + for(int i = 0; i < 100; i++) + zk.create("/test" + i, new byte[0], Ids.OPEN_ACL_UNSAFE, + 0, this, results); + zk.sync("/test", this, results); + for(int i = 0; i < 100; i++) + zk.delete("/test" + i, 0, this, results); + for(int i = 0; i < 100; i++) + zk.getChildren("/", this, this, results); + + LOG.info("Submitted all operations:" + (new Date()).toString()); + + if(!opsCount.await(10000, TimeUnit.MILLISECONDS)) + fail("Haven't received all confirmations" + opsCount.getCount()); + + for(int i = 0; i < limit ; i++){ + assertEquals(0, (int) results.get(i)); + } + + } catch (IOException e) { + System.out.println(e.toString()); + } + } + + private ZooKeeper createClient() throws IOException,InterruptedException{ + clientConnected=new CountDownLatch(1); + ZooKeeper zk = new ZooKeeper(hostPort, 30000, this); + if(!clientConnected.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)){ + fail("Unable to connect to server"); + } + return zk; + } + + public void process(WatcherEvent event) { + //LOG.info("Process: " + event.getType() + " " + event.getPath()); + if (event.getState() == Event.KeeperStateSyncConnected) { + clientConnected.countDown(); + } + } + + @SuppressWarnings("unchecked") + public void processResult(int rc, String path, Object ctx, + List<String> children) { + ((List<Integer>)ctx).add(rc); + opsCount.countDown(); + } + + @SuppressWarnings("unchecked") + public void processResult(int rc, String path, Object ctx, String name){ + ((List<Integer>) ctx).add(rc); + opsCount.countDown(); + + } + + @SuppressWarnings("unchecked") + public void processResult(int rc, String path, Object ctx){ + ((List<Integer>) ctx).add(rc); + opsCount.countDown(); + + } +} Propchange: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/SyncCallTest.java ------------------------------------------------------------------------------ svn:eol-style = native From zookeeper-commits-returnsamanthajackson@example.org Wed Aug 13 17:59:24 2008 Return-Path: <zookeeper-commits-returnsamanthajackson@example.org> Delivered-To: samanthajackson@example.org Received: (qmail 69301 invoked from network); 13 Aug 2008 17:59:24 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (83.161.120.155) by minotaur.apache.org with SMTP; 13 Aug 2008 17:59:24 -0000 Received: (qmail 90024 invoked by uid 500); 13 Aug 2008 17:59:23 -0000 Delivered-To: samanthajackson@example.org Received: (qmail 90002 invoked by uid 500); 13 Aug 2008 17:59:23 -0000 Mailing-List: contact samanthajackson@example.org; run by ezmlm Precedence: bulk List-Help: <mailto:samanthajackson@example.org> List-Unsubscribe: <mailto:samanthajackson@example.org> List-Post: <mailto:samanthajackson@example.org> List-Id: <zookeeper-commits.hadoop.apache.org> Reply-To: zookeeper-dev@<hadoop.apache.org> Delivered-To: mailing list samanthajackson@example.org Received: (qmail 89986 invoked by uid 99); 13 Aug 2008 17:59:22 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Aug 2008 10:59:22 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Aug 2008 17:58:33 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id CFC5523889BB; Wed, 13 Aug 2008 10:59:01 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r685624 [3/3] - in /hadoop/zookeeper/trunk/src/contrib: ./ zkfuse/ zkfuse/src/ Date: Wed, 13 Aug 2008 17:59:00 -0000 To: samanthajackson@example.org From: samanthajackson@example.org X-Mailer: svnmailer-1.0.8 Message-Id: <samanthajackson@example.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: hadoop/zookeeper/trunk/src/contrib/zkfuse/src/zkfuse.cc URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/zkfuse/src/zkfuse.cc?rev=685624&view=auto ============================================================================== --- hadoop/zookeeper/trunk/src/contrib/zkfuse/src/zkfuse.cc (added) +++ hadoop/zookeeper/trunk/src/contrib/zkfuse/src/zkfuse.cc Wed Aug 13 10:58:59 2008 @@ -0,0 +1,4492 @@ +/** + * 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. + */ + +#define FUSE_USE_VERSION 26 + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#undef _GNU_SOURCE +#define _GNU_SOURCE + +extern "C" { +#include <fuse.h> +#include <ulockmgr.h> +} +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <dirent.h> +#include <errno.h> +#include <sys/time.h> +#ifdef HAVE_SETXATTR +#include <sys/xattr.h> +#endif + +#include <getopt.h> + +#include <iostream> +#include <sstream> +#include <map> +#include <string> +#include <boost/utility.hpp> +#include <boost/weak_ptr.hpp> + +#include "log.h" +#include "mutex.h" +#include "zkadapter.h" + +#define ZOOKEEPER_ROOT_CHILDREN_WATCH_BUG + +/** + Typedef for ZooKeeperAdapter888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4ta. +*/ +typedef st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string Data; +/** + Typedef for ZooKeeperAdapter888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4NodeNames. +*/ +typedef vector<st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string> NodeNames; + +#define MAX_DATA_SIZE 1024; + +DEFINE_LOGGER(LOG, "zkfuse"); + +inline +uint64_t millisecsToSecs(uint64_t millisecs) +{ + return millisecs / 1000; +} +inline +uint64_t secsToMillisecs(uint64_t secs) +{ + return secs * 1000; +} +inline +uint64_t nanosecsToMillisecs(uint64_t nanosecs) +{ + return nanosecs * 1000000; +} +inline +uint64_t timespecToMillisecs(const struct timespec & ts) +{ + return secsToMillisecs(ts.tv_sec) + nanosecsToMillisecs(ts.tv_nsec); +} + +typedef boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4shared_ptr<ZooKeeperAdapter> ZooKeeperAdapterSharedPtr; + +/** + * ZkFuseCommon - holds immutable configuration objects. + * + * No locks are required to access these objects. + * A ZkFuseCommon instance is considered to be a data object and may be copied. + */ +class ZkFuseCommon +{ + private: + /** + References the ZooKeeperAdapter instance to be used. + */ + ZooKeeperAdapterSharedPtr _zkAdapter; + /** + Path to the ZooKeeper root node. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _rootPathName; + /** + Name used to access data "file" when the ZK node has + children. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _dataFileName; + /** + Suffix added to path components to force interpretation of + path components as directory. This is usually only required + for the last component. For example, ZkFuse may consider + a leaf node a regular file, e.g. /a/b/c/leaf. The suffix + can be used to create child under this node, e.g. + mkdir /a/b/c/leaf{forceDirSuffix}/new_leaf. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _forceDirSuffix; + /** + Prefix common to all metadata nodes created by ZkFuse. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _metadataNamePrefix; + /** + Path component name that identifies a directory metadata node. + A directory metadata node is currently empty. It is used by ZkFuse + to create a child when mkdir is used. This prevents ZkFuse + from interpreting the new child as a regular file. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _dirMetadataName; + /** + Path component name that identifies a regular file metadata node. + A regular metadata node holds metadata required to implement + Posix regular file semantics, such as setting mtime. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string _regMetadataName; + /** + Number of not-in-use nodes to cache. + */ + unsigned _cacheSize; + /** + Assume this userid owns all nodes. + */ + const uid_t _uid; + /** + Assume this groupid owns all nodes. + */ + const gid_t _gid; + /** + Blocksize used to calculate number of blocks used for stat. + */ + const unsigned _blkSize; + + public: + /** + Constructor. + */ + ZkFuseCommon() + : _zkAdapter(), + _rootPathName("/"), + _dataFileName(), + _forceDirSuffix(), + _metadataNamePrefix(".zkfuse."), + _dirMetadataName(_metadataNamePrefix + "dir"), + _regMetadataName(_metadataNamePrefix + "file"), + _cacheSize(256), + _uid(geteuid()), + _gid(getegid()), + _blkSize(8192) + { + } + /** + Get root path name. Always "/". + \see _rootPathName + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getRootPathName() const + { + return _rootPathName; + } + /** + Get dataFileName - the name for synthesized files to access + ZooKeeper node data. + \see _dataFileName + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getDataFileName() const + { + return _dataFileName; + } + /** + Set dataFileName. + \see getDataFileName + \see _dataFileName + */ + void setDataFileName(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & dataFileName) + { + _dataFileName = dataFileName; + } + /** + Get metadataNamePrefix - the common prefix for all ZkFuse created + metadata ZooKeeper nodes. + \see _metadataNamePrefix + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getMetadataNamePrefix() const + { + return _metadataNamePrefix; + } + /** + Get forceDirSuffix - the suffix added to a path component to force + the path component to be treated like a directory. + \see _forceDirSuffix + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getForceDirSuffix() const + { + return _forceDirSuffix; + } + /** + Set forceDirSuffix. + \see getForceDirSuffix + \see _forceDirSuffix + */ + void setForceDirSuffix(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & forceDirSuffix) + { + _forceDirSuffix = forceDirSuffix; + } + /** + Get dirMetadataName - path component name of all directory + metadata ZooKeeper nodes. + \see _dirMetadataname + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getDirMetadataName() const + { + return _dirMetadataName; + } + /** + Get regMetadataName - path component name of all regular file + metadata ZooKeeper nodes. + \see _regMetadataname + */ + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & getRegMetadataName() const + { + return _regMetadataName; + } + /** + Get number of not-in-use ZkFuseFile instances to to cache. + \see _cacheSize + */ + unsigned getCacheSize() const + { + return _cacheSize; + } + /** + Set cache size. + \see getCacheSize + \see _cacheSize + */ + void setCacheSize(unsigned v) + { + _cacheSize = v; + } + /** + Get userid. + \see _uid + */ + uid_t getUid() const + { + return _uid; + } + /** + Get groupid. + \see _gid + */ + gid_t getGid() const + { + return _gid; + } + /** + Get block size. + \see _blkSize + */ + unsigned getBlkSize() const + { + return _blkSize; + } + /** + Get ZooKeeperAdapter. + \see _zkAdapter. + */ + const ZooKeeperAdapterSharedPtr & getZkAdapter() const + { + return _zkAdapter; + } + /** + Set ZooKeeperAdapter. + \see _zkAdaptor + */ + void setZkAdapter(const ZooKeeperAdapterSharedPtr & zkAdapter) + { + _zkAdapter = zkAdapter; + } +}; + +/** + ZkFuseNameType - identifies the type of the ZkFuse path. + */ +enum ZkFuseNameType { + /** + ZkFuse path is not syntheiszed. + ZkFuse should use its default rules to determine the Posix representation + of the path. + */ + ZkFuseNameDefaultType = 0, + /** + ZkFuse path is synthesized and identifies the data part of a + ZooKeeper node, i.e. Posix regular file semantics is expected. + */ + ZkFuseNameRegType = 1, + /** + ZkFuse path is synthesized and identifies the chidlren part of a + ZooKeeper node, i.e. Posix directory semantics is expected. + */ + ZkFuseNameDirType = 2 +}; + +class ZkFuseFile; + +typedef ZkFuseFile * ZkFuseFilePtr; + +class ZkFuseHandleManagerFactory; + +/** + ZkFuseHandleManager - keeps track of all the ZkFuseFile instances + allocated by a ZkFuseHandleManager instance and provides them + with a handle that can be used by FUSE. + + It maps a ZooKeeper path to a handle and a handle to a ZkFuse instance. + It also implements the methods that takes path names as arguments, such + as open, mknod, rmdir, and rename. + + Memory management + - References ZkFuseFile instances using regular pointers + Smart pointer is not used because reference counts are needed to + determine how many time a node is opened as a regular file or + directory. This also avoids circular smart pointer references. + - Each ZkFuseFile instance holds a reference to its ZkFuseHandleManager + using a boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4shared_ptr. This ensures that the ZkFuseHandleManager + instance that has the handle for the ZkFuseFile instance does not + get garbage collected while the ZkFuseFile instance exists. + + Concurrency control + - Except for the immutable ZkFuseCommon, all other member variables + are protected by _mutex. + - A method in this class can hold _mutex when it directly or + indirectly invokes ZkFuseFile methods. A ZkFuseFile method that holds + a ZkFuseFile instance _mutex cannot invoke a ZkFuseHandleManager + method that acquires the ZkFuseHandleManager instance's _mutex. + Otherwise, this may cause a dead lock. + - Methods that with names that begin with "_" do not acquire _mutex. + They are usually called by public methods that acquire and hold _mutex. + */ +class ZkFuseHandleManager : boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4noncopyable +{ + private: + /** + Typedef of handle, which is an int. + */ + typedef int Handle; + /** + Typedef of st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4map used to map path to handle. + */ + typedef st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4map<st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string, Handle> Map; + /** + Typedef of st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4vector used to map handle to ZkFuseFile instances. + */ + typedef st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4vector<ZkFuseFilePtr> Files; + /** + Typedef of st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4vector used to hold unused handles. + */ + typedef st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4vector<Handle> FreeList; + /** + Typedef of boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4weak_ptr to the ZkFuseHandleManager instance. + */ + typedef boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4weak_ptr<ZkFuseHandleManager> WeakPtr; + + /* Only ZkFuseHandleManagerFactory can create instances of this class */ + friend class ZkFuseHandleManagerFactory; + + /** + Contains common configuration. + Immutable so that it can be accessed without locks. + */ + const ZkFuseCommon _common; + /** + Maps a path name to a Handle. + */ + Map _map; + /** + Maps a handle to a ZkFuseFile instances. + Also holds pointers to all known ZkFuseFile instances. + An element may point to an allocated ZkFuseFile instance or be NULL. + + An allocated ZkFuseFile instance may be in one of the following states: + - in-use + Currently open, i.e. the ZkFuseFile instance's reference count + greater than 0. + - in-cache + Not currently open, i.e. the ZkFuseFile instances's + reference count is 0. + */ + Files _files; + /** + List of free'ed handles. + */ + FreeList _freeList; + /** + Mutex used to protect this instance. + */ + mutable zkfus888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4Mutex _mutex; + /** + Count of number of in-use entries. + It used to calculate number of cached nodes. + Number cached nodes is (_files.size() - _numInUse). + */ + unsigned _numInUse; + /** + WeakPtr to myself. + */ + WeakPtr _thisWeakPtr; + + /** + Obtain a handle for the given path. + - If path is not known, then allocate a new handle and increment + _numInUse, and set newFile to true. The allocated + ZkFuseFile instance's reference count should be 1. + - If path is known, increase the corresponding + ZkFuseFile instance's reference count. + + \return the allocated handle. + \param path the path to lookup. + \param newFile indicates whether a new handle has been allocated. + */ + Handle allocate(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path, bool & newFile); + + /** + Constructor. + + \param common the immutable common configuration. + \param reserve number of elements to pre-allocate for + _files and _freeList. + */ + ZkFuseHandleManager( + const ZkFuseCommon & common, + const unsigned reserve) + : _common(common), + _files(), + _freeList(), + _mutex(), + _numInUse(0) + { + _files.reserve(reserve); + _files[0] = NULL; /* 0 never allocated */ + _files.resize(1); + _freeList.reserve(reserve); + } + + public: + /** + Typedef for boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4shared_ptr for this ZkFuseHandleManager class. + */ + typedef boost888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4shared_ptr<ZkFuseHandleManager> SharedPtr; + + /** + Destructor. + */ + ~ZkFuseHandleManager() + { + } + /** + Get the ZkFuseFile instance for a handle. + + \return the ZkFuseFile instance identified by the handle. + \param handle get ZkFuseFile instance for this handle. + */ + ZkFuseFilePtr getFile(Handle handle) const + { + AutoLock lock(_mutex); + return _files[handle]; + } + /** + Get the immutable common configuration. + + \return the common configuration instance. + */ + const ZkFuseCommon & getCommon() const + { + return _common; + } + /** + Deallocate a previously allocated handle. + This decrements the reference count of the corresponding + ZkFuseFile instance. If the reference count becomes zero, + decrement _numInUse. It may also cause the ZkFuseFile instance + to be reclaimed if there are too many cached ZkFuseFile instances. + + The ZkFuseFile instance should be reclaimed if the number of + unused ZkFuseFile instances exceeds the configured cache size, i.e. + (_files.size() - _numInUse) > _common.getCacheSize() + and the ZkFuseFile instance has a reference count of zero. + + Reclaiming a ZkFuseFile instance involves removing the ZkFuseFile + instance's path to handle mapping from _map and the handle to the + ZkFuseFile instance mapping from _files, adding the handle to + the _freeList, and finally deleting the ZkFuseFile instance. + + \param handle the handle that should be deallocated. + */ + void deallocate(Handle handle); + /** + Handles ZooKeeper session events. + It invokes the known ZkFuseFile instances to let them know + that their watches will no longer be valid. + */ + void eventReceived(const ZKWatcherEvent & event); + /** + Get data from the specified the ZooKeeper path. + + \return 0 if successful, otherwise return negative errno. + \param path the path of the ZooKeeper node. + \param data return data read. + */ + int getData(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path, Data & data); + /** + Set data into the specified ZooKeeper path. + + \return 0 if successful, otherwise return negative errno. + \param path the path of the ZooKeeper node. + \param data the data to be written. + \param exists set to true if this path exists. + \param doFlush set to true if new data should be flushed to ZooKeeper. + */ + int setData(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path, + const Data & data, + bool exists, + bool doFlush); + /** + Create a ZooKeeper node to represent a ZkFuse file or directory. + + \return handle if successful, otherwise return negative errno. + \param path to create. + \param mode should be either S_IFDIR for directory or + S_IFREG for regular file. + \param mayExist if set and the ZooKeeper node already exist, return + valid handle instead of -EEXIST. + \param created returns whether a new ZooKeeper node had been created. + */ + int mknod(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path, + mode_t mode, + bool mayExist, + bool & created); + /** + Open a ZooKeeper node. + + The justCreated argument is used to differentiate if the _deleted flag + of the ZkFuseFile instance is to be trusted (i.e. the path + does not exist in ZooKeeper.) The _deleted flag is trusted + if the ZkFuseFile instance is known to exist in ZooKeeper after + invoking ZooKeeper with the path. + + If justCreated is true, then the ZkFuseFile instance was just created. + The ZkFuseFile constructor sets the _deleted flag to true because + path is not known to exist and hence should not be accessed. + The justCreated flag will force the ZkFuseFile instance to invoke + ZooKeeper to determine if the path exists. + + \return handle if successful, otherwise return negative errno. + \param path the path to open. + \param justCreated indicates if this is newly created ZkFuseFile instance. + */ + int open(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path, bool justCreated); + /** + Remove a ZkFuse directory. + + If force is not set, then the ZooKeeper node will be removed only + if it has no data and no child nodes except ZkFuse metadata nodes. + + \return 0 if successful, otherwise return negative errno. + \param path the path to remove. + \param force force removal, i.e. bypass checks. + */ + int rmdir(const char * path, bool force = false); + /** + Make a ZkFuse directory. + + ZkFuse represents a ZooKeeper node with no data and no children + as a regular file. In order to differentiate a newly created + directory from an empty regular file, mkdir will create a directory + metadata node as a child of the directory. + + \return 0 if successful, otherwise return negative errno. + \param path the path of the directory to create. + \param mode create directory with this mode + (mode currently not implemented). + */ + int mkdir(const char * path, mode_t mode); + /** + Remove a ZkFuse regular file. + + A file is the abstraction for the data part of a ZooKeeper node. + - If ZkFuse represents a ZooKeeper node as a directory, the data part + of the node is represented by synthesizing a name for this file. This + synthesized name is visible through readdir if the ZooKeeper node's + data is not empty. Removing such a file is done by truncating + the ZooKeeper node's data to 0 length. + - If ZkFuse represents a ZooKeeper node as a file, then removing the + is done by removing the ZooKeeper node (and its metadata). + + \return 0 if successful, otherwise return negative errno. + \param path the path of the file to remove. + */ + int unlink(const char * path); + /** + Get attributes of a ZkFuse regular file or directory. + + \return 0 if successful, otherwise return negative errno. + \param path get attributes for this path + \param stbuf store attributes here. + */ + int getattr(const char * path, struct stat & stbuf); + /** + Rename a ZkFuse regular file. + + It creates a new ZooKeeper node at toPath, copies data and file + metadata from the ZooKeeper node at fromPath to the new node, + and deletes the current ZooKeeper node. If the current ZooKeeper + node is not deleted if the new ZooKeeper node cannot be created + or the data copy fails. + + It cannot be used to rename a directory. + + \return 0 if successful, otherwise return negative errno. + \param fromPath the current path. + \param toPath rename to this path. + */ + int rename(const char * fromPath, const char * toPath); + /** + Add a child ZooKeeper path to the children information cache + of the ZkFuseFile instance that caches the parent ZooKeeper node. + + This is used to add a child path after a new ZooKeeper node has + been created to the children information cache of the parent + ZooKeeper node. This is needed because waiting for the children + changed event to update the cache may result in inconsistent local + views of the changes. + \see removeChildFromParent + + \parama childPath the path of the child ZooKeeper node. + */ + void addChildToParent(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & childPath) const; + /** + Remove a child ZooKeeper path from the children information cache + of the ZkFuseFile instance that caches the parent ZooKeeper node. + + For example, this should happen whenever a path is deleted. + This child information cache of the parent will eventually be + invalidated by watches. However, the delivery of the children + change event may come after the next access and thus provide + the client with an inconsistent view. One example is that + client deletes the last file in a directory, but the children + changed event is not delivered before the client invokes rmdir. + to remove the parent. In this case, the rmdir fails because + the cached children information of the parent indicates the + "directory" is not empty. + + \param childPath the path of the child ZooKeeper node. + */ + void removeChildFromParent(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & childPath) const; + /** + Return the path for the parent of the specified ZooKeeper path. + + \return the parent path. + \param childPath the child path. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string getParentPath(const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & childPath) const; + /** + Return the ZooKeeper path from a ZkFuse path. + + The ZkFuse path may be a synthesized path. For example, a synthesized + path is required to access the data part of a ZooKeeper node's + data when ZkFuse represents the ZooKeeper node as directory. + A synthesized path is also required to create a child ZooKeeper node + under a ZooKeeper node that is represented by a regular file. + + \return the ZooKeeper path for path. + \param path the ZkFuse path, which may be a synthesized path. + \param nameType indicate whether the ZkFuse path is synthesized and + whether the synthesized ZkFuse path identifies a + directory or a regular file. + */ + st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string getZkPath(const char * path, ZkFuseNameType & nameType) const; +}; + +/** + ZkFuseHandleManagerFactory - factory for ZkFuseHandleManager. + + This is the only way to create a ZkFuseHandleManager instance. + to make sure that _thisWeakPtr of the instance is intialized + after the instance is created. + */ +class ZkFuseHandleManagerFactory +{ + public: + /** + Create an instance of ZkFuseHandleManager. + + \return the created ZkFuseHandleManager instance. + \param common the common configuration. + \param reserve initially reserve space for this number of handles. + */ + static ZkFuseHandleManager888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4SharedPtr create( + const ZkFuseCommon & common, + unsigned reserve = 1000) + { + ZkFuseHandleManager888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4SharedPtr manager + (new ZkFuseHandleManager(common, reserve)); + manager->_thisWeakPtr = manager; + return manager; + } +}; + +/** + ZkFuseAutoHandle - automatically closes handle. + + It holds an opened handle and automatically closes this handle + when it is destroyed. This enables code that open a handle + to be exception safe. + */ +class ZkFuseAutoHandle +{ + private: + /** + Typedef for Handle which is an int. + */ + typedef int Handle; + /** + Holds a reference to the ZkFuseHandlerManager instance that + allocated the handle. + */ + ZkFuseHandleManager888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4SharedPtr _manager; + /** + The handle that should be closed when this instance is destroyed. + A valid handle has value that is equal or greater than 0. + A negative value indicates an error condition, usually the value + is a negative errno. + */ + Handle _handle; + /** + Caches a reference to the ZkFuseFile instance with this handle. + This is a performance optimization so that _manager.getFile(_handle) + is only called once when the handle is initialized. + */ + ZkFuseFilePtr _file; + + /** + Initialize reference to the ZkFuseFile instance with this handle. + */ + void _initFile() + { + if (_handle >= 0) { + _file = _manager->getFile(_handle); + } else { + _file = NULL; + } + } + + public: + /** + Constructor - takes an previously opened handle. + + \param manager the ZkFuseHandleManager instance who allocated the handle. + \param handle the handle. + */ + ZkFuseAutoHandle( + const ZkFuseHandleManager888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4SharedPtr & manager, + int handle) + : _manager(manager), + _handle(handle), + _file() + { + _initFile(); + } + /** + Constructor - open path and remember handle. + + \param manager the ZkFuseHandleManager instance who allocated the handle. + \param path open this path and remember its handle in this instance. + */ + ZkFuseAutoHandle( + const ZkFuseHandleManager888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4SharedPtr & manager, + const st888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4string & path) + : _manager(manager), + _handle(_manager->open(path, false)), + _file() + { + _initFile(); + } + /** + Constructor - create path and remember handle. + + The creation mode indicates whether the path identifies a regular file + or a directory. + + \param manager the ZkFuseHandleManager instance who allocated the handle. + \param path create this path and remember its handle in this instance. + \param mode the creation mode for the path, should be either + S_IFDIR or S_IFDIR. + \param
{'source': 'Apache Software Foundation Public Mail Archives'}