conman/If-connect-fails-let-other-side-accept-connection-and-come-back.patch
Egbert Eich d6056244f7 Accepting request 624088 from home:eeich:branches:network:cluster
- If-connect-fails-let-other-side-accept-connection-and-come-back.patch:
  Make sure conmand connects to a newly created UNIX socket with
  minimal delay. The implementation uses inotify, however this triggers
  when the other side bind()s to the socket, however a connection is
  not possible until the other side calls listen().
  Thus if the connection fails, reset the poll() timeout to return to
  connect() as soon as possible (bsc#1101647).
- Support %license in a backward compatible way.

OBS-URL: https://build.opensuse.org/request/show/624088
OBS-URL: https://build.opensuse.org/package/show/network:cluster/conman?expand=0&rev=27
2018-07-19 14:01:55 +00:00

101 lines
3.6 KiB
Diff

From: Egbert Eich <eich@suse.com>
Date: Wed Jul 18 11:26:07 2018 +0200
Subject: If connect fails let other side accept connection and come back
Patch-mainline: Not yet
Git-commit: 1fc96affadb267bb03058293e9d31af95cfd6f2d
References: bsc#
The UNIX socket code uses inotify to get notified when a socket
it monitors appears. The inotify is triggered when the other side
does bind(). However, we are not able to connect until the other
side calls listen(). Therefore, we need to let the other side continue
if the connect fails and should come back at the earliest time to
attempt a connect() again.
For this we just reset the poll() delay.
Signed-off-by: Egbert Eich <eich@suse.com>
---
server-unixsock.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/server-unixsock.c b/server-unixsock.c
index 152bd31..7302acf 100644
--- a/server-unixsock.c
+++ b/server-unixsock.c
@@ -46,8 +46,10 @@
static size_t max_unixsock_dev_strlen(void);
+static int connect_unixsock_obj_int(obj_t *unixsock, int reset_delay);
static int connect_unixsock_obj(obj_t *unixsock);
static int disconnect_unixsock_obj(obj_t *unixsock);
+static int open_unixsock_obj_reset_delay(obj_t *unixsock);
static void reset_unixsock_delay(obj_t *unixsock);
extern tpoll_t tp_global; /* defined in server.c */
@@ -147,7 +149,7 @@ obj_t * create_unixsock_obj(server_conf_t *conf, char *name, char *dev,
list_append(conf->objs, unixsock);
rv = inevent_add(unixsock->aux.unixsock.dev,
- (inevent_cb_f) open_unixsock_obj, unixsock);
+ (inevent_cb_f) open_unixsock_obj_reset_delay, unixsock);
if (rv < 0) {
log_msg(LOG_INFO,
"Console [%s] unable to register device \"%s\" for inotify events",
@@ -157,7 +159,7 @@ obj_t * create_unixsock_obj(server_conf_t *conf, char *name, char *dev,
}
-int open_unixsock_obj(obj_t *unixsock)
+static int open_unixsock_obj_int(obj_t *unixsock, int reset_delay)
{
/* (Re)opens the specified 'unixsock' obj.
* Returns 0 if the console is successfully opened; o/w, returns -1.
@@ -171,11 +173,18 @@ int open_unixsock_obj(obj_t *unixsock)
rc = disconnect_unixsock_obj(unixsock);
}
else {
- rc = connect_unixsock_obj(unixsock);
+ rc = connect_unixsock_obj_int(unixsock, reset_delay);
}
return(rc);
}
+int open_unixsock_obj(obj_t *unixsock) {
+ return open_unixsock_obj_int(unixsock, 0);
+}
+
+int open_unixsock_obj_reset_delay(obj_t *unixsock) {
+ return open_unixsock_obj_int(unixsock, 1);
+}
static size_t max_unixsock_dev_strlen(void)
{
@@ -193,7 +202,7 @@ static size_t max_unixsock_dev_strlen(void)
}
-static int connect_unixsock_obj(obj_t *unixsock)
+static int connect_unixsock_obj_int(obj_t *unixsock, int reset_delay)
{
/* Opens a connection to the specified (unixsock) obj.
* Returns 0 if the connection is successfully completed; o/w, returns -1.
@@ -257,6 +266,8 @@ static int connect_unixsock_obj(obj_t *unixsock)
(struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
log_msg(LOG_INFO, "Console [%s] cannot connect to device \"%s\": %s",
unixsock->name, auxp->dev, strerror(errno));
+ if (reset_delay)
+ reset_unixsock_delay(unixsock);
return(disconnect_unixsock_obj(unixsock));
}
/* Write-locking the unix domain socket appears ineffective. But since
@@ -284,6 +295,9 @@ static int connect_unixsock_obj(obj_t *unixsock)
return(0);
}
+static int connect_unixsock_obj(obj_t *unixsock) {
+ return connect_unixsock_obj_int(unixsock, 0);
+}
static int disconnect_unixsock_obj(obj_t *unixsock)
{