[PATCH v5 0/2] hw/nvme: Support for Namespaces Management from guest OS

2023-01-02 Thread Jonathan Derrick
From: Michael Kropaczek 

Description:

Currently namespaces could be configured as follows:
1. Legacy Namespace - just one namespace within Nvme controller's
   where the back-end was specified for nvme device by -drive parameter
   pointing directly to the image file.
2. Additional Namespaces - specified by nvme-ns devices each having its
   own back-end. To have multiple namespaces each needed to be specified
   at Qemu's command line being associated with the most recently defined
   nvme-bus from nvme device.
   If a such additional namespace should be attached and/or detached by the
   guest OS, nvme controller has to be linked with another device nvme-subsys.

All that have a static nature, all need to be specified at the Qemu's 
command line, all specified virtual nvme entities will be processed during
Qemu's start-up then created and provided to the guest OS.

To have a support for nvme create-ns and delete-ns commands with specified
parameters a different approach is needed.
Virtual devices representing namespaces need to be created and/or deleted 
during Qemu's running session, at anytime. The back-end image sizes for a
namespace must accommodate the payload size and size of metadata resulted
from specified parameters. The total capacity of the nvme controller
altogether with un-allocated capacity needs to be taken into account and
updated according to nvme create-ns and delete-ns commands respectively.

Here is the approach:
The nvme device will get new parameter:
 - auto-ns-path, which specifies the path to the storage area where back-end
   image and necessary config files located stored.

The virtual devices representing namespaces will be created dynamically during
the Qemu running session following issuance of nvme create-ns and delete-ns
commands from the guest OS. QOM classes and instances will be created utilizing
existing configuration scheme used during Qemu's start-up. Back-end image files
will be neither created nor deleted during Qemu's startup or running session.
Instead a set of back-end image files and relevant config will be created by
qemu-img tool with createns sub-command prior to Qemu's session.
Required parameters are: -S serial number which must match serial parameter of
qemu-system-xx -device nvme command line specification, -C total capacity, and
optional -N that will set a maximal limit on number of allowed
namespaces (default 256) which will be followed by path name pointing to
storage location corresponding to auto-ns-path of qemu-system-xx -device nvme
parameter.

Those created back-end image files will be pre-loaded during Qemu's start-up
and then during running Qemu's session will be associated or disassociated with
QOM namespaces virtual instances, as a result of issuing nvme create-ns or
delete-ns commands. The associated back-end image file for relevant namespace
will be re-sized as follows: delete-ns command will truncate image file to the
size of 0, whereas create-ns command will re-size the image file to the size
provided by nvme create-ns command parameters. Truncating/re-sizing is a result
of blk_truncate() API which utilizes co-routines and should not block Qemu main
thread while scheduling AIO operations. It is assured that all settings will
retain over Qemu's start-ups and shutdowns. The implementation makes it
possible to combine the existing "Additional Namespace" implementation with the
new "Managed Namespaces". Those will coexist with obvious restrictions, like
both will share the same NsIds space, "static" namespaces cannot be deleted or
if its NsId specified at Qemu's command line will conflicts with previously
created one by nvme create-ns (and retained), this will lead to an abort of
Qemu at its start up.

More than one of NVMe controllers associated with NVMe subsystem are supported.
This feature requires that parameters serial= and subsys= of additional
controllers must match those of the primary controller and auto-ns-path=
must not be specified.

Michael Kropaczek (2):
  hw/nvme: Support for Namespaces Management from guest OS - create-ns
  hw/nvme: Support for Namespaces Management from guest OS - delete-ns

 docs/system/devices/nvme.rst |  60 +-
 hw/nvme/cfg_key_checker.c|  51 +
 hw/nvme/ctrl-cfg.c   | 219 +
 hw/nvme/ctrl.c   | 311 -
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 288 +++
 hw/nvme/ns.c | 366 +++
 hw/nvme/nvme.h   |  32 ++-
 hw/nvme/subsys.c |  11 +-
 hw/nvme/trace-events |   3 +
 include/block/nvme.h |  31 +++
 include/hw/nvme/ctrl-cfg.h   |  24 +++
 include/hw/nvme/ns-cfg.h |  28 +++
 include/hw/nvme/nvme-cfg.h   | 168 
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 132 +
 16 files changed, 1678 insertions(+), 54 deletions(-)
 create mode 100644 

[PATCH v5 1/2] hw/nvme: Support for Namespaces Management from guest OS - create-ns

2023-01-02 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
create namespaces by issuing nvme create-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  59 ++-
 hw/nvme/cfg_key_checker.c|  51 ++
 hw/nvme/ctrl-cfg.c   | 219 ++
 hw/nvme/ctrl.c   | 245 -
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 283 +
 hw/nvme/ns.c | 295 ++-
 hw/nvme/nvme.h   |  30 +++-
 hw/nvme/subsys.c |  11 +-
 hw/nvme/trace-events |   2 +
 include/block/nvme.h |  30 
 include/hw/nvme/ctrl-cfg.h   |  24 +++
 include/hw/nvme/ns-cfg.h |  28 
 include/hw/nvme/nvme-cfg.h   | 168 
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 132 
 16 files changed, 1531 insertions(+), 54 deletions(-)
 create mode 100644 hw/nvme/cfg_key_checker.c
 create mode 100644 hw/nvme/ctrl-cfg.c
 create mode 100644 hw/nvme/ns-backend.c
 create mode 100644 include/hw/nvme/ctrl-cfg.h
 create mode 100644 include/hw/nvme/ns-cfg.h
 create mode 100644 include/hw/nvme/nvme-cfg.h

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 30f841ef62..6b3bee5e5d 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -92,6 +92,63 @@ There are a number of parameters available:
   attach the namespace to a specific ``nvme`` device (identified by an ``id``
   parameter on the controller device).
 
