summaryrefslogtreecommitdiff
path: root/src/responder/autofs
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-12-15 13:22:34 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-12-18 17:25:34 +0100
commit1bcb68cc3069a6bd539289e68a87a0815aa2a1be (patch)
tree67922878218de3f3052f9898353930823ef846fc /src/responder/autofs
parent08c72b84d85d482f030a30cf74786695f097e91c (diff)
downloadsssd-1bcb68cc3069a6bd539289e68a87a0815aa2a1be.tar.gz
sssd-1bcb68cc3069a6bd539289e68a87a0815aa2a1be.tar.bz2
sssd-1bcb68cc3069a6bd539289e68a87a0815aa2a1be.zip
AUTOFS: remove all maps from hash if request for auto.master comes in
https://fedorahosted.org/sssd/ticket/1592 When a request for auto.master comes in, we need to remove all the maps from the lookup hash table. We can't simply delete the maps, because another request might be processing them, so instead the maps are removed from the hash table, effectively becoming orphaned. The maps will get freed when the timed destructor is invoked.
Diffstat (limited to 'src/responder/autofs')
-rw-r--r--src/responder/autofs/autofs_private.h2
-rw-r--r--src/responder/autofs/autofssrv_cmd.c60
2 files changed, 59 insertions, 3 deletions
diff --git a/src/responder/autofs/autofs_private.h b/src/responder/autofs/autofs_private.h
index a2af36e4..58445f35 100644
--- a/src/responder/autofs/autofs_private.h
+++ b/src/responder/autofs/autofs_private.h
@@ -79,6 +79,8 @@ struct sss_cmd_table *get_autofs_cmds(void);
void autofs_map_hash_delete_cb(hash_entry_t *item,
hash_destroy_enum deltype, void *pvt);
+errno_t autofs_orphan_maps(struct autofs_ctx *actx);
+
enum sss_dp_autofs_type {
SSS_DP_AUTOFS
};
diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 0cfdbec5..b85079d0 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -90,6 +90,34 @@ autofs_setent_notify(struct autofs_map_ctx *map_ctx, errno_t ret)
setent_notify(&map_ctx->reqs, ret);
}
+errno_t
+autofs_orphan_maps(struct autofs_ctx *actx)
+{
+ int hret;
+ unsigned long mcount;
+ unsigned long i;
+ hash_key_t *maps;
+
+ if (!actx || !actx->maps) {
+ return EINVAL;
+ }
+
+ hret = hash_keys(actx->maps, &mcount, &maps);
+ if (hret != HASH_SUCCESS) {
+ return EIO;
+ }
+
+ for (i = 0; i < mcount; i++) {
+ hret = hash_delete(actx->maps, &maps[i]);
+ if (hret != HASH_SUCCESS) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Could not delete key from hash\n"));
+ continue;
+ }
+ }
+
+ return EOK;
+}
+
static errno_t
get_autofs_map(struct autofs_ctx *actx,
char *mapname,
@@ -369,6 +397,11 @@ set_autofs_map_lifetime(uint32_t lifetime,
}
}
+static errno_t
+setautomntent_get_autofs_map(struct autofs_ctx *actx,
+ char *mapname,
+ struct autofs_map_ctx **map);
+
static struct tevent_req *
setautomntent_send(TALLOC_CTX *mem_ctx,
const char *rawname,
@@ -442,7 +475,7 @@ setautomntent_send(TALLOC_CTX *mem_ctx,
/* Is the result context already available?
* Check for existing lookups for this map
*/
- ret = get_autofs_map(actx, state->mapname, &state->map);
+ ret = setautomntent_get_autofs_map(actx, state->mapname, &state->map);
if (ret == EOK) {
/* Another process already requested this map
* Check whether it's ready for processing.
@@ -559,6 +592,25 @@ fail:
}
static errno_t
+setautomntent_get_autofs_map(struct autofs_ctx *actx,
+ char *mapname,
+ struct autofs_map_ctx **map)
+{
+ errno_t ret;
+
+ if (strcmp(mapname, "auto.master") == 0) {
+ /* Iterate over the hash and remove all maps */
+ ret = autofs_orphan_maps(actx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Could not remove existing maps from hash\n"));
+ }
+ return ENOENT;
+ }
+
+ return get_autofs_map(actx, mapname, map);
+}
+
+static errno_t
lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx);
static errno_t
@@ -718,8 +770,10 @@ lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx)
struct dp_callback_ctx *cb_ctx = NULL;
if (dctx->map != NULL) {
- cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
- SYSDB_CACHE_EXPIRE, 0);
+ if (strcmp(lookup_ctx->mapname, "auto.master") != 0) {
+ cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
+ SYSDB_CACHE_EXPIRE, 0);
+ }
/* if we have any reply let's check cache validity */
ret = sss_cmd_check_cache(dctx->map, 0, cache_expire);