diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/generator.ml | 8 | ||||
-rw-r--r-- | src/guestfs.c | 45 |
2 files changed, 52 insertions, 1 deletions
diff --git a/src/generator.ml b/src/generator.ml index a54ac3fd..29f74389 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -53,7 +53,13 @@ names can be used. The rules are the same as for L<mount(2)>: A filesystem must first be mounted on C</> before others can be mounted. Other filesystems can only be mounted on directories which already -exist."); +exist. + +The mounted filesystem is writable, if we have sufficient permissions +on the underlying device. + +The filesystem options C<sync> and C<noatime> are set with this +call, in order to improve reliability."); ("sync", (Err, P0), 2, "Sync disks, writes are flushed through to the disk image", diff --git a/src/guestfs.c b/src/guestfs.c index 47af20ad..0c0a37fe 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -67,6 +67,8 @@ static void stdout_event (void *data, int watch, int fd, int events); static void sock_read_event (void *data, int watch, int fd, int events); static void sock_write_event (void *data, int watch, int fd, int events); +static void close_handles (void); + static int select_add_handle (guestfs_h *g, int fd, int events, guestfs_handle_event_cb cb, void *data); static int select_remove_handle (guestfs_h *g, int watch); static int select_add_timeout (guestfs_h *g, int interval, guestfs_handle_timeout_cb cb, void *data); @@ -95,6 +97,8 @@ enum state { CONFIG, LAUNCHING, READY, BUSY, NO_HANDLE }; struct guestfs_h { + struct guestfs_h *next; /* Linked list of open handles. */ + /* State: see the state machine diagram in the man page guestfs(3). */ enum state state; @@ -144,6 +148,9 @@ struct guestfs_h int msg_next_serial; }; +static guestfs_h *handles = NULL; +static int atexit_handler_set = 0; + guestfs_h * guestfs_create (void) { @@ -175,6 +182,21 @@ guestfs_create (void) */ g->msg_next_serial = 0x00123400; + /* Link the handles onto a global list. This is the one area + * where the library needs to be made thread-safe. (XXX) + */ + /* acquire mutex (XXX) */ + g->next = handles; + handles = g; + if (!atexit_handler_set) { + atexit (close_handles); + atexit_handler_set = 1; + } + /* release mutex (XXX) */ + + if (g->verbose) + fprintf (stderr, "new guestfs handle %p\n", g); + return g; } @@ -183,6 +205,7 @@ guestfs_close (guestfs_h *g) { int i; char filename[256]; + guestfs_h *gg; if (g->state == NO_HANDLE) { /* Not safe to call 'error' here, so ... */ @@ -190,6 +213,9 @@ guestfs_close (guestfs_h *g) return; } + if (g->verbose) + fprintf (stderr, "closing guestfs handle %p (state %d)\n", g, g->state); + /* Remove any handlers that might be called back before we kill the * subprocess. */ @@ -216,9 +242,26 @@ guestfs_close (guestfs_h *g) /* Mark the handle as dead before freeing it. */ g->state = NO_HANDLE; + /* acquire mutex (XXX) */ + if (handles == g) + handles = g->next; + else { + for (gg = handles; gg->next != g; gg = gg->next) + ; + gg->next = g->next; + } + /* release mutex (XXX) */ + free (g); } +/* Close all open handles (called from atexit(3)). */ +static void +close_handles (void) +{ + while (handles) guestfs_close (handles); +} + static void default_error_cb (guestfs_h *g, void *data, const char *msg) { @@ -531,6 +574,8 @@ guestfs_launch (guestfs_h *g) close (rfd[0]); dup (wfd[0]); dup (rfd[1]); + close (wfd[0]); + close (rfd[1]); #if 0 /* Set up a new process group, so we can signal this process |