diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bf62ade4e..76ccdc5ec7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -187,6 +187,19 @@ jobs: run: | CC=musl-gcc scripts/build.sh musl + build-musl-minimal-static: + name: musl libc minimal static build on Debian + runs-on: ubuntu-latest + container: + image: ghcr.io/linux-nvme/debian:latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Mark repo as safe for git + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: build + run: | + scripts/build.sh minimal_static + build-alpine: name: musl libc build on Alpine runs-on: ubuntu-latest diff --git a/libnvme/examples/meson.build b/libnvme/examples/meson.build index 5d3e5fb237..31db6a7e17 100644 --- a/libnvme/examples/meson.build +++ b/libnvme/examples/meson.build @@ -35,15 +35,17 @@ executable( ], ) -executable( - 'discover-loop', - ['discover-loop.c'], - dependencies: [ - config_dep, - ccan_dep, - libnvme_dep, - ], -) +if want_fabrics + executable( + 'discover-loop', + ['discover-loop.c'], + dependencies: [ + config_dep, + ccan_dep, + libnvme_dep, + ], + ) +endif executable( 'mi-mctp', diff --git a/libnvme/libnvme/nvme.i b/libnvme/libnvme/nvme.i index c606532b33..460500e06b 100644 --- a/libnvme/libnvme/nvme.i +++ b/libnvme/libnvme/nvme.i @@ -39,13 +39,13 @@ Py_XDECREF(val); /* .. therefore decrement ref. count. */ } PyObject *hostnqn_from_file() { - char * val = nvmf_hostnqn_from_file(); + char * val = nvme_hostnqn_from_file(); PyObject * obj = PyUnicode_FromString(val); free(val); return obj; } PyObject *hostid_from_file() { - char * val = nvmf_hostid_from_file(); + char * val = nvme_hostid_from_file(); PyObject * obj = PyUnicode_FromString(val); free(val); return obj; diff --git a/libnvme/src/libnvme.h b/libnvme/src/libnvme.h.in similarity index 92% rename from libnvme/src/libnvme.h rename to libnvme/src/libnvme.h.in index 56416dcd6e..8168a69933 100644 --- a/libnvme/src/libnvme.h +++ b/libnvme/src/libnvme.h.in @@ -15,13 +15,12 @@ extern "C" { #endif #include -#include +@FABRICS_INCLUDE@ #include #include #include #include #include -#include #include #include #include diff --git a/libnvme/src/libnvme.ld b/libnvme/src/libnvme.ld index 4072407de9..46ab0dcb3f 100644 --- a/libnvme/src/libnvme.ld +++ b/libnvme/src/libnvme.ld @@ -1,8 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -LIBNVME_UNRELEASED { -}; -LIBNVME_2_0 { +LIBNVME_3 { global: nvme_clear_etdas; nvme_close; @@ -108,6 +106,11 @@ LIBNVME_2_0 { nvme_host_set_dhchap_key; nvme_host_set_hostsymname; nvme_host_set_pdc_enabled; + nvme_hostid_from_file; + nvme_hostid_generate; + nvme_hostnqn_from_file; + nvme_hostnqn_generate; + nvme_hostnqn_generate_from_hostid; nvme_import_tls_key; nvme_import_tls_key_versioned; nvme_init_copy_range; @@ -267,75 +270,6 @@ LIBNVME_2_0 { nvme_uuid_from_string; nvme_uuid_random; nvme_uuid_to_string; - nvmf_add_ctrl; - nvmf_adrfam_str; - nvmf_cms_str; - nvmf_config_modify; - nvmf_connect; - nvmf_connect_config_json; - nvmf_connect_ctrl; - nvmf_context_create; - nvmf_context_set_connection; - nvmf_context_set_crypto; - nvmf_context_set_device; - nvmf_context_set_discovery_cbs; - nvmf_context_set_discovery_defaults; - nvmf_context_set_fabrics_config; - nvmf_context_set_hostnqn; - nvmf_context_set_persistent; - nvmf_default_config; - nvmf_discovery; - nvmf_discovery_config_file; - nvmf_discovery_config_json; - nvmf_discovery_ctx_already_connected_set; - nvmf_discovery_ctx_connected_set; - nvmf_discovery_ctx_create; - nvmf_discovery_ctx_ctrlkey_set; - nvmf_discovery_ctx_decide_retry_set; - nvmf_discovery_ctx_default_fabrics_config_set; - nvmf_discovery_ctx_device_set; - nvmf_discovery_ctx_discovery_log_set; - nvmf_discovery_ctx_host_iface_set; - nvmf_discovery_ctx_host_traddr_set; - nvmf_discovery_ctx_hostid_set; - nvmf_discovery_ctx_hostkey_set; - nvmf_discovery_ctx_hostnqn_set; - nvmf_discovery_ctx_keep_alive_timeout; - nvmf_discovery_ctx_keyring_set; - nvmf_discovery_ctx_max_retries; - nvmf_discovery_ctx_parser_cleanup_set; - nvmf_discovery_ctx_parser_init_set; - nvmf_discovery_ctx_parser_next_line_set; - nvmf_discovery_ctx_persistent_set; - nvmf_discovery_ctx_subsysnqn_set; - nvmf_discovery_ctx_tls_key_identity_set; - nvmf_discovery_ctx_tls_key_set; - nvmf_discovery_ctx_traddr_set; - nvmf_discovery_ctx_transport_set; - nvmf_discovery_ctx_trsvcid_set; - nvmf_discovery_nbft; - nvmf_eflags_str; - nvmf_exat_ptr_next; - nvmf_free_uri; - nvmf_get_default_trsvcid; - nvmf_get_discovery_log; - nvmf_get_discovery_wargs; - nvmf_hostid_from_file; - nvmf_hostid_generate; - nvmf_hostnqn_from_file; - nvmf_hostnqn_generate; - nvmf_hostnqn_generate_from_hostid; - nvmf_is_registration_supported; - nvmf_nbft_free; - nvmf_nbft_read_files; - nvmf_prtype_str; - nvmf_qptype_str; - nvmf_register_ctrl; - nvmf_sectype_str; - nvmf_subtype_str; - nvmf_treq_str; - nvmf_trtype_str; - nvmf_update_config; local: *; }; diff --git a/libnvme/src/libnvmf.ld b/libnvme/src/libnvmf.ld new file mode 100644 index 0000000000..976f300be5 --- /dev/null +++ b/libnvme/src/libnvmf.ld @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +LIBNVMF_3 { + global: + nvmf_add_ctrl; + nvmf_adrfam_str; + nvmf_cms_str; + nvmf_config_modify; + nvmf_connect; + nvmf_connect_config_json; + nvmf_connect_ctrl; + nvmf_context_create; + nvmf_context_set_connection; + nvmf_context_set_crypto; + nvmf_context_set_device; + nvmf_context_set_discovery_cbs; + nvmf_context_set_discovery_defaults; + nvmf_context_set_fabrics_config; + nvmf_context_set_hostnqn; + nvmf_context_set_persistent; + nvmf_default_config; + nvmf_discovery; + nvmf_discovery_config_file; + nvmf_discovery_config_json; + nvmf_discovery_ctx_already_connected_set; + nvmf_discovery_ctx_connected_set; + nvmf_discovery_ctx_create; + nvmf_discovery_ctx_ctrlkey_set; + nvmf_discovery_ctx_decide_retry_set; + nvmf_discovery_ctx_default_fabrics_config_set; + nvmf_discovery_ctx_device_set; + nvmf_discovery_ctx_discovery_log_set; + nvmf_discovery_ctx_host_iface_set; + nvmf_discovery_ctx_host_traddr_set; + nvmf_discovery_ctx_hostid_set; + nvmf_discovery_ctx_hostkey_set; + nvmf_discovery_ctx_hostnqn_set; + nvmf_discovery_ctx_keep_alive_timeout; + nvmf_discovery_ctx_keyring_set; + nvmf_discovery_ctx_max_retries; + nvmf_discovery_ctx_parser_cleanup_set; + nvmf_discovery_ctx_parser_init_set; + nvmf_discovery_ctx_parser_next_line_set; + nvmf_discovery_ctx_persistent_set; + nvmf_discovery_ctx_subsysnqn_set; + nvmf_discovery_ctx_tls_key_identity_set; + nvmf_discovery_ctx_tls_key_set; + nvmf_discovery_ctx_traddr_set; + nvmf_discovery_ctx_transport_set; + nvmf_discovery_ctx_trsvcid_set; + nvmf_discovery_nbft; + nvmf_eflags_str; + nvmf_exat_ptr_next; + nvmf_free_uri; + nvmf_get_default_trsvcid; + nvmf_get_discovery_log; + nvmf_get_discovery_wargs; + nvmf_is_registration_supported; + nvmf_nbft_free; + nvmf_nbft_read_files; + nvmf_prtype_str; + nvmf_qptype_str; + nvmf_register_ctrl; + nvmf_sectype_str; + nvmf_subtype_str; + nvmf_treq_str; + nvmf_trtype_str; + nvmf_update_config; + local: + *; +}; diff --git a/libnvme/src/meson.build b/libnvme/src/meson.build index 86c76870d6..4e7c9b7327 100644 --- a/libnvme/src/meson.build +++ b/libnvme/src/meson.build @@ -10,7 +10,6 @@ sources = [ 'nvme/base64.c', 'nvme/cmds.c', 'nvme/crc32.c', - 'nvme/fabrics.c', 'nvme/filters.c', 'nvme/ioctl.c', 'nvme/lib.c', @@ -18,11 +17,34 @@ sources = [ 'nvme/log.c', 'nvme/mi-mctp.c', 'nvme/mi.c', - 'nvme/nbft.c', 'nvme/sysfs.c', 'nvme/tree.c', 'nvme/util.c', ] +headers = [ + 'nvme/accessors.h', + 'nvme/cmds.h', + 'nvme/filters.h', + 'nvme/ioctl.h', + 'nvme/lib-types.h', + 'nvme/lib.h', + 'nvme/linux.h', + 'nvme/mi.h', + 'nvme/tree.h', + 'nvme/types.h', + 'nvme/util.h', +] + +if want_fabrics + sources += [ + 'nvme/fabrics.c', + 'nvme/nbft.c', + ] + headers += [ + 'nvme/fabrics.h', + 'nvme/nbft.h', + ] +endif if json_c_dep.found() sources += 'nvme/json.c' @@ -42,16 +64,36 @@ deps = [ openssl_dep, ] -ldfile = 'libnvme.ld' +nvme_ld = meson.current_source_dir() / 'libnvme.ld' +nvmf_ld = meson.current_source_dir() / 'libnvmf.ld' + +link_args = [ + '-Wl,--version-script=@0@'.format(nvme_ld), + '-Wl,--version-script=@0@'.format(accessors_ld_full_path), +] + +libconf = configuration_data() +if want_fabrics + link_args += '-Wl,--version-script=@0@'.format(nvmf_ld) + libconf.set('FABRICS_INCLUDE', + '#include \n#include ') +else + libconf.set('FABRICS_INCLUDE', '') +endif + +libnvme_header = configure_file( + input: 'libnvme.h.in', + output: 'libnvme.h', + configuration: libconf, + install: true, + install_dir: prefixdir / get_option('includedir') +) libnvme = library( 'nvme', # produces libnvme.so sources, version: libnvme_so_version, - link_args: [ - '-Wl,--version-script=@0@'.format(meson.current_source_dir() / ldfile), - '-Wl,--version-script=@0@'.format(accessors_ld_full_path), - ], + link_args: link_args, dependencies: deps, install: true, ) @@ -90,27 +132,12 @@ libnvme_test_dep = declare_dependency( mode = 'rw-r--r--' install_headers( [ - 'libnvme.h', 'libnvme-mi.h', ], install_mode: mode, ) install_headers( - [ - 'nvme/accessors.h', - 'nvme/cmds.h', - 'nvme/fabrics.h', - 'nvme/filters.h', - 'nvme/ioctl.h', - 'nvme/lib-types.h', - 'nvme/lib.h', - 'nvme/linux.h', - 'nvme/mi.h', - 'nvme/nbft.h', - 'nvme/tree.h', - 'nvme/types.h', - 'nvme/util.h', - ], + headers, subdir: 'nvme', install_mode: mode, ) diff --git a/libnvme/src/nvme/fabrics.c b/libnvme/src/nvme/fabrics.c index df754a71a1..fe0fb064ca 100644 --- a/libnvme/src/nvme/fabrics.c +++ b/libnvme/src/nvme/fabrics.c @@ -37,11 +37,6 @@ #include "cleanup.h" #include "private.h" -#define NVMF_HOSTID_SIZE 37 - -#define NVMF_HOSTNQN_FILE SYSCONFDIR "/nvme/hostnqn" -#define NVMF_HOSTID_FILE SYSCONFDIR "/nvme/hostid" - const char *nvmf_dev = "/dev/nvme-fabrics"; /** @@ -338,13 +333,6 @@ static const struct nvme_fabric_options default_supported_options = { .trsvcid = true, }; -void nvmf_default_config(struct nvme_fabrics_config *cfg) -{ - memset(cfg, 0, sizeof(*cfg)); - cfg->tos = -1; - cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; -} - #define MERGE_CFG_OPTION(c, n, o, d) \ if ((c)->o == d) (c)->o = (n)->o static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, @@ -1391,244 +1379,6 @@ int nvmf_get_discovery_wargs(struct nvme_get_discovery_args *args, return 0; } -static int uuid_from_device_tree(char *system_uuid) -{ - _cleanup_fd_ int f = -1; - ssize_t len; - - f = open(nvme_uuid_ibm_filename(), O_RDONLY); - if (f < 0) - return -ENXIO; - - memset(system_uuid, 0, NVME_UUID_LEN_STRING); - len = read(f, system_uuid, NVME_UUID_LEN_STRING - 1); - if (len < 0) - return -ENXIO; - - return strlen(system_uuid) ? 0 : -ENXIO; -} - -/* - * See System Management BIOS (SMBIOS) Reference Specification - * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf - */ -#define DMI_SYSTEM_INFORMATION 1 - -static bool is_dmi_uuid_valid(const char *buf, size_t len) -{ - int i; - - /* UUID bytes are from byte 8 to 23 */ - if (len < 24) - return false; - - /* Test it's a invalid UUID with all zeros */ - for (i = 8; i < 24; i++) { - if (buf[i]) - break; - } - if (i == 24) - return false; - - return true; -} - -static int uuid_from_dmi_entries(char *system_uuid) -{ - _cleanup_dir_ DIR *d = NULL; - const char *entries_dir = nvme_dmi_entries_dir(); - int f; - struct dirent *de; - char buf[512] = {0}; - - system_uuid[0] = '\0'; - d = opendir(entries_dir); - if (!d) - return -ENXIO; - while ((de = readdir(d))) { - char filename[PATH_MAX]; - int len, type; - - if (de->d_name[0] == '.') - continue; - sprintf(filename, "%s/%s/type", entries_dir, de->d_name); - f = open(filename, O_RDONLY); - if (f < 0) - continue; - len = read(f, buf, 512); - close(f); - if (len <= 0) - continue; - if (sscanf(buf, "%d", &type) != 1) - continue; - if (type != DMI_SYSTEM_INFORMATION) - continue; - sprintf(filename, "%s/%s/raw", entries_dir, de->d_name); - f = open(filename, O_RDONLY); - if (f < 0) - continue; - len = read(f, buf, 512); - close(f); - if (len <= 0) - continue; - - if (!is_dmi_uuid_valid(buf, len)) - continue; - - /* Sigh. https://en.wikipedia.org/wiki/Overengineering */ - /* DMTF SMBIOS 3.0 Section 7.2.1 System UUID */ - sprintf(system_uuid, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x", - (uint8_t)buf[8 + 3], (uint8_t)buf[8 + 2], - (uint8_t)buf[8 + 1], (uint8_t)buf[8 + 0], - (uint8_t)buf[8 + 5], (uint8_t)buf[8 + 4], - (uint8_t)buf[8 + 7], (uint8_t)buf[8 + 6], - (uint8_t)buf[8 + 8], (uint8_t)buf[8 + 9], - (uint8_t)buf[8 + 10], (uint8_t)buf[8 + 11], - (uint8_t)buf[8 + 12], (uint8_t)buf[8 + 13], - (uint8_t)buf[8 + 14], (uint8_t)buf[8 + 15]); - break; - } - return strlen(system_uuid) ? 0 : -ENXIO; -} - -#define PATH_DMI_PROD_UUID "/sys/class/dmi/id/product_uuid" - -/** - * uuid_from_product_uuid() - Get system UUID from product_uuid - * @system_uuid: Where to save the system UUID. - * - * Return: 0 on success, -ENXIO otherwise. - */ -static int uuid_from_product_uuid(char *system_uuid) -{ - _cleanup_file_ FILE *stream = NULL; - ssize_t nread; - _cleanup_free_ char *line = NULL; - size_t len = 0; - - stream = fopen(PATH_DMI_PROD_UUID, "re"); - if (!stream) - return -ENXIO; - system_uuid[0] = '\0'; - - nread = getline(&line, &len, stream); - if (nread != NVME_UUID_LEN_STRING) - return -ENXIO; - - /* The kernel is handling the byte swapping according DMTF - * SMBIOS 3.0 Section 7.2.1 System UUID */ - - memcpy(system_uuid, line, NVME_UUID_LEN_STRING - 1); - system_uuid[NVME_UUID_LEN_STRING - 1] = '\0'; - - return 0; -} - -/** - * uuid_from_dmi() - read system UUID - * @system_uuid: buffer for the UUID - * - * The system UUID can be read from two different locations: - * - * 1) /sys/class/dmi/id/product_uuid - * 2) /sys/firmware/dmi/entries - * - * Note that the second location is not present on Debian-based systems. - * - * Return: 0 on success, negative errno otherwise. - */ -static int uuid_from_dmi(char *system_uuid) -{ - int ret = uuid_from_product_uuid(system_uuid); - if (ret != 0) - ret = uuid_from_dmi_entries(system_uuid); - return ret; -} - -char *nvmf_hostid_generate() -{ - int ret; - char uuid_str[NVME_UUID_LEN_STRING]; - unsigned char uuid[NVME_UUID_LEN]; - - ret = uuid_from_dmi(uuid_str); - if (ret < 0) - ret = uuid_from_device_tree(uuid_str); - if (ret < 0) { - if (nvme_uuid_random(uuid) < 0) - memset(uuid, 0, NVME_UUID_LEN); - nvme_uuid_to_string(uuid, uuid_str); - } - - return strdup(uuid_str); -} - -char *nvmf_hostnqn_generate_from_hostid(char *hostid) -{ - char *hid = NULL; - char *hostnqn; - int ret; - - if (!hostid) - hostid = hid = nvmf_hostid_generate(); - - ret = asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s", hostid); - free(hid); - - return (ret < 0) ? NULL : hostnqn; -} - -char *nvmf_hostnqn_generate() -{ - return nvmf_hostnqn_generate_from_hostid(NULL); -} - -static char *nvmf_read_file(const char *f, int len) -{ - char buf[len]; - _cleanup_fd_ int fd = -1; - int ret; - - fd = open(f, O_RDONLY); - if (fd < 0) - return NULL; - - memset(buf, 0, len); - ret = read(fd, buf, len - 1); - - if (ret < 0 || !strlen(buf)) - return NULL; - return strndup(buf, strcspn(buf, "\n")); -} - -char *nvmf_hostnqn_from_file() -{ - char *hostnqn = getenv("LIBNVME_HOSTNQN"); - - if (hostnqn) { - if (!strcmp(hostnqn, "")) - return NULL; - return strdup(hostnqn); - } - - return nvmf_read_file(NVMF_HOSTNQN_FILE, NVMF_NQN_SIZE); -} - -char *nvmf_hostid_from_file() -{ - char *hostid = getenv("LIBNVME_HOSTID"); - - if (hostid) { - if (!strcmp(hostid, "")) - return NULL; - return strdup(hostid); - } - - return nvmf_read_file(NVMF_HOSTID_FILE, NVMF_HOSTID_SIZE); -} - /** * nvmf_get_tel() - Calculate the amount of memory needed for a DIE. * @hostsymname: Symbolic name (may be NULL) @@ -2675,9 +2425,9 @@ int nvmf_config_modify(struct nvme_global_ctx *ctx, struct nvme_ctrl *c; if (!fctx->hostnqn) - fctx->hostnqn = hnqn = nvmf_hostnqn_from_file(); + fctx->hostnqn = hnqn = nvme_hostnqn_from_file(); if (!fctx->hostid && hnqn) - fctx->hostid = hid = nvmf_hostid_from_file(); + fctx->hostid = hid = nvme_hostid_from_file(); h = nvme_lookup_host(ctx, fctx->hostnqn, fctx->hostid); if (!h) { diff --git a/libnvme/src/nvme/fabrics.h b/libnvme/src/nvme/fabrics.h index 9f9549dc51..5a441ec2a0 100644 --- a/libnvme/src/nvme/fabrics.h +++ b/libnvme/src/nvme/fabrics.h @@ -283,57 +283,6 @@ struct nvme_get_discovery_args { int nvmf_get_discovery_wargs(struct nvme_get_discovery_args *args, struct nvmf_discovery_log **log); -/** - * nvmf_hostnqn_generate() - Generate a machine specific host nqn - * Returns: An nvm namespace qualified name string based on the machine - * identifier, or NULL if not successful. - */ -char *nvmf_hostnqn_generate(); - -/** - * nvmf_hostnqn_generate_from_hostid() - Generate a host nqn from host identifier - * @hostid: Host identifier - * - * If @hostid is NULL, the function generates it based on the machine - * identifier. - * - * Return: On success, an NVMe Qualified Name for host identification. This - * name is based on the given host identifier. On failure, NULL. - */ -char *nvmf_hostnqn_generate_from_hostid(char *hostid); - -/** - * nvmf_hostid_generate() - Generate a machine specific host identifier - * - * Return: On success, an identifier string based on the machine identifier to - * be used as NVMe Host Identifier, or NULL on failure. - */ -char *nvmf_hostid_generate(); - -/** - * nvmf_hostnqn_from_file() - Reads the host nvm qualified name from the config - * default location - * - * Retrieve the qualified name from the config file located in $SYSCONFIDR/nvme. - * $SYSCONFDIR is usually /etc. - * - * Return: The host nqn, or NULL if unsuccessful. If found, the caller - * is responsible to free the string. - */ -char *nvmf_hostnqn_from_file(); - -/** - * nvmf_hostid_from_file() - Reads the host identifier from the config default - * location - * - * Retrieve the host idenditifer from the config file located in $SYSCONFDIR/nvme/. - * $SYSCONFDIR is usually /etc. - * - * Return: The host identifier, or NULL if unsuccessful. If found, the caller - * is responsible to free the string. - */ -char *nvmf_hostid_from_file(); - /** * nvmf_is_registration_supported - check whether registration can be performed. * @c: Controller instance @@ -645,15 +594,7 @@ int nvmf_connect_config_json(struct nvme_global_ctx *ctx, int nvmf_config_modify(struct nvme_global_ctx *ctx, struct nvmf_context *fctx); -/** - * struct nbft_file_entry - Linked list entry for NBFT files - * @next: Pointer to next entry - * @nbft: Pointer to NBFT info structure - */ -struct nbft_file_entry { - struct nbft_file_entry *next; - struct nbft_info *nbft; -}; +struct nbft_file_entry; /** * nvmf_nbft_read_files() - Read NBFT files from path diff --git a/libnvme/src/nvme/linux.c b/libnvme/src/nvme/linux.c index 52416bef37..80ce135ca1 100644 --- a/libnvme/src/nvme/linux.c +++ b/libnvme/src/nvme/linux.c @@ -48,6 +48,11 @@ #include "cleanup.h" #include "private.h" +#define NVMF_HOSTID_SIZE 37 + +#define NVMF_HOSTNQN_FILE SYSCONFDIR "/nvme/hostnqn" +#define NVMF_HOSTID_FILE SYSCONFDIR "/nvme/hostid" + static int __nvme_set_attr(const char *path, const char *value) { _cleanup_fd_ int fd = -1; @@ -1561,3 +1566,241 @@ int nvme_import_tls_key(struct nvme_global_ctx *ctx, const char *encoded_key, *keyp = psk; return 0; } + +static int uuid_from_device_tree(char *system_uuid) +{ + _cleanup_fd_ int f = -1; + ssize_t len; + + f = open(nvme_uuid_ibm_filename(), O_RDONLY); + if (f < 0) + return -ENXIO; + + memset(system_uuid, 0, NVME_UUID_LEN_STRING); + len = read(f, system_uuid, NVME_UUID_LEN_STRING - 1); + if (len < 0) + return -ENXIO; + + return strlen(system_uuid) ? 0 : -ENXIO; +} + +/* + * See System Management BIOS (SMBIOS) Reference Specification + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf + */ +#define DMI_SYSTEM_INFORMATION 1 + +static bool is_dmi_uuid_valid(const char *buf, size_t len) +{ + int i; + + /* UUID bytes are from byte 8 to 23 */ + if (len < 24) + return false; + + /* Test it's a invalid UUID with all zeros */ + for (i = 8; i < 24; i++) { + if (buf[i]) + break; + } + if (i == 24) + return false; + + return true; +} + +static int uuid_from_dmi_entries(char *system_uuid) +{ + _cleanup_dir_ DIR *d = NULL; + const char *entries_dir = nvme_dmi_entries_dir(); + int f; + struct dirent *de; + char buf[512] = {0}; + + system_uuid[0] = '\0'; + d = opendir(entries_dir); + if (!d) + return -ENXIO; + while ((de = readdir(d))) { + char filename[PATH_MAX]; + int len, type; + + if (de->d_name[0] == '.') + continue; + sprintf(filename, "%s/%s/type", entries_dir, de->d_name); + f = open(filename, O_RDONLY); + if (f < 0) + continue; + len = read(f, buf, 512); + close(f); + if (len <= 0) + continue; + if (sscanf(buf, "%d", &type) != 1) + continue; + if (type != DMI_SYSTEM_INFORMATION) + continue; + sprintf(filename, "%s/%s/raw", entries_dir, de->d_name); + f = open(filename, O_RDONLY); + if (f < 0) + continue; + len = read(f, buf, 512); + close(f); + if (len <= 0) + continue; + + if (!is_dmi_uuid_valid(buf, len)) + continue; + + /* Sigh. https://en.wikipedia.org/wiki/Overengineering */ + /* DMTF SMBIOS 3.0 Section 7.2.1 System UUID */ + sprintf(system_uuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + (uint8_t)buf[8 + 3], (uint8_t)buf[8 + 2], + (uint8_t)buf[8 + 1], (uint8_t)buf[8 + 0], + (uint8_t)buf[8 + 5], (uint8_t)buf[8 + 4], + (uint8_t)buf[8 + 7], (uint8_t)buf[8 + 6], + (uint8_t)buf[8 + 8], (uint8_t)buf[8 + 9], + (uint8_t)buf[8 + 10], (uint8_t)buf[8 + 11], + (uint8_t)buf[8 + 12], (uint8_t)buf[8 + 13], + (uint8_t)buf[8 + 14], (uint8_t)buf[8 + 15]); + break; + } + return strlen(system_uuid) ? 0 : -ENXIO; +} + +#define PATH_DMI_PROD_UUID "/sys/class/dmi/id/product_uuid" + +/** + * uuid_from_product_uuid() - Get system UUID from product_uuid + * @system_uuid: Where to save the system UUID. + * + * Return: 0 on success, -ENXIO otherwise. + */ +static int uuid_from_product_uuid(char *system_uuid) +{ + _cleanup_file_ FILE *stream = NULL; + ssize_t nread; + _cleanup_free_ char *line = NULL; + size_t len = 0; + + stream = fopen(PATH_DMI_PROD_UUID, "re"); + if (!stream) + return -ENXIO; + system_uuid[0] = '\0'; + + nread = getline(&line, &len, stream); + if (nread != NVME_UUID_LEN_STRING) + return -ENXIO; + + /* The kernel is handling the byte swapping according DMTF + * SMBIOS 3.0 Section 7.2.1 System UUID */ + + memcpy(system_uuid, line, NVME_UUID_LEN_STRING - 1); + system_uuid[NVME_UUID_LEN_STRING - 1] = '\0'; + + return 0; +} + +/** + * uuid_from_dmi() - read system UUID + * @system_uuid: buffer for the UUID + * + * The system UUID can be read from two different locations: + * + * 1) /sys/class/dmi/id/product_uuid + * 2) /sys/firmware/dmi/entries + * + * Note that the second location is not present on Debian-based systems. + * + * Return: 0 on success, negative errno otherwise. + */ +static int uuid_from_dmi(char *system_uuid) +{ + int ret = uuid_from_product_uuid(system_uuid); + if (ret != 0) + ret = uuid_from_dmi_entries(system_uuid); + return ret; +} + +char *nvme_hostid_generate() +{ + int ret; + char uuid_str[NVME_UUID_LEN_STRING]; + unsigned char uuid[NVME_UUID_LEN]; + + ret = uuid_from_dmi(uuid_str); + if (ret < 0) + ret = uuid_from_device_tree(uuid_str); + if (ret < 0) { + if (nvme_uuid_random(uuid) < 0) + memset(uuid, 0, NVME_UUID_LEN); + nvme_uuid_to_string(uuid, uuid_str); + } + + return strdup(uuid_str); +} + +char *nvme_hostnqn_generate_from_hostid(char *hostid) +{ + char *hid = NULL; + char *hostnqn; + int ret; + + if (!hostid) + hostid = hid = nvme_hostid_generate(); + + ret = asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s", hostid); + free(hid); + + return (ret < 0) ? NULL : hostnqn; +} + +char *nvme_hostnqn_generate() +{ + return nvme_hostnqn_generate_from_hostid(NULL); +} + +static char *nvmf_read_file(const char *f, int len) +{ + char buf[len]; + _cleanup_fd_ int fd = -1; + int ret; + + fd = open(f, O_RDONLY); + if (fd < 0) + return NULL; + + memset(buf, 0, len); + ret = read(fd, buf, len - 1); + + if (ret < 0 || !strlen(buf)) + return NULL; + return strndup(buf, strcspn(buf, "\n")); +} + +char *nvme_hostnqn_from_file() +{ + char *hostnqn = getenv("LIBNVME_HOSTNQN"); + + if (hostnqn) { + if (!strcmp(hostnqn, "")) + return NULL; + return strdup(hostnqn); + } + + return nvmf_read_file(NVMF_HOSTNQN_FILE, NVMF_NQN_SIZE); +} + +char *nvme_hostid_from_file() +{ + char *hostid = getenv("LIBNVME_HOSTID"); + + if (hostid) { + if (!strcmp(hostid, "")) + return NULL; + return strdup(hostid); + } + + return nvmf_read_file(NVMF_HOSTID_FILE, NVMF_HOSTID_SIZE); +} diff --git a/libnvme/src/nvme/linux.h b/libnvme/src/nvme/linux.h index 7c947f0fbf..6b9da6ae17 100644 --- a/libnvme/src/nvme/linux.h +++ b/libnvme/src/nvme/linux.h @@ -393,3 +393,55 @@ int nvme_import_tls_key(struct nvme_global_ctx *ctx, const char *encoded_key, int nvme_import_tls_key_versioned(struct nvme_global_ctx *ctx, const char *encoded_key, unsigned char *version, unsigned char *hmac, size_t *key_len, unsigned char **key); + +/** + * nvme_hostnqn_generate() - Generate a machine specific host nqn + * Returns: An nvm namespace qualified name string based on the machine + * identifier, or NULL if not successful. + */ +char *nvme_hostnqn_generate(); + +/** + * nvme_hostnqn_generate_from_hostid() - Generate a host nqn from + * host identifier + * @hostid: Host identifier + * + * If @hostid is NULL, the function generates it based on the machine + * identifier. + * + * Return: On success, an NVMe Qualified Name for host identification. This + * name is based on the given host identifier. On failure, NULL. + */ +char *nvme_hostnqn_generate_from_hostid(char *hostid); + +/** + * nvme_hostid_generate() - Generate a machine specific host identifier + * + * Return: On success, an identifier string based on the machine identifier to + * be used as NVMe Host Identifier, or NULL on failure. + */ +char *nvme_hostid_generate(); + +/** + * nvme_hostnqn_from_file() - Reads the host nvm qualified name from the config + * default location + * + * Retrieve the qualified name from the config file located in $SYSCONFDIR/nvme. + * $SYSCONFDIR is usually /etc. + * + * Return: The host nqn, or NULL if unsuccessful. If found, the caller + * is responsible to free the string. + */ +char *nvme_hostnqn_from_file(); + +/** + * nvme_hostid_from_file() - Reads the host identifier from the config default + * location + * + * Retrieve the host idenditifer from the config file located in + * $SYSCONFDIR/nvme/. $SYSCONFDIR is usually /etc. + * + * Return: The host identifier, or NULL if unsuccessful. If found, the caller + * is responsible to free the string. + */ +char *nvme_hostid_from_file(); diff --git a/libnvme/src/nvme/nbft.h b/libnvme/src/nvme/nbft.h index f14331ac72..16d1606c7a 100644 --- a/libnvme/src/nvme/nbft.h +++ b/libnvme/src/nvme/nbft.h @@ -1254,3 +1254,14 @@ int nvme_nbft_read(struct nvme_global_ctx *ctx, struct nbft_info **nbft, * @nbft: Parsed NBFT table data. */ void nvme_nbft_free(struct nvme_global_ctx *ctx, struct nbft_info *nbft); + +/** + * struct nbft_file_entry - Linked list entry for NBFT files + * @next: Pointer to next entry + * @nbft: Pointer to NBFT info structure + */ +struct nbft_file_entry { + struct nbft_file_entry *next; + struct nbft_info *nbft; +}; + diff --git a/libnvme/src/nvme/no-json.c b/libnvme/src/nvme/no-json.c index 2315b729e9..1060c071c1 100644 --- a/libnvme/src/nvme/no-json.c +++ b/libnvme/src/nvme/no-json.c @@ -15,7 +15,7 @@ int json_read_config(struct nvme_global_ctx *ctx, const char *config_file) return -ENOTSUP; } -int json_update_config(struct nvme_global_ctx *ctx, const char *config_file) +int json_update_config(struct nvme_global_ctx *ctx, int fd) { return -ENOTSUP; } diff --git a/libnvme/src/nvme/tree.c b/libnvme/src/nvme/tree.c index 0f7b0fc2f7..fc207aea5c 100644 --- a/libnvme/src/nvme/tree.c +++ b/libnvme/src/nvme/tree.c @@ -144,9 +144,9 @@ int nvme_host_get_ids(struct nvme_global_ctx *ctx, /* /etc/nvme/hostid and/or /etc/nvme/hostnqn */ if (!hid) - hid = nvmf_hostid_from_file(); + hid = nvme_hostid_from_file(); if (!hnqn) - hnqn = nvmf_hostnqn_from_file(); + hnqn = nvme_hostnqn_from_file(); /* incomplete configuration, thus derive hostid from hostnqn */ if (!hid && hnqn) @@ -157,7 +157,7 @@ int nvme_host_get_ids(struct nvme_global_ctx *ctx, * fails generate one */ if (!hid) { - hid = nvmf_hostid_generate(); + hid = nvme_hostid_generate(); if (!hid) return -ENOMEM; @@ -167,7 +167,7 @@ int nvme_host_get_ids(struct nvme_global_ctx *ctx, /* incomplete configuration, thus derive hostnqn from hostid */ if (!hnqn) { - hnqn = nvmf_hostnqn_generate_from_hostid(hid); + hnqn = nvme_hostnqn_generate_from_hostid(hid); if (!hnqn) return -ENOMEM; } @@ -1118,6 +1118,13 @@ static bool traddr_is_hostname(const char *transport, const char *traddr) return true; } +void nvmf_default_config(struct nvme_fabrics_config *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); + cfg->tos = -1; + cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; +} + int nvme_create_ctrl(struct nvme_global_ctx *ctx, const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, @@ -2573,7 +2580,7 @@ static int __nvme_scan_namespace(struct nvme_global_ctx *ctx, { _cleanup_free_ char *blkdev = NULL; _cleanup_free_ char *path = NULL; - struct nvme_ns *n; + struct nvme_ns *n = NULL; int ret; blkdev = nvme_ns_generic_to_blkdev(name); diff --git a/libnvme/test/ioctl/meson.build b/libnvme/test/ioctl/meson.build index 4e0f80cebe..7aec1f3810 100644 --- a/libnvme/test/ioctl/meson.build +++ b/libnvme/test/ioctl/meson.build @@ -52,17 +52,19 @@ ana = executable( ) test('libnvme - ana', ana, env: mock_ioctl_env) -discovery = executable( - 'test-discovery', - 'discovery.c', - dependencies: [ - config_dep, - ccan_dep, - libnvme_dep, - ], - link_with: mock_ioctl, -) -test('libnvme - discovery', discovery, env: mock_ioctl_env) +if want_fabrics + discovery = executable( + 'test-discovery', + 'discovery.c', + dependencies: [ + config_dep, + ccan_dep, + libnvme_dep, + ], + link_with: mock_ioctl, + ) + test('libnvme - discovery', discovery, env: mock_ioctl_env) +endif features = executable( 'test-features', diff --git a/libnvme/test/meson.build b/libnvme/test/meson.build index 4c4d0b0529..5f952a3509 100644 --- a/libnvme/test/meson.build +++ b/libnvme/test/meson.build @@ -101,17 +101,19 @@ uuid = executable( test('libnvme - uuid', uuid) -uriparser = executable( - 'test-uriparser', - ['uriparser.c'], - dependencies: [ - config_dep, - ccan_dep, - libnvme_dep, - ], -) +if want_fabrics + uriparser = executable( + 'test-uriparser', + ['uriparser.c'], + dependencies: [ + config_dep, + ccan_dep, + libnvme_dep, + ], + ) test('libnvme - uriparser', uriparser) +endif if conf.get('HAVE_NETDB') mock_ifaddrs = library( @@ -162,7 +164,9 @@ psk = executable( test('libnvme - psk', psk) subdir('ioctl') -subdir('nbft') +if want_fabrics + subdir('nbft') +endif if json_c_dep.found() subdir('sysfs') diff --git a/meson.build b/meson.build index c81e8e2d6c..1c1d87351c 100644 --- a/meson.build +++ b/meson.build @@ -51,11 +51,12 @@ cxx_available = add_languages('cpp', required: false, native: false) # dependencies are present. Also, -Dpython=enabled forces -Dlibnvme=enabled. want_nvme = get_option('nvme').disabled() == false want_libnvme = get_option('libnvme').disabled() == false +want_fabrics = get_option('fabrics').disabled() == false want_docs = get_option('docs') want_docs_build = get_option('docs-build') feature_python = get_option('python') -if feature_python.disabled() +if not want_fabrics or feature_python.disabled() py3_dep = dependency('', required: false) # Needed for muon want_python = false else @@ -128,6 +129,8 @@ endif conf.set('SYSCONFDIR', '"@0@"'.format(sysconfdir)) conf.set('RUNDIR', '"@0@"'.format(rundir)) +conf.set('CONFIG_FABRICS', want_fabrics, description: 'Is fabrics enabled') + # Check for libjson-c availability if get_option('json-c').disabled() json_c_dep = dependency('', required: false) @@ -277,14 +280,14 @@ else endif -if get_option('liburing').disabled() +if not want_fabrics or get_option('liburing').disabled() liburing_dep = dependency('', required: false) else liburing_dep = dependency('liburing', version: '>=2.2', required: get_option('liburing')) endif conf.set('CONFIG_LIBURING', liburing_dep.found(), description: 'Is liburing available?') -if get_option('openssl').disabled() +if not want_fabrics or get_option('openssl').disabled() openssl_dep = dependency('', required: false) else openssl_dep = dependency( @@ -313,14 +316,14 @@ if openssl_dep.found() endif conf.set('CONFIG_OPENSSL', openssl_dep.found(), description: 'Is OpenSSL/LibreSSL available?') -if get_option('keyutils').disabled() +if not want_fabrics or get_option('keyutils').disabled() keyutils_dep = dependency('', required: false) else keyutils_dep = dependency('libkeyutils', required : get_option('keyutils')) endif conf.set('CONFIG_KEYUTILS', keyutils_dep.found(), description: 'Is libkeyutils available?') -if get_option('libdbus').disabled() +if not want_fabrics or get_option('libdbus').disabled() libdbus_dep = dependency('', required: false) else # Check for libdbus availability. Optional, only required for MCTP dbus scan @@ -469,7 +472,6 @@ if want_nvme subdir('util') # declares: util_sources sources = [ - 'fabrics.c', 'nvme.c', 'nvme-models.c', 'nvme-print.c', @@ -480,6 +482,10 @@ if want_nvme 'libnvme-wrap.c', 'logging.c', ] + if want_fabrics + sources += 'fabrics.c' + endif + if json_c_dep.found() sources += [ 'nvme-print-json.c', @@ -630,6 +636,7 @@ summary(dep_dict, section: 'Dependencies', bool_yn: true) wanted_dict = { 'nvme': want_nvme, 'libnvme': want_libnvme, + 'fabrics': want_fabrics, 'python bindings ': want_python, 'build docs': want_docs_build, } diff --git a/meson_options.txt b/meson_options.txt index 6fd51daf77..88c8f364cb 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -11,6 +11,12 @@ option( value: 'enabled', description: 'Build libnvme library' ) +option( + 'fabrics', + type : 'feature', + value: 'enabled', + description : 'NVMeoF support' +) option( 'python', type : 'feature', diff --git a/nvme-builtin.h b/nvme-builtin.h index 585174d9b2..3f3d82a497 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -102,12 +102,15 @@ COMMAND_LIST( ENTRY("show-regs", "Shows the controller registers or properties. Requires character device", show_registers) ENTRY("set-reg", "Set a register and show the resulting value", set_register) ENTRY("get-reg", "Get a register and show the resulting value", get_register) +#ifdef CONFIG_FABRICS ENTRY("discover", "Discover NVMeoF subsystems", discover_cmd) ENTRY("connect-all", "Discover and Connect to NVMeoF subsystems", connect_all_cmd) ENTRY("connect", "Connect to NVMeoF subsystem", connect_cmd) ENTRY("disconnect", "Disconnect from NVMeoF subsystem", disconnect_cmd) ENTRY("disconnect-all", "Disconnect from all connected NVMeoF subsystems", disconnect_all_cmd) ENTRY("config", "Configuration of NVMeoF subsystems", config_cmd) + ENTRY("dim", "Send Discovery Information Management command to a Discovery Controller", dim_cmd) +#endif ENTRY("gen-hostnqn", "Generate NVMeoF host NQN", gen_hostnqn_cmd) ENTRY("show-hostnqn", "Show NVMeoF host NQN", show_hostnqn_cmd) ENTRY("gen-dhchap-key", "Generate NVMeoF DH-HMAC-CHAP host key", gen_dhchap_key) @@ -120,8 +123,7 @@ COMMAND_LIST( ENTRY("virt-mgmt", "Manage Flexible Resources between Primary and Secondary Controller", virtual_mgmt) ENTRY("rpmb", "Replay Protection Memory Block commands", rpmb_cmd) ENTRY("lockdown", "Submit a Lockdown command,return result", lockdown_cmd) - ENTRY("dim", "Send Discovery Information Management command to a Discovery Controller", dim_cmd) \ - ENTRY("show-topology", "Show the topology", show_topology_cmd) \ + ENTRY("show-topology", "Show the topology", show_topology_cmd) ENTRY("io-mgmt-recv", "I/O Management Receive", io_mgmt_recv) ENTRY("io-mgmt-send", "I/O Management Send", io_mgmt_send) ENTRY("nvme-mi-recv", "Submit a NVMe-MI Receive command, return results", nmi_recv) diff --git a/nvme-print-json.c b/nvme-print-json.c index 5ac54164a3..5413d31c05 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -5201,6 +5201,7 @@ static void json_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __ json_print(r); } +#ifdef CONFIG_FABRICS static void json_discovery_log(struct nvmf_discovery_log *log, int numrec) { struct json_object *r = json_create_object(); @@ -5242,6 +5243,9 @@ static void json_discovery_log(struct nvmf_discovery_log *log, int numrec) json_print(r); } +#else +static void json_discovery_log(struct nvmf_discovery_log *log, int numrec) {} +#endif static void json_connect_msg(nvme_ctrl_t c) { @@ -5568,6 +5572,7 @@ static void json_reachability_associations_log(struct nvme_reachability_associat json_print(r); } +#ifdef CONFIG_FABRICS static void json_host_discovery_log(struct nvme_host_discover_log *log) { struct json_object *r = json_create_object(); @@ -5695,6 +5700,10 @@ static void json_ave_discovery_log(struct nvme_ave_discover_log *log) obj_add_obj(r, json_str, adlpe_o); } } +#else +static void json_host_discovery_log(struct nvme_host_discover_log *log) {} +static void json_ave_discovery_log(struct nvme_ave_discover_log *log) {} +#endif static void json_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *log) { diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index 394f457d84..ec5ae5c050 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -6354,6 +6354,7 @@ static void stdout_key_value(const char *key, const char *val, va_list ap) printf("%s: %s\n", key, value ? value : alloc_error); } +#ifdef CONFIG_FABRICS static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec) { int i; @@ -6396,6 +6397,9 @@ static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec) } } } +#else +static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec) {} +#endif static void stdout_connect_msg(nvme_ctrl_t c) { @@ -6490,6 +6494,7 @@ static void stdout_reachability_associations_log(struct nvme_reachability_associ } } +#ifdef CONFIG_FABRICS static void stdout_host_discovery_log(struct nvme_host_discover_log *log) { __u32 i; @@ -6600,6 +6605,10 @@ static void stdout_ave_discovery_log(struct nvme_ave_discover_log *log) } } } +#else +static void stdout_host_discovery_log(struct nvme_host_discover_log *log) {} +static void stdout_ave_discovery_log(struct nvme_ave_discover_log *log) {} +#endif static void stdout_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *log) { diff --git a/nvme.c b/nvme.c index 11a2ef0290..7539e937a7 100644 --- a/nvme.c +++ b/nvme.c @@ -8351,9 +8351,9 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char __u32 dsmgmt = 0; int mode = 0644; void *buffer; + __u16 ms = 0; int err = 0; int flags; - __u16 ms; const char *start_block_addr = "64-bit addr of first block to access"; const char *block_size = "if specified, logical block size in bytes;\n" @@ -8530,13 +8530,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char } else { err = get_pi_info(hdl, cfg.nsid, cfg.prinfo, cfg.ilbrt, cfg.lbst, &logical_block_size, &ms); - if (err) { - logical_block_size = 0; - ms = 0; - pi_available = false; - } else { - pi_available = true; - } + pi_available = err == 0; } buffer_size = ((long long)cfg.block_count + 1) * logical_block_size; @@ -9528,7 +9522,7 @@ static int gen_hostnqn_cmd(int argc, char **argv, struct command *acmd, struct p { char *hostnqn; - hostnqn = nvmf_hostnqn_generate(); + hostnqn = nvme_hostnqn_generate(); if (!hostnqn) { nvme_show_error("\"%s\" not supported. Install lib uuid and rebuild.", acmd->name); @@ -9543,9 +9537,9 @@ static int show_hostnqn_cmd(int argc, char **argv, struct command *acmd, struct { char *hostnqn; - hostnqn = nvmf_hostnqn_from_file(); + hostnqn = nvme_hostnqn_from_file(); if (!hostnqn) - hostnqn = nvmf_hostnqn_generate(); + hostnqn = nvme_hostnqn_generate(); if (!hostnqn) { nvme_show_error("hostnqn is not available -- use nvme gen-hostnqn"); @@ -9673,7 +9667,7 @@ static int gen_dhchap_key(int argc, char **argv, struct command *acmd, struct pl } if (!cfg.nqn) { - cfg.nqn = hnqn = nvmf_hostnqn_from_file(); + cfg.nqn = hnqn = nvme_hostnqn_from_file(); if (!cfg.nqn) { nvme_show_error("Could not read host NQN"); return -ENOENT; @@ -9937,7 +9931,7 @@ static int gen_tls_key(int argc, char **argv, struct command *acmd, struct plugi return -EINVAL; } if (!cfg.hostnqn) { - cfg.hostnqn = hnqn = nvmf_hostnqn_from_file(); + cfg.hostnqn = hnqn = nvme_hostnqn_from_file(); if (!cfg.hostnqn) { nvme_show_error("Failed to read host NQN"); return -EINVAL; @@ -10099,7 +10093,7 @@ static int check_tls_key(int argc, char **argv, struct command *acmd, struct plu if (cfg.subsysnqn) { if (!cfg.hostnqn) { - cfg.hostnqn = hnqn = nvmf_hostnqn_from_file(); + cfg.hostnqn = hnqn = nvme_hostnqn_from_file(); if (!cfg.hostnqn) { nvme_show_error("Failed to read host NQN"); return -EINVAL; @@ -10433,6 +10427,7 @@ static int show_topology_cmd(int argc, char **argv, struct command *acmd, struct return err; } +#ifdef CONFIG_FABRICS static int discover_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send Get Log Page request to Discovery Controller."; @@ -10483,6 +10478,7 @@ static int dim_cmd(int argc, char **argv, struct command *acmd, struct plugin *p return fabrics_dim(desc, argc, argv); } +#endif static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) { diff --git a/plugins/meson.build b/plugins/meson.build index 63014b667a..0702954376 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -15,7 +15,6 @@ all_plugins = { 'mangoboost': ['plugins/mangoboost/mangoboost-nvme.c'], 'memblaze': ['plugins/memblaze/memblaze-nvme.c'], 'micron': ['plugins/micron/micron-nvme.c'], - 'nbft': ['plugins/nbft/nbft-plugin.c'], 'netapp': ['plugins/netapp/netapp-nvme.c'], 'nvidia': ['plugins/nvidia/nvidia-nvme.c'], 'sandisk': ['plugins/sandisk/sandisk-nvme.c', 'plugins/sandisk/sandisk-utils.c'], @@ -43,6 +42,10 @@ foreach plugin_name : selected_plugins endif endforeach +if want_fabrics and 'nbft' in selected_plugins + plugin_sources += ['plugins/nbft/nbft-plugin.c'] +endif + if 'feat' in selected_plugins subdir('feat') endif diff --git a/scripts/build.sh b/scripts/build.sh index 223790f113..feced9279f 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -34,6 +34,7 @@ usage() { echo " html_docs build html documentation only" echo " rst_docs build rst documentation only" echo " static build a static binary" + echo " minimal_static build a static binary without fabrics support" echo " libnvme build only libnvme" echo "" echo "configs with muon:" @@ -90,14 +91,17 @@ config_meson_default() { } config_meson_musl() { - local c_args="-U_GNU_SOURCE \ --idirafter /usr/include -idirafter \ -/usr/include/x86_64-linux-gnu" + local cflags=( + -U_GNU_SOURCE + -idirafter /usr/include + -idirafter /usr/include/x86_64-linux-gnu + ) + local cflags_str="${cflags[*]}" CC="${CC}" "${MESON}" setup \ --werror \ --buildtype="${BUILDTYPE}" \ - -Dc_args="${c_args}" \ + -Dc_args="${cflags_str}" \ -Ddefault_library=static \ -Djson-c=disabled \ -Dopenssl=disabled \ @@ -194,6 +198,46 @@ config_meson_static() { "${BUILDDIR}" } +config_meson_minimal_static() { + local cflags=( + -U_GNU_SOURCE + -idirafter /usr/include + -idirafter /usr/include/x86_64-linux-gnu + -Oz + -flto + -ffunction-sections + -fdata-sections + -fno-unwind-tables + -fno-asynchronous-unwind-tables + -fno-stack-protector + ) + local ldflags=( + -flto + -Wl,--gc-sections + -s + -Wl,--build-id=none + -static + ) + local cflags_str="${cflags[*]}" + local ldflags_str="${ldflags[*]}" + + CC=musl-gcc + + CC="${CC}" "${MESON}" setup \ + --werror \ + --buildtype=release \ + --default-library=static \ + --prefix=/usr \ + -Dplugins="sed,lm,feat,zns,fdp" \ + -Dc_args="${cflags_str}" \ + -Dc_link_args="${ldflags_str}" \ + -Dfabrics=disabled \ + -Djson-c=disabled \ + -Dtests=false \ + -Dexamples=false \ + "${BUILDDIR}" +} + config_meson_libnvme() { CC="${CC}" "${MESON}" setup \ --werror \ diff --git a/scripts/release.sh b/scripts/release.sh index c05a2dc10d..5efeec2f4d 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -108,41 +108,6 @@ if [ "$build_doc" = true ]; then git commit -s -m "doc: Regenerate all docs for $VERSION" fi -declare -A ldscripts -ldscripts=( - [libnvme/src/libnvme.ld]=LIBNVME -) - -lib_ver="${ver//./_}" - -for ld_file in "${!ldscripts[@]}" -do - lib_name=${ldscripts[$ld_file]} - - if [ ! -f "${ld_file}" ]; then - continue - fi - - lib_unreleased="${lib_name}_UNRELEASED" - - # Check if UNRELEASED has symbols - if ! awk -v lib_unreleased="$lib_unreleased" ' - $0 ~ "^"lib_unreleased { in_section = 1; next } - in_section && $0 ~ /\}/ { exit } - in_section && $0 !~ /^[[:space:]]*($|\/|\/\*|\*|#)/ { found = 1; exit } - END { exit !found } - ' "${ld_file}"; then - continue - fi - - sed -i \ - -e "s/^${lib_unreleased}\s*{/&\n};\n\n${lib_name}_${lib_ver} {/" \ - "$ld_file" - - git add "${ld_file}" - echo "${ld_file} updated." -done - # update meson.build sed -i -e "0,/[ \t]version: /s/\([ \t]version: \).*/\1\'$ver\',/" meson.build git add meson.build diff --git a/util/cleanup.h b/util/cleanup.h index 891490512a..6ef3e87673 100644 --- a/util/cleanup.h +++ b/util/cleanup.h @@ -45,12 +45,14 @@ static inline void cleanup_nvme_global_ctx(struct nvme_global_ctx **ctx) static inline DEFINE_CLEANUP_FUNC(cleanup_nvme_ctrl, nvme_ctrl_t, nvme_free_ctrl) #define _cleanup_nvme_ctrl_ __cleanup__(cleanup_nvme_ctrl) +#ifdef CONFIG_FABRICS static inline void free_uri(struct nvme_fabrics_uri **uri) { if (*uri) nvmf_free_uri(*uri); } #define _cleanup_uri_ __cleanup__(free_uri) +#endif static inline DEFINE_CLEANUP_FUNC(cleanup_file, FILE *, fclose) #define _cleanup_file_ __cleanup__(cleanup_file) diff --git a/util/types.h b/util/types.h index 4046d5c18c..c009f2f1fa 100644 --- a/util/types.h +++ b/util/types.h @@ -5,6 +5,8 @@ /* type conversion helpers */ #include +#include + #include #include