+Additional Namespaces managed by guest OS Namespaces Management
+-
+
+.. code-block:: console
+
+   -device nvme,id=nvme-ctrl,serial=1234,subsys=nvme-subsys,auto-ns-path=path
+
+Parameters:
+
+``auto-ns-path=``
+  If specified indicates a support for dynamic management of nvme namespaces
+  by means of nvme create-ns command. This path points
+  to the storage area for backend images must exist. Additionally it requires
+  that parameter `ns-subsys` must be specified whereas parameter `drive`
+  must not. The legacy namespace backend is disabled, instead, a pair of
+  files 'nvme__ns_.cfg' and 'nvme__ns_.img'
+  will refer to respective namespaces. The create-ns, attach-ns
+  and detach-ns commands, issued at the guest side, will make changes to
+  those files accordingly.
+  For each namespace exists an image file in raw format and a config file
+  containing namespace parameters and state of the attachment allowing QEMU
+  to configure namespaces accordingly during start up. If for instance an
+  image file has a size of 0 bytes this will be interpreted as non existent
+  namespace. Issuing create-ns command will change the status in the config
+  files and and will re-size the image file accordingly so the image file
+  will be associated with the respective namespace. The main config file
+  nvme__ctrl.cfg keeps the track of allocated capacity to the
+  namespaces within the nvme controller.
+  As it is the case of a typical hard drive, backend images together with
+  config files need to be created. For this reason the qemu-img tool has
+  been extended by adding createns command.
+
+   qemu-img createns {-S  -C }
+ [-N ] {}
+
+  Parameters:
+  -S and -C and  are mandatory, `-S` must match `serial` parameter
+  and  must match `auto-ns-path` parameter of "-device nvme,..."
+  specification.
+  -N is optional, if specified it will set a limit to the number of potential
+  namespaces and will reduce the number of backend images and config files
+  accordingly. As a default, a set of images of 0 bytes size and default
+  config files for 256 namespaces will be created, a total of 513 files.
+
+Please note that ``nvme-ns`` device is not required to support of dynamic
+namespaces management feature. It is not prohibited to assign a such device to
+``nvme`` device specified to support dynamic namespace management if one has
+an use case to do so, however, it will only coexist and be out of the scope of
+Namespaces Management. NsIds will be consistently managed, creation (create-ns)
+of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+device conflicts with previously created one by create-ns (the same NsId),
+it will break QEMU's start up.
+More than one of NVMe controllers associated with NVMe subsystem are supported.
+This feature requires that parameters ``serial=`` and ``subsys=`` of additional
+controllers must match those of the primary controller and ``auto-ns-path=``
+must not be specified.
+
 NVM Subsystems
 --
 
@@ -320,4 +377,4 @@ controller are:
 
 .. code-block:: 

[PATCH v5 2/2] hw/nvme: Support for Namespaces Management from guest OS - delete-ns

2023-01-02 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
delete namespaces by issuing nvme delete-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  9 ++--
 hw/nvme/ctrl.c   | 82 
 hw/nvme/ns-backend.c |  5 +++
 hw/nvme/ns.c | 71 +++
 hw/nvme/nvme.h   |  2 +
 hw/nvme/trace-events |  1 +
 include/block/nvme.h |  1 +
 7 files changed, 159 insertions(+), 12 deletions(-)

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 6b3bee5e5d..f19072f1bc 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -103,12 +103,12 @@ Parameters:
 
 ``auto-ns-path=``
   If specified indicates a support for dynamic management of nvme namespaces
-  by means of nvme create-ns command. This path points
+  by means of nvme create-ns and nvme delete-ns commands. This path points
   to the storage area for backend images must exist. Additionally it requires
   that parameter `ns-subsys` must be specified whereas parameter `drive`
   must not. The legacy namespace backend is disabled, instead, a pair of
   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
-  will refer to respective namespaces. The create-ns, attach-ns
+  will refer to respective namespaces. The create-ns, delete-ns, attach-ns
   and detach-ns commands, issued at the guest side, will make changes to
   those files accordingly.
   For each namespace exists an image file in raw format and a config file
@@ -140,8 +140,9 @@ Please note that ``nvme-ns`` device is not required to 
support of dynamic
 namespaces management feature. It is not prohibited to assign a such device to
 ``nvme`` device specified to support dynamic namespace management if one has
 an use case to do so, however, it will only coexist and be out of the scope of
-Namespaces Management. NsIds will be consistently managed, creation (create-ns)
-of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+Namespaces Management. Deletion (delete-ns) will render an error for this
+namespace. NsIds will be consistently managed, creation (create-ns) of
+a namespace will not allocate the NsId already being taken. If ``nvme-ns``
 device conflicts with previously created one by create-ns (the same NsId),
 it will break QEMU's start up.
 More than one of NVMe controllers associated with NVMe subsystem are supported.
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 5ed35d7cf4..e0fac3c151 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -144,12 +144,12 @@
  *
  * - `auto-ns-path`
  *   If specified indicates a support for dynamic management of nvme namespaces
- *   by means of nvme create-ns command. This path pointing
+ *   by means of nvme create-ns and nvme delete-ns commands. This path pointing
  *   to a storage area for backend images must exist. Additionally it requires
  *   that parameter `ns-subsys` must be specified whereas parameter `drive`
  *   must not. The legacy namespace backend is disabled, instead, a pair of
  *   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
