2016년 10월 6일 목요일

Java에서 Exabyte 급의 File System의 Free Space 구하기

특정 디렉토리가 속한 파일 시스템의 전체 용량과 사용가능한 용량을 주기적으로 체크해서 데이터베이스에 기록하는 프로그램이 있다. 처음 개발한 이후로 2년여 동안 별다른 문제가 없었는데, 지난주에 AWS에 배포된 시스템에서 문제가 생겼다.

전체 용량이 -999999999999999 비슷한 수의 음수로 저장되고 있었다. 로그를 확인해보니 시스템이 계산한 전체 용량은 -9223372036854775808 이었다. 이 또한 무슨 일인지?

시스템에서 df로 확인해 보았더니, 전체 용량이 8 EB였다. 이건 자바의 long 데이터타입의 최대값을 벗어나는 값이다.

[ec2-user@hostname]$ df
Filesystem                                                  1K-blocks      Used        Available Use% Mounted on
xxx.amazonaws.com:/ 9007199254740992 238655488 9007199016085504   1% /efs

찾아보니 프로그램에서 사용한 자바의 File 클래스의 getTotalSpace 메서드의 리턴이 long이고, 이 메서드가 음수를 리턴하고 있었다. 조금더 검색해보니 이미 2016년 7월 26일에 버그로 리포팅된 내용이었다. 여기여기에서 확인이 가능하다. 내용을 보면 리눅스는 64-bit의 unsigned integer 2개로 블록사이즈와 블록갯수로 파일시스템의 용량을 표현하는데 자바는 이걸 곱한 값을 64-bit signed long으로 리턴한다는 것이다.

버그가 고쳐지길 기다릴 수는 없기에 검색을 해보니 apache common io 라이브러리가 만들어놓은 FileSystemUtils 클래스의 freeSpaceKB 메서드가 있었다. 설명을 읽어보니 내부적으로 리눅스의 df 명령의 결과를 파싱해서 리턴하는 것 같다. 그래도 KB로 리턴하니까 overflow는 발생하지 않을 것 같다.

그런데 사용가능한 용량외에도 전체 용량도 KB단위로 리턴하는 메서드가 필요한데 그것은 아무리 찾아봐도 나오지가 않는다.

결국 자체적으로 df를 파싱해서 전체 용량과 사용가능한 용량을 구해야 할 것 같다. 그리고 이 기능은 df가 가능한 리눅스에서만 정상적으로 동작할 것이다.



댓글 없음:

댓글 쓰기