4

Our Spring boot application hanged on production Unix environment. After getting the thread dump we were able to find that getSpace method of UnixFileSystem was locked. Can anyone help me with the Unix command that is called when java calls the getSpace method.

   http-nio-8080-exec-1" - Thread t@45
java.lang.Thread.State: RUNNABLE
at java.io.UnixFileSystem.getSpace(Native Method)
at java.io.File.getUsableSpace(File.java:1885)
kaqqao
  • 12,984
  • 10
  • 64
  • 118
Atul Rai
  • 171
  • 2
  • 4
  • 3
    Here's a question that seems similar to yours: https://stackoverflow.com/questions/224756/java-application-hang-on-linux-at-java-io-unixfilesystem-getbooleanattributes0 It has a couple of upvoted answers, so it might help you. – kaqqao Sep 18 '19 at 12:38
  • Also, where is the file located? Local file system or NFS or something else? – kaqqao Sep 18 '19 at 12:47
  • file is located at NFS. It seems that the linux server on which our application was hosted was not functioning properly – Atul Rai Sep 19 '19 at 03:59

1 Answers1

2

Basically a native call is made in java.io.UnixFileSystem to getSpace(...):

/* -- Disk usage -- */
public native long getSpace(File f, int t);

This native method ends up calling via JNI the method defined in this file of the JDK's repository:

https://github.com/openjdk/jdk/blob/master/src/java.base/unix/native/libjava/UnixFileSystem_md.c


In this file, at line 466, you find the following implementation (parts inside the if/else statements have been omitted for brevity):

JNIEXPORT jlong JNICALL
Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
                                    jobject file, jint t)
{
    jlong rv = 0L;

    WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
#ifdef MACOSX
        struct statfs fsstat;
#else
        struct statvfs64 fsstat;
        int res;
#endif
        memset(&fsstat, 0, sizeof(fsstat));
#ifdef MACOSX
        if (statfs(path, &fsstat) == 0) {
            switch(t) {
                // omitted
            }
        }
#else
        RESTARTABLE(statvfs64(path, &fsstat), res);
        if (res == 0) {
            switch(t) {
                // omitted
            }
        }
#endif
    } END_PLATFORM_STRING(env, path);
    return rv;
}

So as you can see, if you are using MACOSX the C library function statfs is called, otherwise the function statvfs64 is called.

Thomas Kabassis
  • 1,326
  • 1
  • 12
  • 17
  • Thanks this helped me to identify the root cause. Can I assume that df unix command internally calls statvfs64? – Atul Rai Sep 19 '19 at 04:01
  • 1
    No, the df command doesn't use the same exact calls as the JDK call (although I think they boil down to almost the same system calls in the end). You can have a look at [df command's source code](https://github.com/coreutils/coreutils/blob/master/src/df.c) if you're feeling brave! Towards the end you'll find the main() function of the utility. – Thomas Kabassis Sep 19 '19 at 13:53