Skip to content

Commit 50df284

Browse files
ocadarumafrankvicky
authored andcommitted
KAFKA-19334 MetadataShell execution unintentionally deletes lock file (apache#19817)
## Summary - MetadataShell may deletes lock file unintentionally when it exists or fails to acquire lock. If there's running server, this causes unexpected result as below: * MetadataShell succeeds on 2nd run unexpectedly * Even worse, LogManager/RaftManager's lock also no longer work from concurrent Kafka process startup Reviewers: TengYao Chi <[email protected]> # Conflicts: # shell/src/test/java/org/apache/kafka/shell/MetadataShellIntegrationTest.java
1 parent 7e9d50a commit 50df284

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

server-common/src/main/java/org/apache/kafka/server/util/FileLock.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,12 @@ public synchronized void destroy() throws IOException {
9191
}
9292
channel.close();
9393
}
94+
95+
/**
96+
* Unlock the file and close the associated FileChannel
97+
*/
98+
public synchronized void unlockAndClose() throws IOException {
99+
unlock();
100+
channel.close();
101+
}
94102
}

shell/src/main/java/org/apache/kafka/shell/MetadataShell.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static FileLock takeDirectoryLock(File directory) throws IOException {
128128
"directory before proceeding.");
129129
}
130130
} catch (Throwable e) {
131-
fileLock.destroy();
131+
fileLock.unlockAndClose();
132132
throw e;
133133
}
134134
return fileLock;
@@ -232,9 +232,9 @@ public void close() {
232232
Utils.closeQuietly(snapshotFileReader, "raftManager");
233233
if (fileLock != null) {
234234
try {
235-
fileLock.destroy();
235+
fileLock.unlockAndClose();
236236
} catch (Exception e) {
237-
log.error("Error destroying fileLock", e);
237+
log.error("Error cleaning up fileLock", e);
238238
} finally {
239239
fileLock = null;
240240
}

shell/src/test/java/org/apache/kafka/shell/MetadataShellIntegrationTest.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,16 @@ public void testLock(boolean canLock) throws Exception {
9797
FileLock fileLock = new FileLock(new File(env.tempDir, ".lock"));
9898
try {
9999
fileLock.lock();
100-
assertEquals("Unable to lock " + env.tempDir.getAbsolutePath() +
101-
". Please ensure that no broker or controller process is using this " +
102-
"directory before proceeding.",
103-
assertThrows(RuntimeException.class,
104-
() -> env.shell.run(Collections.emptyList())).
105-
getMessage());
100+
// We had a bug where the shell can lock the directory unintentionally
101+
// at the 2nd run, so we check that it fails (See KAFKA-19334)
102+
for (int i = 0; i < 2; i++) {
103+
assertEquals("Unable to lock " + env.tempDir.getAbsolutePath() +
104+
". Please ensure that no broker or controller process is using this " +
105+
"directory before proceeding.",
106+
assertThrows(RuntimeException.class,
107+
() -> env.shell.run(Collections.emptyList())).
108+
getMessage());
109+
}
106110
} finally {
107111
fileLock.destroy();
108112
}

0 commit comments

Comments
 (0)