diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-09-04 15:34:35 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-09-04 15:36:29 +0100 |
commit | c4171ad58f61f72f5f6c6c8e711a7bcc19d20f75 (patch) | |
tree | c39e82b8e8846ec74a13d8795d5d7a857dfadb7b /src | |
parent | cc4b3139d17b98d734d98286bb698bb3b105da05 (diff) | |
download | libguestfs-c4171ad58f61f72f5f6c6c8e711a7bcc19d20f75.tar.gz libguestfs-c4171ad58f61f72f5f6c6c8e711a7bcc19d20f75.tar.xz libguestfs-c4171ad58f61f72f5f6c6c8e711a7bcc19d20f75.zip |
shutdown: Add 'check_for_errors' hint along the shutdown path.
This hint tells the backend whether anyone cares about errors when the
appliance is shut down.
Currently this only has any effect on the libvirt backend, where it
controls whether or not we use the VIR_DOMAIN_DESTROY_GRACEFUL flag.
Diffstat (limited to 'src')
-rw-r--r-- | src/guestfs-internal.h | 3 | ||||
-rw-r--r-- | src/guestfs.c | 19 | ||||
-rw-r--r-- | src/launch-appliance.c | 2 | ||||
-rw-r--r-- | src/launch-libvirt.c | 8 | ||||
-rw-r--r-- | src/launch-unix.c | 2 | ||||
-rw-r--r-- | src/proto.c | 2 |
6 files changed, 26 insertions, 10 deletions
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 9644cecd..9bc41f0c 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -163,7 +163,8 @@ struct qemu_param { /* Backend (attach-method) operations. */ struct attach_ops { int (*launch) (guestfs_h *g, const char *arg); /* Initialize and launch. */ - int (*shutdown) (guestfs_h *g); /* Shutdown and cleanup. */ + /* Shutdown and cleanup. */ + int (*shutdown) (guestfs_h *g, int check_for_errors); int (*get_pid) (guestfs_h *g); /* get-pid API. */ int (*max_disks) (guestfs_h *g); /* max-disks API. */ diff --git a/src/guestfs.c b/src/guestfs.c index 0fed8cd2..abf4a61b 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -83,6 +83,7 @@ static int parse_attach_method (guestfs_h *g, const char *method); static void default_error_cb (guestfs_h *g, void *data, const char *msg); +static int shutdown_backend (guestfs_h *g, int check_for_errors); static void close_handles (void); gl_lock_define_initialized (static, handles_lock); @@ -261,7 +262,7 @@ guestfs_close (guestfs_h *g) */ #ifndef VALGRIND_DAEMON if (g->state != CONFIG) - ignore_value (guestfs_shutdown (g)); + shutdown_backend (g, 0); #endif /* Run user close callbacks. */ @@ -306,10 +307,22 @@ guestfs_close (guestfs_h *g) free (g); } -/* Shutdown the backend. */ int guestfs__shutdown (guestfs_h *g) { + return shutdown_backend (g, 1); +} + +/* guestfs_shutdown calls shutdown_backend with check_for_errors = 1. + * guestfs_close calls shutdown_backend with check_for_errors = 0. + * + * 'check_for_errors' is a hint to the backend about whether we care + * about errors or not. In the libvirt case it can be used to + * optimize the shutdown for speed when we don't care. + */ +static int +shutdown_backend (guestfs_h *g, int check_for_errors) +{ int ret = 0; if (g->state == CONFIG) @@ -332,7 +345,7 @@ guestfs__shutdown (guestfs_h *g) g->fd[1] = -1; g->sock = -1; - if (g->attach_ops->shutdown (g) == -1) + if (g->attach_ops->shutdown (g, check_for_errors) == -1) ret = -1; g->state = CONFIG; diff --git a/src/launch-appliance.c b/src/launch-appliance.c index 134ddde0..d63d3140 100644 --- a/src/launch-appliance.c +++ b/src/launch-appliance.c @@ -953,7 +953,7 @@ guestfs___drive_name (size_t index, char *ret) } static int -shutdown_appliance (guestfs_h *g) +shutdown_appliance (guestfs_h *g, int check_for_errors) { int ret = 0; int status, sig; diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c index 04431641..37113633 100644 --- a/src/launch-libvirt.c +++ b/src/launch-libvirt.c @@ -1139,18 +1139,20 @@ ignore_errors (void *ignore, virErrorPtr ignore2) } static int -shutdown_libvirt (guestfs_h *g) +shutdown_libvirt (guestfs_h *g, int check_for_errors) { virConnectPtr conn = g->virt.connv; virDomainPtr dom = g->virt.domv; int ret = 0; + int flags; /* Note that we can be called back very early in launch (specifically * from launch_libvirt itself), when conn and dom might be NULL. */ if (dom != NULL) { - if (virDomainDestroyFlags (dom, VIR_DOMAIN_DESTROY_GRACEFUL) == -1) { + flags = check_for_errors ? VIR_DOMAIN_DESTROY_GRACEFUL : 0; + if (virDomainDestroyFlags (dom, flags) == -1) { libvirt_error (g, _("could not destroy libvirt domain")); ret = -1; } @@ -1220,7 +1222,7 @@ launch_libvirt (guestfs_h *g, const char *arg) } static int -shutdown_libvirt (guestfs_h *g) +shutdown_libvirt (guestfs_h *g, int check_for_errors) { NOT_IMPL (-1); } diff --git a/src/launch-unix.c b/src/launch-unix.c index b971cac7..ab0e9d07 100644 --- a/src/launch-unix.c +++ b/src/launch-unix.c @@ -103,7 +103,7 @@ launch_unix (guestfs_h *g, const char *sockpath) } static int -shutdown_unix (guestfs_h *g) +shutdown_unix (guestfs_h *g, int check_for_errors) { /* Merely closing g->sock is sufficient and that is already done * in the calling code. diff --git a/src/proto.c b/src/proto.c index 6f239a90..ae62748c 100644 --- a/src/proto.c +++ b/src/proto.c @@ -181,7 +181,7 @@ child_cleanup (guestfs_h *g) { debug (g, "child_cleanup: %p: child process died", g); - g->attach_ops->shutdown (g); + g->attach_ops->shutdown (g, 0); if (g->fd[0] >= 0) close (g->fd[0]); if (g->fd[1] >= 0) close (g->fd[1]); close (g->sock); |