- *   will refer to respective namespaces. The create-ns, attach-ns
+ *   will refer to respective namespaces. The create-ns, delete-ns, attach-ns
  *   and detach-ns commands, issued at the guest side, will make changes to
  *   those files accordingly.
  *   For each namespace exists an image file in raw format and a config file
@@ -5702,17 +5702,13 @@ static uint16_t nvme_ns_mgmt_create(NvmeCtrl *n, 
NvmeRequest *req, uint32_t nsid
 }
 
 if (nvme_cfg_update(n, ns->size, NVME_NS_ALLOC_CHK)) {
-/* place for delete-ns */
-error_setg(_err, "Insufficient capacity, an orphaned 
ns[%"PRIu32"] will be left behind", nsid);
-error_report_err(local_err);
+nvme_ns_delete(n, nsid, NULL);
 return NVME_NS_INSUFFICIENT_CAPAC | NVME_DNR;
 }
 (void)nvme_cfg_update(n, ns->size, NVME_NS_ALLOC);
 if (nvme_cfg_save(n)) {
 (void)nvme_cfg_update(n, ns->size, NVME_NS_DEALLOC);
-/* place for delete-ns */
-error_setg(_err, "Cannot save conf file, an orphaned 
ns[%"PRIu32"] will be left behind", nsid);
-error_report_err(local_err);
+nvme_ns_delete(n, nsid, NULL);
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
@@ -5726,6 +5722,66 @@ fail:
 return NVME_SUCCESS;
 }
 
+static uint16_t nvme_ns_mgmt_delete(NvmeCtrl *n, uint32_t nsid)
+{
+NvmeNamespace *ns = NULL;
+uint16_t first = nsid;
+uint16_t last = nsid;
+uint16_t i;
+uint64_t image_size;
+Error *local_err = NULL;
+
+if (!nsid) {
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
+if (!n->params.ns_directory) {
+

[PATCH v4 1/2] hw/nvme: Support for Namespaces Management from guest OS - create-ns

2022-12-28 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
create namespaces by issuing nvme create-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  59 ++-
 hw/nvme/cfg_key_checker.c|  51 ++
 hw/nvme/ctrl-cfg.c   | 224 ++
 hw/nvme/ctrl.c   | 244 -
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 283 +
 hw/nvme/ns.c | 293 ++-
 hw/nvme/nvme.h   |  31 +++-
 hw/nvme/subsys.c |  11 +-
 hw/nvme/trace-events |   2 +
 include/block/nvme.h |  30 
 include/hw/nvme/ctrl-cfg.h   |  24 +++
 include/hw/nvme/ns-cfg.h |  28 
 include/hw/nvme/nvme-cfg.h   | 188 ++
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 132 
 16 files changed, 1554 insertions(+), 54 deletions(-)
 create mode 100644 hw/nvme/cfg_key_checker.c
 create mode 100644 hw/nvme/ctrl-cfg.c
 create mode 100644 hw/nvme/ns-backend.c
 create mode 100644 include/hw/nvme/ctrl-cfg.h
 create mode 100644 include/hw/nvme/ns-cfg.h
 create mode 100644 include/hw/nvme/nvme-cfg.h

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 30f841ef62..6b3bee5e5d 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -92,6 +92,63 @@ There are a number of parameters available:
   attach the namespace to a specific ``nvme`` device (identified by an ``id``
   parameter on the controller device).
 
+Additional Namespaces managed by guest OS Namespaces Management
+-
+
+.. code-block:: console
+
+   -device nvme,id=nvme-ctrl,serial=1234,subsys=nvme-subsys,auto-ns-path=path
+
+Parameters:
+
+``auto-ns-path=``
+  If specified indicates a support for dynamic management of nvme namespaces
+  by means of nvme create-ns command. This path points
+  to the storage area for backend images must exist. Additionally it requires
+  that parameter `ns-subsys` must be specified whereas parameter `drive`
+  must not. The legacy namespace backend is disabled, instead, a pair of
+  files 'nvme__ns_.cfg' and 'nvme__ns_.img'
+  will refer to respective namespaces. The create-ns, attach-ns
+  and detach-ns commands, issued at the guest side, will make changes to
+  those files accordingly.
+  For each namespace exists an image file in raw format and a config file
+  containing namespace parameters and state of the attachment allowing QEMU
+  to configure namespaces accordingly during start up. If for instance an
+  image file has a size of 0 bytes this will be interpreted as non existent
+  namespace. Issuing create-ns command will change the status in the config
+  files and and will re-size the image file accordingly so the image file
+  will be associated with the respective namespace. The main config file
+  nvme__ctrl.cfg keeps the track of allocated capacity to the
+  namespaces within the nvme controller.
+  As it is the case of a typical hard drive, backend images together with
+  config files need to be created. For this reason the qemu-img tool has
+  been extended by adding createns command.
+
+   qemu-img createns {-S  -C }
+ [-N ] {}
+
+  Parameters:
+  -S and -C and  are mandatory, `-S` must match `serial` parameter
+  and  must match `auto-ns-path` parameter of "-device nvme,..."
+  specification.
+  -N is optional, if specified it will set a limit to the number of potential
+  namespaces and will reduce the number of backend images and config files
+  accordingly. As a default, a set of images of 0 bytes size and default
+  config files for 256 namespaces will be created, a total of 513 files.
+
+Please note that ``nvme-ns`` device is not required to support of dynamic
+namespaces management feature. It is not prohibited to assign a such device to
+``nvme`` device specified to support dynamic namespace management if one has
+an use case to do so, however, it will only coexist and be out of the scope of
+Namespaces Management. NsIds will be consistently managed, creation (create-ns)
+of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+device conflicts with previously created one by create-ns (the same NsId),
+it will break QEMU's start up.
+More than one of NVMe controllers associated with NVMe subsystem are supported.
+This feature requires that parameters ``serial=`` and ``subsys=`` of additional
+controllers must match those of the primary controller and ``auto-ns-path=``
+must not be specified.
+
 NVM Subsystems
 --
 
@@ -320,4 +377,4 @@ controller are:
 
 .. 

[PATCH v4 2/2] hw/nvme: Support for Namespaces Management from guest OS - delete-ns

2022-12-28 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
delete namespaces by issuing nvme delete-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  9 ++--
 hw/nvme/ctrl.c   | 81 +---
 hw/nvme/ns-backend.c |  5 +++
 hw/nvme/ns.c | 72 
 hw/nvme/nvme.h   |  3 +-
 hw/nvme/trace-events |  1 +
 include/block/nvme.h |  1 +
 7 files changed, 161 insertions(+), 11 deletions(-)

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 6b3bee5e5d..f19072f1bc 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -103,12 +103,12 @@ Parameters:
 
 ``auto-ns-path=``
   If specified indicates a support for dynamic management of nvme namespaces
-  by means of nvme create-ns command. This path points
+  by means of nvme create-ns and nvme delete-ns commands. This path points
   to the storage area for backend images must exist. Additionally it requires
   that parameter `ns-subsys` must be specified whereas parameter `drive`
   must not. The legacy namespace backend is disabled, instead, a pair of
   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
-  will refer to respective namespaces. The create-ns, attach-ns
+  will refer to respective namespaces. The create-ns, delete-ns, attach-ns
   and detach-ns commands, issued at the guest side, will make changes to
   those files accordingly.
   For each namespace exists an image file in raw format and a config file
@@ -140,8 +140,9 @@ Please note that ``nvme-ns`` device is not required to 
support of dynamic
 namespaces management feature. It is not prohibited to assign a such device to
 ``nvme`` device specified to support dynamic namespace management if one has
 an use case to do so, however, it will only coexist and be out of the scope of
-Namespaces Management. NsIds will be consistently managed, creation (create-ns)
-of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+Namespaces Management. Deletion (delete-ns) will render an error for this
+namespace. NsIds will be consistently managed, creation (create-ns) of
+a namespace will not allocate the NsId already being taken. If ``nvme-ns``
 device conflicts with previously created one by create-ns (the same NsId),
 it will break QEMU's start up.
 More than one of NVMe controllers associated with NVMe subsystem are supported.
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 6155c2013e..6b93911f01 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -144,12 +144,12 @@
  *
  * - `auto-ns-path`
  *   If specified indicates a support for dynamic management of nvme namespaces
- *   by means of nvme create-ns command. This path pointing
+ *   by means of nvme create-ns and nvme delete-ns commands. This path pointing
  *   to a storage area for backend images must exist. Additionally it requires
  *   that parameter `ns-subsys` must be specified whereas parameter `drive`
  *   must not. The legacy namespace backend is disabled, instead, a pair of
  *   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
- *   will refer to respective namespaces. The create-ns, attach-ns
+ *   will refer to respective namespaces. The create-ns, delete-ns, attach-ns
  *   and detach-ns commands, issued at the guest side, will make changes to
  *   those files accordingly.
  *   For each namespace exists an image file in raw format and a config file
@@ -5660,6 +5660,23 @@ static NvmeNamespace *nvme_ns_mgmt_create(NvmeCtrl *n, 
uint32_t nsid, NvmeIdNsMg
 return ns;
 }
 
+static void nvme_ns_mgmt_delete(NvmeCtrl *n, uint32_t nsid, Error **errp)
+{
+Error *local_err = NULL;
+
+if (!n->params.ns_directory) {
+error_setg(_err, "delete-ns not supported if 'auto-ns-path' is 
not specified");
+} else if (n->namespace.blkconf.blk) {
+error_setg(_err, "delete-ns not supported if 'drive' is 
specified");
+} else {
+nvme_ns_delete(n, nsid, _err);
+}
+
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
 static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeCtrl *n_p = NULL; /* primary controller */
@@ -5673,6 +5690,9 @@ static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest 
*req)
 uint8_t sel = dw10 & 0xf;
 uint8_t csi = (dw11 >> 24) & 0xf;
 uint16_t i;
+uint16_t first = nsid;
+uint16_t last = nsid;;
+uint64_t image_size;
 uint16_t ret;
 Error *local_err = NULL;
 
@@ -5739,16 +5759,15 @@ static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
+/* ns->size is the real image size after creation */
 if 

[PATCH v4 0/2] hw/nvme: Support for Namespaces Management from guest OS

2022-12-28 Thread Jonathan Derrick
From: Michael Kropaczek 

Description:

Currently namespaces could be configured as follows:
1. Legacy Namespace - just one namespace within Nvme controller's
   where the back-end was specified for nvme device by -drive parameter
   pointing directly to the image file.
2. Additional Namespaces - specified by nvme-ns devices each having its
   own back-end. To have multiple namespaces each needed to be specified
   at Qemu's command line being associated with the most recently defined
   nvme-bus from nvme device.
   If a such additional namespace should be attached and/or detached by the
   guest OS, nvme controller has to be linked with another device nvme-subsys.

All that have a static nature, all need to be specified at the Qemu's 
command line, all specified virtual nvme entities will be processed during
Qemu's start-up then created and provided to the guest OS.

To have a support for nvme create-ns and delete-ns commands with specified
parameters a different approach is needed.
Virtual devices representing namespaces need to be created and/or deleted 
during Qemu's running session, at anytime. The back-end image sizes for a
namespace must accommodate the payload size and size of metadata resulted
from specified parameters. The total capacity of the nvme controller
altogether with un-allocated capacity needs to be taken into account and
updated according to nvme create-ns and delete-ns commands respectively.

Here is the approach:
The nvme device will get new parameter:
 - auto-ns-path, which specifies the path to the storage area where back-end
   image and necessary config files located stored.

The virtual devices representing namespaces will be created dynamically during
the Qemu running session following issuance of nvme create-ns and delete-ns
commands from the guest OS. QOM classes and instances will be created utilizing
existing configuration scheme used during Qemu's start-up. Back-end image files
will be neither created nor deleted during Qemu's startup or running session.
Instead a set of back-end image files and relevant config will be created by
qemu-img tool with createns sub-command prior to Qemu's session.
Required parameters are: -S serial number which must match serial parameter of
qemu-system-xx -device nvme command line specification, -C total capacity, and
optional -N that will set a maximal limit on number of allowed
namespaces (default 256) which will be followed by path name pointing to
storage location corresponding to auto-ns-path of qemu-system-xx -device nvme
parameter.

Those created back-end image files will be pre-loaded during Qemu's start-up
and then during running Qemu's session will be associated or disassociated with
QOM namespaces virtual instances, as a result of issuing nvme create-ns or
delete-ns commands. The associated back-end image file for relevant namespace
will be re-sized as follows: delete-ns command will truncate image file to the
size of 0, whereas create-ns command will re-size the image file to the size
provided by nvme create-ns command parameters. Truncating/re-sizing is a result
of blk_truncate() API which utilizes co-routines and should not block Qemu main
thread while scheduling AIO operations. It is assured that all settings will
retain over Qemu's start-ups and shutdowns. The implementation makes it
possible to combine the existing "Additional Namespace" implementation with the
new "Managed Namespaces". Those will coexist with obvious restrictions, like
both will share the same NsIds space, "static" namespaces cannot be deleted or
if its NsId specified at Qemu's command line will conflicts with previously
created one by nvme create-ns (and retained), this will lead to an abort of
Qemu at its start up.

More than one of NVMe controllers associated with NVMe subsystem are supported.
This feature requires that parameters serial= and subsys= of additional
controllers must match those of the primary controller and auto-ns-path=
must not be specified.

Michael Kropaczek (2):
  hw/nvme: Support for Namespaces Management from guest OS - create-ns
  hw/nvme: Support for Namespaces Management from guest OS - delete-ns

 docs/system/devices/nvme.rst |  60 +-
 hw/nvme/cfg_key_checker.c|  51 +
 hw/nvme/ctrl-cfg.c   | 224 +
 hw/nvme/ctrl.c   | 313 +-
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 288 +++
 hw/nvme/ns.c | 365 +++
 hw/nvme/nvme.h   |  32 ++-
 hw/nvme/subsys.c |  11 +-
 hw/nvme/trace-events |   3 +
 include/block/nvme.h |  31 +++
 include/hw/nvme/ctrl-cfg.h   |  24 +++
 include/hw/nvme/ns-cfg.h |  28 +++
 include/hw/nvme/nvme-cfg.h   | 188 ++
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 132 +
 16 files changed, 1704 insertions(+), 54 deletions(-)
 create mode 100644 

[PATCH v3 2/2] hw/nvme: Support for Namespaces Management from guest OS - delete-ns

2022-10-27 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
delete namespaces by issuing nvme delete-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  9 ++--
 hw/nvme/ctrl.c   | 86 ++--
 hw/nvme/ns-backend.c |  5 +++
 hw/nvme/ns.c | 74 +++
 hw/nvme/nvme.h   |  2 +
 hw/nvme/trace-events |  1 +
 include/block/nvme.h |  1 +
 7 files changed, 170 insertions(+), 8 deletions(-)

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 13e2fbc0d6..97b2453a00 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -103,12 +103,12 @@ Parameters:
 
 ``auto-ns-path=``
   If specified indicates a support for dynamic management of nvme namespaces
-  by means of nvme create-ns command. This path points
+  by means of nvme create-ns and nvme delete-ns commands. This path points
   to the storage area for backend images must exist. Additionally it requires
   that parameter `ns-subsys` must be specified whereas parameter `drive`
   must not. The legacy namespace backend is disabled, instead, a pair of
   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
-  will refer to respective namespaces. The create-ns, attach-ns
+  will refer to respective namespaces. The create-ns, delete-ns, attach-ns
   and detach-ns commands, issued at the guest side, will make changes to
   those files accordingly.
   For each namespace exists an image file in raw format and a config file
@@ -140,8 +140,9 @@ Please note that ``nvme-ns`` device is not required to 
support of dynamic
 namespaces management feature. It is not prohibited to assign a such device to
 ``nvme`` device specified to support dynamic namespace management if one has
 an use case to do so, however, it will only coexist and be out of the scope of
-Namespaces Management. NsIds will be consistently managed, creation (create-ns)
-of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+Namespaces Management. Deletion (delete-ns) will render an error for this
+namespace. NsIds will be consistently managed, creation (create-ns) of
+a namespace will not allocate the NsId already being taken. If ``nvme-ns``
 device conflicts with previously created one by create-ns (the same NsId),
 it will break QEMU's start up.
 
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index d2b9d65eb9..87eb88486a 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -144,12 +144,12 @@
  *
  * - `auto-ns-path`
  *   If specified indicates a support for dynamic management of nvme namespaces
- *   by means of nvme create-ns command. This path pointing
+ *   by means of nvme create-ns and nvme delete-ns commands. This path pointing
  *   to a storage area for backend images must exist. Additionally it requires
  *   that parameter `ns-subsys` must be specified whereas parameter `drive`
  *   must not. The legacy namespace backend is disabled, instead, a pair of
  *   files 'nvme__ns_.cfg' and 'nvme__ns_.img'
- *   will refer to respective namespaces. The create-ns, attach-ns
+ *   will refer to respective namespaces. The create-ns, delete-ns, attach-ns
  *   and detach-ns commands, issued at the guest side, will make changes to
  *   those files accordingly.
  *   For each namespace exists an image file in raw format and a config file
@@ -5738,6 +5738,23 @@ static NvmeNamespace *nvme_ns_mgmt_create(NvmeCtrl *n, 
uint32_t nsid, NvmeIdNsMg
 return ns;
 }
 
+static void nvme_ns_mgmt_delete(NvmeCtrl *n, uint32_t nsid, Error **errp)
+{
+Error *local_err = NULL;
+
+if (!n->params.ns_directory) {
+error_setg(_err, "delete-ns not supported if 'auto-ns-path' is 
not specified");
+} else if (n->namespace.blkconf.blk) {
+error_setg(_err, "delete-ns not supported if 'drive' is 
specified");
+} else {
+nvme_ns_delete(n, nsid, _err);
+}
+
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
 static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeIdCtrl *id = >id_ctrl;
@@ -5750,6 +5767,7 @@ static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest 
*req)
 uint8_t sel = dw10 & 0xf;
 uint8_t csi = (dw11 >> 24) & 0xf;
 uint16_t i;
+uint64_t image_size;
 uint16_t ret;
 Error *local_err = NULL;
 
@@ -5807,14 +5825,15 @@ static uint16_t nvme_ns_mgmt(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
+/* ns->size is the real image size after creation */
 if (nvme_cfg_update(n, ns->size, NVME_NS_ALLOC_CHK)) {
-/* place for delete-ns */
+nvme_ns_mgmt_delete(n, nsid, NULL);
 

[PATCH v3 0/2] hw/nvme: Support for Namespaces Management from guest OS

2022-10-27 Thread Jonathan Derrick
From: Michael Kropaczek 

Description:

Currently namespaces could be configured as follows:
1. Legacy Namespace - just one namespace within Nvme controller's
   where the back-end was specified for nvme device by -drive parameter
   pointing directly to the image file.
2. Additional Namespaces - specified by nvme-ns devices each having its
   own back-end. To have multiple namespaces each needed to be specified
   at Qemu's command line being associated with the most recently defined
   nvme-bus from nvme device.
   If a such additional namespace should be attached and/or detached by the
   guest OS, nvme controller has to be linked with another device nvme-subsys.

All that have a static nature, all need to be specified at the Qemu's 
command line, all specified virtual nvme entities will be processed during
Qemu's start-up then created and provided to the guest OS.

To have a support for nvme create-ns and delete-ns commands with specified
parameters a different approach is needed.
Virtual devices representing namespaces need to be created and/or deleted 
during Qemu's running session, at anytime. The back-end image sizes for a
namespace must accommodate the payload size and size of metadata resulted
from specified parameters. The total capacity of the nvme controller
altogether with un-allocated capacity needs to be taken into account and
updated according to nvme create-ns and delete-ns commands respectively.

Here is the approach:
The nvme device will get new parameter:
 - auto-ns-path, which specifies the path to the storage area where back-end
   image and necessary config files located stored.

The virtual devices representing namespaces will be created dynamically during
the Qemu running session following issuance of nvme create-ns and delete-ns
commands from the guest OS. QOM classes and instances will be created utilizing
existing configuration scheme used during Qemu's start-up. Back-end image files
will be neither created nor deleted during Qemu's startup or running session.
Instead a set of back-end image files and relevant config will be created by
qemu-img tool with createns sub-command prior to Qemu's session.
Required parameters are: -S serial number which must match serial parameter of
qemu-system-xx -device nvme command line specification, -C total capacity, and
optional -N that will set a maximal limit on number of allowed
namespaces (default 256) which will be followed by path name pointing to
storage location corresponding to auto-ns-path of qemu-system-xx -device nvme
parameter.

Those created back-end image files will be pre-loaded during Qemu's start-up
and then during running Qemu's session will be associated or disassociated with
QOM namespaces virtual instances, as a result of issuing nvme create-ns or
delete-ns commands. The associated back-end image file for relevant namespace
will be re-sized as follows: delete-ns command will truncate image file to the
size of 0, whereas create-ns command will re-size the image file to the size
provided by nvme create-ns command parameters. Truncating/re-sizing is a result
of blk_truncate() API which utilizes co-routines and should not block Qemu main
thread while scheduling AIO operations. It is assured that all settings will
retain over Qemu's start-ups and shutdowns. The implementation makes it
possible to combine the existing "Additional Namespace" implementation with the
new "Managed Namespaces". Those will coexist with obvious restrictions, like
both will share the same NsIds space, "static" namespaces cannot be deleted or
if its NsId specified at Qemu's command line will conflicts with previously
created one by nvme create-ns (and retained), this will lead to an abort of
Qemu at its start up.

Michael Kropaczek (2):
  hw/nvme: Support for Namespaces Management from guest OS - create-ns
  hw/nvme: Support for Namespaces Management from guest OS - delete-ns

 docs/system/devices/nvme.rst |  56 ++-
 hw/nvme/cfg_key_checker.c|  51 ++
 hw/nvme/ctrl-cfg.c   | 181 
 hw/nvme/ctrl.c   | 282 +++-
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 239 +++
 hw/nvme/ns.c | 308 +++
 hw/nvme/nvme.h   |  33 +++-
 hw/nvme/trace-events |   3 +
 include/block/nvme.h |  31 
 include/hw/nvme/ctrl-cfg.h   |  24 +++
 include/hw/nvme/ns-cfg.h |  28 
 include/hw/nvme/nvme-cfg.h   | 201 +++
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 134 +++
 15 files changed, 1542 insertions(+), 37 deletions(-)
 create mode 100644 hw/nvme/cfg_key_checker.c
 create mode 100644 hw/nvme/ctrl-cfg.c
 create mode 100644 hw/nvme/ns-backend.c
 create mode 100644 include/hw/nvme/ctrl-cfg.h
 create mode 100644 include/hw/nvme/ns-cfg.h
 create mode 100644 include/hw/nvme/nvme-cfg.h

-- 
2.37.3




[PATCH v3 1/2] hw/nvme: Support for Namespaces Management from guest OS - create-ns

2022-10-27 Thread Jonathan Derrick
From: Michael Kropaczek 

Added support for NVMEe NameSpaces Mangement allowing the guest OS to
create namespaces by issuing nvme create-ns command.
It is an extension to currently implemented Qemu nvme virtual device.
Virtual devices representing namespaces will be created and/or deleted
during Qemu's running session, at anytime.

Signed-off-by: Michael Kropaczek 
---
 docs/system/devices/nvme.rst |  55 +++-
 hw/nvme/cfg_key_checker.c|  51 
 hw/nvme/ctrl-cfg.c   | 181 +++
 hw/nvme/ctrl.c   | 204 +-
 hw/nvme/meson.build  |   2 +-
 hw/nvme/ns-backend.c | 234 +++
 hw/nvme/ns.c | 234 ++-
 hw/nvme/nvme.h   |  31 -
 hw/nvme/trace-events |   2 +
 include/block/nvme.h |  30 +
 include/hw/nvme/ctrl-cfg.h   |  24 
 include/hw/nvme/ns-cfg.h |  28 +
 include/hw/nvme/nvme-cfg.h   | 201 ++
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 134 
 15 files changed, 1380 insertions(+), 37 deletions(-)
 create mode 100644 hw/nvme/cfg_key_checker.c
 create mode 100644 hw/nvme/ctrl-cfg.c
 create mode 100644 hw/nvme/ns-backend.c
 create mode 100644 include/hw/nvme/ctrl-cfg.h
 create mode 100644 include/hw/nvme/ns-cfg.h
 create mode 100644 include/hw/nvme/nvme-cfg.h

diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 30f841ef62..13e2fbc0d6 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -92,6 +92,59 @@ There are a number of parameters available:
   attach the namespace to a specific ``nvme`` device (identified by an ``id``
   parameter on the controller device).
 
+Additional Namespaces managed by guest OS Namespaces Management
+-
+
+.. code-block:: console
+
+   -device nvme,id=nvme-ctrl,serial=1234,subsys=nvme-subsys,auto-ns-path=path
+
+Parameters:
+
+``auto-ns-path=``
+  If specified indicates a support for dynamic management of nvme namespaces
+  by means of nvme create-ns command. This path points
+  to the storage area for backend images must exist. Additionally it requires
+  that parameter `ns-subsys` must be specified whereas parameter `drive`
+  must not. The legacy namespace backend is disabled, instead, a pair of
+  files 'nvme__ns_.cfg' and 'nvme__ns_.img'
+  will refer to respective namespaces. The create-ns, attach-ns
+  and detach-ns commands, issued at the guest side, will make changes to
+  those files accordingly.
+  For each namespace exists an image file in raw format and a config file
+  containing namespace parameters and state of the attachment allowing QEMU
+  to configure namespaces accordingly during start up. If for instance an
+  image file has a size of 0 bytes this will be interpreted as non existent
+  namespace. Issuing create-ns command will change the status in the config
+  files and and will re-size the image file accordingly so the image file
+  will be associated with the respective namespace. The main config file
+  nvme__ctrl.cfg keeps the track of allocated capacity to the
+  namespaces within the nvme controller.
+  As it is the case of a typical hard drive, backend images together with
+  config files need to be created. For this reason the qemu-img tool has
+  been extended by adding createns command.
+
+   qemu-img createns {-S  -C }
+ [-N ] {}
+
+  Parameters:
+  -S and -C and  are mandatory, `-S` must match `serial` parameter
+  and  must match `auto-ns-path` parameter of "-device nvme,..."
+  specification.
+  -N is optional, if specified it will set a limit to the number of potential
+  namespaces and will reduce the number of backend images and config files
+  accordingly. As a default, a set of images of 0 bytes size and default
+  config files for 256 namespaces will be created, a total of 513 files.
+
+Please note that ``nvme-ns`` device is not required to support of dynamic
+namespaces management feature. It is not prohibited to assign a such device to
+``nvme`` device specified to support dynamic namespace management if one has
+an use case to do so, however, it will only coexist and be out of the scope of
+Namespaces Management. NsIds will be consistently managed, creation (create-ns)
+of a namespace will not allocate the NsId already being taken. If ``nvme-ns``
+device conflicts with previously created one by create-ns (the same NsId),
+it will break QEMU's start up.
+
 NVM Subsystems
 --
 
@@ -320,4 +373,4 @@ controller are:
 
 .. code-block:: console
 
-   echo :01:00.1 > /sys/bus/pci/drivers/nvme/bind
\ No newline at end of file
+   echo :01:00.1 > /sys/bus/pci/drivers/nvme/bind
diff --git a/hw/nvme/cfg_key_checker.c b/hw/nvme/cfg_key_checker.c
new file mode 100644
index 00..5f19126b29
--- /dev/null

[PATCH] hw/nvme: Fix deallocate when metadata is present

2022-06-03 Thread Jonathan Derrick
When metadata is present in the namespace and deallocates are issued, the first
deallocate could fail to zero the block range, resulting in another
deallocation to be issued. Normally after the deallocation completes and the
range is checked for zeroes, a deallocation is then issued for the metadata
space. In the failure case where the range is not zeroed, deallocation is
reissued for the block range (and followed with metadata deallocation), but the
original range deallocation task will also issue a metadata deallocation:

nvme_dsm_cb()
  *range deallocation*
  nvme_dsm_md_cb()
if (nvme_block_status_all()) (range deallocation failure)
  nvme_dsm_cb()
  *range deallocation*
nvme_dsm_md_cb()
  if (nvme_block_status_all()) (no failure)
  *metadata deallocation*
*metadata deallocation*

This sequence results in reentry of nvme_dsm_cb() before the metadata has been
deallocated. During reentry, the metadata is deallocated in the reentrant task.
nvme_dsm_bh() is called which deletes and sets iocb->bh to NULL. When reentry
returns from nvme_dsm_cb(), metadata deallocation takes place again, and
results in a null pointer dereference on the iocb->bh:

BH deletion:
#0  nvme_dsm_bh (opaque=0x55ef893e2f10) at ../hw/nvme/ctrl.c:2316
#1  0x55ef868eb333 in aio_bh_call (bh=0x55ef8a441b30) at ../util/async.c:141
#2  0x55ef868eb441 in aio_bh_poll (ctx=0x55ef892c6e40) at 
../util/async.c:169
#3  0x55ef868d2789 in aio_dispatch (ctx=0x55ef892c6e40) at 
../util/aio-posix.c:415
#4  0x55ef868eb896 in aio_ctx_dispatch (source=0x55ef892c6e40, 
callback=0x0, user_data=0x0) at ../util/async.c:311
#5  0x7f5bfe4ab17d in g_main_context_dispatch () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
#6  0x55ef868fcd98 in glib_pollfds_poll () at ../util/main-loop.c:232
#7  0x55ef868fce16 in os_host_main_loop_wait (timeout=0) at 
../util/main-loop.c:255
#8  0x55ef868fcf27 in main_loop_wait (nonblocking=0) at 
../util/main-loop.c:531
#9  0x55ef864a2442 in qemu_main_loop () at ../softmmu/runstate.c:726
#10 0x55ef860f957a in main (argc=29, argv=0x7ffdc9705508, 
envp=0x7ffdc97055f8) at ../softmmu/main.c:50

nvme_dsm_cb() called for metadata after nvme_dsm_bh() completes from reentrant 
task:
Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x55ef868eb07c in aio_bh_enqueue (bh=0x0, new_flags=2) at ../util/async.c:70
70  AioContext *ctx = bh->ctx;
(gdb) backtrace
#0  0x55ef868eb07c in aio_bh_enqueue (bh=0x0, new_flags=2) at 
../util/async.c:70
#1  0x55ef868eb4cf in qemu_bh_schedule (bh=0x0) at ../util/async.c:186
#2  0x55ef862db21e in nvme_dsm_cb (opaque=0x55ef897b41a0, ret=0) at 
../hw/nvme/ctrl.c:2423
#3  0x55ef8665a662 in blk_aio_complete (acb=0x55ef89c6d8c0) at 
../block/block-backend.c:1419
#4  0x55ef8665a940 in blk_aio_write_entry (opaque=0x55ef89c6d8c0) at 
../block/block-backend.c:1486
#5  0x55ef868edcf2 in coroutine_trampoline (i0=-536848976, i1=32602) at 
../util/coroutine-ucontext.c:173
#6  0x7f5bfe0bc510 in __start_context () at 
../sysdeps/unix/sysv/linux/x86_64/__start_context.S:91
#7  0x7f5bf757bb40 in  ()
#8  0x in  ()

The fix is to return when an nvme_dsm_cb() is reentered due to failure to
deallocate the block range, so that metadata deallocate is then only issued in
the reentrant task and prevent doing it again when the reentrant task returns
to the original task.

Reproduction steps (with emulated namespace):
nvme format --lbaf=1 -f /dev/nvme0n1
mkfs.ext4 /dev/nvme0n1
mkfs.ext4 -F /dev/nvme0n1

Signed-off-by: Francis Pravin AntonyX Michael Raj 
Signed-off-by: Michael Kropaczek 
Signed-off-by: Jonathan Derrick 
---
 hw/nvme/ctrl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 03760ddeae..74540a03d5 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -2372,6 +2372,7 @@ static void nvme_dsm_md_cb(void *opaque, int ret)
 }
 
 nvme_dsm_cb(iocb, 0);
+return;
 }
 
 iocb->aiocb = blk_aio_pwrite_zeroes(ns->blkconf.blk, nvme_moff(ns, slba),
-- 
2.25.1