Lostup을 스파스 파일로 효율적으로 만들 수 있나요?

Lostup을 스파스 파일로 효율적으로 만들 수 있나요?

그래서 내 설정은 이렇습니다.

$ truncate -s 1T volume
$ losetup -f --show volume
/dev/loop0
$ mkfs.ext4 /dev/loop0
$ ls -sh volume
1.1G volume
$ mount /dev/loop0 /mnt/loop

이제 예상대로 1.1TB 볼륨이 생겼습니다. ext4의 오버헤드는 희소 파일을 1.1G로 확장하지만 괜찮습니다. 이제 파일을 추가하세요.

$ dd if=/dev/urandom of=/mnt/loop/file bs=1M count=10240
$ ls -sh volume
12G volume

좋습니다. 이제 이 파일은 필요하지 않습니다.

$ rm /mnt/loop/file
$ ls -sh volume
12G volume

예상한 대로 여전히 여유 공간을 차지하고 $ fallocate -d volume1GB가 확보됩니다.

제 질문은 볼륨을 전체 크기로 확장하지 않고 어떻게 여유 공간을 0으로 만들 수 있느냐는 것입니다. $ dd if=/dev/zero전체 크기로 확장되어 conv=sparse볼륨 내에 쓸모없는 스파스 파일이 생성됩니다.

losetup핵심요약: 빈 블록에서 빈 섹터에 대한 쓰기를 무시하고 다른 모든 것을 허용하는 방법이 있습니까 ?

답변1

데이터 블록이 더 이상 사용되지 않을 때 자동으로 삭제하려면 를 사용하십시오 mount -o discard .... 아니면 수동으로 실행할 수도 있습니다 fstrim.

이 기능은 Linux 3.2의 루프 장치에 추가된 것으로 보입니다. https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/


일반적으로 mount -o discard일부 유형의 장치는 사용 중일 때 삭제 요청을 무시할 수 있으므로 작동이 보장되지 않습니다. 그러나 이는 스파스 파일의 크기에는 영향을 미치지 않습니다.

이 일반적인 경우(예: 기본 물리적 장치에도 삭제 요청을 보내려는 경우) 가장 신뢰할 수 있는 방법은 fstrim주기적으로 실행하는 것입니다.

답변2

내장 도구를 사용한 솔루션은 아니지만 원하는 작업을 수행하기 위해 Python 스크립트를 작성했습니다. 누군가에게 도움이 된다면 여기 있습니다. 내장된 솔루션이 있다면 여전히 찾고 있습니다.

#!/usr/bin/python3.6
import os
import time
import sys

if len(sys.argv) != 2:
    print('''Usage: {} <file>

Fills a file/device with zeros, with efficiencies for sparse files.'''.format(sys.argv[0]))
    exit(1)

f = open(sys.argv[1], 'rb+', 0)

bs = 1024*1024 # block size
zb = b'\0'*bs  # a full block of zeros

lasttime = round(time.time())
block = f.read(bs)
while len(block) == bs:

    # IFF a block contains non-zero characters, zero it
    if block != zb:
        f.seek(-bs, os.SEEK_CUR)
        f.write(zb)
    block = f.read(bs)

    # Print the processed bytes every second
    # Could add a MB/s or % completed, but too lazy
    if round(time.time()) != lasttime:
        print(f.tell())
        lasttime = round(time.time())

# Hit EOF, might have missed bytes at the end
# Zero last block unconditionally, too lazy to check if its required
f.seek(-bs, os.SEEK_CUR)
f.write(zb)
f.close()

관련 정보