/* Call trace messages. These are enabled by setting g->trace, and * calls to this function should only happen from the generated code * in src/actions.c */ void guestfs___trace (guestfs_h *g, const char *fs, ...) { va_list args; CLEANUP_FREE char *msg = NULL; int len; va_start (args, fs); len = vasprintf (&msg, fs, args); va_end (args); if (len < 0) return; guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, msg, len); }
/* Warning are printed unconditionally. We try to make these rare. * Generally speaking, a warning should either be an error, or if it's * not important for end users then it should be a debug message. */ void guestfs___warning (guestfs_h *g, const char *fs, ...) { va_list args; char *msg, *msg2; int len; va_start (args, fs); len = vasprintf (&msg, fs, args); va_end (args); if (len < 0) return; len = asprintf (&msg2, _("warning: %s"), msg); free (msg); if (len < 0) return; guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg2, len); free (msg2); }
/* Debug messages. */ void guestfs___debug (guestfs_h *g, const char *fs, ...) { va_list args; CLEANUP_FREE char *msg = NULL; int len; /* The cpp macro "debug" has already checked that g->verbose is true * before calling this function, but we check it again just in case * anyone calls this function directly. */ if (!g->verbose) return; va_start (args, fs); len = vasprintf (&msg, fs, args); va_end (args); if (len < 0) return; guestfs___call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len); }
void guestfs_close (guestfs_h *g) { if (g->state == NO_HANDLE) { /* Not safe to call ANY callbacks here, so ... */ fprintf (stderr, _("guestfs_close: called twice on the same handle\n")); return; } if (g->trace) { const char trace_msg[] = "close"; guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, trace_msg, strlen (trace_msg)); } debug (g, "closing guestfs handle %p (state %d)", g, g->state); /* Try to sync if autosync flag is set. */ if (g->autosync && g->state == READY) guestfs_internal_autosync (g); /* If we are valgrinding the daemon, then we *don't* want to kill * the subprocess because we want the final valgrind messages sent * when we close sockets below. However for normal production use, * killing the subprocess is the right thing to do (in case the * daemon or qemu is not responding). */ #ifndef VALGRIND_DAEMON /* Kill the qemu subprocess. */ if (g->state != CONFIG) guestfs_kill_subprocess (g); #endif /* Run user close callbacks. */ guestfs___call_callbacks_void (g, GUESTFS_EVENT_CLOSE); /* Remove all other registered callbacks. Since we've already * called the close callbacks, we shouldn't call any others. */ free (g->events); g->nr_events = 0; g->events = NULL; guestfs___free_inspect_info (g); guestfs___free_drives (&g->drives); /* Close sockets. */ if (g->fd[0] >= 0) close (g->fd[0]); if (g->fd[1] >= 0) close (g->fd[1]); if (g->sock >= 0) close (g->sock); g->fd[0] = -1; g->fd[1] = -1; g->sock = -1; /* Wait for subprocess(es) to exit. */ if (g->pid > 0) waitpid (g->pid, NULL, 0); if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0); /* Remove whole temporary directory. */ guestfs___remove_tmpdir (g->tmpdir); free (g->tmpdir); if (g->cmdline) { size_t i; for (i = 0; i < g->cmdline_size; ++i) free (g->cmdline[i]); free (g->cmdline); } /* Mark the handle as dead before freeing it. */ g->state = NO_HANDLE; gl_lock_lock (handles_lock); if (handles == g) handles = g->next; else { guestfs_h *gg; for (gg = handles; gg->next != g; gg = gg->next) ; gg->next = g->next; } gl_lock_unlock (handles_lock); if (g->pda) hash_free (g->pda); free (g->last_error); free (g->path); free (g->qemu); free (g->append); free (g->qemu_help); free (g->qemu_version); free (g); }
static int read_log_message_or_eof (guestfs_h *g, int fd, int error_if_eof) { char buf[BUFSIZ]; ssize_t n; #if 0 debug (g, "read_log_message_or_eof: %p g->state = %d, fd = %d", g, g->state, fd); #endif /* QEMU's console emulates a 16550A serial port. The real 16550A * device has a small FIFO buffer (16 bytes) which means here we see * lots of small reads of 1-16 bytes in length, usually single * bytes. Sleeping here for a very brief period groups reads * together (so we usually get a few lines of output at once) and * improves overall throughput, as well as making the event * interface a bit more sane for callers. With a virtio-serial * based console (not yet implemented) we may be able to remove * this. XXX */ usleep (1000); n = read (fd, buf, sizeof buf); if (n == 0) { /* Hopefully this indicates the qemu child process has died. */ child_cleanup (g); if (error_if_eof) { /* We weren't expecting eof here (called from launch) so place * something in the error buffer. RHBZ#588851. */ error (g, "child process died unexpectedly"); } return -1; } if (n == -1) { if (errno == EINTR || errno == EAGAIN) return 0; perrorf (g, "read"); return -1; } /* It's an actual log message, send it upwards if anyone is listening. */ guestfs___call_callbacks_message (g, GUESTFS_EVENT_APPLIANCE, buf, n); /* This is a gross hack. See the comment above * guestfs___launch_send_progress. */ if (g->state == LAUNCHING) { const char *sentinel; size_t len; sentinel = "Linux version"; /* kernel up */ len = strlen (sentinel); if (memmem (buf, n, sentinel, len) != NULL) guestfs___launch_send_progress (g, 6); sentinel = "Starting /init script"; /* /init running */ len = strlen (sentinel); if (memmem (buf, n, sentinel, len) != NULL) guestfs___launch_send_progress (g, 9); } return 0; }
void guestfs_close (guestfs_h *g) { struct qemu_param *qp, *qp_next; if (g->state == NO_HANDLE) { /* Not safe to call ANY callbacks here, so ... */ fprintf (stderr, _("guestfs_close: called twice on the same handle\n")); return; } /* Remove the handle from the handles list. */ gl_lock_lock (handles_lock); if (handles == g) handles = g->next; else { guestfs_h *gg; for (gg = handles; gg->next != g; gg = gg->next) ; gg->next = g->next; } gl_lock_unlock (handles_lock); if (g->trace) { const char trace_msg[] = "close"; guestfs___call_callbacks_message (g, GUESTFS_EVENT_TRACE, trace_msg, strlen (trace_msg)); } debug (g, "closing guestfs handle %p (state %d)", g, g->state); /* If we are valgrinding the daemon, then we *don't* want to kill * the subprocess because we want the final valgrind messages sent * when we close sockets below. However for normal production use, * killing the subprocess is the right thing to do (in case the * daemon or qemu is not responding). */ #ifndef VALGRIND_DAEMON if (g->state != CONFIG) ignore_value (guestfs_shutdown (g)); #endif /* Run user close callbacks. */ guestfs___call_callbacks_void (g, GUESTFS_EVENT_CLOSE); /* Remove whole temporary directory. */ guestfs___remove_tmpdir (g->tmpdir); /* Mark the handle as dead and then free up all memory. */ g->state = NO_HANDLE; free (g->events); g->nr_events = 0; g->events = NULL; #if HAVE_FUSE guestfs___free_fuse (g); #endif guestfs___free_inspect_info (g); guestfs___free_drives (&g->drives); for (qp = g->qemu_params; qp; qp = qp_next) { free (qp->qemu_param); free (qp->qemu_value); qp_next = qp->next; free (qp); } if (g->pda) hash_free (g->pda); free (g->tmpdir); free (g->last_error); free (g->path); free (g->qemu); free (g->append); free (g); }