pv(1) を使用して rsync 速度を制限する

pv(1) を使用して rsync 速度を制限する

pv私は、rsyncの組み込みではなく、--bwlimitrsync転送の帯域幅を制限するために使用しようとしています--bwlimit。これは、最終的に一貫性のある方法で実装されており、転送が非常に短いため、制限が実際に発動することはありません。ほぼ動作しますが、システムは正常に終了しません。

よく知らない人のために説明すると、これpvはパイプ ビューア ユーティリティですが、パイプを通過するデータの速度を制限するあまり知られていない機能があります。


編集して追加: 根本的な問題を見つけたと思います。通常、パイプラインのプロセスが停止するのは、a) stdin が閉じるか、b) stdout への書き込み中に SIGPIPE を受け取った場合です。これらのどちらも発生しないのは、a) rsync が stdin のソケットを閉じない (どうやら) ため、b) rsync が stdout が閉じると同時に stdin へのデータ送信を停止するため、stdout への書き込みを試みないからです。

必要なのは、stdin がまだデータを送信しているかどうかに関係なく、stdout が閉じるとすぐに pv をシャットダウンする、何らかのラッピング コマンドです。


デモンストレーション:

head -c 100000 /dev/urandom > random4.bin
ls -lh random4.bin
>    -rw-r--r-- 1 buck users 98K 2014-07-07 11:01 random4.bin

export RSYNC_RSH='sh -c '\''pv -qL10k | ssh "$@" | pv -qL11k'\'' ssh'

rsync -av --progress localhost:$PWD/random4.bin random5.bin
>    receiving incremental file list
>    random4.bin
>          100000 100%   17.47kB/s    0:00:05 (xfer#1, to-check=0/1)
>    
>    sent 30 bytes  received 100109 bytes  10540.95 bytes/sec
>    total size is 100000  speedup is 1.00
>    (never exits)

この時点で、ターミナルの制御を取り戻すには Ctrl + C を押す必要があります。問題は、pv出力が閉じているにもかかわらず、ssh の入力にある が終了しないことです。

ちょっとしたデバッグ:

pstree -lap 29532
>     rsync,29532 -av --progress localhost:/nail/home/buck/tmp/random4.bin random5.bin
>      └─sh,29533 -c pv -qL10k | ssh "$@" | pv -qL11k ssh localhost rsync --server --sender -vlogDtpre.iLsf . /nail/home/buck/tmp/random4.bin
>          └─pv,29534 -qL10k


lsof -p 29532
>    COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
>    rsync   29532 buck  cwd    DIR              252,0     4096   7345851 /nail/home/buck/tmp
>    rsync   29532 buck  rtd    DIR                9,1     4096         2 /
>    rsync   29532 buck  txt    REG                9,1   405368     94575 /usr/bin/rsync
>    rsync   29532 buck  mem    REG                9,1    51712    554006 /lib/libnss_files-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1    43552    553997 /lib/libnss_nis-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1    97256    553992 /lib/libnsl-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1    35712    553831 /lib/libnss_compat-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1    18704    553802 /lib/libattr.so.1.1.0
>    rsync   29532 buck  mem    REG                9,1  1584520    554000 /lib/libc-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1    44008    554064 /lib/libpopt.so.0.0.0
>    rsync   29532 buck  mem    REG                9,1    31208    553800 /lib/libacl.so.1.1.0
>    rsync   29532 buck  mem    REG                9,1   136936    554003 /lib/ld-2.11.1.so
>    rsync   29532 buck  mem    REG                9,1   256324    172607 /usr/lib/locale/en_US.utf8/LC_CTYPE
>    rsync   29532 buck  mem    REG                9,1    26048     93726 /usr/lib/gconv/gconv-modules.cache
>    rsync   29532 buck    0u   CHR             136,10      0t0        13 /dev/pts/10
>    rsync   29532 buck    1u   CHR             136,10      0t0        13 /dev/pts/10
>    rsync   29532 buck    2u   CHR             136,10      0t0        13 /dev/pts/10
>    rsync   29532 buck    3u  unix 0xffff882026de4100      0t0 349807593 socket
>    rsync   29532 buck    4u  unix 0xffff880d79016e80      0t0 349851596 socket


lsof -p 29533
>    COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
>    sh      29533 buck  cwd    DIR              252,0     4096   7345851 /nail/home/buck/tmp
>    sh      29533 buck  rtd    DIR                9,1     4096         2 /
>    sh      29533 buck  txt    REG                9,1   101608    504936 /bin/dash
>    sh      29533 buck  mem    REG                9,1  1584520    554000 /lib/libc-2.11.1.so
>    sh      29533 buck  mem    REG                9,1   136936    554003 /lib/ld-2.11.1.so
>    sh      29533 buck    0u  unix 0xffff880d79014100      0t0 349851595 socket
>    sh      29533 buck    1u  unix 0xffff880d79014e00      0t0 349851598 socket
>    sh      29533 buck    2u   CHR             136,10      0t0        13 /dev/pts/10

lsof -p 29534
>    COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
>    pv      29534 buck  cwd    DIR              252,0     4096   7345851 /nail/home/buck/tmp
>    pv      29534 buck  rtd    DIR                9,1     4096         2 /
>    pv      29534 buck  txt    REG                9,1    35336    106025 /usr/bin/pv
>    pv      29534 buck  mem    REG                9,1  1584520    554000 /lib/libc-2.11.1.so
>    pv      29534 buck  mem    REG                9,1   136936    554003 /lib/ld-2.11.1.so
>    pv      29534 buck  mem    REG                9,1   256324    172607 /usr/lib/locale/en_US.utf8/LC_CTYPE
>    pv      29534 buck  mem    REG                9,1       54    172608 /usr/lib/locale/en_US.utf8/LC_NUMERIC
>    pv      29534 buck  mem    REG                9,1     2454    172707 /usr/lib/locale/en_US.utf8/LC_TIME
>    pv      29534 buck  mem    REG                9,1  1170770    172610 /usr/lib/locale/en_US.utf8/LC_COLLATE
>    pv      29534 buck  mem    REG                9,1      286    172708 /usr/lib/locale/en_US.utf8/LC_MONETARY
>    pv      29534 buck  mem    REG                9,1       57    172710 /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
>    pv      29534 buck  mem    REG                9,1       34    172614 /usr/lib/locale/en_US.utf8/LC_PAPER
>    pv      29534 buck  mem    REG                9,1       77    172615 /usr/lib/locale/en_US.utf8/LC_NAME
>    pv      29534 buck  mem    REG                9,1      155    172711 /usr/lib/locale/en_US.utf8/LC_ADDRESS
>    pv      29534 buck  mem    REG                9,1       59    172712 /usr/lib/locale/en_US.utf8/LC_TELEPHONE
>    pv      29534 buck  mem    REG                9,1       23    172618 /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
>    pv      29534 buck  mem    REG                9,1    26048     93726 /usr/lib/gconv/gconv-modules.cache
>    pv      29534 buck  mem    REG                9,1      373    172713 /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
>    pv      29534 buck    0u  unix 0xffff880d79014100      0t0 349851595 socket
>    pv      29534 buck    1w  FIFO                0,8      0t0 349847461 pipe
>    pv      29534 buck    2u   CHR             136,10      0t0        13 /dev/pts/10

答え1

pvは からのデータを待機しており、rsyncrsyncデータを待機しており ( でスタックselect())、 への入力を閉じていないようです。つまり、デッドロックです。 を他の何か ( など) にpv置き換えた場合も同じことが起こります。これらのコマンドはが期待するように動作しないようです。pvddrsync

すべてを削除する以外に回避策は見つかりませんでした:

export RSYNC_RSH="sh -c 'pv -qL10k | ssh \"\$@\" | (pv -qL11k; kill \$\$)' ssh"

kill私にとって満足できる解決策ではありません。しかし、他に解決策が見つかりませんでした。

もちろん、使用するのは$$怠惰な方法であり、pv代わりに kill を使用する必要がありますが、ワンライナーで PID を取得するにはどうすればよいでしょうか。任意の PIDpidofを返すだけですpv。それぞれの親 PID を照会するのは、ワンライナーとしては少し奇妙に思えます。

本当の解決策を期待しています... ;)

関連情報