나는 복제의 "고급 사례"를 만들려고 노력하고 있습니다.
블록 장치에 쓰는 파이프가 있고, 그 끝에는 건드리면 안되는 파티션이 있습니다. 나는 이 파티션이 어디서 시작되는지 알고 있습니다. 이 경우에는 파티션 테이블을 덮어쓰고 싶습니다.
단순화를 위해 파이프라인은 dd if=myfile
.
dd if=myfile > /dev/sda
나는 다음과 같은 일을 할 수 있습니다
dd if=myfile | dd bs=1B count=startofmypartition-~1000000 > /dev/sda
하지만 이를 수행하는 더 좋은 방법이 있습니까? 이 접근 방식에 단점이 있습니까?
pv
크기 옵션이 있지만 ETA를 계산하는 데만 사용된다고 명시되어 있으므로 이것이 작동하는지 확실하지 않습니다. (맨페이지에서:)
-s SIZE, --size SIZE Assume the total amount of data to be transferred is SIZE bytes when calculating percentages and ETAs. The same suffixes of "k", "m" etc can be used as with -L.
더 많은 쓰기가 있을 것이라는 것을 알고 있지만 결과적으로 테이프 드라이브가 아닌 한 동일한 양의 공간을 사용하여 디스크에 동일한 데이터가 있어야 합니다.
답변1
dd bs=1
read()
바이트당 시스템 호출을 반복적으로 수행하므로 매우 비효율적입니다 write()
. dd
블록 장치에서 사용하는 것은 어쨌든 의미가 없습니다(특수 플래그(예: conv=noerror,sync...
오류 또는 오프셋 처리 등)를 사용하려는 경우 제외).
여기에서 다음을 수행할 수 있습니다.
offset=$(($(cat /sys/class/block/sda3/start) * 512)) &&
pv -trabSs "$offset" < myfile > /dev/sda
head -c "$offset"
(또는 진행 상황 정보에 관심이 없는 경우 사용합니다).
pv
그리고 head
성능을 최적화하기 위해 충분한 버퍼 크기가 선택됩니다.
(디스크 시작 부분에 데이터를 쓰기 때문에 파티션 테이블을 효과적으로 덮어쓰게 됩니다!)
/dev/sda
또 다른 옵션은 덮어쓰려는 부분만 매핑하여 새 블록 장치를 만드는 것입니다.
좋다:
echo "0 $(cat /sys/class/block/sda3/start) linear /dev/sda 0" |
dmsetup create writable_sda &&
cp myfile /dev/mapper/writable_sda