From db77001f27575a1c2e8723b1257a91423867171d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 31 Aug 2023 11:07:38 -0400 Subject: pwcache: Don't use _SC_GET{PW,GR}_R_SIZE_MAX They tend be 1024, which is a lot of memory per user/group. 128 is usually enough, so start there instead. --- src/pwcache.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) (limited to 'src/pwcache.c') diff --git a/src/pwcache.c b/src/pwcache.c index a9acfc0..0e2f5c1 100644 --- a/src/pwcache.c +++ b/src/pwcache.c @@ -20,12 +20,16 @@ static void *MISSING = &MISSING; typedef void *bfs_getent_fn(const void *key, void *ptr, size_t bufsize); /** Shared scaffolding for get{pw,gr}{nam,?id}_r(). */ -static void *bfs_getent(bfs_getent_fn *fn, const void *key, struct trie_leaf *leaf, struct varena *varena, size_t bufsize) { +static void *bfs_getent(bfs_getent_fn *fn, const void *key, struct trie_leaf *leaf, struct varena *varena) { if (leaf->value) { errno = 0; return leaf->value == MISSING ? NULL : leaf->value; } + // _SC_GET{PW,GR}_R_SIZE_MAX tend to be fairly large (~1K). That's okay + // for temporary allocations, but for these long-lived ones, let's start + // with a smaller buffer. + size_t bufsize = 128; void *ptr = varena_alloc(varena, bufsize); if (!ptr) { return NULL; @@ -63,8 +67,6 @@ struct bfs_passwd { }; struct bfs_users { - /** Initial buffer size for getpw*_r(). */ - size_t bufsize; /** bfs_passwd arena. */ struct varena varena; /** A map from usernames to entries. */ @@ -79,13 +81,6 @@ struct bfs_users *bfs_users_new(void) { return NULL; } - long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize > 0) { - users->bufsize = bufsize; - } else { - users->bufsize = 1024; - } - VARENA_INIT(&users->varena, struct bfs_passwd, buf); trie_init(&users->by_name); trie_init(&users->by_uid); @@ -107,7 +102,7 @@ const struct passwd *bfs_getpwnam(struct bfs_users *users, const char *name) { return NULL; } - return bfs_getent(bfs_getpwnam_impl, name, leaf, &users->varena, users->bufsize); + return bfs_getent(bfs_getpwnam_impl, name, leaf, &users->varena); } /** bfs_getent() callback for getpwuid_r(). */ @@ -126,7 +121,7 @@ const struct passwd *bfs_getpwuid(struct bfs_users *users, uid_t uid) { return NULL; } - return bfs_getent(bfs_getpwuid_impl, &uid, leaf, &users->varena, users->bufsize); + return bfs_getent(bfs_getpwuid_impl, &uid, leaf, &users->varena); } void bfs_users_flush(struct bfs_users *users) { @@ -153,8 +148,6 @@ struct bfs_group { }; struct bfs_groups { - /** Initial buffer size for getgr*_r(). */ - size_t bufsize; /** bfs_group arena. */ struct varena varena; /** A map from group names to entries. */ @@ -169,13 +162,6 @@ struct bfs_groups *bfs_groups_new(void) { return NULL; } - long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); - if (bufsize > 0) { - groups->bufsize = bufsize; - } else { - groups->bufsize = 1024; - } - VARENA_INIT(&groups->varena, struct bfs_group, buf); trie_init(&groups->by_name); trie_init(&groups->by_gid); @@ -197,7 +183,7 @@ const struct group *bfs_getgrnam(struct bfs_groups *groups, const char *name) { return NULL; } - return bfs_getent(bfs_getgrnam_impl, name, leaf, &groups->varena, groups->bufsize); + return bfs_getent(bfs_getgrnam_impl, name, leaf, &groups->varena); } /** bfs_getent() callback for getgrgid_r(). */ @@ -216,7 +202,7 @@ const struct group *bfs_getgrgid(struct bfs_groups *groups, gid_t gid) { return NULL; } - return bfs_getent(bfs_getgrgid_impl, &gid, leaf, &groups->varena, groups->bufsize); + return bfs_getent(bfs_getgrgid_impl, &gid, leaf, &groups->varena); } void bfs_groups_flush(struct bfs_groups *groups) { -- cgit v1.2.3