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_context.h>
17 #include <linux/vs_cvirt.h>
18 #include <linux/vserver/switch.h>
19 #include <linux/vserver/cvirt_cmd.h>
21 #include <asm/errno.h>
22 #include <asm/uaccess.h>
25 void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
27 struct vx_info *vxi = current->vx_info;
29 set_normalized_timespec(uptime,
30 uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
31 uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
34 set_normalized_timespec(idle,
35 idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
36 idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
40 uint64_t vx_idle_jiffies(void)
42 return init_task.utime + init_task.stime;
47 static inline uint32_t __update_loadavg(uint32_t load,
48 int wsize, int delta, int n)
50 unsigned long long calc, prev;
52 /* just set it to n */
53 if (unlikely(delta >= wsize))
58 prev = (wsize - delta);
66 void vx_update_load(struct vx_info *vxi)
68 uint32_t now, last, delta;
69 unsigned int nr_running, nr_uninterruptible;
73 spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
76 last = vxi->cvirt.load_last;
82 nr_running = atomic_read(&vxi->cvirt.nr_running);
83 nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
84 total = nr_running + nr_uninterruptible;
86 vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
88 vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
89 5*60*HZ, delta, total);
90 vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
91 15*60*HZ, delta, total);
93 vxi->cvirt.load_last = now;
95 atomic_inc(&vxi->cvirt.load_updates);
96 spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
100 int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid,
101 void **datap, size_t *lenp)
103 switch (ctl->ctl_name) {
105 *datap = vx_new_uts(sysname);
108 *datap = vx_new_uts(release);
111 *datap = vx_new_uts(version);
114 *datap = vx_new_uts(nodename);
116 case KERN_DOMAINNAME:
117 *datap = vx_new_uts(domainname);
127 * Commands to do_syslog:
129 * 0 -- Close the log. Currently a NOP.
130 * 1 -- Open the log. Currently a NOP.
131 * 2 -- Read from the log.
132 * 3 -- Read all messages remaining in the ring buffer.
133 * 4 -- Read and clear all messages remaining in the ring buffer
134 * 5 -- Clear ring buffer.
135 * 6 -- Disable printk's to console
136 * 7 -- Enable printk's to console
137 * 8 -- Set level of messages printed to console
138 * 9 -- Return number of unread characters in the log buffer
139 * 10 -- Return size of the log buffer
141 int vx_do_syslog(int type, char __user *buf, int len)
145 struct vx_info *vxi = current->vx_info;
146 struct _vx_syslog *log;
150 log = &vxi->cvirt.syslog;
153 case 0: /* Close log */
154 case 1: /* Open log */
156 case 2: /* Read from log */
157 error = wait_event_interruptible(log->log_wait,
158 (log->log_start - log->log_end));
161 spin_lock_irq(&log->logbuf_lock);
162 spin_unlock_irq(&log->logbuf_lock);
164 case 4: /* Read/clear last kernel messages */
167 case 3: /* Read last kernel messages */
170 case 5: /* Clear ring buffer */
173 case 6: /* Disable logging to console */
174 case 7: /* Enable logging to console */
175 case 8: /* Set level of messages printed to console */
178 case 9: /* Number of chars in the log buffer */
180 case 10: /* Size of the log buffer */
190 /* virtual host info names */
192 static char * vx_vhi_name(struct vx_info *vxi, int id)
198 return vxi->cvirt.utsname.sysname;
200 return vxi->cvirt.utsname.nodename;
202 return vxi->cvirt.utsname.release;
204 return vxi->cvirt.utsname.version;
206 return vxi->cvirt.utsname.machine;
207 case VHIN_DOMAINNAME:
208 return vxi->cvirt.utsname.domainname;
215 int vc_set_vhi_name(uint32_t id, void __user *data)
218 struct vcmd_vhi_name_v0 vc_data;
221 if (!capable(CAP_SYS_ADMIN))
223 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
226 vxi = lookup_vx_info(id);
230 name = vx_vhi_name(vxi, vc_data.field);
232 memcpy(name, vc_data.name, 65);
234 return (name ? 0 : -EFAULT);
237 int vc_get_vhi_name(uint32_t id, void __user *data)
240 struct vcmd_vhi_name_v0 vc_data;
243 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
246 vxi = lookup_vx_info(id);
250 name = vx_vhi_name(vxi, vc_data.field);
254 memcpy(vc_data.name, name, 65);
255 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
259 return (name ? 0 : -EFAULT);