--- linux-2.6.18.2/arch/parisc/kernel/sys_parisc32.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/parisc/kernel/sys_parisc32.c 2006-09-25 15:40:02 +0200 @@ -598,6 +598,7 @@ asmlinkage int sys32_sysinfo(struct sysi do { seq = read_seqbegin(&xtime_lock); + /* FIXME: requires vx virtualization */ val.uptime = jiffies / HZ; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); --- linux-2.6.18.2/fs/ioprio.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/ioprio.c 2006-10-07 04:29:47 +0200 @@ -104,7 +104,7 @@ asmlinkage long sys_ioprio_set(int which if (!who) user = current->user; else - user = find_user(who); + user = find_user(vx_current_xid(), who); if (!user) break; --- linux-2.6.18.2/fs/ioprio.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/ioprio.c 2006-10-07 04:29:47 +0200 @@ -197,7 +197,7 @@ asmlinkage long sys_ioprio_get(int which if (!who) user = current->user; else - user = find_user(who); + user = find_user(vx_current_xid(), who); if (!user) break; --- linux-2.6.18.2/fs/open.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/open.c 2006-11-04 08:24:09 +0100 @@ -36,8 +40,10 @@ int vfs_statfs(struct dentry *dentry, st int retval = -ENODEV; if (dentry) { + struct super_block *sb = dentry->d_sb; + retval = -ENOSYS; - if (dentry->d_sb->s_op->statfs) { + if (sb->s_op->statfs) { memset(buf, 0, sizeof(*buf)); retval = security_sb_statfs(dentry); if (retval) --- linux-2.6.18.2/fs/open.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/open.c 2006-11-04 08:24:09 +0100 @@ -42,7 +48,7 @@ ***** retval = security_sb_statfs(dentry); if (retval) return retval; - retval = dentry->d_sb->s_op->statfs(dentry, buf); + retval = sb->s_op->statfs(dentry, buf); if (retval == 0 && buf->f_frsize == 0) buf->f_frsize = buf->f_bsize; } --- linux-2.6.18.2/fs/open.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/open.c 2006-11-04 08:24:09 +0100 @@ -46,6 +52,8 @@ ***** if (retval == 0 && buf->f_frsize == 0) buf->f_frsize = buf->f_bsize; } + if (!vx_check(0, VX_ADMIN|VX_WATCH)) + vx_vsi_statfs(sb, buf); } return retval; } --- linux-2.6.18.2/fs/proc/array.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/proc/array.c 2006-10-25 03:39:09 +0200 @@ -410,6 +472,17 @@ static int do_task_stat(struct task_stru /* convert nsec -> ticks */ start_time = nsec_to_clock_t(start_time); + /* fixup start time for virt uptime */ + if (vx_flags(VXF_VIRT_UPTIME, 0)) { + unsigned long long bias = + current->vx_info->cvirt.bias_clock; + + if (start_time > bias) + start_time -= bias; + else + start_time = 0; + } + res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n", --- linux-2.6.18.2/fs/proc/proc_misc.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/proc/proc_misc.c 2006-09-20 18:36:46 +0200 @@ -84,10 +87,24 @@ ***** int a, b, c; int len; - a = avenrun[0] + (FIXED_1/200); - b = avenrun[1] + (FIXED_1/200); - c = avenrun[2] + (FIXED_1/200); - len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", + if (vx_flags(VXF_VIRT_LOAD, 0)) { + struct vx_info *vxi = current->vx_info; + + a = vxi->cvirt.load[0] + (FIXED_1/200); + b = vxi->cvirt.load[1] + (FIXED_1/200); + c = vxi->cvirt.load[2] + (FIXED_1/200); + + running = atomic_read(&vxi->cvirt.nr_running); + threads = atomic_read(&vxi->cvirt.nr_threads); + } else { + a = avenrun[0] + (FIXED_1/200); + b = avenrun[1] + (FIXED_1/200); + c = avenrun[2] + (FIXED_1/200); + + running = nr_running(); + threads = nr_threads; + } + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n", LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c), --- linux-2.6.18.2/fs/proc/proc_misc.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/proc/proc_misc.c 2006-09-20 18:36:46 +0200 @@ -105,6 +122,9 @@ static int uptime_read_proc(char *page, do_posix_clock_monotonic_gettime(&uptime); cputime_to_timespec(idletime, &idle); + if (vx_flags(VXF_VIRT_UPTIME, 0)) + vx_vsi_uptime(&uptime, &idle); + len = sprintf(page,"%lu.%02lu %lu.%02lu\n", (unsigned long) uptime.tv_sec, (uptime.tv_nsec / (NSEC_PER_SEC / 100)), --- linux-2.6.18.2/fs/proc/proc_misc.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/proc/proc_misc.c 2006-09-20 18:36:46 +0200 @@ -141,7 +161,7 @@ static int meminfo_read_proc(char *page, cached = global_page_state(NR_FILE_PAGES) - total_swapcache_pages - i.bufferram; - if (cached < 0) + if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0)) cached = 0; get_vmalloc_info(&vmi); --- linux-2.6.18.2/include/linux/vserver/cvirt.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.18.2-vs2.1.1/include/linux/vserver/cvirt.h 2006-09-25 15:40:02 +0200 @@ -0,0 +1,24 @@ +#ifndef _VX_CVIRT_H +#define _VX_CVIRT_H + + +#ifdef __KERNEL__ + +struct timespec; + +void vx_vsi_uptime(struct timespec *, struct timespec *); + + +struct vx_info; + +void vx_update_load(struct vx_info *); + + +int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid, + void **datap, size_t *lenp); + + +int vx_do_syslog(int, char __user *, int); + +#endif /* __KERNEL__ */ +#endif /* _VX_CVIRT_H */ --- linux-2.6.18.2/kernel/sched.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/kernel/sched.c 2006-10-28 19:04:30 +0200 @@ -2951,9 +2998,12 @@ static inline int expired_starving(struc void account_user_time(struct task_struct *p, cputime_t cputime) { struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; + struct vx_info *vxi = p->vx_info; /* p is _always_ current */ cputime64_t tmp; + int nice = (TASK_NICE(p) > 0); p->utime = cputime_add(p->utime, cputime); + vx_account_user(vxi, cputime, nice); /* Add user time to cpustat. */ tmp = cputime_to_cputime64(cputime); --- linux-2.6.18.2/kernel/sched.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/kernel/sched.c 2006-10-28 19:04:30 +0200 @@ -2973,6 +3023,7 @@ void account_system_time(struct task_str cputime_t cputime) { struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; + struct vx_info *vxi = p->vx_info; /* p is _always_ current */ struct rq *rq = this_rq(); cputime64_t tmp; --- linux-2.6.18.2/kernel/sched.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/kernel/sched.c 2006-10-28 19:04:30 +0200 @@ -2977,6 +3028,7 @@ ***** cputime64_t tmp; p->stime = cputime_add(p->stime, cputime); + vx_account_system(vxi, cputime, (p == rq->idle)); /* Add system time to cpustat. */ tmp = cputime_to_cputime64(cputime); --- linux-2.6.18.2/kernel/sysctl.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/kernel/sysctl.c 2006-10-18 01:14:31 +0200 @@ -1644,7 +1664,7 @@ ***** if (len > *lenp) len = *lenp; if (len) - if(copy_to_user(buffer, table->data, len)) + if(copy_to_user(buffer, data, len)) return -EFAULT; if (len < *lenp) { if(put_user('\n', ((char __user *) buffer) + len)) --- linux-2.6.18.2/kernel/timer.c 2006-09-20 16:58:44 +0200 +++ linux-2.6.18.2-vs2.1.1/kernel/timer.c 2006-11-03 00:38:37 +0100 @@ -1500,6 +1510,8 @@ asmlinkage long sys_sysinfo(struct sysin tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; tp.tv_sec++; } + if (vx_flags(VXF_VIRT_UPTIME, 0)) + vx_vsi_uptime(&tp, NULL); val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); --- linux-2.6.18.2/kernel/vserver/cvirt.c 1970-01-01 01:00:00 +0100 +++ linux-2.6.18.2-vs2.1.1/kernel/vserver/cvirt.c 2006-10-02 02:28:37 +0200 @@ -0,0 +1,318 @@ +/* + * linux/kernel/vserver/cvirt.c + * + * Virtual Server: Context Virtualization + * + * Copyright (C) 2004-2006 Herbert Pötzl + * + * V0.01 broken out from limit.c + * V0.02 added utsname stuff + * V0.03 changed vcmds to vxi arg + * + */ + +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include + + +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle) +{ + struct vx_info *vxi = current->vx_info; + + set_normalized_timespec(uptime, + uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec, + uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec); + if (!idle) + return; + set_normalized_timespec(idle, + idle->tv_sec - vxi->cvirt.bias_idle.tv_sec, + idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec); + return; +} + +uint64_t vx_idle_jiffies(void) +{ + return init_task.utime + init_task.stime; +} + + + +static inline uint32_t __update_loadavg(uint32_t load, + int wsize, int delta, int n) +{ + unsigned long long calc, prev; + + /* just set it to n */ + if (unlikely(delta >= wsize)) + return (n << FSHIFT); + + calc = delta * n; + calc <<= FSHIFT; + prev = (wsize - delta); + prev *= load; + calc += prev; + do_div(calc, wsize); + return calc; +} + + +void vx_update_load(struct vx_info *vxi) +{ + uint32_t now, last, delta; + unsigned int nr_running, nr_uninterruptible; + unsigned int total; + unsigned long flags; + + spin_lock_irqsave(&vxi->cvirt.load_lock, flags); + + now = jiffies; + last = vxi->cvirt.load_last; + delta = now - last; + + if (delta < 5*HZ) + goto out; + + nr_running = atomic_read(&vxi->cvirt.nr_running); + nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible); + total = nr_running + nr_uninterruptible; + + vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0], + 60*HZ, delta, total); + vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1], + 5*60*HZ, delta, total); + vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2], + 15*60*HZ, delta, total); + + vxi->cvirt.load_last = now; +out: + atomic_inc(&vxi->cvirt.load_updates); + spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags); +} + + +int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid, + void **datap, size_t *lenp) +{ + switch (ctl->ctl_name) { + case KERN_OSTYPE: + *datap = vx_new_uts(sysname); + break; + case KERN_OSRELEASE: + *datap = vx_new_uts(release); + break; + case KERN_VERSION: + *datap = vx_new_uts(version); + break; + case KERN_NODENAME: + *datap = vx_new_uts(nodename); + break; + case KERN_DOMAINNAME: + *datap = vx_new_uts(domainname); + break; + } + + return 0; +} + + + +/* + * Commands to do_syslog: + * + * 0 -- Close the log. Currently a NOP. + * 1 -- Open the log. Currently a NOP. + * 2 -- Read from the log. + * 3 -- Read all messages remaining in the ring buffer. + * 4 -- Read and clear all messages remaining in the ring buffer + * 5 -- Clear ring buffer. + * 6 -- Disable printk's to console + * 7 -- Enable printk's to console + * 8 -- Set level of messages printed to console + * 9 -- Return number of unread characters in the log buffer + * 10 -- Return size of the log buffer + */ +int vx_do_syslog(int type, char __user *buf, int len) +{ + int error = 0; + int do_clear = 0; + struct vx_info *vxi = current->vx_info; + struct _vx_syslog *log; + + if (!vxi) + return -EINVAL; + log = &vxi->cvirt.syslog; + + switch (type) { + case 0: /* Close log */ + case 1: /* Open log */ + break; + case 2: /* Read from log */ + error = wait_event_interruptible(log->log_wait, + (log->log_start - log->log_end)); + if (error) + break; + spin_lock_irq(&log->logbuf_lock); + spin_unlock_irq(&log->logbuf_lock); + break; + case 4: /* Read/clear last kernel messages */ + do_clear = 1; + /* fall through */ + case 3: /* Read last kernel messages */ + return 0; + + case 5: /* Clear ring buffer */ + return 0; + + case 6: /* Disable logging to console */ + case 7: /* Enable logging to console */ + case 8: /* Set level of messages printed to console */ + break; + + case 9: /* Number of chars in the log buffer */ + return 0; + case 10: /* Size of the log buffer */ + return 0; + default: + error = -EINVAL; + break; + } + return error; +} + + +/* virtual host info names */ + +static char * vx_vhi_name(struct vx_info *vxi, int id) +{ + switch (id) { + case VHIN_CONTEXT: + return vxi->vx_name; + case VHIN_SYSNAME: + return vxi->cvirt.utsname.sysname; + case VHIN_NODENAME: + return vxi->cvirt.utsname.nodename; + case VHIN_RELEASE: + return vxi->cvirt.utsname.release; + case VHIN_VERSION: + return vxi->cvirt.utsname.version; + case VHIN_MACHINE: + return vxi->cvirt.utsname.machine; + case VHIN_DOMAINNAME: + return vxi->cvirt.utsname.domainname; + default: + return NULL; + } + return NULL; +} + +int vc_set_vhi_name(struct vx_info *vxi, void __user *data) +{ + struct vcmd_vhi_name_v0 vc_data; + char *name; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + name = vx_vhi_name(vxi, vc_data.field); + if (!name) + return -EINVAL; + + memcpy(name, vc_data.name, 65); + return 0; +} + +int vc_get_vhi_name(struct vx_info *vxi, void __user *data) +{ + struct vcmd_vhi_name_v0 vc_data; + char *name; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + name = vx_vhi_name(vxi, vc_data.field); + if (!name) + return -EINVAL; + + memcpy(vc_data.name, name, 65); + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + return -EFAULT; + return 0; +} + + +int vc_virt_stat(struct vx_info *vxi, void __user *data) +{ + struct vcmd_virt_stat_v0 vc_data; + struct _vx_cvirt *cvirt = &vxi->cvirt; + struct timespec uptime; + + do_posix_clock_monotonic_gettime(&uptime); + set_normalized_timespec(&uptime, + uptime.tv_sec - cvirt->bias_uptime.tv_sec, + uptime.tv_nsec - cvirt->bias_uptime.tv_nsec); + + vc_data.offset = timeval_to_ns(&cvirt->bias_tv); + vc_data.uptime = timespec_to_ns(&uptime); + vc_data.nr_threads = atomic_read(&cvirt->nr_threads); + vc_data.nr_running = atomic_read(&cvirt->nr_running); + vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible); + vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold); + vc_data.nr_forks = atomic_read(&cvirt->total_forks); + vc_data.load[0] = cvirt->load[0]; + vc_data.load[1] = cvirt->load[1]; + vc_data.load[2] = cvirt->load[2]; + + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + return -EFAULT; + return 0; +} + + +#ifdef CONFIG_VSERVER_VTIME + +/* virtualized time base */ + +void vx_gettimeofday(struct timeval *tv) +{ + do_gettimeofday(tv); + if (!vx_flags(VXF_VIRT_TIME, 0)) + return; + + tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec; + tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec; + + if (tv->tv_usec >= USEC_PER_SEC) { + tv->tv_sec++; + tv->tv_usec -= USEC_PER_SEC; + } else if (tv->tv_usec < 0) { + tv->tv_sec--; + tv->tv_usec += USEC_PER_SEC; + } +} + +int vx_settimeofday(struct timespec *ts) +{ + struct timeval tv; + + if (!vx_flags(VXF_VIRT_TIME, 0)) + return do_settimeofday(ts); + + do_gettimeofday(&tv); + current->vx_info->cvirt.bias_tv.tv_sec = + ts->tv_sec - tv.tv_sec; + current->vx_info->cvirt.bias_tv.tv_usec = + (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec; + return 0; +} + +#endif + --- linux-2.6.18.2/mm/page_alloc.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/mm/page_alloc.c 2006-11-04 19:12:54 +0100 @@ -1223,6 +1224,8 @@ void si_meminfo(struct sysinfo *val) val->freehigh = 0; #endif val->mem_unit = PAGE_SIZE; + if (vx_flags(VXF_VIRT_MEM, 0)) + vx_vsi_meminfo(val); } EXPORT_SYMBOL(si_meminfo); --- linux-2.6.18.2/mm/page_alloc.c 2006-11-04 19:43:24 +0100 +++ linux-2.6.18.2-vs2.1.1/mm/page_alloc.c 2006-11-04 19:12:54 +0100 @@ -1237,6 +1240,8 @@ void si_meminfo_node(struct sysinfo *val val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].present_pages; val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages; val->mem_unit = PAGE_SIZE; + if (vx_flags(VXF_VIRT_MEM, 0)) + vx_vsi_meminfo(val); } #endif --- linux-2.6.18.2/mm/swapfile.c 2006-09-20 16:58:45 +0200 +++ linux-2.6.18.2-vs2.1.1/mm/swapfile.c 2006-09-20 17:01:45 +0200 @@ -1667,6 +1668,8 @@ void si_swapinfo(struct sysinfo *val) val->freeswap = nr_swap_pages + nr_to_be_unused; val->totalswap = total_swap_pages + nr_to_be_unused; spin_unlock(&swap_lock); + if (vx_flags(VXF_VIRT_MEM, 0)) + vx_vsi_swapinfo(val); } /*