是什么导致此复制命令进入睡眠状态?

是什么导致此复制命令进入睡眠状态?

我正在尝试递归复制超过 25G 的巨大可安装目录,并希望保留所有者和组 ID、权限模式等。

所以我运行了以下命令:

bash-3.2$ date; cp -rpP /source/path/Oracle /target/path/Oracle;date;
Tue Jun  4 09:44:54 EDT 2013

...

一些观察结果:

  • 今天(2013 年 6 月 5 日星期三 12:09:25 EDT)我注意到它仍然没有完成并且似乎卡在某个地方。我开始分析这个过程,它似乎在睡觉:

    bash-3.2$ truss -p 09431;
    read(10, 0xFFBEF288, 32768)     (sleeping...)
    
  • 最后一个条目还显示它正在睡觉。

    bash-3.2$ pflags 09431
    9431:   cp -rpP /source/path/Oracle /target/path/Oracle
            data model = _ILP32  flags = RLC|ASYNC|MSACCT|MSFORK
            flttrace = 0xfffffbff
            sigtrace = 0xfffffeff 0xffffffff
            HUP|INT|QUIT|ILL|TRAP|ABRT|EMT|FPE|BUS|SEGV|SYS|PIPE|ALRM|TERM|USR1|USR2|CLD|PWR|WINCH|URG|POLL|STOP|TSTP|CONT|TTIN|TTOU|VTALRM|PROF|XCPU|XFSZ|WAITING|LWP|FREEZE|THAW|CANCEL|LOST|XRES|JVM1|JVM2|RTMIN|RTMIN+1|RTMIN+2|RTMIN+3|RTMAX-3|RTMAX-2|RTMAX-1|RTMAX
        entryset = 0x00000401 0x04000000 0x00000000 0x00000028
                   0x80000000 0x00000000 0x00000000 0x00000000
        exitset  = 0xfffffffe 0xffffffff 0xffffffff 0xffffffd7
                   0x7fffffff 0xffffffff 0xffffffff 0xffffffff
     /1:    flags = ASLEEP  read(0xa,0xffbef288,0x8000)
    
  • 终于尝试了pfiles

    bash-3.2$ pfiles -F 09431
    9431:   cp -rpP /source/path/Oracle /target/path/Oracle
    Current rlimit: 256 file descriptors
    0: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /devices/pseudo/pts@0:3
    1: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /devices/pseudo/pts@0:3
    2: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /devices/pseudo/pts@0:3
    3: S_IFDIR mode:0750 dev:377,1 ino:1135681 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle
    4: S_IFDIR mode:0750 dev:377,1 ino:1135682 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware
    5: S_IFDIR mode:0750 dev:377,1 ino:14640507 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware/user_projects
    6: S_IFDIR mode:0750 dev:377,1 ino:14640508 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware/user_projects/epmsystem2
    7: S_IFDIR mode:0750 dev:377,1 ino:6480147 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer
    8: S_IFDIR mode:0750 dev:377,1 ino:6480149 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1
    9: S_IFDIR mode:0750 dev:377,1 ino:6480151 uid:502012187 gid:502012187 size:4096
      O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
      /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin
    10: S_IFIFO mode:0660 dev:377,1 ino:9088704 uid:502012187 gid:502012187 size:0
      O_RDONLY|O_LARGEFILE
      /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
    11: S_IFREG mode:0660 dev:326,22000 ino:128325 uid:502012187 gid:502012187 size:0
      O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE
      /target/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
    

更新: 注意上面的cp进程已经被杀死了。因此,以下观察试图重现该问题。

  • 文件被阻止:

    bash-3.2$ ls -l ESSBASE1_1
    prw-rw----   1 kent   kent         0 Nov 22  2011 ESSBASE1_1
    
  • 当我尝试单独 cp 这个文件时:

    bash-3.2$ cp ESSBASE1_1 ESSBASE1_1kent  # PID = 08745
    
    ...
    

    它也挂了。

  • 看样子pflags,它似乎正在睡觉。

    bash-3.2$ pflags 08745
    8745:   cp ESSBASE1_1 ESSBASE1_1kent
            data model = _ILP32  flags = MSACCT|MSFORK
    /1:    flags = ASLEEP  read(0x3,0xffbf6bc8,0x8000)
    
  • 搜索使用该文件的所有其他进程

    bash-3.2$ fuser -f /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
    /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1:     8745o   25057o
    

    请注意,“o”表示进程正在使用该文件作为打开的文件。

  • 在进程中查找:

    bash-3.2$ pstree | grep 8745
     | | |       |--- 09695 kent grep 8745
     | |         \--- 08745 kent cp ESSBASE1_1 ESSBASE1_1kent
    bash-3.2$ pstree | grep 25057
     | | |       \--- 09700 kent grep 25057
     | |   |-+- 25057 kent 86:43 /some/path/Oracle/Middlewa
    

    PID 25057 的进程是服务器进程。

  • 打开的文件位于安装点上。这是一个NAS磁盘。

    bash-3.2$ cat /etc/mnttab | grep apps
    server1.com:/vol/server1_nec_nosnap0/dev_apps   /source/path/       nfs     rw,xattr,dev=5e40001    1362894854
    

  • 谁能帮我理解是什么导致复制命令冻结?
  • 我可以猜测该应用程序正在运行,并且可能会以某种方式阻止任何其他进程访问特定文件。
  • 但在这种情况下,我希望cp中止并抛出错误,而不是无限期地被阻止。
  • 根据更新,进程似乎PID=25057正在使用该文件作为打开的文件。但是为什么这会阻止cp命令呢?

答案1

如果您查看pfiles文件描述符 10 的输出,您会注意到该文件是 FIFO;p您列表中的类型也证明了这一点ls。 FIFO 的本质是读取会阻塞,除非另一个进程正在写入数据,这就是为什么cp在尝试读取其内容时会卡住的原因。

为了解决这个问题,您可以使用rsync复制目录树来代替。

rsync -a /source/path/Oracle /target/path

rsync它足够聪明,能够创建一个重复的 FIFO,而不是从原始的 FIFO 中读取。请注意,您没有指定Oracle目标,因为rsync将在那里创建目录。

相关内容