|
|
d702dc |
autofs-5.1.6 - improve sss getautomntbyname() error handling
|
|
|
d702dc |
|
|
|
d702dc |
From: Ian Kent <raven@themaw.net>
|
|
|
d702dc |
|
|
|
d702dc |
Recent versions of the sss autofs access library will return EHOSTDOWN
|
|
|
d702dc |
if the backend server is down.
|
|
|
d702dc |
|
|
|
d702dc |
The presence of this improvement in error handling is determined by an
|
|
|
d702dc |
added function to get the sss autofs protocol version.
|
|
|
d702dc |
|
|
|
d702dc |
Update the getautomntbyname() function to use this.
|
|
|
d702dc |
|
|
|
d702dc |
Also introduce a wait function so we can wait (for a while) for the host
|
|
|
d702dc |
to come back up.
|
|
|
d702dc |
|
|
|
d702dc |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
d702dc |
---
|
|
|
d702dc |
CHANGELOG | 1
|
|
|
d702dc |
modules/lookup_sss.c | 106 ++++++++++++++++++++++++++++++++++++++++++++------
|
|
|
d702dc |
2 files changed, 95 insertions(+), 12 deletions(-)
|
|
|
d702dc |
|
|
|
d702dc |
diff --git a/CHANGELOG b/CHANGELOG
|
|
|
d702dc |
index 8b662d7..309def2 100644
|
|
|
d702dc |
--- a/CHANGELOG
|
|
|
d702dc |
+++ b/CHANGELOG
|
|
|
d702dc |
@@ -107,6 +107,7 @@ xx/xx/2018 autofs-5.1.5
|
|
|
d702dc |
- sss introduce a flag to indicate map being read.
|
|
|
d702dc |
- update sss timeout documentation.
|
|
|
d702dc |
- refactor sss getautomntbyname().
|
|
|
d702dc |
+- improve sss getautomntbyname() error handling.
|
|
|
d702dc |
|
|
|
d702dc |
19/12/2017 autofs-5.1.4
|
|
|
d702dc |
- fix spec file url.
|
|
|
d702dc |
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
|
|
|
d702dc |
index 1a56ea1..70efc11 100644
|
|
|
d702dc |
--- a/modules/lookup_sss.c
|
|
|
d702dc |
+++ b/modules/lookup_sss.c
|
|
|
d702dc |
@@ -566,27 +566,106 @@ free:
|
|
|
d702dc |
return err;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
+static int getautomntbyname_wait(unsigned int logopt,
|
|
|
d702dc |
+ struct lookup_context *ctxt,
|
|
|
d702dc |
+ char *key, char **value, void *sss_ctxt,
|
|
|
d702dc |
+ unsigned int flags)
|
|
|
d702dc |
+{
|
|
|
d702dc |
+ unsigned int retries;
|
|
|
d702dc |
+ unsigned int retry = 0;
|
|
|
d702dc |
+ int ret = 0;
|
|
|
d702dc |
+
|
|
|
d702dc |
+ retries = calculate_retry_count(ctxt, flags);
|
|
|
d702dc |
+ if (retries == 0) {
|
|
|
d702dc |
+ if (proto_version(ctxt) == 0)
|
|
|
d702dc |
+ return EINVAL;
|
|
|
d702dc |
+ return ENOENT;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ warn(logopt,
|
|
|
d702dc |
+ "can't contact sssd to to lookup key value, retry for %d seconds",
|
|
|
d702dc |
+ retries);
|
|
|
d702dc |
+
|
|
|
d702dc |
+ while (++retry <= retries) {
|
|
|
d702dc |
+ struct timespec t = { SSS_WAIT_INTERVAL, 0 };
|
|
|
d702dc |
+ struct timespec r;
|
|
|
d702dc |
+
|
|
|
d702dc |
+ ret = ctxt->getautomntbyname_r(key, value, sss_ctxt);
|
|
|
d702dc |
+ if (proto_version(ctxt) == 0) {
|
|
|
d702dc |
+ if (ret != ENOENT)
|
|
|
d702dc |
+ break;
|
|
|
d702dc |
+ } else {
|
|
|
d702dc |
+ if (ret != EHOSTDOWN)
|
|
|
d702dc |
+ break;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
|
|
|
d702dc |
+ memcpy(&t, &r, sizeof(struct timespec));
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ if (!ret)
|
|
|
d702dc |
+ info(logopt,
|
|
|
d702dc |
+ "successfully contacted sssd to lookup key value");
|
|
|
d702dc |
+ else {
|
|
|
d702dc |
+ if (proto_version(ctxt) == 0 && retry > retries)
|
|
|
d702dc |
+ ret = ETIMEDOUT;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ return ret;
|
|
|
d702dc |
+}
|
|
|
d702dc |
+
|
|
|
d702dc |
static int getautomntbyname(unsigned int logopt,
|
|
|
d702dc |
struct lookup_context *ctxt,
|
|
|
d702dc |
- char *key, char **value, void *sss_ctxt)
|
|
|
d702dc |
+ char *key, char **value, void *sss_ctxt,
|
|
|
d702dc |
+ unsigned int flags)
|
|
|
d702dc |
{
|
|
|
d702dc |
char buf[MAX_ERR_BUF];
|
|
|
d702dc |
char *estr;
|
|
|
d702dc |
- int ret = NSS_STATUS_UNAVAIL;
|
|
|
d702dc |
+ int err = NSS_STATUS_UNAVAIL;
|
|
|
d702dc |
+ int ret;
|
|
|
d702dc |
|
|
|
d702dc |
ret = ctxt->getautomntbyname_r(key, value, sss_ctxt);
|
|
|
d702dc |
if (ret) {
|
|
|
d702dc |
/* Host has gone down */
|
|
|
d702dc |
if (ret == ECONNREFUSED)
|
|
|
d702dc |
- return NSS_STATUS_UNKNOWN;
|
|
|
d702dc |
-
|
|
|
d702dc |
- if (ret != ENOENT)
|
|
|
d702dc |
goto error;
|
|
|
d702dc |
|
|
|
d702dc |
- ret = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
- goto free;
|
|
|
d702dc |
+ if (proto_version(ctxt) == 0) {
|
|
|
d702dc |
+ if (ret != ENOENT)
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ /* For prorocol version 0 ENOENT can only be
|
|
|
d702dc |
+ * used to indicate no entry was found. So it
|
|
|
d702dc |
+ * can't be used to determine if we need to wait
|
|
|
d702dc |
+ * on sss.
|
|
|
d702dc |
+ */
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ } else {
|
|
|
d702dc |
+ if (ret == ENOENT) {
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ if (ret != EHOSTDOWN)
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ ret = getautomntbyname_wait(logopt, ctxt,
|
|
|
d702dc |
+ key, value, sss_ctxt, flags);
|
|
|
d702dc |
+ if (ret) {
|
|
|
d702dc |
+ if (ret == ECONNREFUSED)
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ if (ret == ETIMEDOUT)
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ /* sss proto version 0 and sss timeout not set */
|
|
|
d702dc |
+ if (ret == EINVAL)
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ if (ret == ENOENT) {
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
}
|
|
|
d702dc |
- return ret;
|
|
|
d702dc |
+ return NSS_STATUS_SUCCESS;
|
|
|
d702dc |
|
|
|
d702dc |
error:
|
|
|
d702dc |
estr = strerror_r(ret, buf, MAX_ERR_BUF);
|
|
|
d702dc |
@@ -596,7 +675,7 @@ free:
|
|
|
d702dc |
free(*value);
|
|
|
d702dc |
*value = NULL;
|
|
|
d702dc |
}
|
|
|
d702dc |
- return ret;
|
|
|
d702dc |
+ return err;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
int lookup_read_master(struct master *master, time_t age, void *context)
|
|
|
d702dc |
@@ -802,7 +881,8 @@ static int lookup_one(struct autofs_point *ap,
|
|
|
d702dc |
if (ret)
|
|
|
d702dc |
return ret;
|
|
|
d702dc |
|
|
|
d702dc |
- ret = getautomntbyname(ap->logopt, ctxt, qKey, &value, sss_ctxt);
|
|
|
d702dc |
+ ret = getautomntbyname(ap->logopt, ctxt,
|
|
|
d702dc |
+ qKey, &value, sss_ctxt, SSS_LOOKUP_KEY);
|
|
|
d702dc |
if (ret == NSS_STATUS_NOTFOUND)
|
|
|
d702dc |
goto wild;
|
|
|
d702dc |
if (ret) {
|
|
|
d702dc |
@@ -829,13 +909,15 @@ static int lookup_one(struct autofs_point *ap,
|
|
|
d702dc |
return NSS_STATUS_SUCCESS;
|
|
|
d702dc |
|
|
|
d702dc |
wild:
|
|
|
d702dc |
- ret = getautomntbyname(ap->logopt, ctxt, "/", &value, sss_ctxt);
|
|
|
d702dc |
+ ret = getautomntbyname(ap->logopt, ctxt,
|
|
|
d702dc |
+ "/", &value, sss_ctxt, SSS_LOOKUP_KEY);
|
|
|
d702dc |
if (ret) {
|
|
|
d702dc |
if (ret != NSS_STATUS_NOTFOUND) {
|
|
|
d702dc |
endautomntent(ap->logopt, ctxt, &sss_ctxt);
|
|
|
d702dc |
return ret;
|
|
|
d702dc |
}
|
|
|
d702dc |
- ret = getautomntbyname(ap->logopt, ctxt, "*", &value, sss_ctxt);
|
|
|
d702dc |
+ ret = getautomntbyname(ap->logopt, ctxt,
|
|
|
d702dc |
+ "*", &value, sss_ctxt, SSS_LOOKUP_KEY);
|
|
|
d702dc |
if (ret && ret != NSS_STATUS_NOTFOUND) {
|
|
|
d702dc |
endautomntent(ap->logopt, ctxt, &sss_ctxt);
|
|
|
d702dc |
return ret;
|