cowfs is bootable now!
authorMartin Willi <martin@strongswan.org>
Mon, 6 Aug 2007 11:42:32 +0000 (11:42 -0000)
committerMartin Willi <martin@strongswan.org>
Mon, 6 Aug 2007 11:42:32 +0000 (11:42 -0000)
src/dumm/cowfs.c
src/dumm/dumm.c
src/dumm/guest.c

index 6e0fa92..941211c 100644 (file)
@@ -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);
index 486e8d3..3246284 100644 (file)
@@ -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 */
 }
index 55d4f12..0506c00 100644 (file)
@@ -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;