/** * 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); } }
/* 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); }
/* 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); }
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); }