1 --- a/arch/um/drivers/mconsole_kern.c 2008-07-13 23:51:29.000000000 +0200
2 +++ b/arch/um/drivers/mconsole_kern.c 2008-08-06 09:32:52.000000000 +0200
4 * Licensed under the GPL
7 +#include "linux/kmod.h"
8 #include <linux/console.h>
9 #include <linux/ctype.h>
10 #include <linux/interrupt.h>
12 #include <linux/utsname.h>
13 #include <linux/workqueue.h>
14 #include <linux/mutex.h>
15 +#include <linux/completion.h>
16 +#include <linux/file.h>
17 #include <asm/uaccess.h>
24 +void mconsole_exec(struct mc_request *req)
26 + DECLARE_COMPLETION_ONSTACK(done);
27 + struct subprocess_info *sub_info;
30 + char buf[MCONSOLE_MAX_DATA];
33 + "HOME=/", "TERM=linux",
34 + "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
39 + req->request.data + strlen("exec "),
43 + sub_info = call_usermodehelper_setup("/bin/sh", argv, envp);
44 + if (sub_info == NULL) {
45 + mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
48 + res = call_usermodehelper_stdoutpipe(sub_info, &out);
50 + call_usermodehelper_freeinfo(sub_info);
51 + mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
55 + call_usermodehelper_setcomplete(sub_info, &done);
57 + res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT);
59 + call_usermodehelper_freeinfo(sub_info);
60 + mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
65 + len = out->f_op->read(out, buf, sizeof(buf), 0);
67 + mconsole_reply(req, "reading output failed", 1, 0);
72 + mconsole_reply_len(req, buf, len, 0, 1);
76 + wait_for_completion(&done);
77 + res = call_usermodehelper_getretval(sub_info) >> 8;
78 + call_usermodehelper_freeinfo(sub_info);
80 + mconsole_reply_len(req, buf, len, res, 0);
83 void mconsole_proc(struct mc_request *req)
87 stop - pause the UML; it will do nothing until it receives a 'go' \n\
88 go - continue the UML after a 'stop' \n\
89 log <string> - make UML enter <string> into the kernel log\n\
90 + exec <string> - pass <string> to /bin/sh -c synchronously\n\
91 proc <file> - returns the contents of the UML's /proc/<file>\n\
92 stack <pid> - returns the stack of the specified pid\n\
94 --- a/arch/um/drivers/mconsole_user.c 2008-07-13 23:51:29.000000000 +0200
95 +++ b/arch/um/drivers/mconsole_user.c 2008-07-15 15:41:54.000000000 +0200
97 { "stop", mconsole_stop, MCONSOLE_PROC },
98 { "go", mconsole_go, MCONSOLE_INTR },
99 { "log", mconsole_log, MCONSOLE_INTR },
100 + { "exec", mconsole_exec, MCONSOLE_PROC },
101 { "proc", mconsole_proc, MCONSOLE_PROC },
102 { "stack", mconsole_stack, MCONSOLE_INTR },
104 --- a/arch/um/include/mconsole.h 2008-07-13 23:51:29.000000000 +0200
105 +++ b/arch/um/include/mconsole.h 2008-07-15 15:41:54.000000000 +0200
107 extern void mconsole_stop(struct mc_request *req);
108 extern void mconsole_go(struct mc_request *req);
109 extern void mconsole_log(struct mc_request *req);
110 +extern void mconsole_exec(struct mc_request *req);
111 extern void mconsole_proc(struct mc_request *req);
112 extern void mconsole_stack(struct mc_request *req);
114 --- a/kernel/kmod.c 2008-07-13 23:51:29.000000000 +0200
115 +++ b/kernel/kmod.c 2008-07-31 14:46:31.000000000 +0200
117 struct subprocess_info {
118 struct work_struct work;
119 struct completion *complete;
120 + struct completion *executed;
128 + struct file *stdout;
129 void (*cleanup)(char **argv, char **envp);
133 FD_SET(0, fdt->open_fds);
134 FD_CLR(0, fdt->close_on_exec);
135 spin_unlock(&f->file_lock);
137 - /* and disallow core files too */
139 + if (sub_info->stdout) {
140 + struct files_struct *f = current->files;
141 + struct fdtable *fdt;
145 + get_file(sub_info->stdout);
146 + fd_install(1, sub_info->stdout);
147 + fd_install(2, sub_info->stdout);
148 + spin_lock(&f->file_lock);
149 + fdt = files_fdtable(f);
150 + FD_SET(1, fdt->open_fds);
151 + FD_CLR(1, fdt->close_on_exec);
152 + FD_SET(2, fdt->open_fds);
153 + FD_CLR(2, fdt->close_on_exec);
154 + spin_unlock(&f->file_lock);
156 + if (sub_info->stdin || sub_info->stdout) {
157 + /* disallow core files */
158 current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
162 /* CLONE_VFORK: wait until the usermode helper has execve'd
163 * successfully We need the data structures to stay around
164 * until that is done. */
165 - if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
166 + if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
167 pid = kernel_thread(wait_for_helper, sub_info,
168 CLONE_FS | CLONE_FILES | SIGCHLD);
176 + complete(sub_info->executed);
179 + sub_info->retval = pid;
180 + complete(sub_info->executed);
181 + complete(sub_info->complete);
189 EXPORT_SYMBOL(call_usermodehelper_setcleanup);
191 +void call_usermodehelper_setcomplete(struct subprocess_info *info,
192 + struct completion* complete)
194 + info->complete = complete;
196 +EXPORT_SYMBOL(call_usermodehelper_setcomplete);
198 +int call_usermodehelper_getretval(struct subprocess_info *info)
200 + return info->retval;
202 +EXPORT_SYMBOL(call_usermodehelper_getretval);
205 * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
206 * @sub_info: a subprocess_info returned by call_usermodehelper_setup
209 EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
211 +int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
212 + struct file **filp)
216 + f = create_write_pipe();
219 + sub_info->stdout = f;
221 + f = create_read_pipe(f);
223 + free_write_pipe(sub_info->stdout);
224 + sub_info->stdout = NULL;
231 +EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
235 * call_usermodehelper_exec - start a usermode application
236 * @sub_info: information about the subprocessa
237 @@ -460,15 +526,22 @@
241 - sub_info->complete = &done;
242 + if (wait == UMH_WAIT_EXT)
243 + sub_info->executed = &done;
245 + sub_info->complete = &done;
247 sub_info->wait = wait;
249 queue_work(khelper_wq, &sub_info->work);
250 if (wait == UMH_NO_WAIT) /* task has freed sub_info */
253 wait_for_completion(&done);
254 - retval = sub_info->retval;
256 + retval = sub_info->retval;
257 + if (wait == UMH_WAIT_EXT) /* caller will free sub_info */
260 call_usermodehelper_freeinfo(sub_info);
262 --- a/include/linux/kmod.h 2008-07-13 23:51:29.000000000 +0200
263 +++ b/include/linux/kmod.h 2008-07-31 14:43:33.000000000 +0200
267 struct subprocess_info;
270 /* Allocate a subprocess_info structure */
271 struct subprocess_info *call_usermodehelper_setup(char *path,
273 struct key *session_keyring);
274 int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
276 +int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
277 + struct file **filp);
278 +void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
279 + struct completion *complete);
280 void call_usermodehelper_setcleanup(struct subprocess_info *info,
281 void (*cleanup)(char **argv, char **envp));
282 +int call_usermodehelper_getretval(struct subprocess_info *sub_info);
285 UMH_NO_WAIT = -1, /* don't wait at all */
286 UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */
287 UMH_WAIT_PROC = 1, /* wait for the process to complete */
288 + UMH_WAIT_EXT = 2, /* wait for the exec then return and signal
289 + when the process is complete */
292 /* Actually execute the sub-process */
293 --- a/arch/um/Makefile 2008-07-13 23:51:29.000000000 +0200
294 +++ b/arch/um/Makefile 2008-07-15 16:27:02.000000000 +0200
296 KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
297 -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
298 KBUILD_CFLAGS += $(KERNEL_DEFINES)
299 +KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
303 --- a/arch/um/Makefile-i386 2008-07-13 23:51:29.000000000 +0200
304 +++ b/arch/um/Makefile-i386 2008-07-15 16:23:57.000000000 +0200
306 # an unresolved reference.
307 cflags-y += -ffreestanding
309 -# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
310 -# a lot more stack due to the lack of sharing of stacklots. Also, gcc
311 -# 4.3.0 needs -funit-at-a-time for extern inline functions.
312 -KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
313 - echo $(call cc-option,-fno-unit-at-a-time); \
314 - else echo $(call cc-option,-funit-at-a-time); fi ;)
316 KBUILD_CFLAGS += $(cflags-y)
317 --- a/arch/um/Makefile-x86_64 2008-07-13 23:51:29.000000000 +0200
318 +++ b/arch/um/Makefile-x86_64 2008-07-15 16:24:20.000000000 +0200
321 LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
324 -# Do unit-at-a-time unconditionally on x86_64, following the host
325 -KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
326 --- a/arch/um/drivers/line.c 2008-07-13 23:51:29.000000000 +0200
327 +++ b/arch/um/drivers/line.c 2008-07-28 15:13:19.000000000 +0200
332 - snprintf(title, len, "%s (%s)", base, umid);
333 + snprintf(title, len, "%s (%s)", umid, base);