PrivCopyFileExW Ошибка в Windows? - PullRequest
4 голосов
/ 19 марта 2012

Я выполняю много параллельных вызовов robocopy для копирования файлов из одного сетевого ресурса в один каталог. Поскольку файлы доступны только для чтения, я приказываю robocopy убрать атрибут только для чтения в целевом каталоге через / A-: R. Похоже, что на некоторых компьютерах (12 или более) целевой каталог! блокируется на срок до 16 секунд.

Эта проблема возникает, когда выполняются параллельные задачи MSBuild и задача CopyFile выполняется для файлов только для чтения. Это также происходит, когда выполняется robocopy для параллельной загрузки зависимостей для сборки TFS из общего сетевого ресурса. Поскольку все эти проблемы указывают на CopyFile kernel32 (или его частную реализацию), я подозреваю, что проблема связана с тем, как Windows копирует файлы.

Похоже, что это не является общей проблемой в ядре, поскольку временная папка основана на том факте, что параллельный доступ к каталогу должен быть возможен. Но реализация пользовательского режима внутри kernel32.dll в CopyFile кажется некорректной.

Обновление 2 С воспроизведением ниже это происходит независимо от того, доступен ли файл только для чтения или нет.

Обновление 3 Это воспроизведение также показывает ту же проблему в Windows 8.

Трассировки стека procmon действительно показывают, что магия происходит в kernel32.dll внутри PrivCopyFileExW, который кажется довольно недокументированным. Там выдается IRP_MJ_CREATE , чтобы открыть каталог, а чуть позже каталог закрывается. По-видимому, это является основной причиной состояния гонки, когда многие параллельные процессы Robocopy пытаются скопировать файлы в один каталог.

Вот несколько выводов procmon о том, как выглядит эта проблема.

С какой стати PrivCopyFileExW удается заблокировать каталог? Файловая система должна поддерживать копирование файлов в один каталог. Я использую Windows Server 2008 R2 и некоторые новейшие многоядерные машины с RAID-массивами, твердотельными накопителями и тому подобным.

Похоже, это связано с сообщениями о проблемах с CopyFile в kernel32.dll , которые до сих пор не решены. Я могу исключить антивирусные сканеры, потому что это также происходит на компьютерах, которые не установлены.

Обновление 1

Кажется, что другой процесс robocopy пытается скопировать файл в каталог назначения, который открывает каталог

Date & Time:    20.03.2012 08:30:06
Event Class:    File System
Operation:  CreateFile
Result: SUCCESS
Path:   C:\temp\dest
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:\Windows\system32\drivers\fltmgr.sys
1   fltmgr.sys  FltpPassThroughInternal + 0x4a  0xfffff880010478ca  C:\Windows\system32\drivers\fltmgr.sys
2   fltmgr.sys  FltpCreate + 0x293  0xfffff880010652a3  C:\Windows\system32\drivers\fltmgr.sys
3   ntoskrnl.exe    IopParseDevice + 0x5a7  0xfffff800031cb537  C:\Windows\system32\ntoskrnl.exe
4   ntoskrnl.exe    ObpLookupObjectName + 0x585 0xfffff800031c1ba4  C:\Windows\system32\ntoskrnl.exe
5   ntoskrnl.exe    ObOpenObjectByName + 0x1cd  0xfffff800031c6b7d  C:\Windows\system32\ntoskrnl.exe
6   ntoskrnl.exe    IopCreateFile + 0x2b7   0xfffff800031cd647  C:\Windows\system32\ntoskrnl.exe
7   ntoskrnl.exe    NtCreateFile + 0x78 0xfffff800031d7398  C:\Windows\system32\ntoskrnl.exe
8   ntoskrnl.exe    KiSystemServiceCopyEnd + 0x13   0xfffff80002eca813  C:\Windows\system32\ntoskrnl.exe
9   ntdll.dll   NtCreateFile + 0xa  0x7718fc0a  C:\Windows\System32\ntdll.dll
10  kernel32.dll    BaseCopyStream + 0x11a9 0x77034b89  C:\Windows\System32\kernel32.dll
11  kernel32.dll    BasepCopyFileExW + 0x545    0x77033d85  C:\Windows\System32\kernel32.dll
12  kernel32.dll    PrivCopyFileExW + 0xb6  0x770b5296  C:\Windows\System32\kernel32.dll
13  Robocopy.exe    CZDir::CopyData + 0xb5  0xff8623a9  C:\Windows\System32\Robocopy.exe
14  Robocopy.exe    RoboCopyDir + 0xe4  0xff85af00  C:\Windows\System32\Robocopy.exe
15  Robocopy.exe    Walk + 0x12a    0xff85c6b6  C:\Windows\System32\Robocopy.exe
16  Robocopy.exe    wmain + 0x4f4   0xff85de78  C:\Windows\System32\Robocopy.exe
17  Robocopy.exe    operator+ + 0x19b   0xff867be5  C:\Windows\System32\Robocopy.exe
18  kernel32.dll    BaseThreadInitThunk + 0xd   0x7703f33d  C:\Windows\System32\kernel32.dll
19  ntdll.dll   RtlUserThreadStart + 0x1d   0x77172ca1  C:\Windows\System32\ntdll.dll

