У нас проблема с общим доступом к файлам, когда процессы на нескольких хостах обращаются к одному и тому же файлу. Все хосты работают под управлением одной и той же версии Windows 2012 R2. (узел A, упомянутый ниже, является узлом в отказоустойчивом кластере HA, не уверен, что это актуально.) Один из наших сервисных инженеров смог перехватить журнал Wireshark, когда возникла проблема. Из журналов я могу следить за сообщениями smb2 и видеть, что:
- write_process на хосте A создает пустой файл (smb2 Создание запроса / ответа и обмен закрытыми запросами / ответами)
- read_processна хосте B получить доступ к файлу (smb2 Создать запрос / ответ; создать с опцией блокировки аренды)
- read_process на хосте C получить доступ к файлу (smb2 Создать запрос / ответ; создать с опцией аренды)
В этот момент хосты B и C не отправили SMB2 close, даже если файл был закрыт из кода в read_processes, но закрытие SMB2 не отправлено из-за оппортунистической блокировки. Теперь write_process на хосте A хочет выполнить запись в файл, но запрос Create постоянно получает статус NT: STATUS_SHARING_VIOLATION (0xc0000043)
Интересно то, что я вижу в том же Wireshark другой доступ к файлу, который работает, как и ожидалось:
- write_process на хосте A создает пустой файл (smb2 Создает запрос / ответ и обменивается запросом на запрос / ответом)
- read_process на хосте C обращается к файлу (smb2 Create Request / Response; создать с опцией аренды)
- write_process на хосте A хочет получить доступ к файлу (smb2 Создать запрос отправлен)
- smb2 сообщение об остановке аренды отправлено на хост C
- хост C закрываетfile
- процесс записи на хост A получает доступ (smb2 Create Reponse отправляется на хост A)
Прежде чем увидеть второй, успешный пример, у меня была теория, что проблема заключалась в том, что хостДоступ к файлу без оплок. Но я бы сейчас исключил эту теорию.
Вот как выглядит запрос на создание с хоста A:
Frame 14521: 416 bytes on wire (3328 bits), 416 bytes captured (3328 bits) on interface 6
Null/Loopback
Internet Protocol Version 4, Src: <ip A>, Dst: <ip D>
Transmission Control Protocol, Src Port: 50198, Dst Port: 445, Seq: 3973846, Ack: 68498, Len: 372
NetBIOS Session Service
SMB2 (Server Message Block Protocol version 2)
SMB2 Header
Server Component: SMB2
Header Length: 64
Credit Charge: 1
Channel Sequence: 0
Reserved: 0000
Command: Create (5)
Credits requested: 1536
Flags: 0x00000008, Signing
Chain Offset: 0x00000000
Message ID: Unknown (811455)
Process Id: 0x0000feff
Tree Id: 0x001c0025 <share name>
Session Id: 0x0008500d64000069
Signature: a8ac43ccf4b4d59f2fb9b930ea01c421
[Response in: 14523]
Create Request (0x05)
StructureSize: 0x0039
Oplock: No oplock (0x00)
Impersonation level: Impersonation (2)
Create Flags: 0x0000000000000000
Reserved: 0000000000000000
Access Mask: 0x00120089
File Attributes: 0x00000080
Share Access: 0x00000003, Read, Write
Disposition: Create (if file exists fail, else create it) (2)
Create Options: 0x00000060
Filename: <filename>
ExtraInfo SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST SMB2_CREATE_QUERY_ON_DISK_ID
Запрос на создание с хоста C выглядит следующим образом:
Frame 16263: 502 bytes on wire (4016 bits), 502 bytes captured (4016 bits) on interface 0
Ethernet II, Src: Cisco_a5:07:01 (00:24:14:a5:07:01), Dst: HewlettP_7a:d4:58 (14:02:ec:7a:d4:58)
Internet Protocol Version 4, Src: <ip C>, Dst: <ip D>
Transmission Control Protocol, Src Port: 51747, Dst Port: 445, Seq: 29594, Ack: 5030645, Len: 448
NetBIOS Session Service
SMB2 (Server Message Block Protocol version 2)
SMB2 Header
Server Component: SMB2
Header Length: 64
Credit Charge: 1
Channel Sequence: 0
Reserved: 0000
Command: Create (5)
Credits requested: 0
Flags: 0x00000008, Signing
Chain Offset: 0x00000000
Message ID: Unknown (2340656)
Process Id: 0x0000feff
Tree Id: 0x001c0029 <share name>
Session Id: 0x0008500b7c000d81
Signature: ff6476de30378d5fbba4f438c2168510
[Response in: 16304]
Create Request (0x05)
StructureSize: 0x0039
Oplock: Lease (0xff)
Impersonation level: Anonymous (0)
Create Flags: 0x0000000000000000
Reserved: 0000000000000000
Access Mask: 0x00120089
File Attributes: 0x00000000
Share Access: 0x00000005, Read, Delete
Disposition: Open (if file exists open it, else fail) (1)
Create Options: 0x00400060
Filename: <filename>
Offset: 0x00000078
Length: 140
ExtraInfo SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST SMB2_CREATE_QUERY_ON_DISK_ID SMB2_CREATE_REQUEST_LEASE
Offset: 0x00000108
Length: 180
Chain Element: SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 "DH2Q"
Chain Element: SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc"
Chain Element: SMB2_CREATE_QUERY_ON_DISK_ID "QFid"
Chain Element: SMB2_CREATE_REQUEST_LEASE "RqLs"
Есть идеи, почему взлом оплока работает в одном случае, а не в другом?