From: Nikolay Ivanets <stenavin(a)gmail.com>
I faced with situation where libguestfs cannot recognize partitions on a
disk image which was partitioned on a system with "4K native" sector
size support.
In order to fix the issue we need to allow users to specify desired
physical and/or logical block size per drive basis.
It is definitely not a complete patch but rather a way to request for a
comments. Nevertheless it is already working patch. I've added an
optional parameters to add_drive API method which allow specifying
physical and logical block size for a drive separetely.
There are no documentation and tests yet. Input parameters are not
validated for correctness.
Here are my questions:
- Am I move in the right direction adding support for physical/logical
block size?
- I'm not sure I've made a good choise for parameter names: 'pblocksize'
and 'lblocksize' respectively. I've tried to avoid long names like
'physicalblocksize' while keeping readability and semantic.
- Do we want to add the same optional parameters to 'add_drive_scratch'
API method? I think it would be nice but it is up to you.
- What about 'add_dom', 'add_libvirt_dom' API methods? Should they also
handle 'blokio' tag in domain XML and act respectively?
- Anything else I didn't spot yet?
- Do we want guestfish to accept physical/logical block size per drive
from command line?
- What about other virt tools like virt-df, virt-cat and so on?
Sorry for a long list of questions.
---
generator/actions_core.ml | 2 +-
lib/drives.c | 14 ++++++++++++++
lib/guestfs-internal.h | 2 ++
lib/launch-direct.c | 24 ++++++++++++++++++++++++
lib/launch-libvirt.c | 21 +++++++++++++++++++++
lib/launch-uml.c | 10 ++++++++++
6 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index cb7e8dcd0..9de3a6484 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -210,7 +210,7 @@ this function fails and the C<errno> is set to
C<EINVAL>." };
{ defaults with
name = "add_drive"; added = (0, 0, 3);
- style = RErr, [String (PlainString, "filename")], [OBool
"readonly"; OString "format"; OString "iface"; OString
"name"; OString "label"; OString "protocol"; OStringList
"server"; OString "username"; OString "secret"; OString
"cachemode"; OString "discard"; OBool "copyonread"];
+ style = RErr, [String (PlainString, "filename")], [OBool
"readonly"; OString "format"; OString "iface"; OString
"name"; OString "label"; OString "protocol"; OStringList
"server"; OString "username"; OString "secret"; OString
"cachemode"; OString "discard"; OBool "copyonread"; OInt
"pblocksize"; OInt "lblocksize"];
once_had_no_optargs = true;
blocking = false;
fish_alias = ["add"];
diff --git a/lib/drives.c b/lib/drives.c
index 5a8d29ab4..bb160cc34 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -58,6 +58,8 @@ struct drive_create_data {
const char *cachemode;
enum discard discard;
bool copyonread;
+ int pblocksize;
+ int lblocksize;
};
COMPILE_REGEXP (re_hostname_port, "(.*):(\\d+)$", 0)
@@ -114,6 +116,8 @@ create_drive_file (guestfs_h *g,
drv->cachemode = data->cachemode ? safe_strdup (g, data->cachemode) : NULL;
drv->discard = data->discard;
drv->copyonread = data->copyonread;
+ drv->pblocksize = data->pblocksize;
+ drv->lblocksize = data->lblocksize;
if (data->readonly) {
if (create_overlay (g, drv) == -1) {
@@ -150,6 +154,8 @@ create_drive_non_file (guestfs_h *g,
drv->cachemode = data->cachemode ? safe_strdup (g, data->cachemode) : NULL;
drv->discard = data->discard;
drv->copyonread = data->copyonread;
+ drv->pblocksize = data->pblocksize;
+ drv->lblocksize = data->lblocksize;
if (data->readonly) {
if (create_overlay (g, drv) == -1) {
@@ -767,6 +773,14 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_COPYONREAD_BITMASK
? optargs->copyonread : false;
+ data.pblocksize =
+ optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_PBLOCKSIZE_BITMASK
+ ? optargs->pblocksize : 0;
+
+ data.lblocksize =
+ optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_LBLOCKSIZE_BITMASK
+ ? optargs->lblocksize : 0;
+
if (data.readonly && data.discard == discard_enable) {
error (g, _("discard support cannot be enabled on read-only drives"));
free_drive_servers (data.servers, data.nr_servers);
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 6799c265d..20f22a674 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -261,6 +261,8 @@ struct drive {
char *cachemode;
enum discard discard;
bool copyonread;
+ int pblocksize;
+ int lblocksize;
};
/* Extra hv parameters (from guestfs_config). */
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index ae6ca093b..518bd24fc 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -273,6 +273,26 @@ add_drive_standard_params (guestfs_h *g, struct backend_direct_data
*data,
return -1;
}
+/**
+ * Add the blockio elements of the C<-device> parameter.
+ */
+static int
+add_device_blockio_params (guestfs_h *g, struct qemuopts *qopts,
+ struct drive *drv)
+{
+ if (drv->pblocksize)
+ append_list_format ("physical_block_size=%d", drv->pblocksize);
+ if (drv->lblocksize)
+ append_list_format ("logical_block_size=%d", drv->lblocksize);
+
+ return 0;
+
+ /* This label is called implicitly from the qemuopts macros on error. */
+ qemuopts_error:
+ perrorf (g, "qemuopts");
+ return -1;
+}
+
static int
add_drive (guestfs_h *g, struct backend_direct_data *data,
struct qemuopts *qopts, size_t i, struct drive *drv)
@@ -291,6 +311,8 @@ add_drive (guestfs_h *g, struct backend_direct_data *data,
append_list_format ("drive=hd%zu", i);
if (drv->disk_label)
append_list_format ("serial=%s", drv->disk_label);
+ if (add_device_blockio_params (g, qopts, drv) == -1)
+ return -1;
} end_list ();
}
#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__)
@@ -317,6 +339,8 @@ add_drive (guestfs_h *g, struct backend_direct_data *data,
append_list_format ("drive=hd%zu", i);
if (drv->disk_label)
append_list_format ("serial=%s", drv->disk_label);
+ if (add_device_blockio_params (g, qopts, drv) == -1)
+ return -1;
} end_list ();
}
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index f2cad9300..4ce2fa683 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -1043,6 +1043,7 @@ static int construct_libvirt_xml_disk (guestfs_h *g, const struct
backend_libvir
static int construct_libvirt_xml_disk_target (guestfs_h *g, xmlTextWriterPtr xo, size_t
drv_index);
static int construct_libvirt_xml_disk_driver_qemu (guestfs_h *g, const struct
backend_libvirt_data *data, struct drive *drv, xmlTextWriterPtr xo, const char *format,
const char *cachemode, enum discard discard, bool copyonread);
static int construct_libvirt_xml_disk_address (guestfs_h *g, xmlTextWriterPtr xo, size_t
drv_index);
+static int construct_libvirt_xml_disk_blockio (guestfs_h *g, xmlTextWriterPtr xo, int
pblocksize, int lblocksize);
static int construct_libvirt_xml_disk_source_hosts (guestfs_h *g, xmlTextWriterPtr xo,
const struct drive_source *src);
static int construct_libvirt_xml_disk_source_seclabel (guestfs_h *g, const struct
backend_libvirt_data *data, xmlTextWriterPtr xo);
static int construct_libvirt_xml_appliance (guestfs_h *g, const struct libvirt_xml_params
*params, xmlTextWriterPtr xo);
@@ -1578,6 +1579,10 @@ construct_libvirt_xml_disk (guestfs_h *g,
if (construct_libvirt_xml_disk_address (g, xo, drv_index) == -1)
return -1;
+ if (construct_libvirt_xml_disk_blockio (g, xo, drv->pblocksize,
+ drv->lblocksize) == -1)
+ return -1;
+
} end_element (); /* </disk> */
return 0;
@@ -1685,6 +1690,22 @@ construct_libvirt_xml_disk_address (guestfs_h *g, xmlTextWriterPtr
xo,
return 0;
}
+static int construct_libvirt_xml_disk_blockio (guestfs_h *g,
+ xmlTextWriterPtr xo,
+ int pblocksize, int lblocksize)
+{
+ if (pblocksize || lblocksize) {
+ start_element ("blockio") {
+ if (pblocksize)
+ attribute_format ("physical_block_size", "%d", pblocksize);
+ if (lblocksize)
+ attribute_format ("logical_block_size", "%d", lblocksize);
+ } end_element ();
+ }
+
+ return 0;
+}
+
static int
construct_libvirt_xml_disk_source_hosts (guestfs_h *g,
xmlTextWriterPtr xo,
diff --git a/lib/launch-uml.c b/lib/launch-uml.c
index da20c17d9..274287b58 100644
--- a/lib/launch-uml.c
+++ b/lib/launch-uml.c
@@ -124,6 +124,16 @@ uml_supported (guestfs_h *g)
_("uml backend does not support drives with ‘discard’ parameter set to
‘enable’"));
return false;
}
+ if (drv->pblocksize) {
+ error (g,
+ _("uml backend does not support drives with ‘physical_block_size’
parameter"));
+ return false;
+ }
+ if (drv->lblocksize) {
+ error (g,
+ _("uml backend does not support drives with ‘logical_block_size’
parameter"));
+ return false;
+ }
}
return true;
--
2.17.2