![pv(1) を使用して rsync 速度を制限する](https://rvso.com/image/1414685/pv(1)%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%20rsync%20%E9%80%9F%E5%BA%A6%E3%82%92%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B.png)
pv
私は、rsyncの組み込みではなく、--bwlimit
rsync転送の帯域幅を制限するために使用しようとしています--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
は からのデータを待機しており、rsync
もrsync
データを待機しており ( でスタックselect()
)、 への入力を閉じていないようです。つまり、デッドロックです。 を他の何か ( など) にpv
置き換えた場合も同じことが起こります。これらのコマンドはが期待するように動作しないようです。pv
dd
rsync
すべてを削除する以外に回避策は見つかりませんでした:
export RSYNC_RSH="sh -c 'pv -qL10k | ssh \"\$@\" | (pv -qL11k; kill \$\$)' ssh"
kill
私にとって満足できる解決策ではありません。しかし、他に解決策が見つかりませんでした。
もちろん、使用するのは$$
怠惰な方法であり、pv
代わりに kill を使用する必要がありますが、ワンライナーで PID を取得するにはどうすればよいでしょうか。任意の PIDpidof
を返すだけですpv
。それぞれの親 PID を照会するのは、ワンライナーとしては少し奇妙に思えます。
本当の解決策を期待しています... ;)