diff options
author | Martin Willi <martin@strongswan.org> | 2007-08-06 11:42:32 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-08-06 11:42:32 +0000 |
commit | 64a552ae2dce8fed67ebf429d614a1b5f28a79a1 (patch) | |
tree | eb7c6bd3803fd351e7547320ae7adb9d24619955 | |
parent | afc51a247fb01025e3d29d486acd8f4acbea02c3 (diff) | |
download | strongswan-64a552ae2dce8fed67ebf429d614a1b5f28a79a1.tar.bz2 strongswan-64a552ae2dce8fed67ebf429d614a1b5f28a79a1.tar.xz |
cowfs is bootable now!
-rw-r--r-- | src/dumm/cowfs.c | 90 | ||||
-rw-r--r-- | src/dumm/dumm.c | 37 | ||||
-rw-r--r-- | src/dumm/guest.c | 18 |
3 files changed, 92 insertions, 53 deletions
diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c index 6e0fa9222..941211c6c 100644 --- a/src/dumm/cowfs.c +++ b/src/dumm/cowfs.c @@ -67,11 +67,17 @@ struct private_cowfs_t { pthread_t thread; }; +/** + * get this pointer stored in fuse context + */ static private_cowfs_t *get_this() { return (fuse_get_context())->private_data; } +/** + * make a path relative + */ static void rel(const char **path) { if (**path == '/') @@ -85,7 +91,7 @@ static void rel(const char **path) } /** - * get the filesystem to read something from + * get the highest overlay in which path exists */ static int get_rd(const char *path) { @@ -103,7 +109,7 @@ static int get_rd(const char *path) } /** - * get the filesystem to write something to + * get the highest overlay available, to write something */ static int get_wr(const char *path) { @@ -116,7 +122,7 @@ static int get_wr(const char *path) } /** - * create all directories need to create the file "path" + * create full "path" at "wr" the same way they exist at "rd" */ static bool clone_path(int rd, int wr, const char *path) { @@ -130,7 +136,7 @@ static bool clone_path(int rd, int wr, const char *path) *pos = '\0'; if (fstatat(wr, full, &st, 0) < 0) { - /* TODO: handle symlinks! */ + /* TODO: handle symlinks!? */ if (fstatat(rd, full, &st, 0) < 0) { return FALSE; @@ -147,7 +153,7 @@ static bool clone_path(int rd, int wr, const char *path) } /** - * copy a file from a readonly to a read-write overlay + * copy a (special) file from a readonly to a read-write overlay */ static int copy(const char *path) { @@ -169,35 +175,44 @@ static int copy(const char *path) { return -1; } - from = openat(rd, path, O_RDONLY, st.st_mode); - if (from < 0) - { - return -1; - } if (!clone_path(rd, wr, path)) { return -1; } - to = openat(wr, path, O_WRONLY | O_CREAT, st.st_mode); - if (to < 0) + if (mknodat(wr, path, st.st_mode, st.st_rdev) < 0) { - close(from); return -1; } - while ((len = read(from, buf, sizeof(buf))) > 0) + /* copy if no special file */ + if (st.st_size) { - if (write(to, buf, len) < len) + from = openat(rd, path, O_RDONLY, st.st_mode); + if (from < 0) + { + return -1; + } + to = openat(wr, path, O_WRONLY , st.st_mode); + if (to < 0) { close(from); - close(to); return -1; } - } - close(from); - close(to); - if (len < 0) - { - return -1; + while ((len = read(from, buf, sizeof(buf))) > 0) + { + if (write(to, buf, len) < len) + { + /* TODO: only on len < 0 ? */ + close(from); + close(to); + return -1; + } + } + close(from); + close(to); + if (len < 0) + { + return -1; + } } return wr; } @@ -423,10 +438,18 @@ static int cowfs_rmdir(const char *path) */ static int cowfs_symlink(const char *from, const char *to) { + int fd; + const char *fromrel = from; + rel(&to); + rel(&fromrel); - /* TODO: relative from? */ - if (symlinkat(from, get_wr(to), to) < 0) + fd = get_wr(to); + if (!clone_path(get_rd(fromrel), fd, fromrel)) + { + return -errno; + } + if (symlinkat(from, fd, to) < 0) { return -errno; } @@ -466,11 +489,22 @@ static int cowfs_rename(const char *from, const char *to) */ static int cowfs_link(const char *from, const char *to) { + int rd, wr; + rel(&from); rel(&to); - - if (linkat(get_rd(from), from, get_wr(to), to, 0) < 0) + + rd = get_rd(from); + wr = get_wr(to); + + if (!clone_path(rd, wr, to)) + { + DBG1("cloning path '%s' failed", to); + return -errno; + } + if (linkat(rd, from, wr, to, 0) < 0) { + DBG1("linking '%s' to '%s' failed", from, to); return -errno; } return 0; @@ -551,6 +585,7 @@ static int cowfs_truncate(const char *path, off_t size) { int fd; struct stat st; + private_cowfs_t *this = get_this(); rel(&path); @@ -653,6 +688,7 @@ static int cowfs_read(const char *path, char *buf, size_t size, off_t offset, { return -errno; } + res = pread(file, buf, size, offset); if (res < 0) { @@ -848,7 +884,7 @@ cowfs_t *cowfs_create(char *master, char *host, char *mount) this->host = strdup(host); this->scen = NULL; - if (pthread_create(&this->thread, NULL, (void*)fuse_loop_mt, this->fuse) != 0) + if (pthread_create(&this->thread, NULL, (void*)fuse_loop, this->fuse) != 0) { DBG1("creating thread to handle FUSE failed"); fuse_unmount(mount, this->chan); diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c index 486e8d380..32462845b 100644 --- a/src/dumm/dumm.c +++ b/src/dumm/dumm.c @@ -96,25 +96,25 @@ static iterator_t* create_bridge_iterator(private_dumm_t *this) */ void signal_handler(int sig, siginfo_t *info, void *ucontext) { - private_dumm_t *this; - guest_t *guest; - iterator_t *iterator, *guests; - if (sig == SIGCHLD) { - iterator = instances->create_iterator(instances, TRUE); - while (iterator->iterate(iterator, (void**)&this)) + switch (info->si_code) { - if (this->destroying) - { - continue; - } - switch (info->si_code) + case CLD_EXITED: + case CLD_KILLED: + case CLD_DUMPED: { - case CLD_EXITED: - case CLD_KILLED: - case CLD_DUMPED: + private_dumm_t *this; + guest_t *guest; + iterator_t *iterator, *guests; + + iterator = instances->create_iterator(instances, TRUE); + while (iterator->iterate(iterator, (void**)&this)) { + if (this->destroying) + { + continue; + } guests = this->guests->create_iterator(this->guests, TRUE); while (guests->iterate(guests, (void**)&guest)) { @@ -125,13 +125,14 @@ void signal_handler(int sig, siginfo_t *info, void *ucontext) } } guests->destroy(guests); - break; } - default: - break; + iterator->destroy(iterator); + break; } + default: + break; } - iterator->destroy(iterator); + } /* SIGHUP is currently just ignored */ } diff --git a/src/dumm/guest.c b/src/dumm/guest.c index 55d4f12b5..0506c00f1 100644 --- a/src/dumm/guest.c +++ b/src/dumm/guest.c @@ -170,10 +170,8 @@ static void stop(private_guest_t *this) this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy)); this->ifaces = linked_list_create(); kill(this->pid, SIGINT); - while (this->state == GUEST_STOPPING) - { - sched_yield(); - } + waitpid(this->pid, NULL, 0); + this->state = GUEST_STOPPED; } } @@ -208,7 +206,8 @@ static bool start(private_guest_t *this, char *kernel) args[i++] = write_arg(&pos, &left, "mconsole=notify:%s", notify); /*args[i++] = write_arg(&pos, &left, "con=pts");*/ args[i++] = write_arg(&pos, &left, "con0=null,fd:%d", this->bootlog); - /*args[i++] = write_arg(&pos, &left, "con1=fd:0,fd:1");*/ + //args[i++] = write_arg(&pos, &left, "con0=fd:0,fd:1"); + //args[i++] = write_arg(&pos, &left, "con1=null,null"); args[i++] = write_arg(&pos, &left, "con2=null,null"); args[i++] = write_arg(&pos, &left, "con3=null,null"); args[i++] = write_arg(&pos, &left, "con4=null,null"); @@ -221,8 +220,8 @@ static bool start(private_guest_t *this, char *kernel) { case 0: /* child, */ dup2(open("/dev/null", 0), 0); - dup2(open("/dev/null", 0), 1); - dup2(open("/dev/null", 0), 2); + dup2(this->bootlog, 1); + dup2(this->bootlog, 2); execvp(args[0], args); DBG1("starting UML kernel '%s' failed: %m", args[0]); exit(1); @@ -249,7 +248,10 @@ static bool start(private_guest_t *this, char *kernel) */ static void sigchild(private_guest_t *this) { - waitpid(this->pid, NULL, WNOHANG); + if (this->state != GUEST_STOPPING) + { /* collect zombie if uml crashed */ + waitpid(this->pid, NULL, WNOHANG); + } DESTROY_IF(this->mconsole); this->mconsole = NULL; this->state = GUEST_STOPPED; |