17 typedef struct private_guest_t private_guest_t
;
19 struct private_guest_t
{
29 static char* get_name(private_guest_t
*this)
34 static char* write_arg(char **pos
, size_t *left
, char *format
, ...)
40 va_start(args
, format
);
41 len
= vsnprintf(*pos
, *left
, format
, args
);
53 static bool start(private_guest_t
*this)
60 size_t left
= sizeof(buf
);
62 args
[i
++] = this->kernel
;
63 args
[i
++] = write_arg(&pos
, &left
, "root=/dev/root");
64 args
[i
++] = write_arg(&pos
, &left
, "rootfstype=hostfs");
65 args
[i
++] = write_arg(&pos
, &left
, "rootflags=%s/%s/%s",
66 getcwd(cwd
, sizeof(cwd
)), MOUNT_DIR
, this->name
);
67 args
[i
++] = write_arg(&pos
, &left
, "uml_dir=%s/%s", RUN_DIR
, this->name
);
68 args
[i
++] = write_arg(&pos
, &left
, "umid=%s", this->name
);
69 args
[i
++] = write_arg(&pos
, &left
, "mem=%dM", this->mem
);
70 //args[i++] = write_arg(&pos, &left, "con=pts");
71 args
[i
++] = write_arg(&pos
, &left
, "con0=null,fd:%d", this->bootlog
);
72 args
[i
++] = write_arg(&pos
, &left
, "con1=fd:0,fd:1");
73 args
[i
++] = write_arg(&pos
, &left
, "con3=null,null");
74 args
[i
++] = write_arg(&pos
, &left
, "con4=null,null");
75 args
[i
++] = write_arg(&pos
, &left
, "con5=null,null");
76 args
[i
++] = write_arg(&pos
, &left
, "con6=null,null");
83 dup2(open("/dev/null", 0), 0);
84 dup2(open("/dev/null", 0), 1);
85 dup2(open("/dev/null", 0), 2);
86 execvp(args
[0], args
);
96 static void stop(private_guest_t
*this)
100 kill(this->pid
, SIGINT
);
108 static bool makedir(char *dir
, char *name
)
114 len
= snprintf(buf
, sizeof(buf
), "%s/%s", dir
, name
);
115 if (len
< 0 || len
>= sizeof(buf
))
119 if (stat(buf
, &st
) != 0)
121 return mkdir(buf
, S_IRWXU
) == 0;
123 return S_ISDIR(st
.st_mode
);
127 * umount the union filesystem
129 static bool umount_unionfs(char *name
)
134 len
= snprintf(cmd
, sizeof(cmd
), "fusermount -u %s/%s", MOUNT_DIR
, name
);
135 if (len
< 0 || len
>= sizeof(cmd
))
139 if (system(cmd
) != 0)
147 * mount the union filesystem
149 static bool mount_unionfs(char *name
, char *master
)
155 len
= snprintf(cmd
, sizeof(cmd
), "unionfs %s/%s:%s %s/%s",
156 HOST_DIR
, name
, master
, MOUNT_DIR
, name
);
157 if (len
< 0 || len
>= sizeof(cmd
))
161 if (system(cmd
) != 0)
163 DBG1("mounting unionfs using '%s' failed.", cmd
);
170 * open logfile for boot messages
172 static int open_bootlog(char *name
)
178 len
= snprintf(blg
, sizeof(blg
), "%s/%s/boot.log", RUN_DIR
, name
);
179 if (len
< 0 || len
>= sizeof(blg
))
183 fd
= open(blg
, O_WRONLY
| O_CREAT
, S_IRUSR
| S_IWUSR
);
192 * stop guest, unmount mounts
194 static void destroy(private_guest_t
*this)
197 umount_unionfs(this->name
);
205 * create the guest instance, including required dirs and mounts
207 guest_t
*guest_create(char *name
, char *kernel
, char *master
, int mem
)
209 private_guest_t
*this = malloc_thing(private_guest_t
);
211 this->public.get_name
= (void*)get_name
;
212 this->public.start
= (void*)start
;
213 this->public.stop
= (void*)stop
;
214 this->public.destroy
= (void*)destroy
;
216 if (!makedir(HOST_DIR
, name
) || !makedir(MOUNT_DIR
, name
) ||
217 !makedir(RUN_DIR
, name
))
219 DBG1("creating guest directories for %s failed failed.", name
);
224 if (!mount_unionfs(name
, master
))
226 DBG1("mounting guest unionfs for %s failed.", name
);
231 this->name
= strdup(name
);
232 this->kernel
= strdup(kernel
);
233 this->master
= strdup(master
);
236 this->bootlog
= open_bootlog(name
);
238 return &this->public;