[PATCH v3 0/1] rpc: Re-read the data if EAGAIN or EINTR were captured

From: Hyman Huang <yong.huang@smartx.com> v3: Add the overlooked Signed-off-by v2: 1. Move the retry logic outside of virNetTLSSession{Read,Write} 2. Try re-polling when handing EAGAIN suggested by Daniel v1: 1. Encapsulate the retry logic inside virNetTLSSession{Read,Write} 2. Use VIR_DEBUG instead of VIR_WARN to log the retry operation rfc: https://patchew.org/Libvirt/d716a59dc2c61916917c6d2e07d62055745606d5.1744044... Please review, thanks. Yong Hyman Huang (1): rpc: Add the {repoll,retry} logic in virNetClientSetTLSSession src/rpc/virnetclient.c | 8 ++++++++ 1 file changed, 8 insertions(+) -- 2.27.0

From: Hyman Huang <yong.huang@smartx.com> As advised by the GNU TLS, the caller should attempt again if the gnutls_record_{recv,send} return EAGAIN or EINTR; check the following link to view the details: https://www.gnutls.org/manual/html_node/Data-transfer-and-termination.html virNetClientSetTLSSession failed to handle EINTR/EGAIN, though EGAIN seems like it ought to be unlikely given that the caller waited for G_IO_IN. Add the {repoll, retry} logic to handle EINTR/EGAIN that may happen theoretically. This may reduce the likelihood that the upper application receives the following error message utmostly when it calls the virConnectOpenAuth API: Unable to read TLS confirmation: Resource temporarily unavailable Note that in order to fully avoid the mentioned problem, the upper application should retry virConnectOpenAuth. Signed-off-by: Hyman Huang <yong.huang@smartx.com> --- src/rpc/virnetclient.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 92933220e2..ee729d5e62 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -987,6 +987,7 @@ int virNetClientSetTLSSession(virNetClient *client, * etc. If we make the grade, it will send us a '\1' byte. */ + repoll: source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), G_IO_IN, client->eventCtx, @@ -1003,7 +1004,14 @@ int virNetClientSetTLSSession(virNetClient *client, ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL)); #endif /* !WIN32 */ + retry: len = virNetTLSSessionRead(client->tls, buf, 1); + if (len < 0 && errno == EINTR) { + goto retry; + } + if (len < 0 && errno == EAGAIN) { + goto repoll; + } if (len < 0 && errno != ENOMSG) { virReportSystemError(errno, "%s", _("Unable to read TLS confirmation")); -- 2.27.0

On Thu, May 15, 2025 at 09:07:41AM +0800, yong.huang@smartx.com wrote:
From: Hyman Huang <yong.huang@smartx.com>
As advised by the GNU TLS, the caller should attempt again if the gnutls_record_{recv,send} return EAGAIN or EINTR; check the following link to view the details: https://www.gnutls.org/manual/html_node/Data-transfer-and-termination.html
virNetClientSetTLSSession failed to handle EINTR/EGAIN, though EGAIN seems like it ought to be unlikely given that the caller waited for G_IO_IN.
Add the {repoll, retry} logic to handle EINTR/EGAIN that may happen theoretically. This may reduce the likelihood that the upper application receives the following error message utmostly when it calls the virConnectOpenAuth API: Unable to read TLS confirmation: Resource temporarily unavailable
Note that in order to fully avoid the mentioned problem, the upper application should retry virConnectOpenAuth.
Signed-off-by: Hyman Huang <yong.huang@smartx.com> --- src/rpc/virnetclient.c | 8 ++++++++ 1 file changed, 8 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> and pushed With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (2)
-
Daniel P. Berrangé
-
yong.huang@smartx.com