RHEL Java Application retorna "Não há espaço disponível no dispositivo", mas apenas 3% usaram [duplicados]

2

Meu aplicativo Java retorna após a Exceção ao salvar um novo arquivo em /opt/wso2 em um CentOS 6.4:

Caused by java.io.FileNotFoundException: ... (No space left on device)

Caused by: java.io.FileNotFoundException: /opt/wso2/FrameworkFiles/trk_2014062500042488825_TRCK_PatfallHospis_pFromHospis_66601fb3-a03c-4149-93c3-6892e0a10fea.txt (No space left on device)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:99)
at com.avintis.esb.framework.adapter.wso2.FrameworkAdapterWSO2.sendMessages(FrameworkAdapterWSO2.java:634)
... 23 more

Mas quando executo df -a , vejo que a partição ainda tem muito espaço disponível:

[root@stzsi466 wso2]# df -a
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vg_stzsi466-lv_root
                      12054824   2116092   9326380  19% /
proc                         0         0         0   -  /proc
sysfs                        0         0         0   -  /sys
devpts                       0         0         0   -  /dev/pts
tmpfs                  4030764         0   4030764   0% /dev/shm
/dev/sda1               495844     53858    416386  12% /boot
/dev/sdb1             51605436   1424288  47559744   3% /opt/wso2
none                         0         0         0   -  /proc/sys/fs/binfmt_misc

[root@stzsi466 ~]# df -i
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/mapper/vg_stzsi466-lv_root
                      765536   45181  720355    6% /
tmpfs                1007691       1 1007690    1% /dev/shm
/dev/sda1             128016      44  127972    1% /boot
/dev/sdb1            3276800    6137 3270663    1% /opt/wso2

Qual é o problema aqui? É causado pelo Java no CentOS 6.4? Eu tenho outro servidor rodando Redhat REHL 6.4 e tudo funciona bem - mesmo Java etc.

Alguém sabe deste problema?

    
por FiveO 19.08.2014 / 14:36

1 resposta

0

Assim, a partir do rastreamento de pilha, podemos ver que quando o objeto FileOutputStream está sendo criado, dentro desse código, ele faz uma chamada para open () que falha e lança uma FileNotFoundException com o erro "Sem espaço no dispositivo" mensagem.

É interessante ver o código que está falhando (FileOutputStream.java):

       public FileOutputStream(File file, boolean append)
           throws FileNotFoundException
       {
           String name = (file != null ? file.getPath() : null);
           SecurityManager security = System.getSecurityManager();
           if (security != null) {
               security.checkWrite(name);
           }
           if (name == null) {
               throw new NullPointerException();
           }
           this.fd = new FileDescriptor();
           this.append = append;

           fd.incrementAndGetUseCount();
           open(name, append);                /* HERE */
       }

Portanto, esta é uma chamada para o código nativo (FileOutputStream_md.c):

Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
                                   jstring path, jboolean append) {
    fileOpen(env, this, path, fos_fd,
             O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
}

E fileOpen (io_util_md.c):

fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
{
    WITH_PLATFORM_STRING(env, path, ps) {
        FD fd;

#ifdef __linux__
        /* Remove trailing slashes, since the kernel won't */
        char *p = (char *)ps + strlen(ps) - 1;
        while ((p > ps) && (*p == '/'))
            *p-- = '
JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode))
  JVMWrapper2("JVM_Open (%s)", fname);

  //%note jvm_r6
  int result = os::open(fname, flags, mode);
  if (result >= 0) {
    return result;
  } else {
    switch(errno) {
      case EEXIST:
        return JVM_EEXIST;       /* returns -100, will trigger Exception */
      default:
        return -1;               /* returns -1, will trigger Exception */
    }
  }
JVM_END
'; #endif fd = JVM_Open(ps, flags, 0666); /* HERE IS WHERE THINGS BREAK */ if (fd >= 0) { SET_FD(this, fd, fid); } else { throwFileNotFoundException(env, path); /* EXCEPTION */ } } END_PLATFORM_STRING(env, ps); }

E JVM_Open (jvm.cpp):

       public FileOutputStream(File file, boolean append)
           throws FileNotFoundException
       {
           String name = (file != null ? file.getPath() : null);
           SecurityManager security = System.getSecurityManager();
           if (security != null) {
               security.checkWrite(name);
           }
           if (name == null) {
               throw new NullPointerException();
           }
           this.fd = new FileDescriptor();
           this.append = append;

           fd.incrementAndGetUseCount();
           open(name, append);                /* HERE */
       }

E os :: open é apenas um wrapper em torno fdopen (2) syscall.

Você pode reproduzir esse erro sempre que quiser? Em caso afirmativo, execute o comando com strace -e trace=fopen,fdopen,freopen e publique os resultados (ou anexe ao processo em execução com strace -p <PID> ).

    
por 19.08.2014 / 17:49