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