X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Fcvirt.c;h=00a3a6a908f8d02e4ac92af2cc904d79e5e530a2;hb=refs%2Fheads%2Fvserver;hp=fb0684f7a75e679d584607e9157f63c4a60fa06f;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/kernel/vserver/cvirt.c b/kernel/vserver/cvirt.c index fb0684f7a..00a3a6a90 100644 --- a/kernel/vserver/cvirt.c +++ b/kernel/vserver/cvirt.c @@ -3,10 +3,11 @@ * * Virtual Server: Context Virtualization * - * Copyright (C) 2004-2005 Herbert Pötzl + * Copyright (C) 2004-2007 Herbert Pötzl * * V0.01 broken out from limit.c * V0.02 added utsname stuff + * V0.03 changed vcmds to vxi arg * */ @@ -97,32 +98,6 @@ out: } -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: * @@ -191,70 +166,139 @@ int vx_do_syslog(int type, char __user *buf, int len) static char * vx_vhi_name(struct vx_info *vxi, int id) { - switch (id) { - case VHIN_CONTEXT: + struct nsproxy *nsproxy; + struct uts_namespace *uts; + + + if (id == VHIN_CONTEXT) return vxi->vx_name; + + nsproxy = vxi->vx_nsproxy; + if (!nsproxy) + return NULL; + + uts = nsproxy->uts_ns; + if (!uts) + return NULL; + + switch (id) { case VHIN_SYSNAME: - return vxi->cvirt.utsname.sysname; + return uts->name.sysname; case VHIN_NODENAME: - return vxi->cvirt.utsname.nodename; + return uts->name.nodename; case VHIN_RELEASE: - return vxi->cvirt.utsname.release; + return uts->name.release; case VHIN_VERSION: - return vxi->cvirt.utsname.version; + return uts->name.version; case VHIN_MACHINE: - return vxi->cvirt.utsname.machine; + return uts->name.machine; case VHIN_DOMAINNAME: - return vxi->cvirt.utsname.domainname; + return uts->name.domainname; default: return NULL; } return NULL; } -int vc_set_vhi_name(uint32_t id, void __user *data) +int vc_set_vhi_name(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_vhi_name_v0 vc_data; char *name; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - name = vx_vhi_name(vxi, vc_data.field); - if (name) - memcpy(name, vc_data.name, 65); - put_vx_info(vxi); - return (name ? 0 : -EFAULT); + if (!name) + return -EINVAL; + + memcpy(name, vc_data.name, 65); + return 0; } -int vc_get_vhi_name(uint32_t id, void __user *data) +int vc_get_vhi_name(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_vhi_name_v0 vc_data; char *name; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - name = vx_vhi_name(vxi, vc_data.field); if (!name) - goto out_put; + return -EINVAL; memcpy(vc_data.name, name, 65); if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; -out_put: - put_vx_info(vxi); - return (name ? 0 : -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 +