winapi - PrivCopyFileExW fejl i Windows?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg udsteder mange parallelle robokopkald til at kopiere filer fra et netværk til en enkelt mappe. Da filerne kun er læst, fortæller jeg robocopy at fjerne den skrivebeskyttede attribut i målkataloget via/A-: R. Det ser ud til, at på nogle mange kernemaskiner (12 eller flere) målkataloget! bliver låst i op til 16'erne.


Dette problem er overfladen, når samtidige MSBuild-opgaver kører, og CopyFile-opgaven udføres på skrivebeskyttede filer. Det sker også, når robocopy udføres for at downloade afhængigheder for en TFS, der bygger parallelt fra en netværksandel. Da alle disse problemer peger på kernel32 CopyFile (eller dens private implementering), formoder jeg, at problemet er relateret til, hvordan Windows kopierer filer.


Dette ser ikke ud til at være et generelt problem i kernen, da temp-mappen lever af, at samtidig adgang til en mappe skal være mulig. Men implementeringen af ​​brugerens tilstand inden for kernel32.dll af CopyFile synes at være fejlbehæftet.


Opdater 2
Med repro nedenfor sker dette uanset om filen kun er læst eller ej.


Opdater 3
Denne repro viser også det samme problem på Windows 8.


Promon-stack-sporene viste, at magien sker i kernel32.dll inde
PrivCopyFileExW, som synes at være ret utokumenteret. Der udstedes et IRP\_MJ\_CREATE opkald for at åbne mappen, og lidt senere er mappen lukket. Dette ser ud til at være årsagen til løbstilstanden, når mange parallelle robokopiske processer forsøger at kopiere filer til en mappe. [4]


Her er nogle procmon output, hvordan dette problem føles. [5]


Hvorfor på jorden klarer PrivCopyFileExW at låse biblioteket? Et filsystem skal kunne understøtte kopiering af filer til en mappe. Jeg bruger Windows Server 2008 R2 og nogle nyere multi kerner maskiner med RAID arrayer, SSD'er og sådanne ting.


Dette ser ud til at være relateret til rapporterede problemer med CopyFile i kernel32.dll, som ikke er løst indtil i dag. Jeg kan udelukke virus scannere, fordi det også sker på maskiner, som ingen har installeret. [6]


Opdater 1


Det ser ud til, at en anden robokopieringsproces forsøger at kopiere en fil til destinationsmappen, som åbner biblioteket


Date & Time:    20.03.2012 08:30:06
Event Class:    File System
Operation:  CreateFile
Result: SUCCESS
Path:   C:	empdest
TID:    11672
Duration:   0.0000150
Desired Access: Read Data/List Directory, Write Data/Add File, Write EA, Read Attributes, Write Attributes, Delete, Synchronize
Disposition:    OpenIf
Options:    Directory, Synchronous IO Non-Alert, Open For Backup
Attributes: D
ShareMode:  None  <---- No sharing
AllocationSize: 0
OpenResult: Opened

0   fltmgr.sys  FltpPerformPreCallbacks + 0x2f7 0xfffff88001045027  C:Windowssystem32driversfltmgr.sys
1   fltmgr.sys  FltpPassThroughInternal + 0x4a  0xfffff880010478ca  C:Windowssystem32driversfltmgr.sys
2   fltmgr.sys  FltpCreate + 0x293  0xfffff880010652a3  C:Windowssystem32driversfltmgr.sys
3   ntoskrnl.exe    IopParseDevice + 0x5a7  0xfffff800031cb537  C:Windowssystem32
toskrnl.exe
4   ntoskrnl.exe    ObpLookupObjectName + 0x585 0xfffff800031c1ba4  C:Windowssystem32
toskrnl.exe
5   ntoskrnl.exe    ObOpenObjectByName + 0x1cd  0xfffff800031c6b7d  C:Windowssystem32
toskrnl.exe
6   ntoskrnl.exe    IopCreateFile + 0x2b7   0xfffff800031cd647  C:Windowssystem32
toskrnl.exe
7   ntoskrnl.exe    NtCreateFile + 0x78 0xfffff800031d7398  C:Windowssystem32
toskrnl.exe
8   ntoskrnl.exe    KiSystemServiceCopyEnd + 0x13   0xfffff80002eca813  C:Windowssystem32
toskrnl.exe
9   ntdll.dll   NtCreateFile + 0xa  0x7718fc0a  C:WindowsSystem32
tdll.dll
10  kernel32.dll    BaseCopyStream + 0x11a9 0x77034b89  C:WindowsSystem32kernel32.dll
11  kernel32.dll    BasepCopyFileExW + 0x545    0x77033d85  C:WindowsSystem32kernel32.dll
12  kernel32.dll    PrivCopyFileExW + 0xb6  0x770b5296  C:WindowsSystem32kernel32.dll
13  Robocopy.exe    CZDir::CopyData + 0xb5  0xff8623a9  C:WindowsSystem32Robocopy.exe
14  Robocopy.exe    RoboCopyDir + 0xe4  0xff85af00  C:WindowsSystem32Robocopy.exe
15  Robocopy.exe    Walk + 0x12a    0xff85c6b6  C:WindowsSystem32Robocopy.exe
16  Robocopy.exe    wmain + 0x4f4   0xff85de78  C:WindowsSystem32Robocopy.exe
17  Robocopy.exe    operator+ + 0x19b   0xff867be5  C:WindowsSystem32Robocopy.exe
18  kernel32.dll    BaseThreadInitThunk + 0xd   0x7703f33d  C:WindowsSystem32kernel32.dll
19  ntdll.dll   RtlUserThreadStart + 0x1d   0x77172ca1  C:WindowsSystem32
tdll.dll


