Skip to content

Commit 1bcb68c

Browse files
committed
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.
1 parent 08c72b8 commit 1bcb68c

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

src/responder/autofs/autofs_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ struct sss_cmd_table *get_autofs_cmds(void);
7979
void autofs_map_hash_delete_cb(hash_entry_t *item,
8080
hash_destroy_enum deltype, void *pvt);
8181

82+
errno_t autofs_orphan_maps(struct autofs_ctx *actx);
83+
8284
enum sss_dp_autofs_type {
8385
SSS_DP_AUTOFS
8486
};

src/responder/autofs/autofssrv_cmd.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,34 @@ autofs_setent_notify(struct autofs_map_ctx *map_ctx, errno_t ret)
9090
setent_notify(&map_ctx->reqs, ret);
9191
}
9292

93+
errno_t
94+
autofs_orphan_maps(struct autofs_ctx *actx)
95+
{
96+
int hret;
97+
unsigned long mcount;
98+
unsigned long i;
99+
hash_key_t *maps;
100+
101+
if (!actx || !actx->maps) {
102+
return EINVAL;
103+
}
104+
105+
hret = hash_keys(actx->maps, &mcount, &maps);
106+
if (hret != HASH_SUCCESS) {
107+
return EIO;
108+
}
109+
110+
for (i = 0; i < mcount; i++) {
111+
hret = hash_delete(actx->maps, &maps[i]);
112+
if (hret != HASH_SUCCESS) {
113+
DEBUG(SSSDBG_MINOR_FAILURE, ("Could not delete key from hash\n"));
114+
continue;
115+
}
116+
}
117+
118+
return EOK;
119+
}
120+
93121
static errno_t
94122
get_autofs_map(struct autofs_ctx *actx,
95123
char *mapname,
@@ -369,6 +397,11 @@ set_autofs_map_lifetime(uint32_t lifetime,
369397
}
370398
}
371399

400+
static errno_t
401+
setautomntent_get_autofs_map(struct autofs_ctx *actx,
402+
char *mapname,
403+
struct autofs_map_ctx **map);
404+
372405
static struct tevent_req *
373406
setautomntent_send(TALLOC_CTX *mem_ctx,
374407
const char *rawname,
@@ -442,7 +475,7 @@ setautomntent_send(TALLOC_CTX *mem_ctx,
442475
/* Is the result context already available?
443476
* Check for existing lookups for this map
444477
*/
445-
ret = get_autofs_map(actx, state->mapname, &state->map);
478+
ret = setautomntent_get_autofs_map(actx, state->mapname, &state->map);
446479
if (ret == EOK) {
447480
/* Another process already requested this map
448481
* Check whether it's ready for processing.
@@ -558,6 +591,25 @@ setautomntent_send(TALLOC_CTX *mem_ctx,
558591
return req;
559592
}
560593

594+
static errno_t
595+
setautomntent_get_autofs_map(struct autofs_ctx *actx,
596+
char *mapname,
597+
struct autofs_map_ctx **map)
598+
{
599+
errno_t ret;
600+
601+
if (strcmp(mapname, "auto.master") == 0) {
602+
/* Iterate over the hash and remove all maps */
603+
ret = autofs_orphan_maps(actx);
604+
if (ret != EOK) {
605+
DEBUG(SSSDBG_MINOR_FAILURE, ("Could not remove existing maps from hash\n"));
606+
}
607+
return ENOENT;
608+
}
609+
610+
return get_autofs_map(actx, mapname, map);
611+
}
612+
561613
static errno_t
562614
lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx);
563615

@@ -718,8 +770,10 @@ lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx)
718770
struct dp_callback_ctx *cb_ctx = NULL;
719771

720772
if (dctx->map != NULL) {
721-
cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
722-
SYSDB_CACHE_EXPIRE, 0);
773+
if (strcmp(lookup_ctx->mapname, "auto.master") != 0) {
774+
cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
775+
SYSDB_CACHE_EXPIRE, 0);
776+
}
723777

724778
/* if we have any reply let's check cache validity */
725779
ret = sss_cmd_check_cache(dctx->map, 0, cache_expire);

0 commit comments

Comments
 (0)