Allow `launch` call to accept an optional argument, called `blocksize`.
Example:
$ guestfish --listen -a raw.img
$ guestfish --remote -- launch blocksize:4096
The actual qemu command is:
[...]
-device virtio-scsi-ccw,id=scsi
-drive file=raw.img,cache=writeback,id=hd0,if=none
-device scsi-hd,drive=hd0,physical_block_size=4096,logical_block_size=4096
[...]
Signed-off-by: Tuan Hoang <tmhoang(a)linux.ibm.com>
---
generator/actions_core.ml | 18 ++++++++++++++++--
lib/guestfs-internal.h | 3 +++
lib/launch-direct.c | 6 ++++++
lib/launch.c | 12 +++++++++++-
4 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 7b6568b..0026650 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -26,7 +26,7 @@ open Types
let non_daemon_functions = [
{ defaults with
name = "launch"; added = (0, 0, 3);
- style = RErr, [], [];
+ style = RErr, [], [OInt "blocksize"];
fish_alias = ["run"]; progress = true; config_only = true;
shortdesc = "launch the backend";
longdesc = "\
@@ -36,7 +36,21 @@ You should call this after configuring the handle
Do not call C<guestfs_launch> twice on the same handle. Although
it will not give an error (for historical reasons), the precise
behaviour when you do this is not well defined. Handles are
-very cheap to create, so create a new one for each launch." };
+very cheap to create, so create a new one for each launch.
+
+The optional arguments are:
+
+=over 4
+
+=item C<blocksize>
+
+If provided, the call will add C<physical_block_size=\"blocksize\"> and
+C<logical_block_size=\"blocksize\"> to qemu's C<-device>
directive. The blocksize
+must be a power of 2 between 512 and 32768, or else it will be ignored.
+
+The default is none, and qemu would assume a blocksize of 512.
+
+=back" };
{ defaults with
name = "add_drive_ro"; added = (1, 0, 38);
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 75b8a5c..090ba58 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -513,6 +513,9 @@ struct guestfs_h {
/* Used by lib/info.c. -1 = not tested or error; else 0 or 1. */
int qemu_img_supports_U_option;
+
+ /* Used by guestfish's launch call */
+ int blocksize;
};
/**
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index ee2dcb8..54cd8c6 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -315,6 +315,12 @@ add_drive (guestfs_h *g, struct backend_direct_data *data,
start_list ("-device") {
append_list ("scsi-hd");
append_list_format ("drive=hd%zu", i);
+ if (g->blocksize >= 512 && g->blocksize <= 32768
+ && (g->blocksize & (g->blocksize-1)) == 0)
+ {
+ append_list_format ("physical_block_size=%d", g->blocksize);
+ append_list_format ("logical_block_size=%d", g->blocksize);
+ }
if (drv->disk_label)
append_list_format ("serial=%s", drv->disk_label);
} end_list ();
diff --git a/lib/launch.c b/lib/launch.c
index eb7f85c..f56e389 100644
--- a/lib/launch.c
+++ b/lib/launch.c
@@ -54,7 +54,7 @@ static struct backend {
} *backends = NULL;
int
-guestfs_impl_launch (guestfs_h *g)
+guestfs_impl_launch (guestfs_h *g, const struct guestfs_launch_argv *optargs)
{
int r;
@@ -85,6 +85,16 @@ guestfs_impl_launch (guestfs_h *g)
if (guestfs_int_lazy_make_tmpdir (g) == -1)
return -1;
+ /* Add the blocksize. */
+ if (optargs->blocksize >= 512 && optargs->blocksize <= 32768
+ && (optargs->blocksize & (optargs->blocksize-1)) == 0) {
+ g->blocksize = optargs->blocksize;
+ debug (g, "using blocksize of %d", g->blocksize);
+ }
+ else {
+ debug (g, _("blocksize must be a power of 2 between 512 and 32768"));
+ }
+
/* Some common debugging information. */
if (g->verbose) {
CLEANUP_FREE_VERSION struct guestfs_version *v =
--
2.21.0