Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
No build reason found for pool-leap-15.4:x86_64
openSUSE:Step:15
conman.8577
Reset-delay-for-unixsock-connect-from-inotify.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File Reset-delay-for-unixsock-connect-from-inotify.patch of Package conman.8577
From: Egbert Eich <eich@suse.com> Date: Wed Jul 18 11:26:07 2018 +0200 Subject: Reset delay for unixsock connect from inotify Patch-mainline: Not yet Git-repo: https://github.com/dun/conman Git-commit: 8f5bd09162307a23efb8532a95c4e4a562ce30fe References: bsc#1101647 Consoles over UNIX domain sockets use inotify to detect when their socket appears in the filesystem. This inotify event is triggered when the remote has successfully called bind(). However, the remote may not have called listen() before the inotify event is serviced by conmand. In such a case, connect() will fail with ECONNREFUSED, after which the connection delay will be increased before the next connection attempt. This can result in connection establishment taking up to UNIXSOCK_MAX_TIMEOUT seconds once the socket appears. To handle this case, reset the connection delay to UNIXSOCK_MIN_TIMEOUT when a connection attempt triggered by inotify fails. [cdunlap@llnl.gov: Restructured to use isViaInotify flag] Signed-off-by: Egbert Eich <eich@suse.com> Signed-off-by: Chris Dunlap <cdunlap@llnl.gov> Closes #28 Closes #29 Signed-off-by: Egbert Eich <eich@suse.de> --- server-unixsock.c | 36 ++++++++++++++++++++++++++++++++++-- server.h | 1 + 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/server-unixsock.c b/server-unixsock.c index e683ec7..b44adb4 100644 --- a/server-unixsock.c +++ b/server-unixsock.c @@ -45,6 +45,7 @@ #include "util-str.h" +static int open_unixsock_obj_via_inotify(obj_t *unixsock); static size_t max_unixsock_dev_strlen(void); static int connect_unixsock_obj(obj_t *unixsock); static int disconnect_unixsock_obj(obj_t *unixsock); @@ -140,6 +141,7 @@ obj_t * create_unixsock_obj(server_conf_t *conf, char *name, char *dev, unixsock->aux.unixsock.logfile = NULL; unixsock->aux.unixsock.timer = -1; unixsock->aux.unixsock.state = CONMAN_UNIXSOCK_DOWN; + unixsock->aux.unixsock.isViaInotify = 0; unixsock->aux.unixsock.delay = UNIXSOCK_MIN_TIMEOUT; /* * Add obj to the master conf->objs list. @@ -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_via_inotify, unixsock); if (rv < 0) { log_msg(LOG_INFO, "Console [%s] unable to register device \"%s\" for inotify events", @@ -177,6 +179,23 @@ int open_unixsock_obj(obj_t *unixsock) } +static int open_unixsock_obj_via_inotify(obj_t *unixsock) +{ +/* Opens the specified 'unixsock' obj via an inotify callback. + * Returns 0 if the console is successfully opened; o/w, returns -1. + */ + unixsock_obj_t *auxp; + + assert(unixsock != NULL); + assert(is_unixsock_obj(unixsock)); + + auxp = &(unixsock->aux.unixsock); + auxp->isViaInotify = 1; + + return(open_unixsock_obj(unixsock)); +} + + static size_t max_unixsock_dev_strlen(void) { /* Returns the maximum string length allowed for a unix domain device. @@ -199,6 +218,7 @@ static int connect_unixsock_obj(obj_t *unixsock) * Returns 0 if the connection is successfully completed; o/w, returns -1. */ unixsock_obj_t *auxp; + int isViaInotify; struct stat st; struct sockaddr_un saddr; size_t n; @@ -210,6 +230,9 @@ static int connect_unixsock_obj(obj_t *unixsock) auxp = &(unixsock->aux.unixsock); + isViaInotify = auxp->isViaInotify; + auxp->isViaInotify = 0; + if (auxp->timer >= 0) { (void) tpoll_timeout_cancel(tp_global, auxp->timer); auxp->timer = -1; @@ -250,11 +273,20 @@ static int connect_unixsock_obj(obj_t *unixsock) set_fd_nonblocking(unixsock->fd); set_fd_closed_on_exec(unixsock->fd); - /* FIXME: Check to see if connect() on a nonblocking unix domain socket + /* If a connect() triggered via an inotify event fails, reset the + * reconnect delay to its minimum to quickly re-attempt the connection. + * This handles the case where the remote has successfully called bind() + * (triggering the inotify event) but has not yet called listen(). + * FIXME: Check to see if connect() on a nonblocking unix domain socket * can return EINPROGRESS. I don't think it can. */ if (connect(unixsock->fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { + if (isViaInotify) { + auxp->delay = UNIXSOCK_MIN_TIMEOUT; + DPRINTF((15, "Reset [%s] reconnect delay due to inotify event\n", + unixsock->name)); + } log_msg(LOG_INFO, "Console [%s] cannot connect to device \"%s\": %s", unixsock->name, auxp->dev, strerror(errno)); return(disconnect_unixsock_obj(unixsock)); diff --git a/server.h b/server.h index 8ccbcf9..6cc7c1b 100644 --- a/server.h +++ b/server.h @@ -180,6 +180,7 @@ typedef struct unixsock_obj { /* UNIXSOCK AUX OBJ DATA: */ int timer; /* timer id for reconnects */ int delay; /* secs 'til next reconnect attempt */ unsigned state:1; /* unixsock_state_t conn state */ + unsigned isViaInotify:1; /* true if triggered via inotify */ } unixsock_obj_t; /* Refer to struct ipmiconsole_ipmi_config in <ipmiconsole.h>.
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor