core: increase the auxillary group limit to 65536

Make the allocation of groups dynamic and increase the limit
to 65536.

Change-Id: I702364ff460e3a982e44ccbcb3e337cac9c2df51
BUG: 953694
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/5111
Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
Anand Avati 2013-05-02 23:36:01 -07:00 committed by Vijay Bellur
parent e45e0037f6
commit 7cfef51189
7 changed files with 75 additions and 12 deletions

View File

@ -148,7 +148,7 @@
/* TODO: Keeping it to 200, so that we can fit in 2KB buffer for auth data
* in RPC server code, if there is ever need for having more aux-gids, then
* we have to add aux-gid in payload of actors */
#define GF_MAX_AUX_GROUPS 200
#define GF_MAX_AUX_GROUPS 65536
#define GF_UUID_BUF_SIZE 50

View File

@ -108,6 +108,7 @@ enum gf_common_mem_types_ {
gf_common_mt_drc_globals_t = 92,
gf_common_mt_drc_rbtree_node_t = 93,
gf_common_mt_iov_base_t = 94,
gf_common_mt_end = 95,
gf_common_mt_groups_t = 95,
gf_common_mt_end = 96
};
#endif

View File

@ -82,6 +82,8 @@ struct _call_frame_t {
const char *unwind_to;
};
#define SMALL_GROUP_COUNT 128
struct _call_stack_t {
union {
struct list_head all_frames;
@ -99,7 +101,9 @@ struct _call_stack_t {
gid_t gid;
pid_t pid;
uint16_t ngrps;
uint32_t groups[GF_MAX_AUX_GROUPS];
uint32_t groups_small[SMALL_GROUP_COUNT];
uint32_t *groups_large;
uint32_t *groups;
gf_lkowner_t lk_owner;
glusterfs_ctx_t *ctx;
@ -174,6 +178,9 @@ STACK_DESTROY (call_stack_t *stack)
while (stack->frames.next) {
FRAME_DESTROY (stack->frames.next);
}
GF_FREE (stack->groups_large);
mem_put (stack);
if (local)
@ -370,6 +377,24 @@ STACK_RESET (call_stack_t *stack)
} while (0)
static inline int
call_stack_alloc_groups (call_stack_t *stack, int ngrps)
{
if (ngrps <= SMALL_GROUP_COUNT) {
stack->groups = stack->groups_small;
} else {
stack->groups_large = GF_CALLOC (sizeof (gid_t), ngrps,
gf_common_mt_groups_t);
if (!stack->groups_large)
return -1;
stack->groups = stack->groups_large;
}
stack->ngrps = ngrps;
return 0;
}
static inline call_frame_t *
copy_frame (call_frame_t *frame)
{
@ -393,8 +418,12 @@ copy_frame (call_frame_t *frame)
newstack->ngrps = oldstack->ngrps;
newstack->op = oldstack->op;
newstack->type = oldstack->type;
if (call_stack_alloc_groups (newstack, oldstack->ngrps) != 0) {
mem_put (newstack);
return NULL;
}
memcpy (newstack->groups, oldstack->groups,
sizeof (gid_t) * GF_MAX_AUX_GROUPS);
sizeof (gid_t) * oldstack->ngrps);
newstack->unique = oldstack->unique;
newstack->frames.this = frame->this;

View File

@ -240,6 +240,7 @@ static inline call_frame_t *
syncop_create_frame (xlator_t *this)
{
call_frame_t *frame = NULL;
int ngrps = -1;
frame = create_frame (this, this->ctx->pool);
if (!frame)
@ -248,7 +249,21 @@ syncop_create_frame (xlator_t *this)
frame->root->pid = getpid();
frame->root->uid = geteuid ();
frame->root->gid = getegid ();
frame->root->ngrps = getgroups (GF_MAX_AUX_GROUPS, frame->root->groups);
ngrps = getgroups (0, 0);
if (ngrps < 0) {
STACK_DESTROY (frame->root);
return NULL;
}
if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
STACK_DESTROY (frame->root);
return NULL;
}
if (getgroups (ngrps, frame->root->groups) < 0) {
STACK_DESTROY (frame->root);
return NULL;
}
return frame;
}

View File

@ -14,9 +14,6 @@
#include <sys/sysctl.h>
#endif
#ifndef GF_REQUEST_MAXGROUPS
#define GF_REQUEST_MAXGROUPS 16
#endif /* GF_REQUEST_MAXGROUPS */
static void
fuse_resolve_wipe (fuse_resolve_t *resolve)
@ -138,6 +135,7 @@ get_fuse_state (xlator_t *this, fuse_in_header_t *finh)
}
#define FUSE_MAX_AUX_GROUPS 32 /* We can get only up to 32 aux groups from /proc */
void
frame_fill_groups (call_frame_t *frame)
{
@ -160,6 +158,9 @@ frame_fill_groups (call_frame_t *frame)
if (!fp)
goto out;
if (call_stack_alloc_groups (frame->root, FUSE_MAX_AUX_GROUPS) != 0)
goto out;
while ((ptr = fgets (line, sizeof line, fp))) {
if (strncmp (ptr, "Groups:", 7) != 0)
continue;
@ -176,7 +177,7 @@ frame_fill_groups (call_frame_t *frame)
if (!endptr || *endptr)
break;
frame->root->groups[idx++] = id;
if (idx == GF_MAX_AUX_GROUPS)
if (idx == FUSE_MAX_AUX_GROUPS)
break;
}
@ -192,6 +193,7 @@ out:
prcred_t *prcred = (prcred_t *) scratch;
FILE *fp = NULL;
int ret = 0;
int ngrps;
ret = snprintf (filename, sizeof filename,
"/proc/%d/cred", frame->root->pid);
@ -200,8 +202,11 @@ out:
fp = fopen (filename, "r");
if (fp != NULL) {
if (fgets (scratch, sizeof scratch, fp) != NULL) {
frame->root->ngrps = MIN(prcred->pr_ngroups,
GF_REQUEST_MAXGROUPS);
ngrps = MIN(prcred->pr_ngroups,
GF_MAX_AUX_GROUPS);
if (call_stack_alloc_groups (frame->root,
ngrps) != 0)
return;
}
fclose (fp);
}
@ -226,7 +231,9 @@ out:
if (sysctl(name, namelen, &kp, &kplen, NULL, 0) != 0)
return;
ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_REQUEST_MAXGROUPS);
ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_MAX_AUX_GROUPS);
if (call_stack_alloc_groups (frame->root, ngroups) != 0)
return;
for (i = 0; i < ngroups; i++)
frame->root->groups[i] = kp.kp_eproc.e_ucred.cr_groups[i];
frame->root->ngrps = ngroups;
@ -257,6 +264,8 @@ static void get_groups(fuse_private_t *priv, call_frame_t *frame)
gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid);
if (gl) {
if (call_stack_alloc_groups (frame->root, gl->gl_count) != 0)
return;
frame->root->ngrps = gl->gl_count;
for (i = 0; i < gl->gl_count; i++)
frame->root->groups[i] = gl->gl_list[i];

View File

@ -191,6 +191,12 @@ nfs_create_frame (xlator_t *xl, nfs_user_t *nfu)
frame = create_frame (xl, (call_pool_t *)xl->ctx->pool);
if (!frame)
goto err;
if (call_stack_alloc_groups (frame->root, nfu->ngrps) != 0) {
STACK_DESTROY (frame->root);
frame = NULL;
goto err;
}
frame->root->pid = NFS_PID;
frame->root->uid = nfu->uid;
frame->root->gid = nfu->gids[NFS_PRIMGID_IDX];

View File

@ -26,6 +26,9 @@ server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req)
GF_VALIDATE_OR_GOTO ("server", frame, out);
GF_VALIDATE_OR_GOTO ("server", req, out);
if (call_stack_alloc_groups (frame->root, req->auxgidcount) != 0)
return -1;
frame->root->ngrps = req->auxgidcount;
if (frame->root->ngrps == 0)
return 0;