Storage namespaces endpoint overview
Overview
An NVMe namespace is a collection of addressable logical blocks presented to hosts connected to the storage virtual machine using the NVMe over Fabrics protocol.
The NVMe namespace REST API allows you to create, update, delete and discover NVMe namespaces.
In ONTAP, an NVMe namespace is located within a volume. Optionally, it can be located within a qtree in a volume.
An NVMe namespace is created to a specified size using thin or thick provisioning as determined by the volume on which it is created. NVMe namespaces support being cloned. An NVMe namespace cannot be renamed, resized, or moved to a different volume. NVMe namespaces do not support the assignment of a QoS policy for performance management, but a QoS policy can be assigned to the volume containing the namespace. See the NVMe namespace object model to learn more about each of the properties supported by the NVMe namespace REST API.
An NVMe namespace must be mapped to an NVMe subsystem to grant access to the subsystem's hosts. Hosts can then access the NVMe namespace and perform I/O using the NVMe over Fabrics protocol.
Performance monitoring
Performance of an NVMe namespace can be monitored by observing the metric.*
and statistics.*
properties. These properties show the performance of an NVMe namespace in terms of IOPS, latency, and throughput. The metric.*
properties denote an average, whereas statistics.*
properties denote a real-time monotonically increasing value aggregated across all nodes.
Examples
Creating an NVMe namespace
This example creates a 300 gigabyte NVMe namespace, with 4096-byte blocks, in SVM svm1, volume vol1, configured for use by linux hosts. The return_records
query parameter is used to retrieve properties of the newly created NVMe namespace in the POST response.
# The API: POST /api/storage/namespaces # The call: curl -X POST 'https://<mgmt-ip>/api/storage/namespaces?return_records=true' -H 'accept: application/hal+json' -d '{ "svm": { "name": "svm1" }, "os_type": "linux", "space": { "block_size": "4096", "size": "300G" }, "name" : "/vol/vol1/namespace1" }' # The response: { "num_records": 1, "records": [ { "uuid": "dccdc3e6-cf4e-498f-bec6-f7897f945669", "svm": { "uuid": "6bf967fd-2a1c-11e9-b682-005056bbc17d", "name": "svm1", "_links": { "self": { "href": "/api/svm/svms/6bf967fd-2a1c-11e9-b682-005056bbc17d" } } }, "name": "/vol/vol1/namespace1", "location": { "namespace": "namespace1", "volume": { "uuid": "71cd0dba-2a1c-11e9-b682-005056bbc17d", "name": "vol1", "_links": { "self": { "href": "/api/storage/volumes/71cd0dba-2a1c-11e9-b682-005056bbc17d" } } } }, "enabled": true, "os_type": "linux", "space": { "block_size": 4096, "size": 322122547200, "used": 0, "guarantee": { "requested": false, "reserved": false } }, "status": { "container_state": "online", "read_only": false, "state": "online" }, "_links": { "self": { "href": "/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669" } } } ] }
Updating an NVMe namespace comment
This example sets the comment
property of an NVMe namespace.
# The API: PATCH /api/storage/namespaces/{uuid} # The call: curl -X PATCH 'https://<mgmt-ip>/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669' -H 'accept: application/hal+json' -d '{ "comment": "Data for the research department." }'
Updating the size of an NVMe namespace
This example increases the size of an NVMe namespace.
# The API: PATCH /api/storage/namespaces/{uuid} # The call: curl -X PATCH 'https://<mgmt-ip>/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669' -H 'accept: application/hal+json' -d '{ "space": { "size": "1073741824" } }'
Retrieving NVMe namespaces
This example retrieves summary information for all online NVMe namespaces in SVM svm1. The svm.name
and status.state
query parameters are to find the desired NVMe namespaces.
# The API: GET /api/storage/namespaces # The call: curl -X GET 'https://<mgmt-ip>/api/storage/namespaces?svm.name=svm1&status.state=online' -H 'accept: application/hal+json' # The response: { "records": [ { "uuid": "5c254d22-96a6-42ac-aad8-0cd9ebd126b6", "svm": { "name": "svm1" }, "name": "/vol/vol1/namespace2", "status": { "state": "online" }, "_links": { "self": { "href": "/api/storage/namespaces/5c254d22-96a6-42ac-aad8-0cd9ebd126b6" } } }, { "uuid": "dccdc3e6-cf4e-498f-bec6-f7897f945669", "svm": { "name": "svm1" }, "name": "/vol/vol1/namespace1", "status": { "state": "online" }, "_links": { "self": { "href": "/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669" } } }, { "uuid": "be732687-20cf-47d2-a0e2-2a989d15661d", "svm": { "name": "svm1" }, "name": "/vol/vol2/namespace3", "status": { "state": "online" }, "_links": { "self": { "href": "/api/storage/namespaces/be732687-20cf-47d2-a0e2-2a989d15661d" } } } ], "num_records": 3, "_links": { "self": { "href": "/api/storage/namespaces?svm.name=svm1&status.state=online" } } }
Retrieving details for a specific NVMe namespace
In this example, the fields
query parameter is used to request all fields, including advanced fields, that would not otherwise be returned by default for the NVMe namespace.
# The API: GET /api/storage/namespaces/{uuid} # The call: curl -X GET 'https://<mgmt-ip>/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669?fields=**' -H 'accept: application/hal+json' # The response: { "uuid": "dccdc3e6-cf4e-498f-bec6-f7897f945669", "svm": { "uuid": "6bf967fd-2a1c-11e9-b682-005056bbc17d", "name": "svm1", "_links": { "self": { "href": "/api/svm/svms/6bf967fd-2a1c-11e9-b682-005056bbc17d" } } }, "name": "/vol/vol1/namespace1", "location": { "namespace": "namespace1", "volume": { "uuid": "71cd0dba-2a1c-11e9-b682-005056bbc17d", "name": "vol1", "_links": { "self": { "href": "/api/storage/volumes/71cd0dba-2a1c-11e9-b682-005056bbc17d" } } } }, "auto_delete": false, "enabled": true, "comment": "Data for the research department.", "os_type": "linux", "space": { "block_size": 4096, "size": 322122547200, "used": 0, "guarantee": { "requested": false, "reserved": false } }, "status": { "container_state": "online", "mapped": true, "read_only": false, "state": "online" }, "subsystem_map": { "nsid": "00000001h", "anagrpid": "00000001h", "subsystem": { "uuid": "01f17d05-2be9-11e9-bed2-005056bbc17d", "name": "subsystem1", "_links": { "self": { "href": "/api/protocols/nvme/subsystems/01f17d05-2be9-11e9-bed2-005056bbc17d" } } }, "_links": { "self": { "href": "/api/protocols/nvme/subsystem-maps/dccdc3e6-cf4e-498f-bec6-f7897f945669/01f17d05-2be9-11e9-bed2-005056bbc17d" } } }, "metric": { "timestamp": "2019-04-09T05:50:15Z", "duration": "PT15S", "status": "ok", "latency": { "other": 0, "total": 0, "read": 0, "write": 0 }, "iops": { "read": 0, "write": 0, "other": 0, "total": 0 }, "throughput": { "read": 0, "write": 0, "total": 0 } }, "statistics": { "timestamp": "2019-04-09T05:50:42Z", "status": "ok", "latency_raw": { "other": 38298, "total": 38298, "read": 0, "write": 0 }, "iops_raw": { "read": 0, "write": 0, "other": 3, "total": 3 }, "throughput_raw": { "read": 0, "write": 0, "total": 0 } }, "_links": { "self": { "href": "/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669?fields=**" } } }
Cloning NVMe namespaces
A clone of an NVMe namespace is an independent "copy" of the namespace that shares unchanged data blocks with the original. As blocks of the source and clone are modified, unique blocks are written for each. NVMe namespace clones can be created quickly and consume very little space initially. They can be created for the purpose of back-up, or to replicate data for multiple consumers.
An NVMe namespace clone can also be set to auto-delete by setting the auto_delete
property. If the namespace's volume is configured for automatic deletion, NVMe namespaces that have auto-delete enabled are deleted when a volume is nearly full to reclaim a target amount of free space in the volume.
Creating a new NVMe namespace clone
You create an NVMe namespace clone as you create any NVMe namespace — a POST to /storage/namespaces. Set clone.source.uuid
or clone.source.name
to identify the source NVMe namespace from which the clone is created. The NVMe namespace clone and its source must reside in the same volume.
The source NVMe namespace can reside in a Snapshot copy, in which case, the clone.source.name
field must be used to identify it. Add /.snapshot/<snapshot_name>
to the path after the volume name to identify the Snapshot copy. For example /vol/vol1/.snapshot/snap1/namespace1
.
# The API: POST /api/storage/namespaces # The call: curl -X POST 'https://<mgmt-ip>/api/storage/namespaces' -H 'accept: application/hal+json' -d '{ "svm": { "name": "svm1" }, "name": "/vol/vol1/namespace2clone1", "clone": { "source": { "name": "/vol/vol1/namespace2" } } }'
Over-writing an existing NVMe namespace's data as a clone of another
You can over-write an existing NVMe namespace as a clone of another. You do this as a PATCH on the NVMe namespace to overwrite — a PATCH to /storage/namespaces/{uuid}. Set the clone.source.uuid
or clone.source.name
property to identify the source NVMe namespace from which the clone data is taken. The NVMe namespace clone and its source must reside in the same volume.
When used in a PATCH, the patched NVMe namespace's data is over-written as a clone of the source and the following properties are preserved from the patched namespace unless otherwise specified as part of the PATCH: auto_delete
, subsystem_map
, status.state
, and uuid
.
# The API: PATCH /api/storage/namespaces/{uuid} # The call: curl -X PATCH 'https://<mgmt-ip>/api/storage/namespaces/dccdc3e6-cf4e-498f-bec6-f7897f945669' -H 'accept: application/hal+json' -d '{ "clone": { "source": { "name": "/vol/vol1/namespace2" } } }'
Deleting an NVMe namespace
# The API: DELETE /api/storage/namespaces/{uuid} # The call: curl -X DELETE 'https://<mgmt-ip>/api/storage/namespaces/5c254d22-96a6-42ac-aad8-0cd9ebd126b6' -H 'accept: application/hal+json'