About this document

본 내용을 통해 du -s 명령어와 df 명령어의 결과값이 왜 다른지에 대해서 살펴볼 것이며 이는 AIX V4.x 에 모두 적용된다.


About du -s and df

dudf 는 실제 데이터가 쓰이기 위해 allocate된 block에 대한 정보를 표시하는 반면 ls 명령은 파일의 종류에 따라 약간 틀린 정보를 표시해준다. 보다 자세한 사항은 뒤에서 언급되는 ls 명령어에 대한 부분을 참고하기바란다.

AIX V4.1 이전의 경우, df는 결과를 1024byte 단위로, du는 512byte 단위로 표시해 주었다. 하지만 AIX V4.1 이후부터는 dfdu 모두 결과값을 512byte 단위로 표시해준다. 아래의 내용은 모두 AIX V4.1 이후의 dfdu 에 대한 설명으로 모든 단위는 512 byte이다.


The problem

dudf 는 free block 값을 얻기 위해 사용된다:

df 는 총 block 개수를 확인한후 du -s /filesystem_path 을 통해 얻은 값을 빼어 free block 값을 계산해낸다. 하지만 이러한 방법의 결과는 실제 df 명령을 통해 얻은 free block 의 수보다 더 크게 나오는 것을 다음의 예를 통해 알 수 있다.

예를 들어 du -s /tmp 를 통해 얻은 결과는 다음과 같다:
    12920   /tmp
그리고 같은 시스템에서 df /tmp 를 통해 얻은 결과는 다음과 같다:
    Filesystem    512-blocks      Free  %Used    Iused  %Iused  Mounted on
    /dev/hd3           57344     42208    26%      391      4%  /tmp
여기서 <total from df> - <used from du> = <false free block count>: 57344 - 12920 = 44424.

44424 는 df /tmp 에서 얻은 42208 보다 크다는 것을 알 수 있다.

그 이유는 dudf 가 실행되는 방법이 다르기 때문이다.

du -s
    du -s 는 파일 tree를 분석하여 stat() 이라는 시스템 call 에 의해 발견된 각 디렉토리, 파일, symlink 들에 할당된 block의 수를 합하여 전체 값을 계산해 낸다.

df
    반면 df 는 파일시스템의 disk block allocation map을 통해 total 및 free 값을 계산해낸다.


Why the numbers do not add up

파일시스템은 데이터를 기록하기 위해 자신의 디스크 block 일부를 할당 받는데 이때의 정보를 Meta Data로 불르며 inode, disk map, indirect block, super block이 이에 해당되며 이는 사용자 레벨의 프로그램에서는 볼 수 없는 정보입니다.

  1. du 는 사용자 레벨의 프로그램으로 파일시스템의 meta data에 대해서는 알 수 없다. 하지만 df 는 파일시스템의 disk allocation map 을 보기 때문에 파일시스템의 meta data 를 알 수 있다. 따라서 df 는 정확한 파일시스템의 상태정보를 알 수 있는 반면 du 는 전체의 일부분만을 볼 수 밖에 없는 것이다. 예를 들어, frag=4096, nbpi=4096 으로 생성된 비어있는 4MB의 JFS 파일시스템에는 다음과 같은 meta data 가 포함되어 있다:
       1  4k block for the LVM
       2  4k super blocks
       2  4k blocks for disk maps
       2  4k blocks for inode maps
       2  4k blocks for .indirect
       32 4k blocks for inodes
       -------------------------
       41 4k blocks for meta data on an empty 4MB file system
    
    AIX Version 4.x 의 경우:

    du /foo 의 결과값이 다음과 같다면:
        8       /foo/lost+found
        16      /foo
    
    이때 16개의 512-byte block은 root 디렉토리가 사용하는 공간이다.

    du 의 결과값을 df 와 일치시키려면 meta data 부분을 포함시켜야 한다.

    먼저 41개의 4K block을 512-byte 단위로 환산하면:
        41 * 8 = 328
        328(meta data) + 16(from du) = 344
    
    따라서 총 344개의 512-byte block들이 meta data 영역이다.

    이로부터 실제 파일시스템의 free 값을 계산해보면:
        8192(total blocks) - 344(used from du + meta data) = 7848
    
    이렇게 해서 df /foo. 으로 계산된 free 값과 일치함을 알수 있다.
        Filesystem  512-blocks  Free   %Used   Iused   %Iused   Mounted on
        /dev/lv01         8192  7848      5%      16       2%   /foo
    
    위의 예는 비어있는 파일시스템에 대해 계산된 것이라 다소 쉽게 이루어졌지만 만약, 그렇지 않은 경우 파일의 indirect block까지 meta data로 계산해야 하므로 작업이 사실상 쉽지 않다.

    결론적으로 du -s 는 파일과 디렉토리에 할당된 block 수이지만 df 는 파일시스템에 실제로 할당되어 있는 block수를 나타낸다.

  2. dudf 의 값이 다른 이유의 또다른 변수의 한 예는:

    만약 사용자가 어떤 프로그램으로 특정 디렉토리 내의 파일을 열고 있는 상태에서 해당 파일이 삭제되었다고 했을 때 그 파일이 속해있는 디렉토리에 대해 du는 삭제된 파일만큼 감소된 크기를 바로 보여주지만 df는 파일을 연 프로그램이 파일을 닫고 나서야 감소된 크기를 보여줍니다.


The ls command

다음은 ls 의 결과값을 dudf 에 비교하여 보여준다.
  • ls 명령은 각각의 파일에 할당된 공간의 사이즈와 관계없이 end-of-file 과 beginning-of-file 의 차이를 계산하여 그 크기를 보여준다. 따라서 그 결과가 32MB 의 크기라 할지라도 실제 32MB 크기의 영역 모두에 데이터가 저장되어 있다고 볼 수 없다.
  • du 는 각각의 파일에 할당된 block의 크기를 나타낸다.
  • df 는 inode와 meta data를 포함한 전체 파일시스템에 할당된 block의 크기를 나타낸다.
예를 들어 다음과 같은 sparse 파일을 만들어 보면 보다 정확하게 비교할 수 있게 된다. 이를 위해 하나의 파일을 열고 dd 명령어를 사용하여 약간의 데이터를 써보면:

  1. 일반적인 파일 하나를 만든다.

        date > notsparse
        ls -l
    
    이때 ls 명령을 이용한 결과값은 다음과 같은 형태로 나타날 것이다:
        total 8
        -rw-r--r--   1 root     sys         29 Dec 21 08:12 notsparse
    
  2. fileplace 명령어를 이용하여 notsparse 파일에 실제로 할당된, 비할당된 block의 수를 알 수 있다.

    NOTE: AIX Version 4.x 인 경우 Performance Analysis and Control Commands (perfagent.tools) 가 설치되어 있어야 한다.
        fileplace notsparse
    
    AIX Version 4.x 인 경우, 그 결과값은 다음과 같은 형태로 표시될 것이다:
        File: notsparse  Size: 29 bytes  Vol: /dev/lv03
        Bkl Size: 4096  Frag size: 4096 Nfrags: 1 Compress: no
        Logical Fragment
        ----------------
        00716                   1 frags        4096 bytes,  100.0%
    
  3. du 명령을 이용하여 파일에 할당된 512-byte 단위의 block 수를 확인할 수 있다.
        du -rs *
    
    이때 다음과 같은 결과가 표시될 것이다:
        8 notsparse
    
  4. 이제 다음과 같은 방법으로 1번에서 생성한 파일을 이용하여 새로운 sparse 파일을 만들수 있다. :
        touch sparse.1
        dd if=notsparse of=sparse.1 seek=100
    
    이때 결과값은 다음과 같이 나타날 수 있다.:
        dd: 0+1 records in.
        dd: 0+1 records out.
    
    위의 dd 명령은 notsparse 파일의 데이터를 sparse.1 이라는 파일의 100번째 512-byte block에 저장한다. 따리서 앞의 99개의 512-byte block에는 아무것도 저장되지 않는다. 다음은 이 결과 파일의 특성을 보여주는 예이다.

  5. ls 명령은 파일에 존재하는 block zero 에서부터 마지막 block까지의 차이를 나타낸다:
        ls -l
    
    다음은 상기 명령의 결과값의 한 예이다:
        total 16
        -rw-r--r--  1 root   sys       29 Dec 21 08:12 notsparse
        -rw-r--r--  1 root   sys    51229 Dec 21 08:13 sparse.1
    
  6. fileplace 명령은 어느 block이 할당 또는 비할당되었는지를 자세히 표시해준다:
        fileplace sparse.1
    
    AIX V4.1 에서의 결과값의 한 예이다:
        File: sparse.1  Size: 51229 bytes Vol: /dev/lv03
        Blk Size: 4096  Frag Size: 4096  Nfrags: 1  Compress: no
        Logical Fragment
        ----------------
        unallocated               12 frags  49152 Bytes,  0.0%
        0000769                    1 frags   4096 Bytes, 100.0%
    
    du 명령은 파일에 할당된 block의 수를 나타낸다. 예를들면:
        du -rs *
    
    이때의 결과값은 :
        8 notsparse
        8 sparse.1
    
    각 명령어는 그것이 가지고 있는 고유한 특성에 따라 그 결과를 표시해준다. 즉, ls 는 파일에 데이터를 읽거나 쓸 수 있는 범위를 나타내는 것이고 dudf 는 실제로 쓰여진 데이터를 위한 block의 영역을 나타낸다.

+ Recent posts