Duplication de handles de socket pour un SAN
Plusieurs applications qui s’exécutent dans différents processus peuvent utiliser le commutateur Windows Sockets pour effectuer des opérations sur un socket sous-jacent partagé. Toutefois, une seule application à la fois peut effectuer des opérations sur ce socket sous-jacent partagé.
Pour utiliser un socket sous-jacent partagé, une application doit récupérer un handle en double sur ce socket sous-jacent de l’une des manières suivantes :
Directement, en appelant la fonction WSADuplicateSocket windows Sockets
L’appel est effectué dans le contexte du processus de contrôle (processus dans lequel le socket a été créé).
Indirectement, en appelant la fonction Win32 DuplicateHandle
L’appel est effectué dans le contexte d’un processus non contrôle (autre que le processus dans lequel le socket a été créé).
Utilisation du mécanisme d’héritage de handle
Un processus enfant (le processus non contrôlant) hérite de tout ou partie des handles créés dans son processus parent (le processus de contrôle).
Pendant la fermeture normale de la connexion
Si une application dans le processus de contrôle ferme un socket et se ferme alors que certaines données restent à envoyer, ces données restantes sont mises en mémoire tampon dans la DLL Windows Sockets. Une autre application dans le contexte du processus de service système (processus non contrôlable) envoie ensuite ces données.
Le commutateur Windows Sockets, conjointement avec le fournisseur TCP/IP, détecte et gère chacune des conditions précédentes. Le commutateur permet à un seul processus à la fois d’exécuter des opérations qui transfèrent des données ou modifient l’état d’un socket partagé sous-jacent. Traite le contrôle d’échange dynamique du socket sous-jacent, selon les besoins, pour exécuter les opérations demandées. Le commutateur sérialise les opérations que différents processus demandent à effectuer sur un socket partagé et exécute ces opérations dans l’ordre FIFO (premier entré, premier sorti). Le commutateur attend que toutes les opérations en cours se terminent avant de remplacer le contrôle d’un socket sous-jacent par un autre processus. Logiquement, le commutateur prend le contrôle du socket sous-jacent loin du processus de contrôle dès qu’un processus non contrôlant demande une opération éligible. Une fois le contrôle retiré, le commutateur traite le processus de contrôle d’origine comme un processus non contrôlant si le processus de contrôle d’origine demande des opérations éligibles. Notez que le commutateur n’effectue aucune action sur un handle de socket en double jusqu’à ce que le processus non contrôle utilise réellement le handle de socket en double pour une opération de transfert de données ou de changement d’état.
Le commutateur et le fournisseur de services SAN appropriés sont chargés dans tous les processus qui partagent l’accès à un socket sous-jacent particulier. Le commutateur conserve son propre contexte de socket et ses propres informations d’état de connexion dans tous les processus qui partagent le socket. Le fournisseur de services SAN est tenu de conserver son contexte de socket et ses informations d’état de connexion uniquement dans le processus qui a le contrôle du socket sous-jacent à un moment donné dans le temps. Le fournisseur de services SAN doit permuter le contrôle de son contexte et des informations d’état de connexion du processus de contrôle actuel vers le processus de contrôle suivant chaque fois que le commutateur nécessite l’échange, comme décrit dans la séquence suivante. Pour réduire la quantité de ressources requises pour l’échange, un fournisseur de services SAN peut conserver son contexte et ses informations d’état de connexion dans tous les processus qui partagent un socket sous-jacent.
Étant donné que le commutateur ne crée pas le socket SAN qui correspond à un socket d’application tant qu’une application n’appelle pas la fonction de connexion ou d’écoute, le commutateur ne peut pas demander au fournisseur de services SAN d’effectuer une opération d’échange avant que le socket d’application soit connecté ou à l’écoute. Même une fois le socket d’application connecté ou à l’écoute, l’une des conditions suivantes doit être remplie avant que le commutateur demande au fournisseur de services SAN de permuter le contrôle du socket :
Un processus qui ne contrôle pas le socket lance un transfert de données. Le fournisseur de services SAN ne permute pas le contrôle du socket tant que toutes les opérations de transfert de données initiées par le processus de contrôle ne sont pas terminées.
Un processus qui ne contrôle pas le socket appelle la fonction WSAAccept, WSPAccept ou AcceptEx pour démarrer une opération d’acceptation de connexion sur un socket d’écoute. Le fournisseur de services SAN ne permute pas le contrôle du socket tant que toutes les demandes d’acceptation initiées par le processus de contrôle ne sont pas terminées.
Le commutateur effectue les étapes suivantes pour permuter le contrôle d’un socket SAN connecté du processus de contrôle vers le processus de contrôle suivant (pour obtenir une vue d’ensemble du processus d’échange, consultez le tableau dans la section Remarques de la documentation relative à la fonction WSPDuplicateSocket .) :
Le commutateur suspend le traitement des nouvelles demandes de l’application dans le processus de contrôle. Lorsque toutes les opérations d’envoi et RDMA en cours sur le socket SAN sont terminées, le commutateur appelle la fonction WSPSend du fournisseur de services SAN pour envoyer un message à un homologue connecté afin de demander une suspension de la session et appelle la fonction WSPDeregisterMemory du fournisseur de services SAN pour libérer toutes les mémoires tampons locales utilisées pour les opérations d’envoi. Par conséquent, le commutateur au niveau de la connexion homologue interrompt le traitement des nouvelles demandes d’application, attend que toutes les opérations d’envoi et RDMA en cours sur le socket SAN se terminent et libère toute la mémoire RDMA. La connexion homologue envoie ensuite un message de réponse indiquant que la session est suspendue. À la réception de ce message de confirmation, le commutateur au niveau du point de terminaison local appelle la fonction WSPDeregisterRdmaMemory du fournisseur de services SAN pour libérer toute la mémoire RDMA. À ce stade, les sockets SAN aux deux points de terminaison de la connexion peuvent uniquement avoir des demandes de réception en attente. Ces demandes de réception restent en attente sur le socket SAN de l’homologue distant pour permettre la réactivation de la session. Les demandes de réception sur le socket SAN local dans le processus de contrôle sont effectuées à l’étape suivante. Pendant que la connexion est suspendue, le commutateur au niveau de la connexion homologue distante met en file d’attente les nouvelles demandes bloquantes ou superposées, met en mémoire tampon les nouvelles demandes non bloquantes envoyées jusqu’au paramètre SO_SNDBUF, échoue les nouveaux envois non bloquants une fois la limite de mémoire tampon atteinte et échoue toutes les nouvelles réceptions non bloquantes avec WSAEWOULDBLOCK. Le commutateur local dans le processus de contrôle gère les nouvelles requêtes sur le socket d’application comme si le processus n’avait pas le contrôle du socket.
Une fois la session suspendue, le commutateur appelle la fonction WSPDuplicateSocket du fournisseur de services SAN dans le processus de contrôle pour indiquer au fournisseur de services SAN de transférer le contexte de socket dans l’espace d’adressage du processus de contrôle suivant. Le commutateur spécifie le processus de contrôle suivant dans le paramètre dwProcessId de WSPDuplicateSocket. La fonction WSPDuplicateSocket doit appeler la fonction WPUCompleteOverlappedRequest pour terminer toutes les demandes de réception en attente sur le socket avec une réussite status et zéro octet. Le fournisseur de services SAN doit également libérer automatiquement toutes les mémoires tampons associées à ces requêtes. Le fournisseur de services SAN libère toutes les mémoires tampons, car le commutateur ne demande plus d’opérations sur le socket SAN après le retour de WSPDuplicateSocket . La seule exception possible est un appel de fonction WSPCloseSocket , comme décrit à l’étape suivante. Une fois que WSPDuplicateSocket est retourné, le commutateur enregistre la valeur dans le membre dwProviderReserved de la structure WSAPROTOCOL_INFOW vers laquelle pointe le paramètre de sortie lpProtocolInfo . Le commutateur utilise cette valeur pour identifier le socket sous-jacent dans le contexte du processus de contrôle suivant. Par conséquent, la valeur dans dwProviderReserved doit identifier de manière unique le socket sous-jacent et la connexion pour ce socket sur tous les processus sur le système. En outre, cette valeur doit être valide uniquement dans le contexte du processus que le commutateur a spécifié dans le paramètre dwProcessId de WSPDuplicateSocket.
Une fois le contexte de socket transféré dans l’espace d’adressage du processus de contrôle suivant, le commutateur appelle la fonction WSPSocket du fournisseur de services SAN dans le contexte du processus de contrôle suivant. Dans cet appel, le commutateur transmet la valeur du socket sous-jacent qui a été retourné dans l’appel WSPDuplicateSocket au membre dwProviderReserved de la structure WSAPROTOCOL_INFOW vers laquelle pointe le paramètre d’entrée lpProtocolInfo . Si le processus de contrôle suivant n’a pas demandé la création du socket SAN, le fournisseur de services SAN doit créer un nouveau socket et appeler la fonction WPUCreateSocketHandle pour obtenir un handle, comme requis pour tout nouveau socket. Si le socket SAN a été créé dans le contexte du processus de contrôle suivant, le fournisseur de services SAN peut réactiver l’ancien socket et retourner le même descripteur pour le socket utilisé précédemment. Dans ce cas, le fournisseur de services SAN ne doit pas appeler WPUCreateSocketHandle, mais doit continuer à utiliser le handle de socket d’origine fourni par le commutateur. Le fournisseur de services SAN peut également créer un nouveau socket, qu’un socket existait ou non dans le processus. Dans ce cas, le commutateur doit appeler la fonction WSPCloseSocket du fournisseur de services SAN dans le contexte du processus de contrôle suivant pour supprimer l’ancien descripteur de socket.
Le commutateur redémarre le traitement des nouvelles demandes de l’application dans le processus de contrôle suivant.
Le commutateur duplique un socket d’écoute de la même manière, sauf que le commutateur n’est pas nécessaire pour suspendre une session. Le commutateur attend qu’il termine tous les appels WSPAccept lancés par les appels accept et AcceptEx d’une application avant d’appeler la fonction WSPDuplicateSocket du fournisseur de services SAN dans le processus de contrôle.
Étant donné que le commutateur interrompt le traitement des nouvelles demandes sur un socket SAN avant d’appeler la fonction WSPDuplicateSocket du fournisseur de services SAN, le fournisseur de services SAN peut libérer toutes les ressources associées à un point de terminaison local dans le processus de contrôle. Le fournisseur de services SAN peut même mettre fin à une connexion sous-jacente. Si le fournisseur de services SAN ferme une connexion sous-jacente dans le processus de contrôle, le fournisseur de services SAN doit rétablir la connexion après que le commutateur a appelé la fonction WSPSocket du fournisseur de services SAN dans le processus de contrôle suivant. Une fois l’appel WSPSocket retourné, le socket SAN dans le processus de contrôle suivant doit être dans le même état, du point de vue du commutateur, que le socket SAN dans le processus de contrôle était antérieur au commutateur appelant la fonction WSPDuplicateSocket du fournisseur de services SAN.
Si une carte réseau SAN prend en charge le partage de ressources entre des points de terminaison qui s’exécutent dans différents processus, le fournisseur de services SAN n’a pas besoin de libérer des ressources pour un point de terminaison local dans le processus de contrôle avant de recevoir un appel WSPDuplicateSocket . Dans ce cas, le socket SAN associé à un point de terminaison local reste inactif dans l’ancien processus de contrôle jusqu’à ce que le commutateur échange le contexte de socket du processus de contrôle suivant ou appelle la fonction WSPCloseSocket du fournisseur de services SAN pour fermer explicitement le socket. Étant donné que la plupart des applications effectuent leur accès final au socket dans le processus qui l’a créé à l’origine, généralement pour fermer la connexion, le fournisseur de services SAN peut améliorer les performances si le fournisseur de services SAN conserve le contexte de socket dans le processus de contrôle après que le commutateur permute le contrôle du socket au processus de contrôle suivant.
Notez que, dans tous les cas, un descripteur de socket SAN doit rester valide jusqu’à ce que le commutateur appelle la fonction WSPCloseSocket du fournisseur de services SAN pour fermer explicitement le socket. Même si le fournisseur de services SAN libère toutes les ressources pour le socket dans un processus particulier avant de recevoir un appel WSPDuplicateSocket , le fournisseur de services SAN ne doit pas réutiliser le descripteur pour le socket tant que le commutateur n’a pas appelé WSPCloseSocket sur ce descripteur.
Une sortie de processus inattendue ou une autre condition d’erreur peut interrompre l’opération de duplication de socket d’un fournisseur de services SAN. Par exemple, une pénurie de ressources peut entraîner une telle interruption. Le commutateur traite ces conditions d’erreur comme toute autre situation d’erreur. Si nécessaire, le commutateur ferme tous les descripteurs associés au socket sous-jacent dans tous les processus pour arrêter de force la connexion du socket. Si possible, le fournisseur de services SAN de l’homologue distant doit effectuer les appels WSPRecv qui reçoivent des données entrantes avec un code d’erreur approprié, tel que WSAECONNRESET. Ce code d’erreur informe l’homologue distant de l’arrêt de la connexion. Si le commutateur de l’homologue distant ne reçoit pas cette indication de terminaison de connexion, le commutateur de l’homologue distant expire une connexion suspendue si le système qui a demandé la suspension échoue.