调用rsync的子进程在可能的缓冲区fi之后挂起

2024-05-17 04:05:24 发布

您现在位置:Python中文网/ 问答频道 /正文

[root@devdbadmin bin]# uname -a
Linux devdbadmin 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 20 20:32:50 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@devdbadmin bin]# python3.5 --version
Python 3.5.0

我有一个问题,我一直在调试失败,我试图通过子进程和python运行多个rsync命令。我花了大量的时间阅读所有的问题,但一直未能得到一个干净的运行。我不关心rsync的输出,也不关心stderr/stdout。我只是在寻找成功或失败的返回码。发生的情况是第一个rsync会工作,第二个命令偶尔也会起作用,在任何时候,子进程都会间歇性地停止,根据strace,会显示为超时:

^{pr2}$

我已经把这个范围缩小到了子进程,因为我可以在shell中毫无问题地运行命令。或者我认为正在填充缓冲区,或者我正在填充缓冲区。根据手册我读到:

Warning

This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that

问题是,我没有在我的子进程命令中使用管道,所以我很困惑。我尝试用-u调用python以表示未缓冲,并尝试使用rsync-stbuf=L表示行。这是代码的相关部分。在

subfolders = ['7/centosplus/x86_64',
              '7/updates/x86_64',
              '7/x86_64',
              'epel/7/x86_64',
              'remi/x86_64',
              'php56/x86_64',
              'nginx']

princeton_commands = [['rsync -az rsync://mirror.math.princeton.edu/pub/centos/7/os/x86_64/ 7/x86_64/'],
                      ['rsync -az rsync://mirror.math.princeton.edu/pub/centos/7/updates/x86_64/ 7/updates/x86_64/'],
                      ['rsync -az rsync://mirror.math.princeton.edu/pub/centos/7/centosplus/x86_64/ 7/centosplus/x86_64/']]

def makefolders(root_dir, subfolders):
    concat_path = functools.partial(os.path.join, root_dir)
    dir_list = list(map(concat_path, subfolders))
    logger.info('CREATING DIRECTORIES: %s' % dir_list)
    for dirs in dir_list:
        os.makedirs(dirs)

def execute_jobs(cmd):
    try:
        subprocess.run(cmds,shell=True, check=True)
        logger.info('rsync Success: %s' % cmd)
    except subprocess.CalledProcessError as e:
        logger.critical('%s FATAL: Command failed with error: %s' % (cmd,e))

def main():
    if os.path.exists(root_dir):
        logger.critical('PATH EXISTS, manually run [ rm -rf %s ] to proceed...' % root_dir)
        sys.exit(1)

    makefolders(root_dir, subfolders)
    os.chdir(root_dir)

    for cmds in princeton_commands:
        execute_jobs(cmds)

main()

我知道linux有一个pipr缓冲区,但是我没有在rsync命令上使用-v verbose,所以我没有得到足够的输出来填充这个缓冲区,我也没有像前面提到的那样在子进程中使用管道。我正在使用free来查看内存是否填满,我没有看到任何相关内容。在

值得一提的是,我曾尝试过多个镜像主机,但rsync会在我尝试的任何主机上停止运行,只要它运行到一半。在

编辑:

Here is the strace and lsof of the process stuck:
root     29195  8.6  0.0 117488  2084 pts/0    S    10:47   1:54  |                       |           \_ rsync -az rsync://mirror.math.princeton.edu/pub/centos/7/updates/x86_64/ 7/updates/x86_64/

[root@devdbadmin bin]# strace -p 29195
strace: Process 29195 attached
select(4, [3], [], [3], {52, 716623})   = 0 (Timeout)
select(4, [3], [], [3], {60, 0}^Cstrace: Process 29195 detached

[root@devdbadmin bin]# lsof -p 29195 -ad  4,3
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF     NODE NAME
rsync   29195 root    3u  IPv4 1686385      0t0      TCP devdbadmin.afs:40500->mirror.math.princeton.edu:rsync (ESTABLISHED)
rsync   29195 root    4u   REG   253,3   786432 10755679 /u01/repo/monthly/CentOS7/2018-02/7/updates/x86_64/drpms/.python-perf-3.10.0-514.26.1.el7_3.10.0-693.5.2.el7.x86_64.drpm.g7XODd

Tags: 命令bin进程osmirrordirmathroot
1条回答
网友
1楼 · 发布于 2024-05-17 04:05:24

在调试并了解了strace/rsync子进程之后,我联系了官方镜像的一位管理员,解释了我的情况。他们让我在12点到8点之间开始同步。完成此操作后,rsyncs正常完成。所以我认为问题是sender没有足够的rsync插槽或资源来发送数据。strace输出显示它正在等待一个没有获取数据的fd。我希望这对任何人都有帮助,我希望有人可以通过看我的战略来证实这一点。在

相关问题 更多 >