Другой robocopy хочет проверить, существует ли файл, и вызывает FindFirstFile, что также приводит к открытию каталога и полному совместному использованию.

Date & Time:    20.03.2012 08:30:06
Event Class:    File System
Operation:  CreateFile
Result: SHARING VIOLATION
Path:   C:\temp\dest
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:\Windows\system32\drivers\fltmgr.sys
1   fltmgr.sys  FltpPassThroughInternal + 0x4a  0xfffff880010478ca  C:\Windows\system32\drivers\fltmgr.sys
2   fltmgr.sys  FltpCreate + 0x293  0xfffff880010652a3  C:\Windows\system32\drivers\fltmgr.sys
3   ntoskrnl.exe    IopParseDevice + 0x5a7  0xfffff800031cb537  C:\Windows\system32\ntoskrnl.exe
4   ntoskrnl.exe    ObpLookupObjectName + 0x585 0xfffff800031c1ba4  C:\Windows\system32\ntoskrnl.exe
5   ntoskrnl.exe    ObOpenObjectByName + 0x1cd  0xfffff800031c6b7d  C:\Windows\system32\ntoskrnl.exe
6   ntoskrnl.exe    IopCreateFile + 0x2b7   0xfffff800031cd647  C:\Windows\system32\ntoskrnl.exe
7   ntoskrnl.exe    NtOpenFile + 0x58   0xfffff800031e64a8  C:\Windows\system32\ntoskrnl.exe
8   ntoskrnl.exe    KiSystemServiceCopyEnd + 0x13   0xfffff80002eca813  C:\Windows\system32\ntoskrnl.exe
9   ntdll.dll   NtOpenFile + 0xa    0x7718f9ea  C:\Windows\System32\ntdll.dll
10  KernelBase.dll  FindFirstFileExW + 0x1ee    0x7fefd3a560e   C:\Windows\System32\KernelBase.dll
11  KernelBase.dll  FindFirstFileW + 0x1c   0x7fefd3a58dc   C:\Windows\System32\KernelBase.dll
12  Robocopy.exe    CZDir::Exists + 0xf7    0xff861bb7  C:\Windows\System32\Robocopy.exe
13  Robocopy.exe    RoboCopyDir + 0x58  0xff85ae74  C:\Windows\System32\Robocopy.exe
14  Robocopy.exe    Walk + 0x12a    0xff85c6b6  C:\Windows\System32\Robocopy.exe
15  Robocopy.exe    wmain + 0x4f4   0xff85de78  C:\Windows\System32\Robocopy.exe
16  Robocopy.exe    operator+ + 0x19b   0xff867be5  C:\Windows\System32\Robocopy.exe
17  kernel32.dll    BaseThreadInitThunk + 0xd   0x7703f33d  C:\Windows\System32\kernel32.dll
18  ntdll.dll   RtlUserThreadStart + 0x1d   0x77172ca1  C:\Windows\System32\ntdll.dll

Я могу легко воспроизвести это и в Windows 7. Вам нужно только скопировать файлы только для чтения из двух параллельных вызовов robocopy в один и тот же каталог в цикле и подождать, пока это произойдет (около 30 с).

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

Вы можете поместить только один файл только для чтения в исходные каталоги, чтобы получить быструю копию и много одновременных обращений к каталогам. Является ли это известным ограничением Windows, запрещающим доступ к каталогу во время копирования в него файла?

Мое необразованное мнение заключается в том, что это ошибка, и она может стать довольно неприятной, если вам нужен надежный параллельный доступ к файлам.

1 Ответ

1 голос
/ 09 мая 2012

Похоже, что мы наконец-то получили исправление от MS для этой проблемы.Они нашли и поняли проблему.Но это займет некоторое время, пока исправление не будет официально подготовлено.В настоящее время это будет исправлено только для Windows 7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...