autofs-5.1.6 - improve sss setautomntent() error handling From: Ian Kent Recent versions of the sss autofs access library will return EHOSTDOWN if the backend server is down. The presence of this improvement in error handling is determined by an added function to get the sss autofs protocol version. Update the setautomntent() function to use this. Signed-off-by: Ian Kent --- CHANGELOG | 1 + modules/lookup_sss.c | 72 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ce2d4235..ef7a1e3f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -27,6 +27,7 @@ xx/xx/2020 autofs-5.1.7 - add support for new sss autofs proto version call. - fix retries check in setautomntent_wait(). - refactor sss setautomntent(). +- improve sss setautomntent() error handling. 07/10/2019 autofs-5.1.6 - support strictexpire mount option. diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c index b249435d..141e8243 100644 --- a/modules/lookup_sss.c +++ b/modules/lookup_sss.c @@ -259,16 +259,37 @@ static int setautomntent_wait(unsigned int logopt, *sss_ctxt = NULL; retries = defaults_get_sss_master_map_wait(); - if (retries <= 0) - return ENOENT; + + /* If sss_master_map_wait is not set in the autofs + * configuration give it a sensible value since we + * want to wait for a host that's down in case it + * comes back up. + */ + if (retries <= 0) { + /* Protocol version 0 cant't tell us about + * a host being down, return not found. + */ + if (proto_version(ctxt) == 0) + return ENOENT; + retries = 10; + } + + warn(logopt, + "can't connect to sssd, retry for %d seconds", + retries); while (++retry <= retries) { struct timespec t = { SSS_WAIT_INTERVAL, 0 }; struct timespec r; ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); - if (ret != ENOENT) - break; + if (proto_version(ctxt) == 0) { + if (ret != ENOENT) + break; + } else { + if (ret != EHOSTDOWN) + break; + } if (*sss_ctxt) { free(*sss_ctxt); @@ -279,17 +300,17 @@ static int setautomntent_wait(unsigned int logopt, memcpy(&t, &r, sizeof(struct timespec)); } - - if (ret) { + if (!ret) + info(logopt, "successfully connected to sssd"); + else { if (*sss_ctxt) { free(*sss_ctxt); *sss_ctxt = NULL; } - if (retry > retries) + if (proto_version(ctxt) == 0 && retry > retries) ret = ETIMEDOUT; } - return ret; } @@ -298,35 +319,50 @@ static int setautomntent(unsigned int logopt, { char buf[MAX_ERR_BUF]; char *estr; + int err = NSS_STATUS_UNAVAIL; int ret; ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); if (ret) { - if (ret == ECONNREFUSED) - return NSS_STATUS_UNKNOWN; - - if (ret != ENOENT) + if (ret == ECONNREFUSED) { + err = NSS_STATUS_UNKNOWN; goto error; + } + + if (proto_version(ctxt) == 0) { + if (ret != ENOENT) + goto error; + } else { + if (ret != ENOENT && ret != EHOSTDOWN) + goto error; + } ret = setautomntent_wait(logopt, ctxt, sss_ctxt); if (ret) { - if (ret == ECONNREFUSED) - return NSS_STATUS_UNKNOWN; - if (ret == ENOENT) - return NSS_STATUS_NOTFOUND; + if (ret == ECONNREFUSED) { + err = NSS_STATUS_UNKNOWN; + goto error; + } + if (ret == ETIMEDOUT) + goto error; + if (ret == ENOENT) { + err = NSS_STATUS_NOTFOUND; + goto free; + } goto error; } } - return ret; + return NSS_STATUS_SUCCESS; error: estr = strerror_r(ret, buf, MAX_ERR_BUF); error(logopt, MODPREFIX "setautomntent: %s", estr); +free: if (*sss_ctxt) { free(*sss_ctxt); *sss_ctxt = NULL; } - return NSS_STATUS_UNAVAIL; + return err; } static int endautomntent(unsigned int logopt,