Solaris

是什麼導致此 Copy 命令進入睡眠狀態?

  • June 6, 2013

我正在嘗試以遞歸方式複制超過 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命令呢?

如果您查看pfiles文件描述符 10 的輸出,您會注意到該文件是一個 FIFO;pls列表中的類型也證明了這一點。FIFO 的本質是除非另一個程序正在寫入數據,否則讀取將阻塞,這就是為什麼您cp在嘗試讀取其內容時會卡住的原因。

要解決此問題,您可以使用rsync複制目錄樹來代替。

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

rsync足夠聰明,可以製作一個重複的 FIFO,而不是從原始的 FIFO 中讀取。請注意,您沒有指定Oracle目標,因為rsync將在那裡創建目錄。

引用自:https://unix.stackexchange.com/questions/78359