전체 디스크에 dd이지만 빈 부분을 원하지 않음


33

/ dev / sda와 같은 디스크가 있습니다.

다음은 fdisk -l입니다.

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

우리가 제조하는 다른 장치를 플래시하는 데 사용하기 위해 파일 서버에 이미지를 저장해야하므로 사용 된 공간 만 (약 4GB) 원합니다. 복사가 완료되는 즉시이 장치를 부팅 할 수 있도록 mbr 등을 유지하고 싶습니다.

어떤 아이디어? 나는 이전에을 사용 dd if=/dev/sda of=[//fileserver/file]했지만 그 당시 내 마스터 사본은 4GB 플래시 IDE에있었습니다.


2
@sudoer를 제외하고 아래의 모든 답변이 잘못되었습니다. 정답은를 사용하는 것 dd conv=sparse입니다.
bahamat

@bahamat, 아니오, gzip은 데이터를 압축하기 때문에 더 좋습니다.
psusi

1
그것은 드문 드문 것과 다릅니다.
bahamat

@bahamat, 질문은 특별히 sprase를 요구하지 않습니다; 이미지가 적은 공간을 차지하게 만드는 방법.
psusi

답변:


37

당시에는 임베디드 Linux 배포판에서 비슷한 문제가 발생했습니다. 이미지를 압축하기 전에 모든 정크를 제거하십시오.

dd if=/dev/zero of=asdf.txt. 죽을 때까지 기다리십시오. asdf.txt를 삭제하십시오.

장치의 모든 여유 공간에 0을 썼습니다.

이제 디스크 이미지를 가져 와서 gzip을 통해 실행하십시오. 짜잔 한 이미지.

아마도 확장 성이 떨어지고 실제로 디스크에 기록해야 할 경우 문제가 발생할 수 있습니다.

디스크의 rsync 스냅 샷을 다른 볼륨으로 가져 와서 0으로 만든 다음 해당 디스크 이미지를 만들 수 있습니다.

참고 : SSD에 위험 할 수 있으므로 커밋하기 전에이 작업을 고려해야합니다.


gzip을 통해 실행하는 경우 사용하기 전에 압축을 풀어야합니까? 그리고 gzip을 통해 실행하면 dd 프로세스 중에 파이프로 파이프합니까?
Jonathan Henson

3
예. dd if=sda2.gz | gunzip > /dev/sda2dd if=/dev/sda2 | gzip > sda2.gz
롭 보스

3
"기기의 모든 여유 공간에 0을 썼습니다." 당신은 장치가 아니라 파티션을 의미한다고 생각합니다. 따라서 of각 파티션 의 경로를 사용하여 해당 명령을 실행해야 합니다.
jiggunjer

실제 미디어가 SSD 인 경우 이제 장치의 모든 섹터가 사용 된 것으로 생각할 수 있습니다. 이를 통해 SSD는 더 적은 수의 여분의 섹터를 사용하여 성능을 저하시킬 수 있습니다. 드라이버 및 펌웨어가 TRIM을 지원하는 경우 해당 조건은 파일을 다시 삭제할 때까지만 적용됩니다. 이미지를 만드는 동안 파일을 그대로 유지하면 이미지를 복원 한 후 파일을 다시 삭제해야합니다. 이미지가 SSD로 복원 된 경우 유용 할 수 있습니다.
kasperd

명심해야 할 몇 가지 추가 사항이 있습니다. 이 방법을 사용하려면 파일 시스템을 읽기 / 쓰기로 마운트해야하므로 복사가 진행되는 동안 기본 파일 시스템을 변경하면 이미지가 일치하지 않을 위험이 있습니다. 한 번은 결과 사본이 일관성이 없어서 fsck가 사본의 불일치를 복구하려고 할 때 실제로 segfault가되는 것을 보았습니다. 또한 장치를 채우면 매체에 기록해야하는 다른 프로세스가 실패 할 수 있습니다.
kasperd

17

저장하려는 가정 /dev/sdXN/tgtfs/image.raw당신이 루트입니다 :

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. zerofill 또는 just : dd if=/dev/zero of=/srcfs/tmpzero.txt를 사용하여 사용하지 않는 블록을 0으로 채우십시오 (파일 시스템이 완전히 채워질 때까지 기다리십시오 rm /srcfs/tmpzero.txt)

  3. dd를 사용하여 이미지를 가져오고 conv = sparse를 사용하여 0을 즉시 펀치하십시오. dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

압축을 사용하려면 0 블록이 압축률이 높으므로 dd로 0을 펀칭 할 필요가 없습니다.

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

추신 : 이것은 플래시 메모리 기반 저장 매체 (예 : 소스 파일 시스템이 SSD)에서는 좋지 않은 아이디어입니다


5
이것이 정답입니다. 사용하십시오 dd conv=sparse.
bahamat

1
플래시 스토리지에서이 작업을 수행하는 데 어떤 문제가 있습니까?
Dan

2
@Dan (하드웨어 및 소프트웨어 설계 및 구성에 따라 다름) SSD에 광범위한 쓰기가 발생하여 수명이 단축 될 수 있습니다. 그리고 전반적으로, 오래된 디스크에서 새로운 디스크로 (또는 OP가 원했던 것) 데이터를 옮기는 것은 괜찮지 만 디스크 / 파티션 레벨 백업은 HDD에서도 정기적 인 백업 및 복원을위한 좋은 솔루션이 아닙니다. 파일 수준 백업 (예 : 한 파일 시스템에서 다른 파일 시스템으로 파일 복사) 또는 파일 시스템 수준 백업 (BTRFS와 같은 파일 시스템 btrfs snapshotbtrfs send도구 포함)이 더 나은 솔루션 IMHO입니다.
Sudoer

힌트 : 당신이없는 경우 gz에 당신 PATH(I하지 않았다처럼, GParted와 라이브에), 당신이 사용할 수있는 gzip -c대신에.
XtraSimplicity

11

count 옵션과 함께 dd를 사용하십시오.

귀하의 경우 fdisk를 사용하고 있으므로 그 접근법을 취할 것입니다. 당신의 "sudo fdisk -l"는 다음을 생성했습니다 :

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

주의해야 할 두 가지는 1) 단위 크기와 2) "끝"열입니다. 귀하의 경우 8225280 바이트와 동일한 실린더가 있습니다. "End"열에서 sda8은 525에서 종료됩니다 (525 [units] * 16065 * 512 = ~ 4.3GB).

