patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / kernel / sys.c
index 9523213..e7a076d 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/security.h>
 #include <linux/dcookies.h>
 #include <linux/suspend.h>
+#include <linux/vs_base.h>
+#include <linux/vs_cvirt.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -272,6 +274,10 @@ cond_syscall(compat_sys_mq_timedsend)
 cond_syscall(compat_sys_mq_timedreceive)
 cond_syscall(compat_sys_mq_notify)
 cond_syscall(compat_sys_mq_getsetattr)
+cond_syscall(sys_mbind)
+cond_syscall(sys_get_mempolicy)
+cond_syscall(sys_set_mempolicy)
+cond_syscall(compat_get_mempolicy)
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read)
@@ -349,6 +355,8 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                                if (p->uid == who)
                                        error = set_one_prio(p, niceval, error);
                        while_each_thread(g, p);
+                       if (who)
+                               free_uid(user);         /* For find_user() */
                        break;
        }
 out_unlock:
@@ -411,6 +419,8 @@ asmlinkage long sys_getpriority(int which, int who)
                                                retval = niceval;
                                }
                        while_each_thread(g, p);
+                       if (who)
+                               free_uid(user);         /* for find_user() */
                        break;
        }
 out_unlock:
@@ -419,72 +429,7 @@ out_unlock:
        return retval;
 }
 
-/*
- *      vshelper path is set via /proc/sys
- *      invoked by vserver sys_reboot(), with
- *      the following arguments
- *
- *      argv [0] = vshelper_path;
- *      argv [1] = action: "restart", "halt", "poweroff", ...
- *      argv [2] = context identifier
- *      argv [3] = additional argument (restart2)
- *
- *      envp [*] = type-specific parameters
- */
-char vshelper_path[255] = "/sbin/vshelper";
-
-long vs_reboot(unsigned int cmd, void * arg)
-{
-       char id_buf[8], cmd_buf[32];
-       char uid_buf[32], pid_buf[32];
-       char buffer[256];
-
-       char *argv[] = {vshelper_path, NULL, id_buf, NULL, 0};
-       char *envp[] = {"HOME=/", "TERM=linux",
-                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
-                       uid_buf, pid_buf, cmd_buf, 0};
-
-       snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
-
-       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
-       snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
-       snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
-
-       switch (cmd) {
-       case LINUX_REBOOT_CMD_RESTART:
-               argv[1] = "restart";
-               break;  
-
-       case LINUX_REBOOT_CMD_HALT:
-               argv[1] = "halt";
-               break;  
-
-       case LINUX_REBOOT_CMD_POWER_OFF:
-               argv[1] = "poweroff";
-               break;  
-
-       case LINUX_REBOOT_CMD_SW_SUSPEND:
-               argv[1] = "swsusp";
-               break;  
-
-       case LINUX_REBOOT_CMD_RESTART2:
-               if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0)
-                       return -EFAULT;
-               argv[3] = buffer;
-       default:
-               argv[1] = "restart2";
-               break;  
-       }
-
-       /* maybe we should wait ? */
-       if (call_usermodehelper(*argv, argv, envp, 0)) {
-               printk( KERN_WARNING
-                       "vs_reboot(): failed to exec (%s %s %s %s)\n",
-                       vshelper_path, argv[1], argv[2], argv[3]);
-               return -EPERM;
-       }
-       return 0;
-}
+long vs_reboot(unsigned int, void *);
 
 /*
  * Reboot system call: for obvious reasons only root may call it,
@@ -517,7 +462,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
        switch (cmd) {
        case LINUX_REBOOT_CMD_RESTART:
                notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
-               system_state = SYSTEM_SHUTDOWN;
+               system_state = SYSTEM_RESTART;
                device_shutdown();
                printk(KERN_EMERG "Restarting system.\n");
                machine_restart(NULL);
@@ -533,7 +478,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
 
        case LINUX_REBOOT_CMD_HALT:
                notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
-               system_state = SYSTEM_SHUTDOWN;
+               system_state = SYSTEM_HALT;
                device_shutdown();
                printk(KERN_EMERG "System halted.\n");
                machine_halt();
@@ -543,7 +488,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
 
        case LINUX_REBOOT_CMD_POWER_OFF:
                notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
-               system_state = SYSTEM_SHUTDOWN;
+               system_state = SYSTEM_POWER_OFF;
                device_shutdown();
                printk(KERN_EMERG "Power down.\n");
                machine_power_off();
@@ -559,7 +504,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
                buffer[sizeof(buffer) - 1] = '\0';
 
                notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
-               system_state = SYSTEM_SHUTDOWN;
+               system_state = SYSTEM_RESTART;
                device_shutdown();
                printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
                machine_restart(buffer);
@@ -882,7 +827,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
        return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
 }
 
-asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
+asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid)
 {
        int retval;
 
@@ -931,7 +876,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
        return 0;
 }
 
-asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
+asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid)
 {
        int retval;
 
@@ -1126,12 +1071,16 @@ asmlinkage long sys_getpgid(pid_t pid)
        }
 }
 
+#ifdef __ARCH_WANT_SYS_GETPGRP
+
 asmlinkage long sys_getpgrp(void)
 {
        /* SMP - assuming writes are word atomic this is fine */
        return process_group(current);
 }
 
