Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"java.io.IOException: posix_fallocate() returned -1" returned by ChronicleMapBuilder.createPersistedTo #540

Closed
plbpietrz-chronicle opened this issue May 24, 2024 · 5 comments

Comments

@plbpietrz-chronicle
Copy link

When trying to create a new ChronicleMap within a Ubuntu 22.04 docker container (and on bare metal Fedora 38, 39) we are seeing this IOException:

Caused by: java.io.IOException: posix_fallocate() returned -1
	at net.openhft.chronicle.hash.impl.util.jna.PosixFallocate.fallocate(PosixFallocate.java:20) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.hash.impl.VanillaChronicleHash.fallocate(VanillaChronicleHash.java:1107) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.hash.impl.VanillaChronicleHash.map(VanillaChronicleHash.java:1093) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.hash.impl.VanillaChronicleHash.createMappedStoreAndSegments(VanillaChronicleHash.java:514) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.map.ChronicleMapBuilder.createWithNewFile(ChronicleMapBuilder.java:1849) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.map.ChronicleMapBuilder.createWithFile(ChronicleMapBuilder.java:1747) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	at net.openhft.chronicle.map.ChronicleMapBuilder.createPersistedTo(ChronicleMapBuilder.java:1588) ~[chronicle-map-3.25ea6.jar:3.25ea6]
	...

A minimal repro project, composed of posix:2.25ea0 and chronicle-core:2.25ea10 libraries, containing:

...
public static void main(String[] args) throws IOException {
        File testFile = new File("testFile.txt");
        if (!testFile.exists())
            testFile.createNewFile();

        try (FileInputStream fis = new FileInputStream(testFile)) {
            FileDescriptor fd = fis.getFD();

            PosixAPI posix = PosixAPI.posix();
            System.out.println("fallocate=" + posix.fallocate(getNativeFileDescriptor(fd), OpenFlag.O_APPEND.value(), 0, 106496));
        }
    }
...

also ends up with a fallocate=-1 being returned. What is interesting is that this code works if we remove the asm:9.2 library from the classpath. Below is the full dep tree of the test project

[INFO] org.example:test-project:jar:1.0-SNAPSHOT
[INFO] +- net.openhft:posix:jar:2.25ea0:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.7.36:compile
[INFO] |  +- net.java.dev.jna:jna:jar:5.5.0:compile
[INFO] |  +- net.java.dev.jna:jna-platform:jar:5.5.0:compile
[INFO] |  +- com.github.jnr:jnr-ffi:jar:2.2.13:compile
[INFO] |  |  +- com.github.jnr:jffi:jar:1.3.10:compile
[INFO] |  |  +- com.github.jnr:jffi:jar:native:1.3.10:runtime
[INFO] |  |  +- org.ow2.asm:asm:jar:9.2:compile
[INFO] |  |  +- com.github.jnr:jnr-a64asm:jar:1.0.0:compile
[INFO] |  |  \- com.github.jnr:jnr-x86asm:jar:1.0.2:compile
[INFO] |  \- com.github.jnr:jnr-constants:jar:0.10.4:compile
[INFO] \- net.openhft:chronicle-core:jar:2.25ea10:compile
[INFO]    \- net.openhft:chronicle-analytics:jar:2.25ea0:compile
@rogersimmons
Copy link

hi @plbpietrz-chronicle - running the minimal reproducer on an Ubuntu 22.04 VM there are 2 issues:

  1. In order to fallocate the file the associated descriptor must be in RDWR mode. As the file is opened with a FileInputStream it lacks the WR flag, which causes the fallocate to return an EBADF error.

  2. The OpenFlag.O_APPEND.value() does not pass the correct numerical value in this context (it's passing 8, which is the "collapse" option for fallocate). The correct numerical value here is 0.

Putting both fixes in place the minimal reproducer runs without issue.
(The test file is created, and resized to 106496, with fallocate returning 0).

Could you double check the minimal reproducer and/or the original code it is base upon and let me know how things look.

Thanks

@rogersimmons
Copy link

For completeness, this is a working version:
(FileInputStream -> FileOutputStream; 2nd arg OpenFlag.O_APPEND.value() -> 0)

    private static int getNativeFileDescriptor(FileDescriptor fd) {
        return SharedSecrets.getJavaIOFileDescriptorAccess().get(fd);
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        File testFile = new File("testFile.txt");
        if (!testFile.exists())
            testFile.createNewFile();

        try (FileOutputStream fis = new FileOutputStream(testFile)) {
            FileDescriptor fd = fis.getFD();

            PosixAPI posix = PosixAPI.posix();
            System.out.println("fallocate=" + posix.fallocate(getNativeFileDescriptor(fd), 0, 0, 106496));
        }
    }

@plbpietrz-chronicle
Copy link
Author

Another example of the fallocate issue would be this chronicle-map example:

    public static void main(String[] args) throws IOException {
        try (ChronicleMap<String, Double> map = ChronicleMapBuilder.of(String.class, Double.class)
                .averageKeySize(256)
                    .entries(1024)
                    .name("chronicle-map")
                    .createPersistedTo(new File(".", "chronicle-map.cm3"));
        ) {
            System.out.println("Map created: " + map);
        }
    }

with only this library in mvn dependencies section:

<dependency>
    <groupId>net.openhft</groupId>
    <artifactId>chronicle-map</artifactId>
    <version>3.25ea5</version>
</dependency>

@rogersimmons
Copy link

The above works for me with unmodified Chronicle-Map ea on:

  • SUSE 15.4
  • Ubuntu 22.04
  • Fedora 39
    for both Java 8 and 17

@plbpietrz-chronicle - as discussed, pls try a fresh VM of your distro (Fedora) and vanilla Chronicle-Map to rule out something awry in your local env.

@plbpietrz-chronicle
Copy link
Author

Issue fixed in latest release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants