diff -NurpP --minimal DEVEL/linux-2.4.21-vs1.1.5/Makefile DEVEL/linux-2.4.21-vs1.1.6/Makefile --- DEVEL/linux-2.4.21-vs1.1.5/Makefile Mon Dec 1 16:18:06 2003 +++ DEVEL/linux-2.4.21-vs1.1.6/Makefile Mon Dec 1 16:18:26 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 21 -EXTRAVERSION = -vs1.1.5 +EXTRAVERSION = -vs1.1.6 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -NurpP --minimal DEVEL/linux-2.4.21-vs1.1.5/include/linux/vswitch.h DEVEL/linux-2.4.21-vs1.1.6/include/linux/vswitch.h --- DEVEL/linux-2.4.21-vs1.1.5/include/linux/vswitch.h Mon Dec 1 16:18:07 2003 +++ DEVEL/linux-2.4.21-vs1.1.6/include/linux/vswitch.h Mon Dec 1 16:18:26 2003 @@ -92,8 +92,8 @@ struct vcmd_set_ipv4root_v3 { #define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0) struct vcmd_ctx_kill_v0 { - int32_t pid; - int32_t signal; + int32_t pid; + int32_t sig; }; /* rlimit vserver commands */ diff -NurpP --minimal DEVEL/linux-2.4.21-vs1.1.5/kernel/vcontext.c DEVEL/linux-2.4.21-vs1.1.6/kernel/vcontext.c --- DEVEL/linux-2.4.21-vs1.1.5/kernel/vcontext.c Mon Dec 1 16:18:07 2003 +++ DEVEL/linux-2.4.21-vs1.1.6/kernel/vcontext.c Mon Dec 1 16:18:26 2003 @@ -12,9 +12,10 @@ #include #include #include -#include +#include #include #include +#include #include #include @@ -23,7 +24,60 @@ int vc_ctx_kill(uint32_t id, void *data) { - return -ENOSYS; + int retval, count=0; + struct vcmd_ctx_kill_v0 vc_data; + struct siginfo info; + struct task_struct *p; + pid_t initpid = 0; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + if (!vx_check(0, VX_ADMIN)) + return -EPERM; + + info.si_signo = vc_data.sig; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->pid; + info.si_uid = current->uid; + + retval = -ESRCH; + read_lock(&tasklist_lock); + switch (vc_data.pid) { + case -1: + case 0: + for_each_task(p) { + if (!initpid && p->vx_id == id && p->s_info) + initpid = p->s_info->initpid; + if (p->vx_id == id && p->pid > 1 + && (!vc_data.pid || initpid != p->pid) + && thread_group_leader(p)) { + int err = send_sig_info(vc_data.sig, &info, p); + + ++count; + if (err != -EPERM) + retval = err; + } + } + break; + + default: + p = find_task_by_pid(vc_data.pid); + if (p) { + if (!thread_group_leader(p)) { + struct task_struct *tg; + + tg = find_task_by_pid(p->tgid); + if (tg) + p = tg; + } + if (p->vx_id == id) + retval = send_sig_info(vc_data.sig, &info, p); + } + break; + } + read_unlock(&tasklist_lock); + return retval; } int vc_get_rlimit(uint32_t id, void *data) @@ -52,8 +106,9 @@ int vc_get_rlimit_mask(uint32_t id, void */ static void vx_alloc_info(void) { - struct context_info *s_info = vmalloc(sizeof(struct context_info)); + struct context_info *s_info; + s_info = kmalloc(sizeof(struct context_info), GFP_KERNEL); if (s_info) { int i; memset (s_info, 0, sizeof(*s_info)); @@ -66,7 +121,8 @@ static void vx_alloc_info(void) s_info->total_forks = 0; s_info->bias_cswtch = kstat.context_swtch; s_info->bias_jiffies = jiffies; - s_info->bias_idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime; + s_info->bias_idle = init_tasks[0]->times.tms_utime + + init_tasks[0]->times.tms_stime; for (i=0; irlim[i] = 0xffffffff; atomic_set(&s_info->res[i], 0); @@ -116,7 +172,7 @@ void vx_release_info (struct task_struct down_write (&uts_sem); if (p->s_info) { if (atomic_dec_and_test(&p->s_info->refcount)) { - vfree (p->s_info); + kfree(p->s_info); p->s_info = NULL; } } @@ -129,7 +185,8 @@ void vx_release_info (struct task_struct */ static void vx_alloc_ip_info(void) { - struct iproot_info *ip_info = vmalloc(sizeof(struct iproot_info)); + struct iproot_info *ip_info = + kmalloc(sizeof(struct iproot_info), GFP_KERNEL); memset(ip_info, 0, sizeof(*ip_info)); ip_info->mark = 0xdeadbeef; @@ -158,7 +215,7 @@ void vx_release_ip_info (struct iproot_i { if (ip_info) if (atomic_dec_and_test(&ip_info->refcount)) - vfree(ip_info); + kfree(ip_info); } @@ -215,44 +272,51 @@ int vc_new_s_context(uint32_t ctx, void || !(current->s_info->flags & VX_INFO_LOCK)) { /* Ok we allocate a new context. For now, we just increase */ /* it. Wrap around possible, so we loop */ - static int alloc_ctx = MIN_D_CONTEXT; + static int new_xid = MAX_S_CONTEXT; static spinlock_t alloc_ctx_lock = SPIN_LOCK_UNLOCKED; + int old_xid = current->vx_id; + int barrier = new_xid; + int valid = 0; spin_lock(&alloc_ctx_lock); - while (1) { - int found = 0; + do { struct task_struct *p; + + valid = 1; + if (++new_xid > MAX_S_CONTEXT) + new_xid = MIN_D_CONTEXT; - alloc_ctx++; - /* The vx_id 1 is special. It sess all processes */ - if (alloc_ctx == 1) - alloc_ctx++; - else if (alloc_ctx > MAX_S_CONTEXT) - // No need to grow and grow - alloc_ctx = MIN_D_CONTEXT; /* Check if in use */ read_lock(&tasklist_lock); for_each_task(p) { - if (p->vx_id == alloc_ctx) { - found = 1; + if (p->vx_id == new_xid) { + valid = 0; break; } } read_unlock(&tasklist_lock); - if (!found) break; - } - ret = vx_switch_user_struct(alloc_ctx); + + if (valid) { + current->vx_id = new_xid; + break; + } + } while (barrier != new_xid); + spin_unlock(&alloc_ctx_lock); + + if (!valid) + return -EDEADLK; + + ret = vx_switch_user_struct(new_xid); if (ret == 0) { - current->vx_id = alloc_ctx; current->cap_bset &= (~vc_data.remove_cap); - ret = alloc_ctx; + ret = new_xid; vx_alloc_info(); if (current->s_info) { vx_set_initpid(vc_data.flags); current->s_info->flags |= vc_data.flags; } - } - spin_unlock(&alloc_ctx_lock); + } else + current->vx_id = old_xid; } } else if (ctx == -2) { ret = vx_set_initpid(vc_data.flags); diff -NurpP --minimal DEVEL/linux-2.4.21-vs1.1.5/net/ipv6/tcp_ipv6.c DEVEL/linux-2.4.21-vs1.1.6/net/ipv6/tcp_ipv6.c --- DEVEL/linux-2.4.21-vs1.1.5/net/ipv6/tcp_ipv6.c Mon Dec 1 16:18:08 2003 +++ DEVEL/linux-2.4.21-vs1.1.6/net/ipv6/tcp_ipv6.c Mon Dec 1 16:18:27 2003 @@ -2095,7 +2095,7 @@ int tcp6_get_info(char *buffer, char **s tw != NULL; tw = (struct tcp_tw_bucket *)tw->next, num++) { if (tw->family != PF_INET6 || - !vx_check(sk->vx_id, VX_WATCH|VX_IDENT)) + !vx_check(tw->vx_id, VX_WATCH|VX_IDENT)) continue; pos += LINE_LEN+1; if (pos <= offset)