summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-09-04 15:34:35 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-09-04 15:36:29 +0100
commitc4171ad58f61f72f5f6c6c8e711a7bcc19d20f75 (patch)
treec39e82b8e8846ec74a13d8795d5d7a857dfadb7b /src
parentcc4b3139d17b98d734d98286bb698bb3b105da05 (diff)
downloadlibguestfs-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.h3
-rw-r--r--src/guestfs.c19
-rw-r--r--src/launch-appliance.c2
-rw-r--r--src/launch-libvirt.c8
-rw-r--r--src/launch-unix.c2
-rw-r--r--src/proto.c2
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);