Couple bug fixes
[linux-2.6.git] / linux-2.6-595-vserver-setspace.patch
1 diff -Nurb linux-2.6.22-594/arch/i386/kernel/syscall_table.S linux-2.6.22-595/arch/i386/kernel/syscall_table.S
2 --- linux-2.6.22-594/arch/i386/kernel/syscall_table.S   2008-03-20 13:29:27.000000000 -0400
3 +++ linux-2.6.22-595/arch/i386/kernel/syscall_table.S   2008-03-20 13:32:56.000000000 -0400
4 @@ -326,3 +326,4 @@
5         .long sys_revokeat
6         .long sys_frevoke               /* 325 */
7         .long sys_fallocate
8 +       .long sys_set_space             
9 diff -Nurb linux-2.6.22-594/kernel/nsproxy.c linux-2.6.22-595/kernel/nsproxy.c
10 --- linux-2.6.22-594/kernel/nsproxy.c   2008-03-20 13:29:30.000000000 -0400
11 +++ linux-2.6.22-595/kernel/nsproxy.c   2008-03-20 14:28:05.000000000 -0400
12 @@ -23,11 +23,55 @@
13  #include <linux/pid_namespace.h>
14  #include <linux/vserver/global.h>
15  #include <linux/vserver/debug.h>
16 +#include <linux/sched.h>
17 +
18 +#include <net/net_namespace.h>
19 +
20 +int vx_enter_space(struct task_struct *, struct vx_info *, unsigned long);
21  
22  static struct kmem_cache *nsproxy_cachep;
23  
24  struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
25  
26 +asmlinkage long sys_set_space(int pid, int id, int toggle, unsigned long unshare_flags) {
27 +       struct task_struct *p;
28 +       struct fs_struct *fs_cur;
29 +       struct nsproxy *proxy_cur;
30 +       int ret = 0;
31 +
32 +       if (unshare_flags & ~CLONE_NEWNET) {
33 +               printk(KERN_ALERT "sys_set_space currently only supports CLONE_NEWNET\n");
34 +               return -EINVAL;
35 +       }
36 +       else {
37 +               p = find_task_by_pid(pid);
38 +               if (p && (p->xid == id)) {
39 +                       struct vx_info *vxi;
40 +                       task_lock(p);
41 +                       fs_cur = p->fs;
42 +                       atomic_inc(&fs_cur->count);
43 +                       proxy_cur = p->nsproxy;
44 +                       get_nsproxy(proxy_cur);
45 +                       task_unlock(p);
46 +                       if (toggle) {
47 +                               vxi = p->vx_info;
48 +                               ret = vx_enter_space(p, vxi, unshare_flags);
49 +                       }
50 +                       else {
51 +                               /* Major hack - use nsproxy not namespaces here */
52 +                               if (unshare_flags & CLONE_NEWNET) {
53 +                                       struct net *old_net = proxy_cur->net_ns;
54 +                                       proxy_cur->net_ns = &init_net;
55 +                                       get_net(proxy_cur->net_ns);
56 +                               }
57 +                       }
58 +                       atomic_dec(&fs_cur->count);
59 +                       put_nsproxy(proxy_cur);
60 +               }
61 +       }
62 +       return ret;
63 +}
64 +
65  void get_task_namespaces(struct task_struct *tsk)
66  {
67         struct nsproxy *ns = tsk->nsproxy;
68 diff -Nurb linux-2.6.22-594/kernel/vserver/space.c linux-2.6.22-595/kernel/vserver/space.c
69 --- linux-2.6.22-594/kernel/vserver/space.c     2008-03-20 13:29:31.000000000 -0400
70 +++ linux-2.6.22-595/kernel/vserver/space.c     2008-03-20 14:01:00.000000000 -0400
71 @@ -141,7 +141,7 @@
72  }
73  
74  
75 -int vx_enter_space(struct vx_info *vxi, unsigned long mask)
76 +int vx_enter_space(struct task_struct *p, struct vx_info *vxi, unsigned long mask)
77  {
78         struct nsproxy *proxy, *proxy_cur, *proxy_new;
79         struct fs_struct *fs, *fs_cur, *fs_new;
80 @@ -159,12 +159,12 @@
81         proxy = vxi->vx_nsproxy;
82         fs = vxi->vx_fs;
83  
84 -       task_lock(current);
85 -       fs_cur = current->fs;
86 +       task_lock(p);
87 +       fs_cur = p->fs;
88         atomic_inc(&fs_cur->count);
89 -       proxy_cur = current->nsproxy;
90 +       proxy_cur = p->nsproxy;
91         get_nsproxy(proxy_cur);
92 -       task_unlock(current);
93 +       task_unlock(p);
94  
95         fs_new = __vs_merge_fs(fs_cur, fs, mask);
96         if (IS_ERR(fs_new)) {
97 @@ -178,8 +178,8 @@
98                 goto out_put_fs;
99         }
100  
101 -       fs_new = xchg(&current->fs, fs_new);
102 -       proxy_new = xchg(&current->nsproxy, proxy_new);
103 +       fs_new = xchg(&p->fs, fs_new);
104 +       proxy_new = xchg(&p->nsproxy, proxy_new);
105         ret = 0;
106  
107         if (proxy_new)
108 @@ -256,7 +256,7 @@
109         if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
110                 return -EFAULT;
111  
112 -       return vx_enter_space(vxi, vc_data.mask);
113 +       return vx_enter_space(current, vxi, vc_data.mask);
114  }
115  
116  int vc_set_space(struct vx_info *vxi, void __user *data)
117 diff -Nurb linux-2.6.22-594/net/core/dev.c linux-2.6.22-595/net/core/dev.c
118 --- linux-2.6.22-594/net/core/dev.c     2008-03-20 13:29:32.000000000 -0400
119 +++ linux-2.6.22-595/net/core/dev.c     2008-03-20 14:27:05.000000000 -0400
120 @@ -2207,7 +2207,7 @@
121  
122         total = 0;
123         for_each_netdev(net, dev) {
124 -               if (!nx_dev_visible(current->nx_info, dev))
125 +               if (net==&init_net && !nx_dev_visible(current->nx_info, dev))
126                         continue;
127                 for (i = 0; i < NPROTO; i++) {
128                         if (gifconf_list[i]) {
129 @@ -2274,8 +2274,9 @@
130  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
131  {
132         struct net_device_stats *stats = dev->get_stats(dev);
133 +       struct net *net = seq->private;
134  
135 -       if (!nx_dev_visible(current->nx_info, dev))
136 +       if (net==&init_net && !nx_dev_visible(current->nx_info, dev))
137                 return;
138  
139         seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
140 diff -Nurb linux-2.6.22-594/net/core/net_namespace.c linux-2.6.22-595/net/core/net_namespace.c
141 --- linux-2.6.22-594/net/core/net_namespace.c   2008-03-20 13:29:30.000000000 -0400
142 +++ linux-2.6.22-595/net/core/net_namespace.c   2008-03-20 14:27:05.000000000 -0400
143 @@ -112,10 +112,12 @@
144                 ops = list_entry(ptr, struct pernet_operations, list);
145                 if (ops->init) {
146                         error = ops->init(net);
147 -                       if (error < 0)
148 +                       if (error < 0) {
149 +                               printk(KERN_ALERT "Error setting up netns: %x\n", ops->init);
150                                 goto out_undo;
151                 }
152         }
153 +       }
154  out:
155         return error;
156  out_undo:
157 diff -Nurb linux-2.6.22-594/net/socket.c linux-2.6.22-595/net/socket.c
158 --- linux-2.6.22-594/net/socket.c       2008-03-20 13:29:30.000000000 -0400
159 +++ linux-2.6.22-595/net/socket.c       2008-03-20 14:27:05.000000000 -0400
160 @@ -1122,12 +1122,17 @@
161         if (type < 0 || type >= SOCK_MAX)
162                 return -EINVAL;
163  
164 +       /*
165 +        * Hack no. 2 - Sapan
166 +        * Clean this up later
167 +        *
168         if (!nx_check(0, VS_ADMIN)) {
169                 if (family == PF_INET && !current_nx_info_has_v4())
170                         return -EAFNOSUPPORT;
171                 if (family == PF_INET6 && !current_nx_info_has_v6())
172                         return -EAFNOSUPPORT;
173         }
174 +       */
175  
176         /* Compatibility.
177