+#endif
+
 asmlinkage long sys_getsid(pid_t pid)
 {
        if (!pid) {
@@ -1191,10 +1140,10 @@ struct group_info *groups_alloc(int gidsetsize)
        int nblocks;
        int i;
 
-       nblocks = (gidsetsize/NGROUPS_PER_BLOCK) +
-           (gidsetsize%NGROUPS_PER_BLOCK?1:0);
-       group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *),
-           GFP_USER);
+       nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
+       /* Make sure we always allocate at least one indirect block pointer */
+       nblocks = nblocks ? : 1;
+       group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
        if (!group_info)
                return NULL;
        group_info->ngroups = gidsetsize;
@@ -1340,8 +1289,12 @@ int set_current_groups(struct group_info *group_info)
 
        groups_sort(group_info);
        get_group_info(group_info);
+
+       task_lock(current);
        old_info = current->group_info;
        current->group_info = group_info;
+       task_unlock(current);
+
        put_group_info(old_info);
 
        return 0;
@@ -1361,6 +1314,7 @@ asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
        if (gidsetsize < 0)
                return -EINVAL;
 
+       /* no need to grab task_lock here; it cannot change */
        get_group_info(current->group_info);
        i = current->group_info->ngroups;
        if (gidsetsize) {
@@ -1474,6 +1428,8 @@ asmlinkage long sys_sethostname(char __user *name, int len)
        return errno;
 }
 
+#ifdef __ARCH_WANT_SYS_GETHOSTNAME
+
 asmlinkage long sys_gethostname(char __user *name, int len)
 {
        int i, errno;
@@ -1493,6 +1449,8 @@ asmlinkage long sys_gethostname(char __user *name, int len)
        return errno;
 }
 
+#endif
+
 /*
  * Only setdomainname; getdomainname can be implemented by calling
  * uname()
@@ -1529,7 +1487,7 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim)
                        ? -EFAULT : 0;
 }
 
-#if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64) || defined(CONFIG_V850))
+#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
 
 /*
  *     Back compatibility for getrlimit. Needed for some apps.
@@ -1565,7 +1523,7 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
        old_rlim = current->rlim + resource;
        if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
             (new_rlim.rlim_max > old_rlim->rlim_max)) &&
-           !capable(CAP_SYS_RESOURCE) && vx_ccaps(VXC_SET_RLIMIT))
+           !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT))
                return -EPERM;
        if (resource == RLIMIT_NOFILE) {
                if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)