Duplicación de identificadores de socket para una SAN
Varias aplicaciones que se ejecutan en procesos diferentes pueden usar el conmutador Windows Sockets para realizar operaciones en un socket subyacente compartido. Sin embargo, solo una aplicación a la vez puede realizar operaciones en ese socket subyacente compartido.
Para usar un socket subyacente compartido, una aplicación debe recuperar un identificador duplicado en ese socket subyacente de una de las maneras siguientes:
Directamente, llamando a la función WSADuplicateSocket de Windows Sockets
La llamada se realiza en el contexto del proceso de control (el proceso en el que se creó el socket).
Indirectamente, llamando a la función DuplicateHandle de Win32
La llamada se realiza en el contexto de un proceso de no control (distinto del proceso en el que se creó el socket).
Uso del mecanismo de herencia de identificadores
Un proceso secundario (el proceso de no control) hereda todos o algunos de los identificadores creados en su proceso primario (el proceso de control).
Durante el cierre de la conexión correcta
Si una aplicación del proceso de control cierra un socket y sale mientras algunos datos siguen siendo enviados, estos datos restantes se almacenarán en búfer en el archivo DLL de Windows Sockets. Otra aplicación en el contexto del proceso de servicio del sistema (el proceso de no control) envía posteriormente estos datos.
El conmutador Windows Sockets, junto con el proveedor TCP/IP, detecta y controla cada una de las condiciones anteriores. El modificador solo permite un proceso a la vez ejecutar operaciones que transfieren datos o cambian el estado de un socket compartido subyacente. Procesa dinámicamente el control del socket subyacente, según sea necesario, para ejecutar las operaciones solicitadas. El modificador serializa las operaciones que los distintos procesos solicitan realizar en un socket compartido y ejecuta esas operaciones en orden primero en salir (FIFO). El modificador espera a que se completen todas las operaciones en curso antes de intercambiar el control de un socket subyacente a otro proceso. Lógicamente, el conmutador quita el control del socket subyacente del proceso de control en cuanto un proceso no de control solicita una operación apta. Después de quitar el control, el conmutador trata el proceso de control original como un proceso de no control si el proceso de control original solicita operaciones aptas. Tenga en cuenta que el conmutador no realiza ninguna acción en un controlador de socket duplicado hasta que el proceso de no control usa realmente el identificador de socket duplicado para una operación de transferencia de datos o cambio de estado.
Tanto el conmutador como el proveedor de servicios SAN adecuado se cargan en todos los procesos que comparten el acceso a un socket subyacente determinado. El modificador mantiene su propio contexto de socket y información de estado de conexión en todos los procesos que comparten el socket. El proveedor de servicios SAN es necesario para mantener su información de estado de conexión y contexto de socket solo en el proceso que tiene control del socket subyacente en cualquier momento dado. El proveedor de servicios SAN debe intercambiar el control de su información de estado de conexión y contexto del proceso de control actual al siguiente proceso de control siempre que el conmutador requiera el intercambio, tal como se describe en la siguiente secuencia. Para minimizar la cantidad de recursos necesarios para el intercambio, un proveedor de servicios SAN puede mantener su información de contexto y estado de conexión en todos los procesos que comparten un socket subyacente.
Dado que el conmutador no crea el socket SAN que corresponde a un socket de aplicación hasta que una aplicación llama a la función connect o listen , el conmutador no puede solicitar que el proveedor de servicios SAN realice una operación de intercambio antes de que el socket de aplicación esté conectado o escuchando. Incluso después de que el socket de aplicación esté conectado o escuchando, se debe cumplir una de las siguientes condiciones antes de que el conmutador solicite que el proveedor de servicios SAN cambie el control del socket:
Un proceso que no controla el socket inicia una transferencia de datos. El proveedor de servicios SAN no intercambia el control del socket hasta que se hayan completado todas las operaciones de transferencia de datos iniciadas por el proceso de control.
Un proceso que no controla el socket llama a la función WSAAccept, WSPAccept o AcceptEx para iniciar una operación de aceptación de conexión en un socket de escucha. El proveedor de servicios SAN no intercambia el control del socket hasta que se hayan completado todas las solicitudes de aceptación iniciadas por el proceso de control.
El modificador realiza los pasos siguientes para intercambiar el control de un socket SAN conectado desde el proceso de control al proceso de control siguiente (para obtener información general sobre el proceso de intercambio, consulte la tabla de la sección Comentarios de la documentación de la función WSPDuplicateSocket ).
El modificador suspende el procesamiento de nuevas solicitudes de la aplicación en el proceso de control. Cuando se han completado todas las operaciones de envío y RDMA en el socket SAN, el modificador llama a la función WSPSend del proveedor de servicios SAN para enviar un mensaje a un elemento del mismo nivel conectado para solicitar una suspensión de la sesión y llama a la función WSPDeregisterMemory del proveedor de servicios SAN para liberar todos los búferes locales usados para las operaciones de envío. Como resultado, el conmutador en la conexión del mismo nivel suspende el procesamiento de nuevas solicitudes de aplicación, espera a que todas las operaciones de envío y RDMA en curso en el socket SAN se completen y libera toda la memoria RDMA. A continuación, la conexión del mismo nivel envía un mensaje de respuesta que indica que la sesión está suspendida. Al recibir este mensaje de confirmación, el modificador en el punto de conexión local llama a la función WSPDeregisterRdmaMemory del proveedor de servicios SAN para liberar toda la memoria RDMA. En este momento, los sockets SAN en ambos puntos de conexión solo pueden tener solicitudes de recepción pendientes. Estas solicitudes de recepción permanecen pendientes en el socket SAN del mismo nivel remoto para permitir la reactivación de la sesión. Las solicitudes de recepción en el socket SAN local del proceso de control se completan en el paso siguiente. Mientras se suspende la conexión, el modificador de la conexión remota del mismo nivel pone en cola nuevas solicitudes de bloqueo o superpuestas, almacena en búfer nuevos envíos que no se bloquean hasta la configuración de SO_SNDBUF, produce un error en los nuevos envíos que no se bloquean después de alcanzar el límite de búfer y se produce un error en todas las nuevas recepciones sin bloqueo con WSAEWOULDBLOCK. El conmutador local del proceso de control controla las nuevas solicitudes en el socket de aplicación como si el proceso no tuviera control del socket.
Una vez suspendida la sesión, el modificador llama a la función WSPDuplicateSocket del proveedor de servicios SAN en el proceso de control para dirigir al proveedor de servicios SAN para transferir el contexto del socket al espacio de direcciones del proceso de control siguiente. El modificador especifica el proceso de control siguiente en el parámetro dwProcessId de WSPDuplicateSocket. La función WSPDuplicateSocket debe llamar a la función WPUCompleteOverlappedRequest para completar todas las solicitudes de recepción pendientes en el socket con un estado correcto y cero bytes. El proveedor de servicios SAN también debe liberar automáticamente todos los búferes asociados a estas solicitudes. El proveedor de servicios SAN libera todos los búferes, ya que el modificador no solicita más operaciones en el socket SAN después de que WSPDuplicateSocket devuelva. La única excepción posible es una llamada de función WSPCloseSocket , como se describe en el paso siguiente. Después de que WSPDuplicateSocket devuelva, el modificador guarda el valor en el miembro dwProviderReserved de la estructura WSAPROTOCOL_INFOW a la que apunta el parámetro de salida lpProtocolInfo . El modificador usa este valor para identificar el socket subyacente en el contexto del proceso de control siguiente. Por lo tanto, el valor de dwProviderReserved debe identificar de forma única el socket subyacente y la conexión de ese socket en todos los procesos del sistema. Además, este valor solo debe ser válido en el contexto del proceso que el modificador especificado en el parámetro dwProcessId de WSPDuplicateSocket.
Después de transferir el contexto del socket al espacio de direcciones del proceso de control siguiente, el conmutador llama a la función WSPSocket del proveedor de servicios SAN en el contexto del proceso de control siguiente. En esta llamada, el modificador pasa el valor del socket subyacente que se devolvió en la llamada WSPDuplicateSocket al miembro dwProviderReserved de la estructura WSAPROTOCOL_INFOW a la que apunta el parámetro de entrada lpProtocolInfo . Si el siguiente proceso de control no solicitó la creación del socket SAN, el proveedor de servicios SAN debe crear un nuevo socket y llamar a la función WPUCreateSocketHandle para obtener un identificador, según sea necesario para cualquier socket nuevo. Si el socket SAN se creó en el contexto del proceso de control siguiente, el proveedor de servicios SAN puede reactivar el socket anterior y devolver el mismo descriptor para el socket que se usó anteriormente. En este caso, el proveedor de servicios SAN no debe llamar a WPUCreateSocketHandle, pero debe seguir usando el identificador de socket original que proporcionó el conmutador. Como alternativa, el proveedor de servicios SAN puede crear un nuevo socket, independientemente de si un socket existía anteriormente en el proceso. En este caso, el modificador debe llamar a la función WSPCloseSocket del proveedor de servicios SAN en el contexto del proceso de control siguiente para eliminar el descriptor de socket anterior.
El modificador reinicia el procesamiento de nuevas solicitudes de la aplicación en el proceso de control siguiente.
El modificador duplica un socket de escucha de forma similar, salvo que el modificador no es necesario para suspender una sesión. El modificador espera hasta que completa todas las llamadas WSPAccept iniciadas por las llamadas accept y AcceptEx de una aplicación antes de llamar a la función WSPDuplicateSocket del proveedor de servicios SAN en el proceso de control.
Dado que el conmutador suspende el procesamiento de nuevas solicitudes en un socket SAN antes de llamar a la función WSPDuplicateSocket del proveedor de servicios SAN, el proveedor de servicios SAN puede liberar todos los recursos asociados a un punto de conexión local en el proceso de control. El proveedor de servicios SAN puede incluso finalizar una conexión subyacente. Si el proveedor de servicios SAN cierra una conexión subyacente en el proceso de control, el proveedor de servicios SAN debe restablecer la conexión después de que el modificador llame a la función WSPSocket del proveedor de servicios SAN dentro del proceso de control siguiente. Después de que se devuelva la llamada WSPSocket , el socket SAN dentro del proceso de control siguiente debe estar en el mismo estado, desde la perspectiva del conmutador, ya que el socket SAN en el proceso de control era anterior al conmutador que llama a la función WSPDuplicateSocket del proveedor de servicios SAN.
Si una NIC de SAN admite el uso compartido de recursos entre puntos de conexión que se ejecutan en procesos diferentes, el proveedor de servicios SAN no tiene que liberar recursos para un punto de conexión local en el proceso de control antes de recibir una llamada WSPDuplicateSocket . En tal caso, el socket SAN asociado a un punto de conexión local permanece inactivo en el proceso de control anterior hasta que el modificador intercambia el contexto del socket desde el siguiente proceso de control o llama a la función WSPCloseSocket del proveedor de servicios SAN para cerrar explícitamente el socket. Dado que la mayoría de las aplicaciones realizan su acceso final al socket en el proceso que originalmente lo creó,generalmente para cerrar la conexión, el proveedor de servicios SAN puede mejorar el rendimiento si el proveedor de servicios SAN conserva el contexto de socket en el proceso de control después de que el conmutador intercambia el control del socket al proceso de control siguiente.
Tenga en cuenta que, en todos los casos, un descriptor de socket SAN debe permanecer válido hasta que el modificador llame a la función WSPCloseSocket del proveedor de servicios SAN para cerrar explícitamente el socket. Incluso si el proveedor de servicios SAN libera todos los recursos del socket en un proceso determinado antes de recibir una llamada WSPDuplicateSocket , el proveedor de servicios SAN no debe reutilizar el descriptor del socket hasta que el conmutador llame a WSPCloseSocket en ese descriptor.
Una salida de proceso inesperada o alguna otra condición de error puede interrumpir la operación de duplicación de sockets del proveedor de servicios SAN. Por ejemplo, una escasez de recursos puede provocar esta interrupción. El modificador trata estas condiciones de error, ya que realiza cualquier otra situación de error. Si es necesario, el modificador cierra todos los descriptores asociados al socket subyacente en todos los procesos para finalizar la conexión del socket de forma forzada. Si es posible, el proveedor de servicios SAN del mismo nivel remoto debe completar las llamadas WSPRecv que reciben datos entrantes con un código de error adecuado, como WSAECONNRESET. Este código de error informa al mismo nivel remoto de la terminación de la conexión. Si el conmutador del mismo nivel remoto no recibe esta indicación de terminación de conexión, el conmutador en el mismo nivel remoto agota el tiempo de espera de una conexión suspendida si se produce un error en el sistema que solicitó la suspensión.