Den anden robokopi vil kontrollere, om filen allerede eksisterer, og kalder FindFirstFile, der fører til at åbne mappen også med fuld deling.


Date & Time:    20.03.2012 08:30:06
Event Class:    File System
Operation:  CreateFile
Result: SHARING VIOLATION
Path:   C:	empdest
TID:    8280
Duration:   0.0000099
Desired Access: Read Data/List Directory, Synchronize
Disposition:    Open
Options:    Directory, Synchronous IO Non-Alert
Attributes: n/a
ShareMode:  Read, Write, Delete <----- Full sharing
AllocationSize: n/a

0   fltmgr.sys  FltpPerformPreCallbacks + 0x2f7 0xfffff88001045027  C:Windowssystem32driversfltmgr.sys
1   fltmgr.sys  FltpPassThroughInternal + 0x4a  0xfffff880010478ca  C:Windowssystem32driversfltmgr.sys
2   fltmgr.sys  FltpCreate + 0x293  0xfffff880010652a3  C:Windowssystem32driversfltmgr.sys
3   ntoskrnl.exe    IopParseDevice + 0x5a7  0xfffff800031cb537  C:Windowssystem32
toskrnl.exe
4   ntoskrnl.exe    ObpLookupObjectName + 0x585 0xfffff800031c1ba4  C:Windowssystem32
toskrnl.exe
5   ntoskrnl.exe    ObOpenObjectByName + 0x1cd  0xfffff800031c6b7d  C:Windowssystem32
toskrnl.exe
6   ntoskrnl.exe    IopCreateFile + 0x2b7   0xfffff800031cd647  C:Windowssystem32
toskrnl.exe
7   ntoskrnl.exe    NtOpenFile + 0x58   0xfffff800031e64a8  C:Windowssystem32
toskrnl.exe
8   ntoskrnl.exe    KiSystemServiceCopyEnd + 0x13   0xfffff80002eca813  C:Windowssystem32
toskrnl.exe
9   ntdll.dll   NtOpenFile + 0xa    0x7718f9ea  C:WindowsSystem32
tdll.dll
10  KernelBase.dll  FindFirstFileExW + 0x1ee    0x7fefd3a560e   C:WindowsSystem32KernelBase.dll
11  KernelBase.dll  FindFirstFileW + 0x1c   0x7fefd3a58dc   C:WindowsSystem32KernelBase.dll
12  Robocopy.exe    CZDir::Exists + 0xf7    0xff861bb7  C:WindowsSystem32Robocopy.exe
13  Robocopy.exe    RoboCopyDir + 0x58  0xff85ae74  C:WindowsSystem32Robocopy.exe
14  Robocopy.exe    Walk + 0x12a    0xff85c6b6  C:WindowsSystem32Robocopy.exe
15  Robocopy.exe    wmain + 0x4f4   0xff85de78  C:WindowsSystem32Robocopy.exe
16  Robocopy.exe    operator+ + 0x19b   0xff867be5  C:WindowsSystem32Robocopy.exe
17  kernel32.dll    BaseThreadInitThunk + 0xd   0x7703f33d  C:WindowsSystem32kernel32.dll
18  ntdll.dll   RtlUserThreadStart + 0x1d   0x77172ca1  C:WindowsSystem32
tdll.dll


Jeg kan også repro dette nemt på Windows 7. Du skal kun kopiere skrivebeskyttede filer fra to parallelle robocopyopkald til samme mappe i en loop og vente, indtil det sker (ca. 30 sekunder).


for /L \%i in (1,1,1000) do robocopy /E /XO /COPY:DAT /A-:R C:ReadOnlySource1  c:	empdest
for /L \%i in (1,1,1000) do robocopy /E /XO /COPY:DAT /A-:R C:ReadOnlySource2  c:	empdest


Du kan kun sætte en læste fil i kildekatalogerne for at få en hurtig kopi og mange samtidige mapper. Er dette en kendt begrænsning af Windows for ikke at tillade adgang til en mappe, mens en fil kopieres til den?


Min uudviklede mening er, at dette er en fejl, og det kan blive ret ubehageligt, når du ønsker samtidig adgang til filer på en pålidelig måde.

Bedste reference


Det ser ud til, at vi endelig får en løsning fra MS til dette problem. De har fundet og forstået problemet. Men det tager lidt tid, før reparationen er officielt forberedt. I øjeblikket vil det kun blive fastsat for Windows 7.