USR1 없이 dd의 진행 상황을 확인하시겠습니까?

USR1 없이 dd의 진행 상황을 확인하시겠습니까?

나는 Linux busybox 1.27전용 시스템을 사용하고 있으므로 output=progress사용할 수 없으며 busybox 자체 구현 pvpipe_progress없습니다 pv.

두 가지 질문이 있습니다. 첫 번째는 다음을 기반으로합니다.https://www.linux.com/training-tutorials/show-progress-when-using-dd/. USR1신호를 보내 dd프로세스를 "일시 중지"하고 dd인쇄한 후 현재 상태가 수행 중이던 작업을 계속할 것이라고 말합니다 . 몇 가지 벤치마크 테스트를 수행하려고 하므로 작업 dd에 미치는 영향을 최소화하고 싶습니다 dd. 전달되는 데이터가 dd변동하고 전송 속도가 떨어지는 시기를 인식하는 것이 중요하기 때문에 매초마다 현재 작업의 출력을 얻고 싶습니다.

첫 번째 질문: 'dd'가 신호를 받을 때마다 "일시 중지"된다는 것이 사실인가요 USR1?

매초마다 일시 중지 되면 dd수십 기가바이트가 전송될 때 작업에 몇 시간이 추가됩니다.

두 번째 질문: 가정첫 번째 질문에 대한 답변으로 프로세스에 신호를 보내지 않고 현재 상태를 인쇄할 수 있는지 알고 싶습니다 dd. 아마도 일종의 리디렉션 STDOUT(예: 2>&1)이 있을까요?

내가 말하는 것은 다음과 같습니다.

# bs with 1Mib so I can have more control on the test.
dd if=/dev/zero of=/dev/null bs=1048576 count=1024

# Printing current operation status.
sudo kill -USR1 $dd_pid 

답변1

dd if=/dev/zero of=/dev/null bs=1048576 count=1024

참고하세요dd데이터를 망칠 수 있다, 적어도bs매개변수를 사용할 때. 그리고성능상의 이점특정 시스템 구성에 대한 최적의 블록 크기를 직접 선택한 경우 기껏해야 작습니다. cat또는 cp더 잘할 수 있지만 기껏해야 약간 느릴 뿐입니다. 따라서 dd꼭 필요하지 않다면 사용하지 마세요 .

버전 1.23부터 BusyBox는sendfileread및 를 사용하는 대신 데이터를 복사하는 시스템 호출입니다 write. 그러나 catcpuse sendfile: 와 같은 일반 복사본만 크기를 정확하게 제어하기 위해 /를 dd사용해야 합니다 . 따라서 BusyBox ≥1.23을 사용 하면 .readwritecatcpdd

USR1 신호를 수신할 때마다 'dd'가 "일시 중지"된다는 것이 사실입니까?

기술적으로 그렇습니다. 신호를 처리하려면 "일시 중지"해야 합니다. 그러나 일시 중지는 CPU 명령 몇 개에 불과합니다(지금까지 가장 비용이 많이 드는 부분은 진행률 출력을 인쇄하는 것입니다). 따라서 이것은 어떤 식으로든 벤치마크를 무효화하지 않습니다.

dd가 매초마다 일시 중지되면 수십 기가바이트가 전송될 때 작업에 몇 시간이 추가됩니다.

아니요, 규모가 잘못되었습니다. 단일 CPU 스레드에서는 아마도 0.1%의 시간이 추가될 것입니다. 주요 비용은 벤치마킹 프로그램의 커널 시간이지 dd구현하는 방식이 아니라 수행하려는 작업에 내재되어 있습니다.

프로세스에 신호를 보내지 않고 dd가 현재 상태를 인쇄하도록 하는 것이 가능한 경우

음 ... 아니. 이를 수행하는 간단하고 역사적으로 확립된 표준적이고 쉬운 방법이 이미 있습니다. 구현하기 더 어려운 다른 방법이 있는 이유는 무엇입니까?


Linux에는 복사본이 도달한 지점을 알 수 있는 일반적인 방법이 있습니다. 복사를 수행하는 프로그램에 따라 달라지지는 않지만 항상 특수 파일에서 작동하는 것은 아닙니다. $pid복사를 수행하는 프로세스 ID와 입력 및 출력에 사용하는 파일 설명자를 알아보세요 . BusyBox는 일반적 dd으로 fd 0에서 읽고 fd 1에 씁니다. BusyBox는 cp일반적으로 fd 3에서 읽고 fd 4에 씁니다. 의 기호 링크를 통해 어떤 파일이 어떤 파일 설명자에 열려 있는지 확인할 수 있습니다 /proc/$pid/fd.

$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null

$n$그리고 에서 파일 설명자의 위치를 ​​확인할 수 있습니다 /proc/$pid/fd/$n.

$ cat /proc/$pid/fdinfo/4
pos:    74252288
flags:  0100001
mnt_id: 27

그러나 파일 설명자 위치는 /dev/zero, /dev/null, 파이프 또는 소켓과 같은 특수 파일로 업데이트되지 않을 수 있습니다. 항상 일반 파일로 업데이트됩니다. 블록 장치용으로 업데이트되었는지는 모르겠습니다. 따라서 /dev/zero와 사이의 복사에 대한 정보는 제공하지 않지만 /dev/null실제 사용 사례에서는 작동할 수 있습니다.

답변2

인터페이스 를 통해 진행 상황을 쿼리할 수도 있습니다 /proc.

# dd bs=1M if=/dev/mmcblk0 of=/dev/null &
# pidof dd
1358

따라서 이 프로세스에 대한 정보는 다음에서 찾을 수 있습니다 /proc/1358.

# ls -l /proc/1358/fd
total 0
lr-x------    1 root     root            64 Nov  2 09:16 0 -> /dev/mmcblk0
l-wx------    1 root     root            64 Nov  2 09:16 1 -> /dev/null
lrwx------    1 root     root            64 Nov  2 09:16 2 -> /dev/pts/0

파일 핸들 0은 입니다 if=/dev/mmcblk0. 이제 진행 상황은 어디입니까?

# cat /proc/1358/fdinfo/0
pos:    2132803584
flags:  0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos:    2366636032
flags:  0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos:    2587885568
flags:  0400000
mnt_id: 17

이러한 방식으로 busybox dd의 경우 fdinfo pos 값에서 진행 상황을 파생할 수도 있습니다.

즉, USR1 신호를 적당히 보내는 것은 성능에 최소한의 영향을 미칩니다. 리소스가 거의 없는 임베디드 시스템에서는 fdinfo를 폴링하는 것도 비슷한 영향을 미칠 수 있습니다.

관련 정보