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