8272588: Enhanced recording parsing

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2022-02-01 21:37:58 +00:00 committed by robm
parent eb2f497cf0
commit f4a39323bf
7 changed files with 31 additions and 4 deletions

View File

@ -154,6 +154,8 @@ public interface EventStream extends AutoCloseable {
* <p>
* By default, the stream starts with the next event flushed by Flight
* Recorder.
* <p>
* Only trusted disk repositories should be opened.
*
* @param directory location of the disk repository, not {@code null}
*
@ -184,6 +186,8 @@ public interface EventStream extends AutoCloseable {
* Creates an event stream from a file.
* <p>
* By default, the stream starts with the first event in the file.
* <p>
* Only recording files from trusted sources should be opened.
*
* @param file location of the file, not {@code null}
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -72,6 +72,8 @@ public final class RecordingFile implements Closeable {
/**
* Creates a recording file.
* <p>
* Only recording files from trusted sources should be used.
*
* @param file the path of the file to open, not {@code null}
* @throws IOException if it's not a valid recording file, or an I/O error
@ -211,6 +213,8 @@ public final class RecordingFile implements Closeable {
* <p>
* This method is intended for simple cases where it's convenient to read all
* events in a single operation. It isn't intended for reading large files.
* <p>
* Only recording files from trusted sources should be used.
*
* @param path the path to the file, not {@code null}
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -114,7 +114,7 @@ public final class ChunkHeader {
byte fileState1;
input.positionPhysical(absoluteChunkStart + FILE_STATE_POSITION);
while ((fileState1 = input.readPhysicalByte()) == UPDATING_CHUNK_HEADER) {
Utils.takeNap(1);
input.pollWait();
input.positionPhysical(absoluteChunkStart + FILE_STATE_POSITION);
}
input.positionPhysical(absoluteChunkStart + CHUNK_SIZE_POSITION);
@ -184,7 +184,7 @@ public final class ChunkHeader {
finished = true;
return;
}
Utils.takeNap(1);
input.pollWait();
}
} finally {
input.position(pos);

View File

@ -148,6 +148,7 @@ public class EventDirectoryStream extends AbstractEventStream {
}
currentChunkStartNanos = repositoryFiles.getTimestamp(path);
try (RecordingInput input = new RecordingInput(path.toFile(), fileAccess)) {
input.setStreamed();
currentParser = new ChunkParser(input, disp.parserConfiguration, parserState);
long segmentStart = currentParser.getStartNanos() + currentParser.getChunkDuration();
long filterStart = validStartTime ? disp.startNanos : segmentStart;

View File

@ -50,6 +50,7 @@ public final class EventFileStream extends AbstractEventStream {
super(acc, null, Collections.emptyList());
Objects.requireNonNull(path);
this.input = new RecordingInput(path.toFile(), FileAccess.UNPRIVILEGED);
this.input.setStreamed();
}
@Override

View File

@ -214,6 +214,7 @@ public final class OngoingStream extends EventByteStream {
return false;
}
input = new RecordingInput(path.toFile(), SecuritySupport.PRIVILEGED);
input.setStreamed();
header = new ChunkHeader(input);
}
return true;

View File

@ -31,6 +31,7 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Path;
import jdk.jfr.internal.Utils;
public final class RecordingInput implements DataInput, AutoCloseable {
@ -66,6 +67,7 @@ public final class RecordingInput implements DataInput, AutoCloseable {
}
private final int blockSize;
private final FileAccess fileAccess;
private long pollCount = 1000;
private RandomAccessFile file;
private String filename;
private Block currentBlock = new Block();
@ -439,4 +441,18 @@ public final class RecordingInput implements DataInput, AutoCloseable {
initialize(path.toFile());
}
// Marks that it is OK to poll indefinitely for file update
// By default, only 1000 polls are allowed
public void setStreamed() {
this.pollCount = Long.MAX_VALUE;
}
// Wait for file to be updated
public void pollWait() throws IOException {
pollCount--;
if (pollCount < 0) {
throw new IOException("Recording file is stuck in locked stream state.");
}
Utils.takeNap(1);
}
}