summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/guestfs-internal.h3
-rw-r--r--src/launch-appliance.c23
-rw-r--r--src/launch-libvirt.c14
-rw-r--r--src/launch.c62
4 files changed, 73 insertions, 29 deletions
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index fe275f05..5a2e9ba5 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -165,6 +165,9 @@ struct qemu_param {
struct attach_ops {
int (*launch) (guestfs_h *g, const char *arg); /* Initialize and launch. */
int (*shutdown) (guestfs_h *g); /* Shutdown and cleanup. */
+
+ int (*get_pid) (guestfs_h *g); /* get-pid API. */
+ int (*max_disks) (guestfs_h *g); /* max-disks API. */
};
extern struct attach_ops attach_ops_appliance;
extern struct attach_ops attach_ops_libvirt;
diff --git a/src/launch-appliance.c b/src/launch-appliance.c
index 815666fe..a9553600 100644
--- a/src/launch-appliance.c
+++ b/src/launch-appliance.c
@@ -1011,16 +1011,8 @@ shutdown_appliance (guestfs_h *g)
return ret;
}
-struct attach_ops attach_ops_appliance = {
- .launch = launch_appliance,
- .shutdown = shutdown_appliance,
-};
-
-/* The APIs below this line depend in some way on this specific attach
- * method, and need some rethinking.
- */
-int
-guestfs__get_pid (guestfs_h *g)
+static int
+get_pid_appliance (guestfs_h *g)
{
if (g->app.pid > 0)
return g->app.pid;
@@ -1031,11 +1023,18 @@ guestfs__get_pid (guestfs_h *g)
}
/* Maximum number of disks. */
-int
-guestfs__max_disks (guestfs_h *g)
+static int
+max_disks_appliance (guestfs_h *g)
{
if (qemu_supports_virtio_scsi (g))
return 255;
else
return 27; /* conservative estimate */
}
+
+struct attach_ops attach_ops_appliance = {
+ .launch = launch_appliance,
+ .shutdown = shutdown_appliance,
+ .get_pid = get_pid_appliance,
+ .max_disks = max_disks_appliance,
+};
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index bebdcfb1..7c3d189a 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -1193,6 +1193,13 @@ libvirt_error (guestfs_h *g, const char *fs, ...)
free (msg);
}
+/* This backend assumes virtio-scsi is available. */
+static int
+max_disks_libvirt (guestfs_h *g)
+{
+ return 255;
+}
+
#else /* no libvirt or libxml2 at compile time */
#define NOT_IMPL(r) \
@@ -1211,9 +1218,16 @@ shutdown_libvirt (guestfs_h *g)
NOT_IMPL (-1);
}
+static int
+max_disks_libvirt (guestfs_h *g)
+{
+ NOT_IMPL (-1);
+}
+
#endif /* no libvirt or libxml2 at compile time */
struct attach_ops attach_ops_libvirt = {
.launch = launch_libvirt,
.shutdown = shutdown_libvirt,
+ .max_disks = max_disks_libvirt,
};
diff --git a/src/launch.c b/src/launch.c
index 387c91f0..44da00b2 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <errno.h>
#include "c-ctype.h"
@@ -320,6 +321,17 @@ guestfs__debug_drives (guestfs_h *g)
return ret; /* caller frees */
}
+static const struct attach_ops *
+get_attach_ops (guestfs_h *g)
+{
+ switch (g->attach_method) {
+ case ATTACH_METHOD_APPLIANCE: return &attach_ops_appliance;
+ case ATTACH_METHOD_LIBVIRT: return &attach_ops_libvirt;
+ case ATTACH_METHOD_UNIX: return &attach_ops_unix;
+ default: abort ();
+ }
+}
+
int
guestfs__launch (guestfs_h *g)
{
@@ -351,23 +363,7 @@ guestfs__launch (guestfs_h *g)
warning (g, "chmod: %s: %m (ignored)", g->tmpdir);
/* Launch the appliance. */
- switch (g->attach_method) {
- case ATTACH_METHOD_APPLIANCE:
- g->attach_ops = &attach_ops_appliance;
- break;
-
- case ATTACH_METHOD_LIBVIRT:
- g->attach_ops = &attach_ops_libvirt;
- break;
-
- case ATTACH_METHOD_UNIX:
- g->attach_ops = &attach_ops_unix;
- break;
-
- default:
- abort ();
- }
-
+ g->attach_ops = get_attach_ops (g);
return g->attach_ops->launch (g, g->attach_method_arg);
}
@@ -506,6 +502,38 @@ guestfs___remove_tmpdir (const char *dir)
}
}
+int
+guestfs__get_pid (guestfs_h *g)
+{
+ if (g->state != READY || g->attach_ops == NULL) {
+ error (g, _("get-pid can only be called after launch"));
+ return -1;
+ }
+
+ if (g->attach_ops->get_pid == NULL) {
+ guestfs_error_errno (g, ENOTSUP,
+ _("the current attach-method does not support 'get-pid'"));
+ return -1;
+ }
+
+ return g->attach_ops->get_pid (g);
+}
+
+/* Maximum number of disks. */
+int
+guestfs__max_disks (guestfs_h *g)
+{
+ const struct attach_ops *attach_ops = get_attach_ops (g);
+
+ if (attach_ops->max_disks == NULL) {
+ guestfs_error_errno (g, ENOTSUP,
+ _("the current attach-method does not allow max disks to be queried"));
+ return -1;
+ }
+
+ return attach_ops->max_disks (g);
+}
+
/* You had to call this function after launch in versions <= 1.0.70,
* but it is now a no-op.
*/