10P by xguru 2022-07-25 | favorite | 댓글 1개
  • 518GiB tar.gz를 풀면서 엄청나게 느려지는 것 때문에 조사 시작
  • Tar 포맷에 대한 설명과 빠른 tar extractor 코드를 작성하며 설명

오리지널 Tar 파일 포맷

  • Tar는 아카이브 파일로는 매우 이례적임
    → 아카이브 헤더가 없고, 검색용 파일 인덱스가 없으며, tar 인지 확인 가능한 매직바이트도 없고, 푸터도 없고, 메타데이터도 없음
    → Tar 안에 있는 것은 파일 개체 한 종류임
  • 파일 타입 : 0 (일반 파일), 1 (하드 링크), 2 (심볼릭 링크)
  • 512바이트 파일 객체 헤더의 구조 설명
    → 가장 큰 제한은 파일 경로 길이가 100글자 밖에 안된다는 것. 또한 파일 크기는 8GiB가 최대

UStar 확장 파일

  • 파일 경로 길이가 최대 256 이고, 새로운 파일 타입들 추가
  • 헤더를 확장하여 매직 바이트 및 prefix 필드 추가
  • 파일 타입 추가 : 3 (캐릭터 디바이스), 4 (블록 디바이스), 5 (디렉토리), 6 (FIFO 파일), 7 (연속 파일)
  • 하지만 8GiB 크기 한도는 여전 함

Pax 파일 포맷

  • POSIX.1-2001 표준으로 pax CLI를 통해서 tar 포맷을 확장
  • UStar와 동일하지만 x 와 g 파일 포맷 추가
    → 확장 헤더 레코드로 x 는 다음 파일에만 적용되며, g 는 뒤의 모든 파일에 적용

GNU Tar 파일 포맷

  • 자체 포맷은 gnu 로 pax 와는 다름
  • pax 와 비슷하게 UStar 기반이지만, 경로 및 큰 파일을 인코딩하는 다른 방법을 사용
    → 'L' 타입 : 다음 파일 객체의 페이로드가 "file_path" 를 나타냄
    → 'K' 타입 : 다음 파일 객체의 페이로드가 "link_path" 를 나타냄
    → 두가지를 연속으로 적용 가능
    → 파일이 8GiB 보다 크다면 file_size 첫 글자의 하이비트를 세팅. 그러면 문자열의 나머지를 base 256으로 파싱 (95비트 Integer)

왜 GNU tar는 느리게 압축을 해제할까 ?

  • 파일의 헤더에 file_path="../hello.txt" 같은 값을 넣으면 보안 문제 발생. 하지만 막기가 쉽지 않음
  • GNU tar 는 link_path에 ".."를 만나면 플레이스홀더를 생성하고 딜레이 해서 처리함
  • 하지만 ".."가 없는 하드링크의 경우엔 직접 생성하고 싶지만 이미 플레이스홀더가 있기 때문에 생성이 불가
  • 즉, 하드링크를 생성하려면 그게 딜레이드 링크인지 먼저 다 확인 해야하며, 그렇다면 새 링크 역시 딜레이 처리해야함
    → 모든 하드링크에 대해서 딜레이드 링크를 탐색해야함. 이유는 모르겠지만 실제로는 2번 탐색함
  • 작성자의 Tar파일에는 80만개가 넘는 ".."를 가진 링크와 540만개 이상의 하드링크가 있었기에 압축 해제가 느려진 것
  • 이를 방지하기 위해서는 --absolute-paths 또는 -P 옵션을 tar에 추가할 것
    → 절대 경로를 저장하며 ".." 를 거부하는 옵션
    → 즉 -P 옵션을 주면 딜레이드 링킹 메커니즘을 비활성화