Added support for multiple overlays to the copy-on-write filesystem.
[strongswan.git] / src / dumm / patches / mconsole-exec-2.6.29.patch
1 diff --git a/.gitignore b/.gitignore
2 index 869e1a3..978e430 100644
3 --- a/.gitignore
4 +++ b/.gitignore
5 @@ -32,6 +32,7 @@
6  tags
7  TAGS
8  vmlinux
9 +linux
10  System.map
11  Module.markers
12  Module.symvers
13 diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
14 index 14a102e..0acfaeb 100644
15 --- a/arch/um/drivers/line.c
16 +++ b/arch/um/drivers/line.c
17 @@ -866,6 +866,6 @@ char *add_xterm_umid(char *base)
18                 return base;
19         }
20  
21 -       snprintf(title, len, "%s (%s)", base, umid);
22 +       snprintf(title, len, "%s (%s)", umid, base);
23         return title;
24  }
25 diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
26 index e14629c..c488930 100644
27 --- a/arch/um/drivers/mconsole_kern.c
28 +++ b/arch/um/drivers/mconsole_kern.c
29 @@ -4,6 +4,7 @@
30   * Licensed under the GPL
31   */
32  
33 +#include "linux/kmod.h"
34  #include <linux/console.h>
35  #include <linux/ctype.h>
36  #include <linux/interrupt.h>
37 @@ -20,6 +21,8 @@
38  #include <linux/un.h>
39  #include <linux/workqueue.h>
40  #include <linux/mutex.h>
41 +#include <linux/completion.h>
42 +#include <linux/file.h>
43  #include <asm/uaccess.h>
44  
45  #include "init.h"
46 @@ -202,6 +205,65 @@ void mconsole_proc(struct mc_request *req)
47  }
48  #endif
49  
50 +void mconsole_exec(struct mc_request *req)
51 +{
52 +       DECLARE_COMPLETION_ONSTACK(done);
53 +       struct subprocess_info *sub_info;
54 +       int res, len;
55 +       struct file *out;
56 +       char buf[MCONSOLE_MAX_DATA];
57 +
58 +       char *envp[] = {
59 +               "HOME=/", "TERM=linux",
60 +               "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
61 +               NULL
62 +       };
63 +       char *argv[] = {
64 +               "/bin/sh", "-c",
65 +               req->request.data + strlen("exec "),
66 +               NULL
67 +       };
68 +
69 +       sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC);
70 +       if (sub_info == NULL) {
71 +               mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
72 +               return;
73 +       }
74 +       res = call_usermodehelper_stdoutpipe(sub_info, &out);
75 +       if (res < 0) {
76 +               call_usermodehelper_freeinfo(sub_info);
77 +               mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
78 +               return;
79 +       }
80 +
81 +       call_usermodehelper_setcomplete(sub_info, &done);
82 +
83 +       res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT);
84 +       if (res < 0) {
85 +               call_usermodehelper_freeinfo(sub_info);
86 +               mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
87 +               return;
88 +       }
89 +
90 +       for (;;) {
91 +               len = out->f_op->read(out, buf, sizeof(buf), &out->f_pos);
92 +               if (len < 0) {
93 +                       mconsole_reply(req, "reading output failed", 1, 0);
94 +                       break;
95 +               }
96 +               if (len == 0)
97 +                       break;
98 +               mconsole_reply_len(req, buf, len, 0, 1);
99 +       }
100 +       fput(out);
101 +
102 +       wait_for_completion(&done);
103 +       res = call_usermodehelper_getretval(sub_info) >> 8;
104 +       call_usermodehelper_freeinfo(sub_info);
105 +
106 +       mconsole_reply_len(req, buf, len, res, 0);
107 +}
108 +
109  void mconsole_proc(struct mc_request *req)
110  {
111         char path[64];
112 @@ -273,6 +335,7 @@ void mconsole_proc(struct mc_request *req)
113      stop - pause the UML; it will do nothing until it receives a 'go' \n\
114      go - continue the UML after a 'stop' \n\
115      log <string> - make UML enter <string> into the kernel log\n\
116 +    exec <string> - pass <string> to /bin/sh -c synchronously\n\
117      proc <file> - returns the contents of the UML's /proc/<file>\n\
118      stack <pid> - returns the stack of the specified pid\n\
119  "
120 diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
121 index f8cf4c8..019d89f 100644
122 --- a/arch/um/drivers/mconsole_user.c
123 +++ b/arch/um/drivers/mconsole_user.c
124 @@ -32,6 +32,7 @@ static struct mconsole_command commands[] = {
125         { "stop", mconsole_stop, MCONSOLE_PROC },
126         { "go", mconsole_go, MCONSOLE_INTR },
127         { "log", mconsole_log, MCONSOLE_INTR },
128 +       { "exec", mconsole_exec, MCONSOLE_PROC },
129         { "proc", mconsole_proc, MCONSOLE_PROC },
130         { "stack", mconsole_stack, MCONSOLE_INTR },
131  };
132 diff --git a/arch/um/include/.gitignore b/arch/um/include/.gitignore
133 new file mode 100644
134 index 0000000..4c14eba
135 --- /dev/null
136 +++ b/arch/um/include/.gitignore
137 @@ -0,0 +1,2 @@
138 +shared/kern_constants.h
139 +shared/user_constants.h
140 diff --git a/arch/um/include/shared/mconsole.h b/arch/um/include/shared/mconsole.h
141 index c139ae1..dfb83b1 100644
142 --- a/arch/um/include/shared/mconsole.h
143 +++ b/arch/um/include/shared/mconsole.h
144 @@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_request *req);
145  extern void mconsole_stop(struct mc_request *req);
146  extern void mconsole_go(struct mc_request *req);
147  extern void mconsole_log(struct mc_request *req);
148 +extern void mconsole_exec(struct mc_request *req);
149  extern void mconsole_proc(struct mc_request *req);
150  extern void mconsole_stack(struct mc_request *req);
151  
152 diff --git a/arch/um/kernel/.gitignore b/arch/um/kernel/.gitignore
153 new file mode 100644
154 index 0000000..803397e
155 --- /dev/null
156 +++ b/arch/um/kernel/.gitignore
157 @@ -0,0 +1,3 @@
158 +config.c
159 +config.tmp
160 +vmlinux.lds
161 diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
162 index b5afcfd..b598128 100644
163 --- a/arch/um/os-Linux/file.c
164 +++ b/arch/um/os-Linux/file.c
165 @@ -521,6 +521,8 @@ int os_create_unix_socket(const char *file, int len, int close_on_exec)
166  
167         addr.sun_family = AF_UNIX;
168  
169 +       if (len > sizeof(addr.sun_path))
170 +               len = sizeof(addr.sun_path);
171         snprintf(addr.sun_path, len, "%s", file);
172  
173         err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
174 diff --git a/include/linux/kmod.h b/include/linux/kmod.h
175 index 92213a9..db07018 100644
176 --- a/include/linux/kmod.h
177 +++ b/include/linux/kmod.h
178 @@ -40,6 +40,7 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; }
179  struct key;
180  struct file;
181  struct subprocess_info;
182 +struct completion;
183  
184  /* Allocate a subprocess_info structure */
185  struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
186 @@ -50,13 +51,20 @@ void call_usermodehelper_setkeys(struct subprocess_info *info,
187                                  struct key *session_keyring);
188  int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
189                                   struct file **filp);
190 +int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
191 +                                  struct file **filp);
192 +void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
193 +                                    struct completion *complete);
194  void call_usermodehelper_setcleanup(struct subprocess_info *info,
195                                     void (*cleanup)(char **argv, char **envp));
196 +int call_usermodehelper_getretval(struct subprocess_info *sub_info);
197  
198  enum umh_wait {
199         UMH_NO_WAIT = -1,       /* don't wait at all */
200         UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
201         UMH_WAIT_PROC = 1,      /* wait for the process to complete */
202 +       UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal
203 +                                  when the process is complete */
204  };
205  
206  /* Actually execute the sub-process */
207 diff --git a/kernel/kmod.c b/kernel/kmod.c
208 index a27a5f6..61479bf 100644
209 --- a/kernel/kmod.c
210 +++ b/kernel/kmod.c
211 @@ -119,12 +119,14 @@ struct subprocess_info {
212         struct work_struct work;
213         struct completion *complete;
214         struct cred *cred;
215 +       struct completion *executed;
216         char *path;
217         char **argv;
218         char **envp;
219         enum umh_wait wait;
220         int retval;
221         struct file *stdin;
222 +       struct file *stdout;
223         void (*cleanup)(char **argv, char **envp);
224  };
225  
226 @@ -161,8 +163,26 @@ static int ____call_usermodehelper(void *data)
227                 FD_SET(0, fdt->open_fds);
228                 FD_CLR(0, fdt->close_on_exec);
229                 spin_unlock(&f->file_lock);
230 +       }
231 +       if (sub_info->stdout) {
232 +               struct files_struct *f = current->files;
233 +               struct fdtable *fdt;
234  
235 -               /* and disallow core files too */
236 +               sys_close(1);
237 +               sys_close(2);
238 +               get_file(sub_info->stdout);
239 +               fd_install(1, sub_info->stdout);
240 +               fd_install(2, sub_info->stdout);
241 +               spin_lock(&f->file_lock);
242 +               fdt = files_fdtable(f);
243 +               FD_SET(1, fdt->open_fds);
244 +               FD_CLR(1, fdt->close_on_exec);
245 +               FD_SET(2, fdt->open_fds);
246 +               FD_CLR(2, fdt->close_on_exec);
247 +               spin_unlock(&f->file_lock);
248 +       }
249 +       if (sub_info->stdin || sub_info->stdout) {
250 +               /* disallow core files */
251                 current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
252         }
253  
254 @@ -248,7 +268,7 @@ static void __call_usermodehelper(struct work_struct *work)
255         /* CLONE_VFORK: wait until the usermode helper has execve'd
256          * successfully We need the data structures to stay around
257          * until that is done.  */
258 -       if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
259 +       if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
260                 pid = kernel_thread(wait_for_helper, sub_info,
261                                     CLONE_FS | CLONE_FILES | SIGCHLD);
262         else
263 @@ -259,6 +279,16 @@ static void __call_usermodehelper(struct work_struct *work)
264         case UMH_NO_WAIT:
265                 break;
266  
267 +       case UMH_WAIT_EXT:
268 +               if (pid > 0) {
269 +                       complete(sub_info->executed);
270 +                       break;
271 +               }
272 +               sub_info->retval = pid;
273 +               complete(sub_info->executed);
274 +               complete(sub_info->complete);
275 +               break;
276 +
277         case UMH_WAIT_PROC:
278                 if (pid > 0)
279                         break;
280 @@ -411,6 +441,19 @@ void call_usermodehelper_setcleanup(struct subprocess_info *info,
281  }
282  EXPORT_SYMBOL(call_usermodehelper_setcleanup);
283  
284 +void call_usermodehelper_setcomplete(struct subprocess_info *info,
285 +                                   struct completion* complete)
286 +{
287 +       info->complete = complete;
288 +}
289 +EXPORT_SYMBOL(call_usermodehelper_setcomplete);
290 +
291 +int call_usermodehelper_getretval(struct subprocess_info *info)
292 +{
293 +       return info->retval;
294 +}
295 +EXPORT_SYMBOL(call_usermodehelper_getretval);
296 +
297  /**
298   * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
299   * @sub_info: a subprocess_info returned by call_usermodehelper_setup
300 @@ -440,6 +483,29 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
301  }
302  EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
303  
304 +int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
305 +                                 struct file **filp)
306 +{
307 +       struct file *f;
308 +
309 +       f = create_write_pipe(0);
310 +       if (IS_ERR(f))
311 +               return PTR_ERR(f);
312 +       sub_info->stdout = f;
313 +
314 +       f = create_read_pipe(f, 0);
315 +       if (IS_ERR(f)) {
316 +               free_write_pipe(sub_info->stdout);
317 +               sub_info->stdout = NULL;
318 +               return PTR_ERR(f);
319 +       }
320 +       *filp = f;
321 +
322 +       return 0;
323 +}
324 +EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
325 +
326 +
327  /**
328   * call_usermodehelper_exec - start a usermode application
329   * @sub_info: information about the subprocessa
330 @@ -469,15 +535,22 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
331                 goto out;
332         }
333  
334 -       sub_info->complete = &done;
335 +       if (wait == UMH_WAIT_EXT)
336 +               sub_info->executed = &done;
337 +       else
338 +               sub_info->complete = &done;
339 +
340         sub_info->wait = wait;
341  
342         queue_work(khelper_wq, &sub_info->work);
343         if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
344                 goto unlock;
345 +
346         wait_for_completion(&done);
347 -       retval = sub_info->retval;
348  
349 +       retval = sub_info->retval;
350 +       if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
351 +               goto unlock;
352  out:
353         call_usermodehelper_freeinfo(sub_info);
354  unlock: