RFC: Patch for >32 groups
Subsystems (5)
All,
Here is a set of patches (against a recent-ish 2.5 BK) that removes the arbitrary limit of 32 groups.
The first patch creates generic qsort() and bsearch() routines (I have another patch to conver XFS to use it, as discussed with Christoph a while back).
The second patch converts task->groups[] into a dynamic, refcounted, CoW array. It does the needed bits for i386 (minor) but not the other architectures. I have (not included here for brevity) patches that convert other arch trees to do the right thing (I think) and convert other usages of NGROUPS and task->groups and task->ngroups. There are still a few issues I am working out with those.
I wanted to post this (and CC: people who have mailed me about it) and see if there are any complaints about the approach. The patches are simple, and have been in use in our own 2.4.x systems or some time. I did make some changes in forward porting, but they are tested on at least one 2.5.x box here :)
This has the side effect of reducing the size of struct task_struct by a bit, too. :)
This should run on any glibc, without mods. Glibc will need to return a different value instead of NGROUPS (32), to be fully correct, though. I suggest INT_MAX :)
We've found a couple apps that needed to be fixed up in the event of >32 groups being used, and when this goes mainline, we'll pop out those patches, too. Another issue: this changes /proc/pid/status to only show 32 groups - not sure what better solution is preferred.
Comments, read-overs, and flames requested. Ideally I'd like to see this go into 2.5.x real soon now. :)
Tim
Signature · 4 lines
Tim Hockin Systems Software Engineer Sun Microsystems, Linux Kernel Engineering [email protected]
include/linux/kernel.h +5 -0
@@ -206,4 +206,9 @@#define __FUNCTION__ (__func__)#endif +void qsort (void *base,size_t nmemb,size_t size, +int (*compar)(const void *,const void *)); +void *bsearch (const void *key,const void *base,size_t nmemb,size_t size, +int (*compar)(const void *,const void *)); +#endif
lib/Makefile +3 -2
@@ -9,10 +9,11 @@ L_TARGET := lib.a export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \ - crc32.o rbtree.o radix-tree.o + crc32.o rbtree.o radix-tree.o qsort.o bsearch.o obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ - bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o + bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ + qsort.o bsearch.o obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
lib/bsearch.c +49 -0
49 lines not on this page · raw message
lib/qsort.c +180 -0
180 lines not on this page · raw message
fs/proc/array.c +1 -1
@@ -171,7 +171,7 @@ p->files ? p->files->max_fds : 0);task_unlock (p); -for (g =0 ; g < p->ngroups; g++) +for (g =0 ; g <min (p->ngroups,OLD_NGROUPS ); g++) buffer +=sprintf (buffer,"%d " , p->groups[g]); buffer +=sprintf (buffer,"\n" );
include/asm-i386/param.h +0 -4
@@ -13,10 +13,6 @@#define EXEC_PAGESIZE 4096 -#ifndef NGROUPS -#define NGROUPS 32 -#endif -#ifndef NOGROUP #define NOGROUP (-1)#endif
include/linux/init_task.h +1 -0
@@ -80,6 +80,7 @@ .real_timer = { \ .function = it_real_fn \ }, \ + .ngroups = 0, \ .cap_effective = CAP_INIT_EFF_SET, \ .cap_inheritable = CAP_INIT_INH_SET, \ .cap_permitted = CAP_FULL_SET, \
include/linux/limits.h +2 -1
@@ -3,7 +3,6 @@#define NR_OPEN 1024 -#define NGROUPS_MAX 32/* supplemental group IDs are available */ #define ARG_MAX 131072/* # bytes of args + environ for exec() */ #define CHILD_MAX 999/* no limit :-) */ #define OPEN_MAX 256/* # open files a process may have */
@@ -19,4 +18,6 @@#define RTSIG_MAX 32 +#define OLD_NGROUPS 32/* old limit of supplemental group IDs */ +#endif
include/linux/sched.h +2 -1
@@ -351,7 +351,8 @@uid_t uid,euid,suid,fsuid;gid_t gid,egid,sgid,fsgid;int ngroups; -gid_t groups[NGROUPS ]; +gid_t *groups; +atomic_t *groups_refcount;kernel_cap_t cap_effective, cap_inheritable, cap_permitted; int keep_capabilities:1;struct user_struct *user;
kernel/exit.c +7 -0
@@ -7,6 +7,7 @@#include <linux/config.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/vmalloc.h> #include <linux/interrupt.h> #include <linux/smp_lock.h> #include <linux/module.h>
@@ -64,6 +65,12 @@BUG ();if (p != current)wait_task_inactive (p); + +if (p->ngroups &&atomic_dec_and_test (p->groups_refcount)) { +vfree (p->groups_refcount); +vfree (p->groups); + } +atomic_dec (&p->user->processes); security_ops->task_free_security (p);free_uid (p->user);
kernel/fork.c +4 -0
@@ -805,6 +805,10 @@*/ clear_tsk_thread_flag (p,TIF_SYSCALL_TRACE ); +/* increment the groups ref count */ +if (p->ngroups) +atomic_inc (p->groups_refcount); +/* Our parent execution domain becomes current domain These must match for thread signalling to apply */
kernel/sys.c +69 -20
120 lines not on this page · raw message
kernel/uid16.c +48 -15
103 lines not on this page · raw message