upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / kernel / vserver / cvirt.c
index 1cb3eda..799ebf6 100644 (file)
@@ -3,18 +3,21 @@
  *
  *  Virtual Server: Context Virtualization
  *
- *  Copyright (C) 2004  Herbert Pötzl
+ *  Copyright (C) 2004-2005  Herbert Pötzl
  *
  *  V0.01  broken out from limit.c
+ *  V0.02  added utsname stuff
  *
  */
 
 #include <linux/config.h>
 #include <linux/sched.h>
+#include <linux/sysctl.h>
 #include <linux/types.h>
 #include <linux/vs_context.h>
 #include <linux/vs_cvirt.h>
 #include <linux/vserver/switch.h>
+#include <linux/vserver/cvirt_cmd.h>
 
 #include <asm/errno.h>
 #include <asm/uaccess.h>
@@ -94,4 +97,164 @@ 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:
+ *
+ *      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(uint32_t id, 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 = locate_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);
+}
+
+int vc_get_vhi_name(uint32_t id, 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 = locate_vx_info(id);
+       if (!vxi)
+               return -ESRCH;
+
+       name = vx_vhi_name(vxi, vc_data.field);
+       if (!name)
+               goto out_put;
+
+       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);
+}