*
* Virtual Server: Context Virtualization
*
- * Copyright (C) 2004 Herbert Pötzl
+ * Copyright (C) 2004-2005 Herbert Pötzl
*
* V0.01 broken out from limit.c
*
*/
#include <linux/config.h>
-#include <linux/vserver/cvirt.h>
-#include <linux/vserver/context.h>
-#include <linux/vserver/switch.h>
-#include <linux/vs_base.h>
+#include <linux/sched.h>
+#include <linux/types.h>
#include <linux/vs_context.h>
#include <linux/vs_cvirt.h>
+#include <linux/vserver/switch.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
return;
}
-uint64_t vx_idle_jiffies()
+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;
+ unsigned long long calc, prev;
/* just set it to n */
if (unlikely(delta >= wsize))
return (n << FSHIFT);
- calc = (delta * n) << FSHIFT;
- calc += (wsize - delta) * load;
+ 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;
spin_lock(&vxi->cvirt.load_lock);
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, atomic_read(&vxi->cvirt.nr_running));
+ 60*HZ, delta, total);
vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
- 5*60*HZ, delta, atomic_read(&vxi->cvirt.nr_running));
+ 5*60*HZ, delta, total);
vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
- 15*60*HZ, delta, atomic_read(&vxi->cvirt.nr_running));
+ 15*60*HZ, delta, total);
vxi->cvirt.load_last = now;
+out:
+ atomic_inc(&vxi->cvirt.load_updates);
spin_unlock(&vxi->cvirt.load_lock);
}
+/*
+ * 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 THRU */
+ case 3: /* Read last kernel messages */
+ // if (count > log_buf_len)
+ // count = log_buf_len;
+ spin_lock_irq(&log->logbuf_lock);
+ // if (count > logged_chars)
+ // count = logged_chars;
+ // if (do_clear)
+ // logged_chars = 0;
+ spin_unlock_irq(&log->logbuf_lock);
+ if (error)
+ break;
+ return 0;
+
+ case 5: /* Clear ring buffer */
+ // logged_chars = 0;
+ 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;
+}