|
|
d702dc |
autofs-5.1.6 - improve sss getautomntent() 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 getautomntent() 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 | 126 ++++++++++++++++++++++++++++++++++++++++++++++----
|
|
|
d702dc |
2 files changed, 116 insertions(+), 11 deletions(-)
|
|
|
d702dc |
|
|
|
d702dc |
diff --git a/CHANGELOG b/CHANGELOG
|
|
|
d702dc |
index ecd54e9..434e23d 100644
|
|
|
d702dc |
--- a/CHANGELOG
|
|
|
d702dc |
+++ b/CHANGELOG
|
|
|
d702dc |
@@ -101,6 +101,7 @@ xx/xx/2018 autofs-5.1.5
|
|
|
d702dc |
- refactor sss setautomntent().
|
|
|
d702dc |
- improve sss setautomntent() error handling.
|
|
|
d702dc |
- refactor sss getautomntent().
|
|
|
d702dc |
+- improve sss getautomntent() 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 5addd87..f366b48 100644
|
|
|
d702dc |
--- a/modules/lookup_sss.c
|
|
|
d702dc |
+++ b/modules/lookup_sss.c
|
|
|
d702dc |
@@ -377,38 +377,136 @@ static int endautomntent(unsigned int logopt,
|
|
|
d702dc |
return ret;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
+static int getautomntent_wait(unsigned int logopt,
|
|
|
d702dc |
+ struct lookup_context *ctxt,
|
|
|
d702dc |
+ char **key, char **value, void *sss_ctxt)
|
|
|
d702dc |
+{
|
|
|
d702dc |
+ unsigned int retries;
|
|
|
d702dc |
+ unsigned int retry = 0;
|
|
|
d702dc |
+ int ret = 0;
|
|
|
d702dc |
+
|
|
|
d702dc |
+ retries = defaults_get_sss_master_map_wait();
|
|
|
d702dc |
+
|
|
|
d702dc |
+ /* Use the sss_master_map_wait configuration option
|
|
|
d702dc |
+ * for the time to wait when reading a map too. If
|
|
|
d702dc |
+ * it isn't set in the antofs configuration give it
|
|
|
d702dc |
+ * a sensible value since we want to wait for a host
|
|
|
d702dc |
+ * that's down in case it comes back up.
|
|
|
d702dc |
+ */
|
|
|
d702dc |
+ if (retries <= 0) {
|
|
|
d702dc |
+ /* Protocol version 0 cant't tell us about
|
|
|
d702dc |
+ * a host being down, return not found.
|
|
|
d702dc |
+ */
|
|
|
d702dc |
+ if (proto_version(ctxt) == 0)
|
|
|
d702dc |
+ return ENOENT;
|
|
|
d702dc |
+ retries = 10;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ warn(logopt,
|
|
|
d702dc |
+ "can't contact sssd to to get map entry, 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->getautomntent_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 get map entry");
|
|
|
d702dc |
+ else {
|
|
|
d702dc |
+ if (retry == retries)
|
|
|
d702dc |
+ ret = ETIMEDOUT;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ return ret;
|
|
|
d702dc |
+}
|
|
|
d702dc |
+
|
|
|
d702dc |
static int getautomntent(unsigned int logopt,
|
|
|
d702dc |
struct lookup_context *ctxt,
|
|
|
d702dc |
char **key, char **value, int count, void *sss_ctxt)
|
|
|
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->getautomntent_r(key, value, sss_ctxt);
|
|
|
d702dc |
if (ret) {
|
|
|
d702dc |
/* Host has gone down */
|
|
|
d702dc |
- if (ret == ECONNREFUSED)
|
|
|
d702dc |
- return NSS_STATUS_UNKNOWN;
|
|
|
d702dc |
- if (ret != ENOENT)
|
|
|
d702dc |
+ if (ret == ECONNREFUSED) {
|
|
|
d702dc |
+ err = NSS_STATUS_UNKNOWN;
|
|
|
d702dc |
goto error;
|
|
|
d702dc |
- if (!count) {
|
|
|
d702dc |
- ret = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
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 we've read all entries.
|
|
|
d702dc |
+ * So even if we haven't got any values yet we
|
|
|
d702dc |
+ * can't use it to determine if we need to wait
|
|
|
d702dc |
+ * on sss.
|
|
|
d702dc |
+ */
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ if (count)
|
|
|
d702dc |
+ err = NSS_STATUS_SUCCESS;
|
|
|
d702dc |
goto free;
|
|
|
d702dc |
+ } else {
|
|
|
d702dc |
+ if (ret == ENOENT) {
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ if (count)
|
|
|
d702dc |
+ err = NSS_STATUS_SUCCESS;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ if (ret != EHOSTDOWN)
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+
|
|
|
d702dc |
+ ret = getautomntent_wait(logopt, ctxt,
|
|
|
d702dc |
+ key, value, sss_ctxt);
|
|
|
d702dc |
+ if (ret) {
|
|
|
d702dc |
+ if (ret == ECONNREFUSED) {
|
|
|
d702dc |
+ err = NSS_STATUS_UNKNOWN;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ if (ret == ETIMEDOUT)
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
+ if (ret == ENOENT) {
|
|
|
d702dc |
+ err = NSS_STATUS_NOTFOUND;
|
|
|
d702dc |
+ if (count)
|
|
|
d702dc |
+ err = NSS_STATUS_SUCCESS;
|
|
|
d702dc |
+ goto free;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ goto error;
|
|
|
d702dc |
}
|
|
|
d702dc |
- goto error;
|
|
|
d702dc |
}
|
|
|
d702dc |
- return ret;
|
|
|
d702dc |
+ return NSS_STATUS_SUCCESS;
|
|
|
d702dc |
|
|
|
d702dc |
error:
|
|
|
d702dc |
estr = strerror_r(ret, buf, MAX_ERR_BUF);
|
|
|
d702dc |
error(logopt, MODPREFIX "getautomntent: %s", estr);
|
|
|
d702dc |
free:
|
|
|
d702dc |
- if (*key)
|
|
|
d702dc |
+ if (*key) {
|
|
|
d702dc |
free(*key);
|
|
|
d702dc |
- if (*value)
|
|
|
d702dc |
+ *key = NULL;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ if (*value) {
|
|
|
d702dc |
free(*value);
|
|
|
d702dc |
- return ret;
|
|
|
d702dc |
+ *value = NULL;
|
|
|
d702dc |
+ }
|
|
|
d702dc |
+ return err;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
int lookup_read_master(struct master *master, time_t age, void *context)
|
|
|
d702dc |
@@ -439,6 +537,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
|
d702dc |
return ret;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
+ if (!key || !value)
|
|
|
d702dc |
+ break;
|
|
|
d702dc |
+
|
|
|
d702dc |
count++;
|
|
|
d702dc |
|
|
|
d702dc |
buffer_len = strlen(key) + 1 + strlen(value) + 2;
|
|
|
d702dc |
@@ -523,6 +624,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
|
d702dc |
return ret;
|
|
|
d702dc |
}
|
|
|
d702dc |
|
|
|
d702dc |
+ if (!key || !value)
|
|
|
d702dc |
+ break;
|
|
|
d702dc |
+
|
|
|
d702dc |
/*
|
|
|
d702dc |
* Ignore keys beginning with '+' as plus map
|
|
|
d702dc |
* inclusion is only valid in file maps.
|