// SPDX-License-Identifier: LGPL-2.1-or-later /* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: Keith Busch * Chaitanya Kulkarni */ #ifndef _LIBNVME_TREE_H #define _LIBNVME_TREE_H #include #include #include #include #include #include "ioctl.h" #include "util.h" /** * DOC: tree.h * * libnvme tree object interface */ typedef struct nvme_ns *nvme_ns_t; typedef struct nvme_path *nvme_path_t; typedef struct nvme_ctrl *nvme_ctrl_t; typedef struct nvme_subsystem *nvme_subsystem_t; typedef struct nvme_host *nvme_host_t; typedef struct nvme_root *nvme_root_t; typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t, nvme_ctrl_t, nvme_ns_t, void *); /** * nvme_create_root() - Initialize root object * @fp: File descriptor for logging messages * @log_level: Logging level to use * * Return: Initialized &nvme_root_t object */ nvme_root_t nvme_create_root(FILE *fp, int log_level); /** * nvme_root_set_application - Specify managing application * @r: &nvme_root_t object * @a: Application string * * Sets the managing application string for @r. */ void nvme_root_set_application(nvme_root_t r, const char *a); /** * nvme_root_get_application - Get managing application * @r: &nvme_root_t object * * Returns the managing application string for @r or NULL if not set. */ const char *nvme_root_get_application(nvme_root_t r); /** * nvme_root_skip_namespaces - Skip namespace scanning * @r: &nvme_root_t object * * Sets a flag to skip namespaces during scanning. */ void nvme_root_skip_namespaces(nvme_root_t r); /** * nvme_root_release_fds - Close all opened file descriptors in the tree * @r: &nvme_root_t object * * Controller and Namespace objects cache the file descriptors * of opened nvme devices. This API can be used to close and * clear all cached fds in the tree. * */ void nvme_root_release_fds(nvme_root_t r); /** * nvme_free_tree() - Free root object * @r: &nvme_root_t object * * Free an &nvme_root_t object and all attached objects */ void nvme_free_tree(nvme_root_t r); /** * nvme_first_host() - Start host iterator * @r: &nvme_root_t object * * Return: First &nvme_host_t object in an iterator */ nvme_host_t nvme_first_host(nvme_root_t r); /** * nvme_next_host() - Next host iterator * @r: &nvme_root_t object * @h: Previous &nvme_host_t iterator * * Return: Next &nvme_host_t object in an iterator */ nvme_host_t nvme_next_host(nvme_root_t r, nvme_host_t h); /** * nvme_host_get_root() - Returns nvme_root_t object * @h: &nvme_host_t object * * Return: &nvme_root_t object from @h */ nvme_root_t nvme_host_get_root(nvme_host_t h); /** * nvme_lookup_host() - Lookup nvme_host_t object * @r: &nvme_root_t object * @hostnqn: Host NQN * @hostid: Host ID * * Lookup a nvme_host_t object based on @hostnqn and @hostid * or create one if not found. * * Return: &nvme_host_t object */ nvme_host_t nvme_lookup_host(nvme_root_t r, const char *hostnqn, const char *hostid); /** * nvme_host_get_dhchap_key() - Return host key * @h: Host for which the key should be returned * * Return: DH-HMAC-CHAP host key or NULL if not set */ const char *nvme_host_get_dhchap_key(nvme_host_t h); /** * nvme_host_set_dhchap_key() - set host key * @h: Host for which the key should be set * @key: DH-HMAC-CHAP Key to set or NULL to clear existing key */ void nvme_host_set_dhchap_key(nvme_host_t h, const char *key); /** * nvme_host_set_pdc_enabled() - Set Persistent Discovery Controller flag * @h: Host for which the falg should be set * @enabled: The bool to set the enabled flag * * When nvme_host_set_pdc_enabled() is not used to set the PDC flag, * nvme_host_is_pdc_enabled() will return the default value which was * passed into the function and not the undefined flag value. */ void nvme_host_set_pdc_enabled(nvme_host_t h, bool enabled); /** * nvme_host_is_pdc_enabled() - Is Persistenct Discovery Controller enabled * @h: Host which to check if PDC is enabled * @fallback: The fallback default value of the flag when * @nvme_host_set_pdc_enabled has not be used * to set the flag. * * Return: true if PDC is enabled for @h, else false */ bool nvme_host_is_pdc_enabled(nvme_host_t h, bool fallback); /** * nvme_default_host() - Initializes the default host * @r: &nvme_root_t object * * Initializes the default host object based on the hostnqn/hostid * values returned by nvme_host_get_ids() and attaches it to @r. * * Return: &nvme_host_t object */ nvme_host_t nvme_default_host(nvme_root_t r); /** * nvme_host_get_ids - Retrieve host ids from various sources * * @r: &nvme_root_t object * @hostnqn_arg: Input hostnqn (command line) argument * @hostid_arg: Input hostid (command line) argument * @hostnqn: Output hostnqn * @hostid: Output hostid * * nvme_host_get_ids figures out which hostnqn/hostid is to be used. * There are several sources where this information can be retrieved. * * The order is: * * - Start with informartion from DMI or device-tree * - Override hostnqn and hostid from /etc/nvme files * - Override hostnqn or hostid with values from JSON * configuration file. The first host entry in the file is * considered the default host. * - Override hostnqn or hostid with values from the command line * (@hostnqn_arg, @hostid_arg). * * If the IDs are still NULL after the lookup algorithm, the function * will generate random IDs. * * The function also verifies that hostnqn and hostid matches. The Linux * NVMe implementation expects a 1:1 matching between the IDs. * * Return: 0 on success (@hostnqn and @hostid contain valid strings * which the caller needs to free), -1 otherwise and errno is set. */ int nvme_host_get_ids(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, char **hostnqn, char **hostid); /** * nvme_first_subsystem() - Start subsystem iterator * @h: &nvme_host_t object * * Return: first &nvme_subsystem_t object in an iterator */ nvme_subsystem_t nvme_first_subsystem(nvme_host_t h); /** * nvme_next_subsystem() - Next subsystem iterator * @h: &nvme_host_t object * @s: Previous &nvme_subsystem_t iterator * * Return: next &nvme_subsystem_t object in an iterator */ nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s); /** * nvme_lookup_subsystem() - Lookup nvme_subsystem_t object * @h: &nvme_host_t object * @name: Name of the subsystem (may be NULL) * @subsysnqn: Subsystem NQN * * Lookup a &nvme_subsystem_t object in @h base on @name (if present) * and @subsysnqn or create one if not found. * * Return: nvme_subsystem_t object */ nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, const char *name, const char *subsysnqn); /** * nvme_free_subsystem() - Free a subsystem * @s: subsystem * * Frees @s and all related objects. */ void nvme_free_subsystem(struct nvme_subsystem *s); /** * nvme_subsystem_get_host() - Returns nvme_host_t object * @s: subsystem * * Return: &nvme_host_t object from @s */ nvme_host_t nvme_subsystem_get_host(nvme_subsystem_t s); /** * nvme_ctrl_first_ns() - Start namespace iterator * @c: Controller instance * * Return: First &nvme_ns_t object of an @c iterator */ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); /** * nvme_ctrl_next_ns() - Next namespace iterator * @c: Controller instance * @n: Previous nvme_ns_t iterator * * Return: Next nvme_ns_t object of an @c iterator */ nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); /** * nvme_ctrl_first_path() - Start path iterator * @c: Controller instance * * Return: First &nvme_path_t object of an @c iterator */ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); /** * nvme_ctrl_next_path() - Next path iterator * @c: Controller instance * @p: Previous &nvme_path_t object of an @c iterator * * Return: Next &nvme_path_t object of an @c iterator */ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); /** * nvme_subsystem_first_ctrl() - First ctrl iterator * @s: &nvme_subsystem_t object * * Return: First controller of an @s iterator */ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); /** * nvme_subsystem_next_ctrl() - Next ctrl iterator * @s: &nvme_subsystem_t object * @c: Previous controller instance of an @s iterator * * Return: Next controller of an @s iterator */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); /** * nvme_namespace_first_path() - Start path iterator * @ns: Namespace instance * * Return: First &nvme_path_t object of an @ns iterator */ nvme_path_t nvme_namespace_first_path(nvme_ns_t ns); /** * nvme_namespace_next_path() - Next path iterator * @ns: Namespace instance * @p: Previous &nvme_path_t object of an @ns iterator * * Return: Next &nvme_path_t object of an @ns iterator */ nvme_path_t nvme_namespace_next_path(nvme_ns_t ns, nvme_path_t p); /** * nvme_lookup_ctrl() - Lookup nvme_ctrl_t object * @s: &nvme_subsystem_t object * @transport: Transport name * @traddr: Transport address * @host_traddr: Host transport address * @host_iface: Host interface name * @trsvcid: Transport service identifier * @p: Previous controller instance * * Lookup a controller in @s based on @transport, @traddr, * @host_traddr, @host_iface, and @trsvcid. @transport must be specified, * other fields may be required depending on the transport. A new * object is created if none is found. If @p is specified the lookup * will start at @p instead of the first controller. * * Return: Controller instance */ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid, nvme_ctrl_t p); /** * nvme_ctrl_find() - Locate an existing controller * @s: &nvme_subsystem_t object * @transport: Transport name * @traddr: Transport address * @trsvcid: Transport service identifier * @subsysnqn: Subsystem NQN * @host_traddr: Host transport address * @host_iface: Host interface name * * Lookup a controller in @s based on @transport, @traddr, @trsvcid, * @subsysnqn, @host_traddr, and @host_iface. @transport must be specified, * other fields may be required depending on the transport. Parameters set * to NULL will be ignored. * * Unlike nvme_lookup_ctrl(), this function does not create a new object if * an existing controller cannot be found. * * Return: Controller instance on success, NULL otherwise. */ nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, const char *traddr, const char *trsvcid, const char *subsysnqn, const char *host_traddr, const char *host_iface); /** * nvme_ctrl_config_match() - Check if ctrl @c matches config params * @c: An existing controller instance * @transport: Transport name * @traddr: Transport address * @trsvcid: Transport service identifier * @subsysnqn: Subsystem NQN * @host_traddr: Host transport address * @host_iface: Host interface name * * Check that controller @c matches parameters: @transport, @traddr, * @trsvcid, @subsysnqn, @host_traddr, and @host_iface. Parameters set * to NULL will be ignored. * * Return: true if there's a match, false otherwise. */ bool nvme_ctrl_config_match(struct nvme_ctrl *c, const char *transport, const char *traddr, const char *trsvcid, const char *subsysnqn, const char *host_traddr, const char *host_iface); /** * nvme_create_ctrl() - Allocate an unconnected NVMe controller * @r: NVMe root element * @subsysnqn: Subsystem NQN * @transport: Transport type * @traddr: Transport address * @host_traddr: Host transport address * @host_iface: Host interface name * @trsvcid: Transport service ID * * Creates an unconnected controller to be used for nvme_add_ctrl(). * * Return: Controller instance */ nvme_ctrl_t nvme_create_ctrl(nvme_root_t r, const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid); /** * nvme_subsystem_first_ns() - Start namespace iterator * @s: &nvme_subsystem_t object * * Return: First &nvme_ns_t object of an @s iterator */ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); /** * nvme_subsystem_next_ns() - Next namespace iterator * @s: &nvme_subsystem_t object * @n: Previous &nvme_ns_t iterator * * Return: Next &nvme_ns_t object of an @s iterator */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); /** * nvme_for_each_host_safe() - Traverse host list * @r: &nvme_root_t object * @h: &nvme_host_t object * @_h: Temporary &nvme_host_t object */ #define nvme_for_each_host_safe(r, h, _h) \ for (h = nvme_first_host(r), \ _h = nvme_next_host(r, h); \ h != NULL; \ h = _h, _h = nvme_next_host(r, h)) /** * nvme_for_each_host() - Traverse host list * @r: &nvme_root_t object * @h: &nvme_host_t object */ #define nvme_for_each_host(r, h) \ for (h = nvme_first_host(r); h != NULL; \ h = nvme_next_host(r, h)) /** * nvme_for_each_subsystem_safe() - Traverse subsystems * @h: &nvme_host_t object * @s: &nvme_subsystem_t object * @_s: Temporary &nvme_subsystem_t object */ #define nvme_for_each_subsystem_safe(h, s, _s) \ for (s = nvme_first_subsystem(h), \ _s = nvme_next_subsystem(h, s); \ s != NULL; \ s = _s, _s = nvme_next_subsystem(h, s)) /** * nvme_for_each_subsystem() - Traverse subsystems * @h: &nvme_host_t object * @s: &nvme_subsystem_t object */ #define nvme_for_each_subsystem(h, s) \ for (s = nvme_first_subsystem(h); s != NULL; \ s = nvme_next_subsystem(h, s)) /** * nvme_subsystem_for_each_ctrl_safe() - Traverse controllers * @s: &nvme_subsystem_t object * @c: Controller instance * @_c: A &nvme_ctrl_t_node to use as temporary storage */ #define nvme_subsystem_for_each_ctrl_safe(s, c, _c) \ for (c = nvme_subsystem_first_ctrl(s), \ _c = nvme_subsystem_next_ctrl(s, c); \ c != NULL; \ c = _c, _c = nvme_subsystem_next_ctrl(s, c)) /** * nvme_subsystem_for_each_ctrl() - Traverse controllers * @s: &nvme_subsystem_t object * @c: Controller instance */ #define nvme_subsystem_for_each_ctrl(s, c) \ for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ c = nvme_subsystem_next_ctrl(s, c)) /** * nvme_ctrl_for_each_ns_safe() - Traverse namespaces * @c: Controller instance * @n: &nvme_ns_t object * @_n: A &nvme_ns_t_node to use as temporary storage */ #define nvme_ctrl_for_each_ns_safe(c, n, _n) \ for (n = nvme_ctrl_first_ns(c), \ _n = nvme_ctrl_next_ns(c, n); \ n != NULL; \ n = _n, _n = nvme_ctrl_next_ns(c, n)) /** * nvme_ctrl_for_each_ns() - Traverse namespaces * @c: Controller instance * @n: &nvme_ns_t object */ #define nvme_ctrl_for_each_ns(c, n) \ for (n = nvme_ctrl_first_ns(c); n != NULL; \ n = nvme_ctrl_next_ns(c, n)) /** * nvme_ctrl_for_each_path_safe() - Traverse paths * @c: Controller instance * @p: &nvme_path_t object * @_p: A &nvme_path_t_node to use as temporary storage */ #define nvme_ctrl_for_each_path_safe(c, p, _p) \ for (p = nvme_ctrl_first_path(c), \ _p = nvme_ctrl_next_path(c, p); \ p != NULL; \ p = _p, _p = nvme_ctrl_next_path(c, p)) /** * nvme_ctrl_for_each_path() - Traverse paths * @c: Controller instance * @p: &nvme_path_t object */ #define nvme_ctrl_for_each_path(c, p) \ for (p = nvme_ctrl_first_path(c); p != NULL; \ p = nvme_ctrl_next_path(c, p)) /** * nvme_subsystem_for_each_ns_safe() - Traverse namespaces * @s: &nvme_subsystem_t object * @n: &nvme_ns_t object * @_n: A &nvme_ns_t_node to use as temporary storage */ #define nvme_subsystem_for_each_ns_safe(s, n, _n) \ for (n = nvme_subsystem_first_ns(s), \ _n = nvme_subsystem_next_ns(s, n); \ n != NULL; \ n = _n, _n = nvme_subsystem_next_ns(s, n)) /** * nvme_subsystem_for_each_ns() - Traverse namespaces * @s: &nvme_subsystem_t object * @n: &nvme_ns_t object */ #define nvme_subsystem_for_each_ns(s, n) \ for (n = nvme_subsystem_first_ns(s); n != NULL; \ n = nvme_subsystem_next_ns(s, n)) /** * nvme_namespace_for_each_path_safe() - Traverse paths * @n: Namespace instance * @p: &nvme_path_t object * @_p: A &nvme_path_t_node to use as temporary storage */ #define nvme_namespace_for_each_path_safe(n, p, _p) \ for (p = nvme_namespace_first_path(n), \ _p = nvme_namespace_next_path(n, p); \ p != NULL; \ p = _p, _p = nvme_namespace_next_path(n, p)) /** * nvme_namespace_for_each_path() - Traverse paths * @n: Namespace instance * @p: &nvme_path_t object */ #define nvme_namespace_for_each_path(n, p) \ for (p = nvme_namespace_first_path(n); p != NULL; \ p = nvme_namespace_next_path(n, p)) /** * nvme_ns_get_fd() - Get associated file descriptor * @n: Namespace instance * * libnvme will open() the file (if not already opened) and keep * an internal copy of the file descriptor. Following calls to * this API retrieve the internal cached copy of the file * descriptor. The file will remain opened and the fd will * remain cached until the ns object is deleted or * nvme_ns_release_fd() is called. * * Return: File descriptor associated with @n or -1 */ int nvme_ns_get_fd(nvme_ns_t n); /** * nvme_ns_release_fd() - Close fd and clear fd from ns object * @n: Namespace instance * */ void nvme_ns_release_fd(nvme_ns_t n); /** * nvme_ns_get_nsid() - NSID of a namespace * @n: Namespace instance * * Return: NSID of @n */ int nvme_ns_get_nsid(nvme_ns_t n); /** * nvme_ns_get_lba_size() - LBA size of a namespace * @n: Namespace instance * * Return: LBA size of @n */ int nvme_ns_get_lba_size(nvme_ns_t n); /** * nvme_ns_get_meta_size() - Metadata size of a namespace * @n: Namespace instance * * Return: Metadata size of @n */ int nvme_ns_get_meta_size(nvme_ns_t n); /** * nvme_ns_get_lba_count() - LBA count of a namespace * @n: Namespace instance * * Return: LBA count of @n */ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); /** * nvme_ns_get_lba_util() - LBA utilization of a namespace * @n: Namespace instance * * Return: LBA utilization of @n */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); /** * nvme_ns_get_csi() - Command set identifier of a namespace * @n: Namespace instance * * Return: The namespace's command set identifier in use */ enum nvme_csi nvme_ns_get_csi(nvme_ns_t n); /** * nvme_ns_get_eui64() - 64-bit eui of a namespace * @n: Namespace instance * * Return: A pointer to the 64-bit eui */ const uint8_t *nvme_ns_get_eui64(nvme_ns_t n); /** * nvme_ns_get_nguid() - 128-bit nguid of a namespace * @n: Namespace instance * * Return: A pointer to the 128-bit nguid */ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n); /** * nvme_ns_get_uuid() - UUID of a namespace * @n: Namespace instance * @out: buffer for the UUID * * Copies the namespace's uuid into @out */ void nvme_ns_get_uuid(nvme_ns_t n, unsigned char out[NVME_UUID_LEN]); /** * nvme_ns_get_sysfs_dir() - sysfs directory of a namespace * @n: Namespace instance * * Return: sysfs directory name of @n */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); /** * nvme_ns_get_name() - sysfs name of a namespace * @n: Namespace instance * * Return: sysfs name of @n */ const char *nvme_ns_get_name(nvme_ns_t n); /** * nvme_ns_get_generic_name() - Returns name of generic namespace chardev. * @n: Namespace instance * * Return: Name of generic namespace chardev */ const char *nvme_ns_get_generic_name(nvme_ns_t n); /** * nvme_ns_get_firmware() - Firmware string of a namespace * @n: Namespace instance * * Return: Firmware string of @n */ const char *nvme_ns_get_firmware(nvme_ns_t n); /** * nvme_ns_get_serial() - Serial number of a namespace * @n: Namespace instance * * Return: Serial number string of @n */ const char *nvme_ns_get_serial(nvme_ns_t n); /** * nvme_ns_get_model() - Model of a namespace * @n: Namespace instance * * Return: Model string of @n */ const char *nvme_ns_get_model(nvme_ns_t n); /** * nvme_ns_get_subsystem() - &nvme_subsystem_t of a namespace * @n: Namespace instance * * Return: nvme_subsystem_t object of @n */ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); /** * nvme_ns_get_ctrl() - &nvme_ctrl_t of a namespace * @n: Namespace instance * * nvme_ctrl_t object may be NULL for a multipathed namespace * * Return: nvme_ctrl_t object of @n if present */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** * nvme_free_ns() - Free a namespace object * @n: Namespace instance */ void nvme_free_ns(struct nvme_ns *n); /** * nvme_ns_read() - Read from a namespace * @n: Namespace instance * @buf: Buffer into which the data will be transferred * @offset: LBA offset of @n * @count: Number of sectors in @buf * * Return: Number of sectors read or -1 on error. */ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_write() - Write to a namespace * @n: Namespace instance * @buf: Buffer with data to be written * @offset: LBA offset of @n * @count: Number of sectors in @buf * * Return: Number of sectors written or -1 on error */ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_verify() - Verify data on a namespace * @n: Namespace instance * @offset: LBA offset of @n * @count: Number of sectors to be verified * * Return: Number of sectors verified */ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_compare() - Compare data on a namespace * @n: Namespace instance * @buf: Buffer with data to be compared * @offset: LBA offset of @n * @count: Number of sectors in @buf * * Return: Number of sectors compared */ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_write_zeros() - Write zeros to a namespace * @n: Namespace instance * @offset: LBA offset in @n * @count: Number of sectors to be written * * Return: Number of sectors written */ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_write_uncorrectable() - Issus a 'write uncorrectable' command * @n: Namespace instance * @offset: LBA offset in @n * @count: Number of sectors to be written * * Return: Number of sectors written */ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_flush() - Flush data to a namespace * @n: Namespace instance * * Return: 0 on success, -1 on error. */ int nvme_ns_flush(nvme_ns_t n); /** * nvme_ns_identify() - Issue an 'identify namespace' command * @n: Namespace instance * @ns: &nvme_id_ns buffer * * Writes the data returned by the 'identify namespace' command * into @ns. * * Return: 0 on success, -1 on error. */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); /** * nvme_ns_identify_descs() - Issue an 'identify descriptors' command * @n: Namespace instance * @descs: List of identify descriptors * * Writes the data returned by the 'identify descriptors' command * into @descs. * * Return: 0 on success, -1 on error. */ int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs); /** * nvme_path_get_name() - sysfs name of an &nvme_path_t object * @p: &nvme_path_t object * * Return: sysfs name of @p */ const char *nvme_path_get_name(nvme_path_t p); /** * nvme_path_get_sysfs_dir() - sysfs directory of an nvme_path_t object * @p: &nvme_path_t object * * Return: sysfs directory of @p */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); /** * nvme_path_get_ana_state() - ANA state of an nvme_path_t object * @p: &nvme_path_t object * * Return: ANA (Asynchronous Namespace Access) state of @p */ const char *nvme_path_get_ana_state(nvme_path_t p); /** * nvme_path_get_ctrl() - Parent controller of an nvme_path_t object * @p: &nvme_path_t object * * Return: Parent controller if present */ nvme_ctrl_t nvme_path_get_ctrl(nvme_path_t p); /** * nvme_path_get_ns() - Parent namespace of an nvme_path_t object * @p: &nvme_path_t object * * Return: Parent namespace if present */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); /** * nvme_ctrl_get_fd() - Get associated file descriptor * @c: Controller instance * * libnvme will open() the file (if not already opened) and keep * an internal copy of the file descriptor. Following calls to * this API retrieve the internal cached copy of the file * descriptor. The file will remain opened and the fd will * remain cached until the controller object is deleted or * nvme_ctrl_release_fd() is called. * * Return: File descriptor associated with @c or -1 */ int nvme_ctrl_get_fd(nvme_ctrl_t c); /** * nvme_ctrl_release_fd() - Close fd and clear fd from controller object * @c: Controller instance * */ void nvme_ctrl_release_fd(nvme_ctrl_t c); /** * nvme_ctrl_get_name() - sysfs name of a controller * @c: Controller instance * * Return: sysfs name of @c */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); /** * nvme_ctrl_get_sysfs_dir() - sysfs directory of a controller * @c: Controller instance * * Return: sysfs directory name of @c */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); /** * nvme_ctrl_get_address() - Address string of a controller * @c: Controller instance * * Return: NVMe-over-Fabrics address string of @c or empty string * of no address is present. */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); /** * nvme_ctrl_get_src_addr() - Extract src_addr from the c->address string * @c: Controller instance * @src_addr: Where to copy the src_addr. Size must be at least INET6_ADDRSTRLEN. * @src_addr_len: Length of the buffer @src_addr. * * Return: Pointer to @src_addr on success. NULL on failure to extract the src_addr. */ char *nvme_ctrl_get_src_addr(nvme_ctrl_t c, char *src_addr, size_t src_addr_len); /** * nvme_ctrl_get_phy_slot() - PCI physical slot number of a controller * @c: Controller instance * * Return: PCI physical slot number of @c or empty string if slot * number is not present. */ const char *nvme_ctrl_get_phy_slot(nvme_ctrl_t c); /** * nvme_ctrl_get_firmware() - Firmware string of a controller * @c: Controller instance * * Return: Firmware string of @c */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); /** * nvme_ctrl_get_model() - Model of a controller * @c: Controller instance * * Return: Model string of @c */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); /** * nvme_ctrl_get_state() - Running state of a controller * @c: Controller instance * * Return: String indicating the running state of @c */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); /** * nvme_ctrl_get_numa_node() - NUMA node of a controller * @c: Controller instance * * Return: String indicating the NUMA node */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); /** * nvme_ctrl_get_queue_count() - Queue count of a controller * @c: Controller instance * * Return: Queue count of @c */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); /** * nvme_ctrl_get_serial() - Serial number of a controller * @c: Controller instance * * Return: Serial number string of @c */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); /** * nvme_ctrl_get_sqsize() - SQ size of a controller * @c: Controller instance * * Return: SQ size (as string) of @c */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); /** * nvme_ctrl_get_transport() - Transport type of a controller * @c: Controller instance * * Return: Transport type of @c */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); /** * nvme_ctrl_get_subsysnqn() - Subsystem NQN of a controller * @c: Controller instance * * Return: Subsystem NQN of @c */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); /** * nvme_ctrl_get_subsystem() - Parent subsystem of a controller * @c: Controller instance * * Return: Parent nvme_subsystem_t object */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); /** * nvme_ctrl_get_traddr() - Transport address of a controller * @c: Controller instance * * Return: Transport address of @c */ const char *nvme_ctrl_get_traddr(nvme_ctrl_t c); /** * nvme_ctrl_get_trsvcid() - Transport service identifier of a controller * @c: Controller instance * * Return: Transport service identifier of @c (if present) */ const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c); /** * nvme_ctrl_get_host_traddr() - Host transport address of a controller * @c: Controller instance * * Return: Host transport address of @c (if present) */ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); /** * nvme_ctrl_get_host_iface() - Host interface name of a controller * @c: Controller instance * * Return: Host interface name of @c (if present) */ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c); /** * nvme_ctrl_get_dhchap_host_key() - Return host key * @c: Controller to be checked * * Return: DH-HMAC-CHAP host key or NULL if not set */ const char *nvme_ctrl_get_dhchap_host_key(nvme_ctrl_t c); /** * nvme_ctrl_get_cntlid() - Controller id * @c: Controller to be checked * * Return : Controller id of @c */ const char *nvme_ctrl_get_cntlid(nvme_ctrl_t c); /** * nvme_ctrl_set_dhchap_host_key() - Set host key * @c: Host for which the key should be set * @key: DH-HMAC-CHAP Key to set or NULL to clear existing key */ void nvme_ctrl_set_dhchap_host_key(nvme_ctrl_t c, const char *key); /** * nvme_ctrl_get_dhchap_key() - Return controller key * @c: Controller for which the key should be set * * Return: DH-HMAC-CHAP controller key or NULL if not set */ const char *nvme_ctrl_get_dhchap_key(nvme_ctrl_t c); /** * nvme_ctrl_set_dhchap_key() - Set controller key * @c: Controller for which the key should be set * @key: DH-HMAC-CHAP Key to set or NULL to clear existing key */ void nvme_ctrl_set_dhchap_key(nvme_ctrl_t c, const char *key); /** * nvme_ctrl_get_keyring() - Return keyring * @c: Controller to be used for the lookup * * Return: Keyring or NULL if not set */ const char *nvme_ctrl_get_keyring(nvme_ctrl_t c); /** * nvme_ctrl_set_keyring() - Set keyring * @c: Controller for which the keyring should be set * @keyring: Keyring name */ void nvme_ctrl_set_keyring(nvme_ctrl_t c, const char *keyring); /** * nvme_ctrl_get_tls_key_identity() - Return Derive TLS Identity * @c: Controller to be used for the lookup * * Return: Derive TLS Identity or NULL if not set */ const char *nvme_ctrl_get_tls_key_identity(nvme_ctrl_t c); /** * nvme_ctrl_set_tls_key_identity() - Set Derive TLS Identity * @c: Controller for which the key should be set * @identity: Derive TLS identity or NULL to clear existing key */ void nvme_ctrl_set_tls_key_identity(nvme_ctrl_t c, const char *identity); /** * nvme_ctrl_get_tls_key() - Return Derive TLS PSK * @c: Controller to be used for the lookup * * Return: Key in PSK interchange format or NULL if not set */ const char *nvme_ctrl_get_tls_key(nvme_ctrl_t c); /** * nvme_ctrl_set_tls_key() - Set Derive TLS PSK * @c: Controller for which the key should be set * @key: Key in interchange format or NULL to clear existing key */ void nvme_ctrl_set_tls_key(nvme_ctrl_t c, const char *key); /** * nvme_ctrl_get_config() - Fabrics configuration of a controller * @c: Controller instance * * Return: Fabrics configuration of @c */ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c); /** * nvme_ctrl_set_discovered() - Set the 'discovered' flag * @c: nvme_ctrl_t object * @discovered: Value of the 'discovered' flag * * Set the 'discovered' flag of @c to @discovered */ void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered); /** * nvme_ctrl_is_discovered() - Returns the value of the 'discovered' flag * @c: Controller instance * * Return: Value of the 'discovered' flag of @c */ bool nvme_ctrl_is_discovered(nvme_ctrl_t c); /** * nvme_ctrl_set_persistent() - Set the 'persistent' flag * @c: Controller instance * @persistent: value of the 'persistent' flag * * Set the 'persistent' flag of @c to @persistent */ void nvme_ctrl_set_persistent(nvme_ctrl_t c, bool persistent); /** * nvme_ctrl_is_persistent() - Returns the value of the 'persistent' flag * @c: Controller instance * * Return: Value of the 'persistent' flag of @c */ bool nvme_ctrl_is_persistent(nvme_ctrl_t c); /** * nvme_ctrl_set_discovery_ctrl() - Set the 'discovery_ctrl' flag * @c: Controller to be modified * @discovery: value of the discovery_ctrl flag * * Sets the 'discovery_ctrl' flag in @c to specify whether * @c connects to a discovery subsystem. * */ void nvme_ctrl_set_discovery_ctrl(nvme_ctrl_t c, bool discovery); /** * nvme_ctrl_is_discovery_ctrl() - Check the 'discovery_ctrl' flag * @c: Controller to be checked * * Returns the value of the 'discovery_ctrl' flag which specifies whether * @c connects to a discovery subsystem. * * Return: Value of the 'discover_ctrl' flag */ bool nvme_ctrl_is_discovery_ctrl(nvme_ctrl_t c); /** * nvme_ctrl_set_unique_discovery_ctrl() - Set the 'unique_discovery_ctrl' flag * @c: Controller to be modified * @unique: value of the unique_disc_ctrl flag * * Sets the 'unique_discovery_ctrl' flag in @c to specify wheter * @c is a unique discovery controller * */ void nvme_ctrl_set_unique_discovery_ctrl(nvme_ctrl_t c, bool unique); /** * nvme_ctrl_is_unique_discovery_ctrl() - Check the 'unique_discovery_ctrl' flag * @c: Controller to be checked * * Return: Value of the 'unique_discovery_ctrl' flag */ bool nvme_ctrl_is_unique_discovery_ctrl(nvme_ctrl_t c); /** * nvme_ctrl_identify() - Issues an 'identify controller' command * @c: Controller instance * @id: Identify controller data structure * * Issues an 'identify controller' command to @c and copies the * data into @id. * * Return: 0 on success or -1 on failure. */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); /** * nvme_disconnect_ctrl() - Disconnect a controller * @c: Controller instance * * Issues a 'disconnect' fabrics command to @c * * Return: 0 on success, -1 on failure. */ int nvme_disconnect_ctrl(nvme_ctrl_t c); /** * nvme_scan_ctrl() - Scan on a controller * @r: nvme_root_t object * @name: Name of the controller * * Scans a controller with sysfs name @name and add it to @r. * * Return: nvme_ctrl_t object */ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); /** * nvme_rescan_ctrl() - Rescan an existing controller * @c: Controller instance */ void nvme_rescan_ctrl(nvme_ctrl_t c); /** * nvme_init_ctrl() - Initialize nvme_ctrl_t object for an existing controller. * @h: nvme_host_t object * @c: nvme_ctrl_t object * @instance: Instance number (e.g. 1 for nvme1) * * Return: The ioctl() return code. Typically 0 on success. */ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); /** * nvme_free_ctrl() - Free controller * @c: Controller instance */ void nvme_free_ctrl(struct nvme_ctrl *c); /** * nvme_unlink_ctrl() - Unlink controller * @c: Controller instance */ void nvme_unlink_ctrl(struct nvme_ctrl *c); /** * nvme_subsystem_get_nqn() - Retrieve NQN from subsystem * @s: nvme_subsystem_t object * * Return: NQN of subsystem */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); /** * nvme_subsystem_get_sysfs_dir() - sysfs directory of an nvme_subsystem_t object * @s: nvme_subsystem_t object * * Return: sysfs directory name of @s */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); /** * nvme_subsystem_get_name() - sysfs name of an nvme_subsystem_t object * @s: nvme_subsystem_t object * * Return: sysfs name of @s */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); /** * nvme_subsystem_get_type() - Returns the type of a subsystem * @s: nvme_subsystem_t object * * Returns the subsystem type of @s. * * Return: 'nvm' or 'discovery' */ const char *nvme_subsystem_get_type(nvme_subsystem_t s); /** * nvme_subsystem_get_application() - Return the application string * @s: nvme_subsystem_t object * * Return: Managing application string or NULL if not set. */ const char *nvme_subsystem_get_application(nvme_subsystem_t s); /** * nvme_subsystem_set_application() - Set the application string * @s: nvme_subsystem_t object * @a: application string * * Sets the managing application string for @s. */ void nvme_subsystem_set_application(nvme_subsystem_t s, const char *a); /** * nvme_subsystem_get_iopolicy() - Return the IO policy of subsytem * @s: nvme_subsystem_t object * * Return: IO policy used by current subsystem */ const char *nvme_subsystem_get_iopolicy(nvme_subsystem_t s); /** * nvme_scan_topology() - Scan NVMe topology and apply filter * @r: nvme_root_t object * @f: filter to apply * @f_args: user-specified argument to @f * * Scans the NVMe topology and filters out the resulting elements * by applying @f. * * Return: Number of elements scanned */ int nvme_scan_topology(nvme_root_t r, nvme_scan_filter_t f, void *f_args); /** * nvme_host_get_hostnqn() - Host NQN of an nvme_host_t object * @h: nvme_host_t object * * Return: Host NQN of @h */ const char *nvme_host_get_hostnqn(nvme_host_t h); /** * nvme_host_get_hostid() - Host ID of an nvme_host_t object * @h: nvme_host_t object * * Return: Host ID of @h */ const char *nvme_host_get_hostid(nvme_host_t h); /** * nvme_host_release_fds() - Close all opened file descriptors under host * @h: nvme_host_t object * * Controller and Namespace objects cache the file descriptors * of opened nvme devices. This API can be used to close and * clear all cached fds under this host. */ void nvme_host_release_fds(struct nvme_host *h); /** * nvme_free_host() - Free nvme_host_t object * @h: nvme_host_t object */ void nvme_free_host(nvme_host_t h); /** * nvme_scan() - Scan NVMe topology * @config_file: Configuration file * * Return: nvme_root_t object of found elements */ nvme_root_t nvme_scan(const char *config_file); /** * nvme_read_config() - Read NVMe JSON configuration file * @r: nvme_root_t object * @config_file: JSON configuration file * * Read in the contents of @config_file and merge them with * the elements in @r. * * Returns: 0 on success, -1 on failure with errno set. */ int nvme_read_config(nvme_root_t r, const char *config_file); /** * nvme_refresh_topology() - Refresh nvme_root_t object contents * @r: nvme_root_t object * * Removes all elements in @r and rescans the existing topology. */ void nvme_refresh_topology(nvme_root_t r); /** * nvme_update_config() - Update JSON configuration * @r: nvme_root_t object * * Updates the JSON configuration file with the contents of @r. * * Return: 0 on success, -1 on failure. */ int nvme_update_config(nvme_root_t r); /** * nvme_dump_config() - Print the JSON configuration * @r: nvme_root_t object * * Prints the current contents of the JSON configuration * file to stdout. * * Return: 0 on success, -1 on failure. */ int nvme_dump_config(nvme_root_t r); /** * nvme_dump_tree() - Dump internal object tree * @r: nvme_root_t object * * Prints the internal object tree in JSON format * to stdout. * * Return: 0 on success, -1 on failure. */ int nvme_dump_tree(nvme_root_t r); /** * nvme_get_attr() - Read sysfs attribute * @d: sysfs directory * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_attr(const char *d, const char *attr); /** * nvme_get_subsys_attr() - Read subsystem sysfs attribute * @s: nvme_subsystem_t object * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); /** * nvme_get_ctrl_attr() - Read controller sysfs attribute * @c: Controller instance * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); /** * nvme_get_ns_attr() - Read namespace sysfs attribute * @n: nvme_ns_t object * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); /** * nvme_subsystem_lookup_namespace() - lookup namespace by NSID * @s: nvme_subsystem_t object * @nsid: Namespace id * * Return: nvme_ns_t of the namespace with id @nsid in subsystem @s */ nvme_ns_t nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, __u32 nsid); /** * nvme_subsystem_release_fds() - Close all opened fds under subsystem * @s: nvme_subsystem_t object * * Controller and Namespace objects cache the file descriptors * of opened nvme devices. This API can be used to close and * clear all cached fds under this subsystem. * */ void nvme_subsystem_release_fds(struct nvme_subsystem *s); /** * nvme_get_path_attr() - Read path sysfs attribute * @p: nvme_path_t object * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); /** * nvme_scan_namespace() - scan namespace based on sysfs name * @name: sysfs name of the namespace to scan * * Return: nvme_ns_t object or NULL if not found. */ nvme_ns_t nvme_scan_namespace(const char *name); /** * nvme_host_get_hostsymname() - Get the host's symbolic name * @h: Host for which the symbolic name should be returned. * * Return: The symbolic name or NULL if a symbolic name hasn't been * configure. */ const char *nvme_host_get_hostsymname(nvme_host_t h); /** * nvme_host_set_hostsymname() - Set the host's symbolic name * @h: Host for which the symbolic name should be set. * @hostsymname: Symbolic name */ void nvme_host_set_hostsymname(nvme_host_t h, const char *hostsymname); #endif /* _LIBNVME_TREE_H */