dd는 오프셋 이후 시작 또는 특정 수의 블록 이후 중지와 같은 많은 작업을 수행 할 수 있습니다. dd의 count 옵션을 사용하여 후자를 수행합니다. 명령은 다음과 같이 나타납니다.

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

여기서 -bs는 블록 크기 (fdisk가 사용하는 장치를 사용하는 것이 가장 쉽지만 count 옵션이이 단위로 선언되는 한 모든 단위가 사용됨)이고 count는 복사하려는 단위 수입니다 (주 마지막 블록을 캡처하기 위해 카운트를 1 씩 증가시킵니다.


참고 : 실린더 단위를 표시하려면fdisk -l -u=cylinders /dev/sda
xinthose를

3
이것이 왜 대답이 맞지 않습니까? 소스를 수정하지 않으므로 가장 방해가되지 않는 옵션 인 것 같습니다.
user33326

이 답변은 파티션 내에서 사용되지 않은 공간이 아닌 드라이브의 파티션되지 않은 공간을 복사하지 않는 것이 좋기 때문에 OP가 중요합니다.
GDorn

8

반면 /dev/zero자유 디스크 공간 사용을 보내고 dd conv=sparse/ gz -c빈 공간이,의 GBS 100 단위에서 실행하는 거대한 디스크에 가능합니다 /dev/zero천천히 고통스럽게 보내고있다 - 다른 답변이 언급 한 바와 같이, 그 말할 것도없고 /dev/zeroEOF까지 SDD를 보내고.

이 상황에 처했을 때 내가 한 일은 다음과 같습니다.

  • lubuntu 라이브 CD gparted에서 디스크를 가능한 최소 크기로 축소하고 나머지 공간은 할당하지 않습니다.


  • dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz 빠른 압축 이미지를 만드는 데 사용 됩니다 (원시 데이터를 저장하기에 충분한 공간이 있거나 CPU로드를 줄이려는 경향이있는 경우 압축을 생략 할 수 있음)


  • dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY 데이터를 다른 디스크로 다시 복사하는 데 사용
  • gparted파티션을 '확장'하기 위해 다시 사용

여러 파티션에 대해 시도하지는 않았지만 대상 디스크의 파티션 테이블이 먼저 생성되고 파티션에 포함 된 데이터만이 dd읽기 / 쓰기 오프셋을 통해 복사되면 위의 프로세스가 '파티션'을 복사하도록 조정할 수 있다고 생각합니다 skip/ seek옵션이 dd각각 필요합니다.


1
이것은 실제 답변입니다, count매개 변수를 사용하십시오
Gordy

7

당신은 할 수 없습니다. dd매우 낮은 수준의 도구이며 파일과 빈 공간을 구분할 방법이 없습니다.

반면에 빈 공간은 매우 잘 압축되므로 쓰기 시간이 아닌 저장 공간에만 관심이 있다면 gzip을 통해 파이프하십시오.


7
여유 공간이 이전에 사용되지 않았다고 가정합니다. 여유 공간을 먼저 채우면 압축이 예상대로 작동합니다.
Sirex

1
참된. 또한 프로세스가 복잡해지고 시간이 더 오래 걸립니다.
c2h5oh

6

드라이브의 나머지 부분이 비어 있다고 가정하면 (0까지) gzip을 통해 DD를 파이프하면 빈 공간이 상당히 잘 압축됩니다. zerofree 와 같은 도구를 사용 하여 빈 공간이 실제로 비어 있는지 확인하여 잘 압축하십시오.

partimage , clonezilla 또는 다른 Linux 복제 도구와 같은 도구를 사용하면 대부분 자동으로 처리됩니다.


partimage와 clonezilla는 실제로 사용 가능한 공간을 읽지 않고 0을 쓰는 대신 dd 또는 gzip을 삭제하거나 0을 읽은 후 압축합니다.
psusi

2

허용 된 답변이 맞지 않습니다. 위의 의견에 동의합니다. ddcount 매개 변수 와 함께 사용 하여 디스크를 정기적으로 백업합니다. BACKUP_FOLDER와 기기의 문자를 "X"로 바꾸십시오.

디스크의 마지막으로 사용 된 블록을 정의하십시오.

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

그런 다음 디스크를 복제합니다 (빈 공간 제외).

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.