- filled in group field, previously missing.
[npfs.git] / fs / cpuhelper.c
blob13f1030f844746d1b6ca70d89b1654e4b3cdcd49
1 /*
2 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sched.h>
27 #include <string.h>
28 #include <sys/mount.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <linux/unistd.h>
36 #define MS_MOVE 8192
38 static char *host;
39 static int port;
40 static char *uname;
41 static char *cmd;
42 static char **args;
43 static char mntpt[256];
45 int
46 procfn(void *a)
48 int n;
49 char opts[256];
50 char mdir[256];
52 snprintf(opts, sizeof(opts), "name=%s,port=%d,debug=1", uname, port);
53 n = mount(host, mntpt, "9P", 0, opts);
54 if (n < 0) {
55 perror("mount");
56 return -1;
59 snprintf(mdir, sizeof(mdir), "%s/dev", mntpt);
60 n = mount("/dev", mdir, NULL, MS_BIND, NULL);
61 if (n < 0) {
62 perror("bind dev");
63 return -1;
66 snprintf(mdir, sizeof(mdir), "%s/proc", mntpt);
67 n = mount("/proc", mdir, NULL, MS_BIND, NULL);
68 if (n < 0) {
69 perror("bind proc");
70 return -1;
73 snprintf(mdir, sizeof(mdir), "%s/sys", mntpt);
74 n = mount("/sys", mdir, NULL, MS_BIND, NULL);
75 if (n < 0) {
76 perror("bind sys");
77 return -1;
80 chdir(mntpt);
82 n = mount(mntpt, "/", NULL, MS_MOVE, NULL);
83 if (n < 0) {
84 perror("move mount");
85 return -1;
88 chroot(".");
90 execv(cmd, args);
91 snprintf(mdir, sizeof(mdir), "execv %s", cmd);
92 perror(mdir);
93 return -1;
96 static void
97 usage()
99 fprintf(stderr, "cpud uname host port\n");
100 exit(-1);
104 main(int argc, char **argv)
106 int i, nargs;
107 char *s;
108 pid_t pid, p;
109 char stk[10000];
111 if (argc < 4)
112 usage();
114 uname = argv[1];
115 host = argv[2];
116 port = strtol(argv[3], &s, 10);
117 if (*s != 0)
118 usage();
120 nargs = argc - 3;
121 if (nargs < 2)
122 nargs = 2;
124 cmd = "/bin/bash";
125 args = calloc(nargs, sizeof(char *));
126 if (argc > 4) {
127 cmd = argv[4];
128 for(i = 4; i < argc; i++)
129 args[i-4] = argv[i];
130 } else {
131 cmd = "/bin/bash";
132 args[1] = "--login";
135 args[0] = cmd;
137 snprintf(mntpt, sizeof(mntpt), "/tmp/cpu%d", getpid());
138 mkdir(mntpt, 0700);
139 pid = clone(procfn, stk + 5000, CLONE_NEWNS | CLONE_FILES
140 | CLONE_PTRACE | SIGCHLD, NULL);
142 if ((int) pid == -1) {
143 perror("clone");
144 exit(-1);
147 p = waitpid(pid, NULL, 0);
148 if ((int) p == -1) {
149 perror("waitpid");
150 exit(-1);
153 if (!rmdir(mntpt))
154 perror("rmdir");
156 return 0;