Esempio n. 1
0
/**
 * Connection modules call us back here when they get a log message.
 */
void
guestfs_int_log_message_callback (guestfs_h *g, const char *buf, size_t len)
{
  /* Send the log message upwards to anyone who is listening. */
  guestfs_int_call_callbacks_message (g, GUESTFS_EVENT_APPLIANCE, buf, len);

  /* This is used to generate launch progress messages.  See comment
   * above guestfs_int_launch_send_progress.
   */
  if (g->state == LAUNCHING) {
    const char *sentinel;
    size_t slen;

    /* Since 2016-03, if !verbose, then we add the "quiet" flag to the
     * kernel, so the following sentinel will never be produced. XXX
     */
    sentinel = "Linux version"; /* kernel up */
    slen = strlen (sentinel);
    if (memmem (buf, len, sentinel, slen) != NULL)
      guestfs_int_launch_send_progress (g, 6);

    sentinel = "Starting /init script"; /* /init running */
    slen = strlen (sentinel);
    if (memmem (buf, len, sentinel, slen) != NULL)
      guestfs_int_launch_send_progress (g, 9);
  }
}
Esempio n. 2
0
/* 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_int_warning (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_int_call_callbacks_message (g, GUESTFS_EVENT_WARNING, msg, len);
}
Esempio n. 3
0
/* Debug messages. */
void
guestfs_int_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_int_call_callbacks_message (g, GUESTFS_EVENT_LIBRARY, msg, len);
}
Esempio n. 4
0
void
guestfs_close (guestfs_h *g)
{
  struct hv_param *hp, *hp_next;
  guestfs_h **gg;

  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. */
  if (g->close_on_exit) {
    gl_lock_lock (handles_lock);
    for (gg = &handles; *gg != g; gg = &(*gg)->next)
      ;
    *gg = g->next;
    gl_lock_unlock (handles_lock);
  }

  if (g->trace) {
    const char trace_msg[] = "close";

    guestfs_int_call_callbacks_message (g, GUESTFS_EVENT_TRACE,
					trace_msg, strlen (trace_msg));
  }

  debug (g, "closing guestfs handle %p (state %d)", g, (int) g->state);

  if (g->state != CONFIG)
    shutdown_backend (g, 0);

  /* Run user close callbacks. */
  guestfs_int_call_callbacks_void (g, GUESTFS_EVENT_CLOSE);

  /* Test output file used by bindtests. */
  if (g->test_fp != NULL)
    fclose (g->test_fp);

  /* Remove temporary directory. */
  guestfs_int_remove_tmpdir (g);

  /* 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_int_free_fuse (g);
#endif

  guestfs_int_free_inspect_info (g);
  guestfs_int_free_drives (g);

  for (hp = g->hv_params; hp; hp = hp_next) {
    free (hp->hv_param);
    free (hp->hv_value);
    hp_next = hp->next;
    free (hp);
  }

  while (g->error_cb_stack)
    guestfs_pop_error_handler (g);

  if (g->pda)
    hash_free (g->pda);
  free (g->tmpdir);
  free (g->env_tmpdir);
  free (g->int_tmpdir);
  free (g->int_cachedir);
  free (g->last_error);
  free (g->identifier);
  free (g->program);
  free (g->path);
  free (g->hv);
  free (g->backend);
  free (g->backend_data);
  guestfs_int_free_string_list (g->backend_settings);
  free (g->append);
  free (g);
}