2 * linux/kernel/vserver/cvirt.c
4 * Virtual Server: Context Virtualization
6 * Copyright (C) 2004-2005 Herbert Pƶtzl
8 * V0.01 broken out from limit.c
9 * V0.02 added utsname stuff
13 #include <linux/sched.h>
14 #include <linux/sysctl.h>
15 #include <linux/types.h>
16 #include <linux/vs_base.h>
17 #include <linux/vs_context.h>
18 #include <linux/vs_cvirt.h>
19 #include <linux/vserver/switch.h>
20 #include <linux/vserver/cvirt_cmd.h>
22 #include <asm/errno.h>
23 #include <asm/uaccess.h>
26 void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
28 struct vx_info *vxi = current->vx_info;
30 set_normalized_timespec(uptime,
31 uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
32 uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
35 set_normalized_timespec(idle,
36 idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
37 idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
41 uint64_t vx_idle_jiffies(void)
43 return init_task.utime + init_task.stime;
48 static inline uint32_t __update_loadavg(uint32_t load,
49 int wsize, int delta, int n)
51 unsigned long long calc, prev;
53 /* just set it to n */
54 if (unlikely(delta >= wsize))
59 prev = (wsize - delta);
67 void vx_update_load(struct vx_info *vxi)
69 uint32_t now, last, delta;
70 unsigned int nr_running, nr_uninterruptible;
74 spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
77 last = vxi->cvirt.load_last;
83 nr_running = atomic_read(&vxi->cvirt.nr_running);
84 nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
85 total = nr_running + nr_uninterruptible;
87 vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
89 vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
90 5*60*HZ, delta, total);
91 vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
92 15*60*HZ, delta, total);
94 vxi->cvirt.load_last = now;
96 atomic_inc(&vxi->cvirt.load_updates);
97 spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
101 int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid,
102 void **datap, size_t *lenp)
104 switch (ctl->ctl_name) {
106 *datap = vx_new_uts(sysname);
109 *datap = vx_new_uts(release);
112 *datap = vx_new_uts(version);
115 *datap = vx_new_uts(nodename);
117 case KERN_DOMAINNAME:
118 *datap = vx_new_uts(domainname);
128 * Commands to do_syslog:
130 * 0 -- Close the log. Currently a NOP.
131 * 1 -- Open the log. Currently a NOP.
132 * 2 -- Read from the log.
133 * 3 -- Read all messages remaining in the ring buffer.
134 * 4 -- Read and clear all messages remaining in the ring buffer
135 * 5 -- Clear ring buffer.
136 * 6 -- Disable printk's to console
137 * 7 -- Enable printk's to console
138 * 8 -- Set level of messages printed to console
139 * 9 -- Return number of unread characters in the log buffer
140 * 10 -- Return size of the log buffer
142 int vx_do_syslog(int type, char __user *buf, int len)
146 struct vx_info *vxi = current->vx_info;
147 struct _vx_syslog *log;
151 log = &vxi->cvirt.syslog;
154 case 0: /* Close log */
155 case 1: /* Open log */
157 case 2: /* Read from log */
158 error = wait_event_interruptible(log->log_wait,
159 (log->log_start - log->log_end));
162 spin_lock_irq(&log->logbuf_lock);
163 spin_unlock_irq(&log->logbuf_lock);
165 case 4: /* Read/clear last kernel messages */
168 case 3: /* Read last kernel messages */
171 case 5: /* Clear ring buffer */
174 case 6: /* Disable logging to console */
175 case 7: /* Enable logging to console */
176 case 8: /* Set level of messages printed to console */
179 case 9: /* Number of chars in the log buffer */
181 case 10: /* Size of the log buffer */
191 /* virtual host info names */
193 static char * vx_vhi_name(struct vx_info *vxi, int id)
199 return vxi->cvirt.utsname.sysname;
201 return vxi->cvirt.utsname.nodename;
203 return vxi->cvirt.utsname.release;
205 return vxi->cvirt.utsname.version;
207 return vxi->cvirt.utsname.machine;
208 case VHIN_DOMAINNAME:
209 return vxi->cvirt.utsname.domainname;
216 int vc_set_vhi_name(uint32_t id, void __user *data)
219 struct vcmd_vhi_name_v0 vc_data;
222 if (!capable(CAP_SYS_ADMIN))
224 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
227 vxi = lookup_vx_info(id);
231 name = vx_vhi_name(vxi, vc_data.field);
233 memcpy(name, vc_data.name, 65);
235 return (name ? 0 : -EFAULT);
238 int vc_get_vhi_name(uint32_t id, void __user *data)
241 struct vcmd_vhi_name_v0 vc_data;
244 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
247 vxi = lookup_vx_info(id);
251 name = vx_vhi_name(vxi, vc_data.field);
255 memcpy(vc_data.name, name, 65);
256 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
260 return (name ? 0 : -EFAULT);